@raketa-cloud/admin 1.8.1 → 1.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -749,40 +749,6 @@ select {
749
749
  --tw-contain-style: ;
750
750
  }
751
751
 
752
- .container {
753
- width: 100%;
754
- }
755
-
756
- @media (min-width: 640px) {
757
- .container {
758
- max-width: 640px;
759
- }
760
- }
761
-
762
- @media (min-width: 768px) {
763
- .container {
764
- max-width: 768px;
765
- }
766
- }
767
-
768
- @media (min-width: 1024px) {
769
- .container {
770
- max-width: 1024px;
771
- }
772
- }
773
-
774
- @media (min-width: 1280px) {
775
- .container {
776
- max-width: 1280px;
777
- }
778
- }
779
-
780
- @media (min-width: 1536px) {
781
- .container {
782
- max-width: 1536px;
783
- }
784
- }
785
-
786
752
  /* Utils */
787
753
 
788
754
  .chip {
@@ -1600,10 +1566,22 @@ select {
1600
1566
  pointer-events: none;
1601
1567
  }
1602
1568
 
1569
+ .visible {
1570
+ visibility: visible;
1571
+ }
1572
+
1573
+ .collapse {
1574
+ visibility: collapse;
1575
+ }
1576
+
1603
1577
  .static {
1604
1578
  position: static;
1605
1579
  }
1606
1580
 
1581
+ .fixed {
1582
+ position: fixed;
1583
+ }
1584
+
1607
1585
  .absolute {
1608
1586
  position: absolute;
1609
1587
  }
@@ -1751,6 +1729,10 @@ select {
1751
1729
  display: inline-block;
1752
1730
  }
1753
1731
 
1732
+ .inline {
1733
+ display: inline;
1734
+ }
1735
+
1754
1736
  .flex {
1755
1737
  display: flex;
1756
1738
  }
@@ -1759,6 +1741,10 @@ select {
1759
1741
  display: inline-flex;
1760
1742
  }
1761
1743
 
1744
+ .\!table {
1745
+ display: table !important;
1746
+ }
1747
+
1762
1748
  .table {
1763
1749
  display: table;
1764
1750
  }
@@ -1898,6 +1884,10 @@ select {
1898
1884
  cursor: pointer;
1899
1885
  }
1900
1886
 
1887
+ .resize {
1888
+ resize: both;
1889
+ }
1890
+
1901
1891
  .flex-col {
1902
1892
  flex-direction: column;
1903
1893
  }
@@ -2257,6 +2247,14 @@ select {
2257
2247
  color: rgb(255 255 255 / var(--tw-text-opacity));
2258
2248
  }
2259
2249
 
2250
+ .underline {
2251
+ text-decoration-line: underline;
2252
+ }
2253
+
2254
+ .overline {
2255
+ text-decoration-line: overline;
2256
+ }
2257
+
2260
2258
  .opacity-10 {
2261
2259
  opacity: 0.1;
2262
2260
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raketa-cloud/admin",
3
- "version": "1.8.1",
3
+ "version": "1.8.4",
4
4
  "main": "src/index.js",
5
5
  "files": [
6
6
  "src/",
@@ -19,7 +19,7 @@
19
19
  "@tailwindcss/forms": "0.5.7",
20
20
  "@tailwindcss/typography": "0.5.13",
21
21
  "@types/node": "24.10.1",
22
- "jest": "30.2.0",
22
+ "jest": "30.3.0",
23
23
  "tailwindcss": "3.4.4",
24
24
  "typescript": "5.9.3"
25
25
  },
@@ -1,4 +1,4 @@
1
- import { dateToUTCISO8601String, toUTCISO8601String, toDateInput } from "../utils";
1
+ import { dateToUTCISO8601String, toDateInput } from "../utils";
2
2
  import RaketaClient from "./RaketaClient";
3
3
  import {
4
4
  ArticleByIdDocument,
@@ -58,6 +58,8 @@ export default class Articles extends RaketaClient {
58
58
  async listAll(query, locale, articleTypeSlug) {
59
59
  const vars = this.buildAllInput(query, locale);
60
60
 
61
+ vars.input.filters = this.formatDateFilters(vars.input.filters);
62
+
61
63
  const { miniArticles: items } = await this.query(MiniArticlesDocument, {
62
64
  input: {
63
65
  ...vars.input,
@@ -71,12 +73,7 @@ export default class Articles extends RaketaClient {
71
73
  async list(query, locale, articleTypeSlug) {
72
74
  const vars = this.buildListInput(query, locale);
73
75
 
74
- if (vars.input.filters.last_updated_from) {
75
- vars.input.filters.last_updated_from = toUTCISO8601String(vars.input.filters.last_updated_from);
76
- }
77
- if (vars.input.filters.last_updated_to) {
78
- vars.input.filters.last_updated_to = toUTCISO8601String(vars.input.filters.last_updated_to);
79
- }
76
+ vars.input.filters = this.formatDateFilters(vars.input.filters);
80
77
 
81
78
  const { articles: items } = await this.query(ArticlesDocument, {
82
79
  input: {
@@ -73,6 +73,8 @@ export default class Events extends RaketaClient {
73
73
  async listAll(query, locale, eventTypeSlug) {
74
74
  const vars = this.buildAllInput(query, locale);
75
75
 
76
+ vars.input.filters = this.formatDateFilters(vars.input.filters);
77
+
76
78
  const { miniEvents: items } = await this.query(MiniEventsDocument, {
77
79
  input: {
78
80
  ...vars.input,
@@ -86,12 +88,7 @@ export default class Events extends RaketaClient {
86
88
  async list(query, locale, eventTypeSlug) {
87
89
  const vars = this.buildListInput(query, locale);
88
90
 
89
- if (vars.input.filters.last_updated_from) {
90
- vars.input.filters.last_updated_from = toUTCISO8601String(vars.input.filters.last_updated_from);
91
- }
92
- if (vars.input.filters.last_updated_to) {
93
- vars.input.filters.last_updated_to = toUTCISO8601String(vars.input.filters.last_updated_to);
94
- }
91
+ vars.input.filters = this.formatDateFilters(vars.input.filters);
95
92
 
96
93
  const { events: items } = await this.query(EventsDocument, {
97
94
  input: {
@@ -1,4 +1,3 @@
1
- import { toUTCISO8601String } from "../utils";
2
1
  import RaketaClient from "./RaketaClient";
3
2
  import {
4
3
  ChangePageSlugDocument,
@@ -49,6 +48,8 @@ export default class Pages extends RaketaClient {
49
48
  async listAll(query, locale, pageTypeSlug) {
50
49
  const vars = this.buildAllInput(query, locale);
51
50
 
51
+ vars.input.filters = this.formatDateFilters(vars.input.filters);
52
+
52
53
  const { miniPages: items } = await this.query(MiniPagesDocument, {
53
54
  input: {
54
55
  ...vars.input,
@@ -62,16 +63,7 @@ export default class Pages extends RaketaClient {
62
63
  async list(query, locale, pageTypeSlug) {
63
64
  const vars = this.buildListInput(query, locale);
64
65
 
65
- if (vars.input.filters.last_updated_from) {
66
- vars.input.filters.last_updated_from = toUTCISO8601String(
67
- vars.input.filters.last_updated_from,
68
- );
69
- }
70
- if (vars.input.filters.last_updated_to) {
71
- vars.input.filters.last_updated_to = toUTCISO8601String(
72
- vars.input.filters.last_updated_to,
73
- );
74
- }
66
+ vars.input.filters = this.formatDateFilters(vars.input.filters);
75
67
 
76
68
  const { pages: items } = await this.query(PagesDocument, {
77
69
  input: {
@@ -1,4 +1,5 @@
1
1
  import { request } from "graphql-request";
2
+ import { toUTCISO8601String } from "../utils";
2
3
 
3
4
  function isObjectEmpty(obj) {
4
5
  for (const key in obj) {
@@ -217,6 +218,16 @@ export default class RaketaClient {
217
218
  return variables;
218
219
  }
219
220
 
221
+ formatDateFilters(filters) {
222
+ if (filters.last_updated_from) {
223
+ filters.last_updated_from = toUTCISO8601String(filters.last_updated_from);
224
+ }
225
+ if (filters.last_updated_to) {
226
+ filters.last_updated_to = toUTCISO8601String(filters.last_updated_to);
227
+ }
228
+ return filters;
229
+ }
230
+
220
231
  deepMerge(target, source) {
221
232
  return parseJsonFields(deepMerge(structuredClone(target), source));
222
233
  }
@@ -18,7 +18,7 @@ const exportCSV = async (ctx) => {
18
18
  const csv = CSVExportHelper.formatDataAsCSV(
19
19
  pages.list,
20
20
  headers,
21
- fieldMapping
21
+ fieldMapping,
22
22
  );
23
23
 
24
24
  return {
@@ -151,6 +151,9 @@ describe("HonoAdapter", () => {
151
151
  cloud: {
152
152
  images_api_key: "api-key",
153
153
  },
154
+ remoteConfig: {
155
+ remoteLogin: "",
156
+ },
154
157
  },
155
158
  },
156
159
  },
@@ -7,7 +7,7 @@
7
7
  <%- f.field('publishing.type', { as: 'radio_group', label: "", options: [["now", "Publish now"], ["later", "Schedule for a date"]] }) %>
8
8
  <%- f.field('publishing.mergeAt', { type: 'datetime-local', label: 'Publish revision at (UTC)' }) %>
9
9
 
10
- <%- f.field('publishing.title'), { required: true, hint: "Appears in the history of changes" } %>
10
+ <%- f.field('publishing.title', { required: true, hint: "Appears in the history of changes" }) %>
11
11
  <%- f.field('publishing.description', { as: "textarea", hint: "Provide optional details" }) %>
12
12
  <%- f.field('publishing.visibility', { as: 'select', required: true, options: visibilityOptions }) %>
13
13
  <%- f.field('publishing.username', { required: true }) %>
@@ -0,0 +1,8 @@
1
+ <div class="body-3 text-raketa-foreground/50">
2
+ <div class="flex items-center gap-1" title="<%= revision.meta.operatorMeta.name %>">
3
+ <% if (revision.meta.operatorMeta.avatar) { %>
4
+ <img src="<%= revision.meta.operatorMeta.avatar %>" class="rounded-full size-4">
5
+ <% } %>
6
+ <%= revision.meta.operatorMeta.name %>
7
+ </div>
8
+ </div>
@@ -143,7 +143,9 @@
143
143
 
144
144
  <div class="mb-4">
145
145
  <label for="widget" class="font-semibold hover:cursor-pointer body-3">Widget</label>
146
- <input type="text" name="f:widget" value="<%= _context.query["f:widget"] %>" />
146
+ <select name="f:widget" data-widget-filter data-current-value="<%= _context.query['f:widget'] || '' %>">
147
+ <option value="">All widgets</option>
148
+ </select>
147
149
  </div>
148
150
 
149
151
  <div class="mb-4">
@@ -86,14 +86,7 @@
86
86
  </td>
87
87
 
88
88
  <td class="whitespace-nowrap">
89
- <div class="body-3 text-raketa-foreground/50">
90
- <div class="flex items-center gap-1" title="<%= revision.meta.operatorMeta.name %>">
91
- <% if (revision.meta.operatorMeta.avatar) { %>
92
- <img src="<%= revision.meta.operatorMeta.avatar %>" class="size-4 rounded-full">
93
- <% } %>
94
- <%= revision.meta.operatorMeta.name %>
95
- </div>
96
- </div>
89
+ <%- render_partial('./_shared/_revision_operator.ejs', { revision }) %>
97
90
  </td>
98
91
 
99
92
  <td class="whitespace-nowrap">
@@ -150,14 +143,7 @@
150
143
  </td>
151
144
 
152
145
  <td class="whitespace-nowrap">
153
- <div class="body-3 text-raketa-foreground/50">
154
- <div class="flex items-center gap-1" title="<%= revision.meta.operatorMeta.name %>">
155
- <% if (revision.meta.operatorMeta.avatar) { %>
156
- <img src="<%= revision.meta.operatorMeta.avatar %>" class="size-4 rounded-full">
157
- <% } %>
158
- <%= revision.meta.operatorMeta.name %>
159
- </div>
160
- </div>
146
+ <%- render_partial('./_shared/_revision_operator.ejs', { revision }) %>
161
147
  </td>
162
148
 
163
149
  <td class="whitespace-nowrap">
@@ -7,7 +7,7 @@
7
7
  <%- f.field('publishing.type', { as: 'radio_group', label: "", options: [["now", "Publish now"], ["later", "Schedule for a date"]] }) %>
8
8
  <%- f.field('publishing.mergeAt', { type: 'datetime-local', label: 'Publish revision at (UTC)' }) %>
9
9
 
10
- <%- f.field('publishing.title'), { required: true, hint: "Appears in the history of changes" } %>
10
+ <%- f.field('publishing.title', { required: true, hint: "Appears in the history of changes" }) %>
11
11
  <%- f.field('publishing.description', { as: "textarea", hint: "Provide optional details" }) %>
12
12
  <%- f.field('publishing.visibility', { as: 'select', required: true, options: visibilityOptions }) %>
13
13
  <%- f.field('publishing.username', { required: true }) %>
@@ -0,0 +1,8 @@
1
+ <div class="body-3 text-raketa-foreground/50">
2
+ <div class="flex items-center gap-1" title="<%= revision.meta.operatorMeta.name %>">
3
+ <% if (revision.meta.operatorMeta.avatar) { %>
4
+ <img src="<%= revision.meta.operatorMeta.avatar %>" class="rounded-full size-4">
5
+ <% } %>
6
+ <%= revision.meta.operatorMeta.name %>
7
+ </div>
8
+ </div>
@@ -143,7 +143,9 @@
143
143
 
144
144
  <div class="mb-4">
145
145
  <label for="widget" class="font-semibold hover:cursor-pointer body-3">Widget</label>
146
- <input type="text" name="f:widget" value="<%= _context.query["f:widget"] %>" />
146
+ <select name="f:widget" data-widget-filter data-current-value="<%= _context.query['f:widget'] || '' %>">
147
+ <option value="">All widgets</option>
148
+ </select>
147
149
  </div>
148
150
 
149
151
  <div class="mb-4">
@@ -86,14 +86,7 @@
86
86
  </td>
87
87
 
88
88
  <td class="whitespace-nowrap">
89
- <div class="body-3 text-raketa-foreground/50">
90
- <div class="flex items-center gap-1" title="<%= revision.meta.operatorMeta.name %>">
91
- <% if (revision.meta.operatorMeta.avatar) { %>
92
- <img src="<%= revision.meta.operatorMeta.avatar %>" class="size-4 rounded-full">
93
- <% } %>
94
- <%= revision.meta.operatorMeta.name %>
95
- </div>
96
- </div>
89
+ <%- render_partial('./_shared/_revision_operator.ejs', { revision }) %>
97
90
  </td>
98
91
 
99
92
  <td class="whitespace-nowrap">
@@ -150,14 +143,7 @@
150
143
  </td>
151
144
 
152
145
  <td class="whitespace-nowrap">
153
- <div class="body-3 text-raketa-foreground/50">
154
- <div class="flex items-center gap-1" title="<%= revision.meta.operatorMeta.name %>">
155
- <% if (revision.meta.operatorMeta.avatar) { %>
156
- <img src="<%= revision.meta.operatorMeta.avatar %>" class="size-4 rounded-full">
157
- <% } %>
158
- <%= revision.meta.operatorMeta.name %>
159
- </div>
160
- </div>
146
+ <%- render_partial('./_shared/_revision_operator.ejs', { revision }) %>
161
147
  </td>
162
148
 
163
149
  <td class="whitespace-nowrap">
@@ -38,6 +38,9 @@
38
38
  var FILE_PICKER_GATEWAY_PROJECT = "<%= _context.globalConfig.cloud.gateway_project %>";
39
39
  var FILE_PICKER_DXP_PRIVATE_SERVICE = "<%= _context.globalConfig.cloud.dxp_service_private %>";
40
40
  var FILE_PICKER_JWT_TOKEN = "<%= _context.adminJwt %>";
41
+ var FRONTEND_URL = (function() {
42
+ try { return new URL("<%= _context.globalConfig.remoteConfig.remoteLogin %>").origin; } catch(e) { return ""; }
43
+ })();
41
44
  </script>
42
45
 
43
46
  <script src="https://storage.googleapis.com/cdn-raketa-cloud/js/raketa-file-picker-webcomponent.umd.js"></script>
@@ -281,6 +284,33 @@
281
284
  }
282
285
  </script>
283
286
 
287
+ <script>
288
+ function initWidgetFilter() {
289
+ var selects = document.querySelectorAll('select[data-widget-filter]');
290
+ if (!selects.length || !FRONTEND_URL) return;
291
+
292
+ fetch(FRONTEND_URL + '/dxp__/widgets/list.json')
293
+ .then(function(response) { return response.text(); })
294
+ .then(function(html) {
295
+ var doc = new DOMParser().parseFromString(html, 'text/html');
296
+ var widgets = JSON.parse(doc.querySelector('pre').textContent);
297
+ selects.forEach(function(select) {
298
+ var currentValue = select.dataset.currentValue;
299
+ widgets.forEach(function(widget) {
300
+ var option = document.createElement('option');
301
+ option.value = widget[0];
302
+ option.textContent = widget[1];
303
+ if (widget[0] === currentValue) option.selected = true;
304
+ select.appendChild(option);
305
+ });
306
+ });
307
+ })
308
+ .catch(function(err) { console.error('[initWidgetFilter] failed:', err); });
309
+ }
310
+
311
+ initWidgetFilter();
312
+ </script>
313
+
284
314
  <script>
285
315
  const forms = document.querySelectorAll('form');
286
316
 
@@ -7,7 +7,7 @@
7
7
  <%- f.field('publishing.type', { as: 'radio_group', label: "", options: [["now", "Publish now"], ["later", "Schedule for a date"]] }) %>
8
8
  <%- f.field('publishing.mergeAt', { type: 'datetime-local', label: 'Publish revision at (UTC)' }) %>
9
9
 
10
- <%- f.field('publishing.title'), { required: true, hint: "Appears in the history of changes" } %>
10
+ <%- f.field('publishing.title', { required: true, hint: "Appears in the history of changes" }) %>
11
11
  <%- f.field('publishing.description', { as: "textarea", hint: "Provide optional details" }) %>
12
12
  <%- f.field('publishing.visibility', { as: 'select', required: true, options: visibilityOptions }) %>
13
13
  <%- f.field('publishing.username', { required: true }) %>
@@ -0,0 +1,8 @@
1
+ <div class="body-3 text-raketa-foreground/50">
2
+ <div class="flex items-center gap-1" title="<%= revision.meta.operatorMeta.name %>">
3
+ <% if (revision.meta.operatorMeta.avatar) { %>
4
+ <img src="<%= revision.meta.operatorMeta.avatar %>" class="rounded-full size-4">
5
+ <% } %>
6
+ <%= revision.meta.operatorMeta.name %>
7
+ </div>
8
+ </div>
@@ -138,7 +138,9 @@
138
138
 
139
139
  <div class="mb-4">
140
140
  <label for="widget" class="font-semibold hover:cursor-pointer body-3">Widget</label>
141
- <input type="text" name="f:widget" value="<%= _context.query["f:widget"] %>" />
141
+ <select name="f:widget" data-widget-filter data-current-value="<%= _context.query['f:widget'] || '' %>">
142
+ <option value="">All widgets</option>
143
+ </select>
142
144
  </div>
143
145
 
144
146
  <div class="mb-4">
@@ -86,14 +86,7 @@
86
86
  </td>
87
87
 
88
88
  <td class="whitespace-nowrap">
89
- <div class="body-3 text-raketa-foreground/50">
90
- <div class="flex items-center gap-1" title="<%= revision.meta.operatorMeta.name %>">
91
- <% if (revision.meta.operatorMeta.avatar) { %>
92
- <img src="<%= revision.meta.operatorMeta.avatar %>" class="rounded-full size-4">
93
- <% } %>
94
- <%= revision.meta.operatorMeta.name %>
95
- </div>
96
- </div>
89
+ <%- render_partial('./_shared/_revision_operator.ejs', { revision }) %>
97
90
  </td>
98
91
 
99
92
  <td class="whitespace-nowrap">
@@ -150,14 +143,7 @@
150
143
  </td>
151
144
 
152
145
  <td class="whitespace-nowrap">
153
- <div class="body-3 text-raketa-foreground/50">
154
- <div class="flex items-center gap-1" title="<%= revision.meta.operatorMeta.name %>">
155
- <% if (revision.meta.operatorMeta.avatar) { %>
156
- <img src="<%= revision.meta.operatorMeta.avatar %>" class="rounded-full size-4">
157
- <% } %>
158
- <%= revision.meta.operatorMeta.name %>
159
- </div>
160
- </div>
146
+ <%- render_partial('./_shared/_revision_operator.ejs', { revision }) %>
161
147
  </td>
162
148
 
163
149
  <td class="whitespace-nowrap">