@raketa-cloud/admin 1.7.6 → 1.7.9
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.
- package/package.json +1 -1
- package/src/HonoAdapter.js +3 -0
- package/src/cloud/documents/articlesDocuments.js +1 -0
- package/src/cloud/documents/eventsDocuments.js +1 -0
- package/src/cloud/documents/pagesDocuments.js +1 -0
- package/src/handlers/pages/ExportsHandler.js +1 -1
- package/src/helpers/CSVExportHelper.js +6 -0
- package/src/tests/handlers/articles/ExportsHandler.test/index.test.js +1 -1
- package/src/tests/handlers/events/ExportsHandler.test/index.test.js +1 -1
- package/src/tests/handlers/pages/ExportsHandler.test/index.test.js +1 -1
- package/src/tests/helpers/CSVExportHelper.test.js +8 -2
- package/src/views/_shared/_translations_search_input.ejs +31 -0
- package/src/views/_shared/_visibility_search_input.ejs +30 -0
- package/src/views/articles/index.ejs +3 -15
- package/src/views/events/index.ejs +3 -15
- package/src/views/layouts/application.ejs +8 -15
- package/src/views/pages/index.ejs +3 -15
package/package.json
CHANGED
package/src/HonoAdapter.js
CHANGED
|
@@ -319,6 +319,9 @@ export default class HonoAdapter {
|
|
|
319
319
|
// Build context object
|
|
320
320
|
const _context = {
|
|
321
321
|
timezones: i18n.timezones,
|
|
322
|
+
timeLocale: i18n.timeLocale,
|
|
323
|
+
dateTimeFormat: i18n.dateTimeFormat,
|
|
324
|
+
dateFormat: i18n.dateFormat,
|
|
322
325
|
locales: ctx.locales,
|
|
323
326
|
locale: ctx.locale,
|
|
324
327
|
defaultLocale: ctx.defaultLocale,
|
|
@@ -72,6 +72,10 @@ const extractResourceType = (resource, type) => {
|
|
|
72
72
|
return type;
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
+
function formatTranslations(item) {
|
|
76
|
+
return Object.keys(item?.translations || {}).map(locale => locale).join(";")
|
|
77
|
+
}
|
|
78
|
+
|
|
75
79
|
const standardFieldMapping = (remoteConfig, locale, type) => ({
|
|
76
80
|
id: "id",
|
|
77
81
|
type: (item) => extractResourceType(item, type),
|
|
@@ -81,6 +85,7 @@ const standardFieldMapping = (remoteConfig, locale, type) => ({
|
|
|
81
85
|
visibility: "visibility",
|
|
82
86
|
created_at: "insertedAt",
|
|
83
87
|
updated_at: "updatedAt",
|
|
88
|
+
translations: formatTranslations
|
|
84
89
|
});
|
|
85
90
|
|
|
86
91
|
const standardHeaders = [
|
|
@@ -92,6 +97,7 @@ const standardHeaders = [
|
|
|
92
97
|
"visibility",
|
|
93
98
|
"created_at",
|
|
94
99
|
"updated_at",
|
|
100
|
+
"translations"
|
|
95
101
|
];
|
|
96
102
|
|
|
97
103
|
export default {
|
|
@@ -144,7 +144,7 @@ describe("Articles ExportsHandler", () => {
|
|
|
144
144
|
const result = await ExportsHandler.index(ctx);
|
|
145
145
|
|
|
146
146
|
expect(result.text).toBe(
|
|
147
|
-
"id,type,locale,title,URL,visibility,created_at,updated_at",
|
|
147
|
+
"id,type,locale,title,URL,visibility,created_at,updated_at,translations",
|
|
148
148
|
);
|
|
149
149
|
});
|
|
150
150
|
|
|
@@ -143,7 +143,7 @@ describe("Events ExportsHandler", () => {
|
|
|
143
143
|
const result = await ExportsHandler.index(ctx);
|
|
144
144
|
|
|
145
145
|
expect(result.text).toBe(
|
|
146
|
-
"id,type,locale,title,URL,visibility,created_at,updated_at",
|
|
146
|
+
"id,type,locale,title,URL,visibility,created_at,updated_at,translations",
|
|
147
147
|
);
|
|
148
148
|
});
|
|
149
149
|
|
|
@@ -143,7 +143,7 @@ describe("Pages ExportsHandler", () => {
|
|
|
143
143
|
const result = await ExportsHandler.index(ctx);
|
|
144
144
|
|
|
145
145
|
expect(result.text).toBe(
|
|
146
|
-
"id,type,locale,title,URL,visibility,created_at,updated_at",
|
|
146
|
+
"id,type,locale,title,URL,visibility,created_at,updated_at,translations",
|
|
147
147
|
);
|
|
148
148
|
});
|
|
149
149
|
|
|
@@ -206,6 +206,10 @@ describe("CSVExportHelper", () => {
|
|
|
206
206
|
visibility: "public",
|
|
207
207
|
insertedAt: "2024-01-01",
|
|
208
208
|
updatedAt: "2024-01-02",
|
|
209
|
+
translations: {
|
|
210
|
+
es: {},
|
|
211
|
+
de: {}
|
|
212
|
+
}
|
|
209
213
|
},
|
|
210
214
|
];
|
|
211
215
|
const headers = [...CSVExportHelper.standardHeaders];
|
|
@@ -222,8 +226,8 @@ describe("CSVExportHelper", () => {
|
|
|
222
226
|
);
|
|
223
227
|
|
|
224
228
|
expect(result).toBe(
|
|
225
|
-
"id,type,locale,title,URL,visibility,created_at,updated_at\r\n" +
|
|
226
|
-
"1,article,en,Test Article,/en/article/1,public,2024-01-01,2024-01-02",
|
|
229
|
+
"id,type,locale,title,URL,visibility,created_at,updated_at,translations\r\n" +
|
|
230
|
+
"1,article,en,Test Article,/en/article/1,public,2024-01-01,2024-01-02,es;de",
|
|
227
231
|
);
|
|
228
232
|
});
|
|
229
233
|
});
|
|
@@ -297,6 +301,7 @@ describe("CSVExportHelper", () => {
|
|
|
297
301
|
visibility: "visibility",
|
|
298
302
|
created_at: "insertedAt",
|
|
299
303
|
updated_at: "updatedAt",
|
|
304
|
+
translations: expect.any(Function),
|
|
300
305
|
});
|
|
301
306
|
});
|
|
302
307
|
|
|
@@ -358,6 +363,7 @@ describe("CSVExportHelper", () => {
|
|
|
358
363
|
"visibility",
|
|
359
364
|
"created_at",
|
|
360
365
|
"updated_at",
|
|
366
|
+
"translations"
|
|
361
367
|
]);
|
|
362
368
|
});
|
|
363
369
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<div class="mb-4">
|
|
2
|
+
<label for="" class="font-semibold hover:cursor-pointer body-3">Translations</label>
|
|
3
|
+
<div class="checkbox-group mb-4">
|
|
4
|
+
<% translations.filter(item => item.code !== _context.locale).forEach((item,idx)=> { %>
|
|
5
|
+
<div class="flex items-center gap-1">
|
|
6
|
+
<% if (utils.includedInCollection(item.code, _context.query["f:translations"])) { %>
|
|
7
|
+
<input type="checkbox" name="f:translations" id='locale-<%= item.code %>' checked value="<%= item.code %>" class="hover:cursor-pointer">
|
|
8
|
+
<% } else { %>
|
|
9
|
+
<input type="checkbox" name="f:translations" id='locale-<%= item.code %>' value="<%= item.code %>" class="hover:cursor-pointer">
|
|
10
|
+
<% } %>
|
|
11
|
+
<label for='locale-<%= item.code %>' class="body-2 hover:cursor-pointer"><%= item.name %></label>
|
|
12
|
+
</div>
|
|
13
|
+
<% }); %>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div class="mb-4">
|
|
18
|
+
<label for="" class="font-semibold hover:cursor-pointer body-3">Without translations</label>
|
|
19
|
+
<div class="checkbox-group mb-4">
|
|
20
|
+
<% translations.filter(item => item.code !== _context.locale).forEach((item,idx)=> { %>
|
|
21
|
+
<div class="flex items-center gap-1">
|
|
22
|
+
<% if (utils.includedInCollection(item.code, _context.query["f:without_translations"])) { %>
|
|
23
|
+
<input type="checkbox" name="f:without_translations" id='n-locale-<%= item.code %>' checked value="<%= item.code %>" class="hover:cursor-pointer">
|
|
24
|
+
<% } else { %>
|
|
25
|
+
<input type="checkbox" name="f:without_translations" id='n-locale-<%= item.code %>' value="<%= item.code %>" class="hover:cursor-pointer">
|
|
26
|
+
<% } %>
|
|
27
|
+
<label for='n-locale-<%= item.code %>' class="body-2 hover:cursor-pointer"><%= item.name %></label>
|
|
28
|
+
</div>
|
|
29
|
+
<% }); %>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<div class="mb-4">
|
|
2
|
+
<label for="visibility" class="font-semibold hover:cursor-pointer body-3">Visibility</label>
|
|
3
|
+
<select name="f:visibility">
|
|
4
|
+
<option value="">Please select...</option>
|
|
5
|
+
|
|
6
|
+
<% if (_context.query["f:visibility"] === "PRIVATE") { %>
|
|
7
|
+
<option value="PRIVATE" selected>Private</option>
|
|
8
|
+
<% } else { %>
|
|
9
|
+
<option value="PRIVATE">Private</option>
|
|
10
|
+
<% } %>
|
|
11
|
+
|
|
12
|
+
<% if (_context.query["f:visibility"] === "PUBLIC") { %>
|
|
13
|
+
<option value="PUBLIC" selected>Public</option>
|
|
14
|
+
<% } else { %>
|
|
15
|
+
<option value="PUBLIC">Public</option>
|
|
16
|
+
<% } %>
|
|
17
|
+
|
|
18
|
+
<% if (_context.query["f:visibility"] === "UNLISTED") { %>
|
|
19
|
+
<option value="UNLISTED" selected>Unlisted</option>
|
|
20
|
+
<% } else { %>
|
|
21
|
+
<option value="UNLISTED">Unlisted</option>
|
|
22
|
+
<% } %>
|
|
23
|
+
|
|
24
|
+
<% if (_context.query["f:visibility"] === "PROTECTED") { %>
|
|
25
|
+
<option value="PROTECTED" selected>Protected</option>
|
|
26
|
+
<% } else { %>
|
|
27
|
+
<option value="PROTECTED">Protected</option>
|
|
28
|
+
<% } %>
|
|
29
|
+
</select>
|
|
30
|
+
</div>
|
|
@@ -139,6 +139,8 @@
|
|
|
139
139
|
<input type="text" name="f:keyword" value="<%= _context.query["f:keyword"] %>" />
|
|
140
140
|
</div>
|
|
141
141
|
|
|
142
|
+
<%- include('./../_shared/_visibility_search_input.ejs') %>
|
|
143
|
+
|
|
142
144
|
<div class="mb-4">
|
|
143
145
|
<label for="widget" class="font-semibold hover:cursor-pointer body-3">Widget</label>
|
|
144
146
|
<input type="text" name="f:widget" value="<%= _context.query["f:widget"] %>" />
|
|
@@ -159,21 +161,7 @@
|
|
|
159
161
|
<input type="datetime-local" name="f:last_updated_to" value="<%= _context.query["f:last_updated_to"] %>" data-no-hints="true" />
|
|
160
162
|
</div>
|
|
161
163
|
|
|
162
|
-
|
|
163
|
-
<label for="" class="font-semibold hover:cursor-pointer body-3">Translations</label>
|
|
164
|
-
<div class="checkbox-group mb-4">
|
|
165
|
-
<% translations.filter(item => item.code !== _context.locale).forEach((item,idx)=> { %>
|
|
166
|
-
<div class="flex items-center gap-1">
|
|
167
|
-
<% if (utils.includedInCollection(item.code, _context.query["f:translations"])) { %>
|
|
168
|
-
<input type="checkbox" name="f:translations" id='locale-<%= item.code %>' checked value="<%= item.code %>" class="hover:cursor-pointer">
|
|
169
|
-
<% } else { %>
|
|
170
|
-
<input type="checkbox" name="f:translations" id='locale-<%= item.code %>' value="<%= item.code %>" class="hover:cursor-pointer">
|
|
171
|
-
<% } %>
|
|
172
|
-
<label for='locale-<%= item.code %>' class="body-2 hover:cursor-pointer"><%= item.name %></label>
|
|
173
|
-
</div>
|
|
174
|
-
<% }); %>
|
|
175
|
-
</div>
|
|
176
|
-
</div>
|
|
164
|
+
<%- include('./../_shared/_translations_search_input.ejs') %>
|
|
177
165
|
|
|
178
166
|
<div class="mb-4">
|
|
179
167
|
<label for="" class="font-semibold hover:cursor-pointer body-3">Tags</label>
|
|
@@ -139,6 +139,8 @@
|
|
|
139
139
|
<input type="text" name="f:keyword" value="<%= _context.query["f:keyword"] %>" />
|
|
140
140
|
</div>
|
|
141
141
|
|
|
142
|
+
<%- include('./../_shared/_visibility_search_input.ejs') %>
|
|
143
|
+
|
|
142
144
|
<div class="mb-4">
|
|
143
145
|
<label for="widget" class="font-semibold hover:cursor-pointer body-3">Widget</label>
|
|
144
146
|
<input type="text" name="f:widget" value="<%= _context.query["f:widget"] %>" />
|
|
@@ -159,21 +161,7 @@
|
|
|
159
161
|
<input type="datetime-local" name="f:last_updated_to" value="<%= _context.query["f:last_updated_to"] %>" />
|
|
160
162
|
</div>
|
|
161
163
|
|
|
162
|
-
|
|
163
|
-
<label for="" class="font-semibold hover:cursor-pointer body-3">Translations</label>
|
|
164
|
-
<div class="checkbox-group mb-4">
|
|
165
|
-
<% translations.filter(item => item.code !== _context.locale).forEach((item,idx)=> { %>
|
|
166
|
-
<div class="flex items-center gap-1">
|
|
167
|
-
<% if (utils.includedInCollection(item.code, _context.query["f:translations"])) { %>
|
|
168
|
-
<input type="checkbox" name="f:translations" id='locale-<%= item.code %>' checked value="<%= item.code %>" class="hover:cursor-pointer">
|
|
169
|
-
<% } else { %>
|
|
170
|
-
<input type="checkbox" name="f:translations" id='locale-<%= item.code %>' value="<%= item.code %>" class="hover:cursor-pointer">
|
|
171
|
-
<% } %>
|
|
172
|
-
<label for='locale-<%= item.code %>' class="body-2 hover:cursor-pointer"><%= item.name %></label>
|
|
173
|
-
</div>
|
|
174
|
-
<% }); %>
|
|
175
|
-
</div>
|
|
176
|
-
</div>
|
|
164
|
+
<%- include('./../_shared/_translations_search_input.ejs') %>
|
|
177
165
|
|
|
178
166
|
<div class="mb-4">
|
|
179
167
|
<label for="" class="font-semibold hover:cursor-pointer body-3">Tags</label>
|
|
@@ -143,7 +143,6 @@
|
|
|
143
143
|
<%- body %>
|
|
144
144
|
</div>
|
|
145
145
|
|
|
146
|
-
|
|
147
146
|
<script>
|
|
148
147
|
const toggleEl = document.getElementById('expand');
|
|
149
148
|
const sidebarEl = document.getElementById('sidebar');
|
|
@@ -163,8 +162,10 @@
|
|
|
163
162
|
</script>
|
|
164
163
|
|
|
165
164
|
<script>
|
|
166
|
-
// Don't ask
|
|
167
165
|
const TIMEZONES = JSON.parse("<%= JSON.stringify(_context.timezones) %>".replaceAll(""", '"'))
|
|
166
|
+
const TIME_LOCALE = JSON.parse("<%= JSON.stringify(_context.timeLocale || 'en-GB') %>".replaceAll(""", '"'))
|
|
167
|
+
const TIME_FORMAT = JSON.parse("<%= JSON.stringify(_context.dateTimeFormat || { dateStyle: 'short', timeStyle: 'short' }) %>".replaceAll(""", '"'))
|
|
168
|
+
const DATE_FORMAT = JSON.parse("<%= JSON.stringify(_context.dateFormat || { dateStyle: 'short' }) %>".replaceAll(""", '"'))
|
|
168
169
|
|
|
169
170
|
function enhanceDateTimeInputs(input) {
|
|
170
171
|
// skew the date so it is like in UTC for the user...
|
|
@@ -176,7 +177,7 @@
|
|
|
176
177
|
parent.querySelectorAll('[data-auto="1"]').forEach(node => node.remove())
|
|
177
178
|
|
|
178
179
|
// Add user's localtime
|
|
179
|
-
const strTime = fakeUTCDate.toLocaleString(
|
|
180
|
+
const strTime = fakeUTCDate.toLocaleString(TIME_LOCALE, {});
|
|
180
181
|
|
|
181
182
|
const hint = document.createElement("div");
|
|
182
183
|
|
|
@@ -187,7 +188,7 @@
|
|
|
187
188
|
parent.appendChild(hint)
|
|
188
189
|
|
|
189
190
|
TIMEZONES.forEach(timeZone => {
|
|
190
|
-
const strTime = fakeUTCDate.toLocaleString(
|
|
191
|
+
const strTime = fakeUTCDate.toLocaleString(TIME_LOCALE, {
|
|
191
192
|
timeZone: `${timeZone.value}`
|
|
192
193
|
});
|
|
193
194
|
|
|
@@ -239,18 +240,13 @@
|
|
|
239
240
|
document.querySelectorAll('time[data-pretty-datetime]').forEach(item => {
|
|
240
241
|
const dateStr = item.getAttribute("datetime");
|
|
241
242
|
|
|
242
|
-
item.innerText = new Date(dateStr).toLocaleString(
|
|
243
|
-
dateStyle: "short",
|
|
244
|
-
timeStyle: "short"
|
|
245
|
-
})
|
|
243
|
+
item.innerText = new Date(dateStr).toLocaleString(TIME_LOCALE, TIME_FORMAT)
|
|
246
244
|
})
|
|
247
245
|
|
|
248
246
|
document.querySelectorAll('time[data-pretty-date]').forEach(item => {
|
|
249
247
|
const dateStr = item.getAttribute("datetime");
|
|
250
248
|
|
|
251
|
-
item.innerText = new Date(dateStr).toLocaleString(
|
|
252
|
-
dateStyle: "short"
|
|
253
|
-
})
|
|
249
|
+
item.innerText = new Date(dateStr).toLocaleString(TIME_LOCALE, DATE_FORMAT)
|
|
254
250
|
})
|
|
255
251
|
|
|
256
252
|
document.querySelectorAll('time[data-pretty-expiration-time]').forEach(item => {
|
|
@@ -258,10 +254,7 @@
|
|
|
258
254
|
|
|
259
255
|
const expTime = new Date(dateStr)
|
|
260
256
|
|
|
261
|
-
item.innerText = expTime.toLocaleString(
|
|
262
|
-
dateStyle: "short",
|
|
263
|
-
timeStyle: "short"
|
|
264
|
-
})
|
|
257
|
+
item.innerText = expTime.toLocaleString(TIME_LOCALE, TIME_FORMAT)
|
|
265
258
|
|
|
266
259
|
if (new Date() > expTime) {
|
|
267
260
|
item.style.color = 'red';
|
|
@@ -134,6 +134,8 @@
|
|
|
134
134
|
<input type="text" name="f:keyword" value="<%= _context.query["f:keyword"] %>" />
|
|
135
135
|
</div>
|
|
136
136
|
|
|
137
|
+
<%- include('./../_shared/_visibility_search_input.ejs') %>
|
|
138
|
+
|
|
137
139
|
<div class="mb-4">
|
|
138
140
|
<label for="widget" class="font-semibold hover:cursor-pointer body-3">Widget</label>
|
|
139
141
|
<input type="text" name="f:widget" value="<%= _context.query["f:widget"] %>" />
|
|
@@ -154,21 +156,7 @@
|
|
|
154
156
|
<input type="datetime-local" name="f:last_updated_to" value="<%= _context.query["f:last_updated_to"] %>" />
|
|
155
157
|
</div>
|
|
156
158
|
|
|
157
|
-
|
|
158
|
-
<label for="" class="font-semibold hover:cursor-pointer body-3">Translations</label>
|
|
159
|
-
<div class="checkbox-group mb-4">
|
|
160
|
-
<% translations.filter(item => item.code !== _context.locale).forEach((item,idx)=> { %>
|
|
161
|
-
<div class="flex items-center gap-1">
|
|
162
|
-
<% if (utils.includedInCollection(item.code, _context.query["f:translations"])) { %>
|
|
163
|
-
<input type="checkbox" name="f:translations" id='locale-<%= item.code %>' checked value="<%= item.code %>" class="hover:cursor-pointer">
|
|
164
|
-
<% } else { %>
|
|
165
|
-
<input type="checkbox" name="f:translations" id='locale-<%= item.code %>' value="<%= item.code %>" class="hover:cursor-pointer">
|
|
166
|
-
<% } %>
|
|
167
|
-
<label for='locale-<%= item.code %>' class="body-2 hover:cursor-pointer"><%= item.name %></label>
|
|
168
|
-
</div>
|
|
169
|
-
<% }); %>
|
|
170
|
-
</div>
|
|
171
|
-
</div>
|
|
159
|
+
<%- include('./../_shared/_translations_search_input.ejs') %>
|
|
172
160
|
|
|
173
161
|
<div class="mb-4">
|
|
174
162
|
<label for="" class="font-semibold hover:cursor-pointer body-3">Tags</label>
|