@raketa-cloud/admin 1.8.18 → 1.8.20
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/dist/application.css +288 -11
- package/package.json +8 -6
- package/src/cloud/Resources.js +16 -4
- package/src/handlers/resources/ReportsAPIHandler.js +27 -0
- package/src/handlers/resources/ResourcesHandler.js +16 -0
- package/src/handlers/resources/TranslationsHandler.js +1 -1
- package/src/helpers/reports/cwv.js +217 -0
- package/src/helpers/reports/googleAuth.js +149 -0
- package/src/helpers/reports/quick-insights.js +294 -0
- package/src/helpers/reports/reportsUtils.js +181 -0
- package/src/index.js +8 -0
- package/src/localCache.js +112 -0
- package/src/report/analytics.js +107 -0
- package/src/report/reports.js +390 -0
- package/src/routeAssets.js +74 -0
- package/src/routeResourceModule.js +24 -0
- package/src/routeStandard.js +7 -1
- package/src/styles/application.css +1 -1
- package/src/tests/handlers/RedirectsHandler.test/notes.test.js +56 -0
- package/src/tests/handlers/_shared/SettingsHandler.test/global_variables.test.js +54 -0
- package/src/tests/handlers/categories/update_defaults.test.js +35 -0
- package/src/tests/handlers/content_tasks/ContentTasksHandler.test/editors.test.js +29 -0
- package/src/tests/handlers/resource_revisions/PublishesHandler.test/schedule.test.js +137 -0
- package/src/tests/handlers/resource_revisions/TagHandler.test/default_locale_tags.test.js +162 -0
- package/src/tests/handlers/resource_revisions/WidgetHandler.test/defaults.test.js +61 -0
- package/src/tests/handlers/resources/DeletesHandler.test/no_redirect.test.js +55 -0
- package/src/tests/handlers/resources/ReportsAPIHandler.test/show.test.js +156 -0
- package/src/tests/handlers/resources/ResourcesHandler.test/show.test.js +8 -0
- package/src/tests/handlers/resources/ResourcesHandler.test/show_reports.test.js +94 -0
- package/src/tests/handlers/resources/TranslationsHandler.test/edge_cases.test.js +213 -0
- package/src/tests/helpers/CSVExportHelper.branches.test.js +57 -0
- package/src/tests/helpers/FormBuilder.branches.test.js +151 -0
- package/src/tests/helpers/HTMLBuilder.test.js +51 -0
- package/src/tests/helpers/historyUtils.branches.test.js +36 -0
- package/src/tests/helpers/reports/cwv.test.js +239 -0
- package/src/tests/helpers/reports/quick-insights.test.js +593 -0
- package/src/tests/helpers/reports/reportsUtils.test.js +425 -0
- package/src/tests/helpers/utils.test.js +37 -0
- package/src/tests/helpers/view_helpers.test.js +87 -0
- package/src/tests/index.test.js +74 -0
- package/src/tests/localCache.test.js +236 -0
- package/src/tests/report/analytics.test.js +230 -0
- package/src/tests/report/reports.test.js +831 -0
- package/src/tests/routeAssets.test.js +120 -0
- package/src/tests/routeResourceModule.test.js +99 -2
- package/src/tests/routeStandard.test.js +3 -3
- package/src/tests/support/fakeDom.js +164 -0
- package/src/views/resources/_shared/_core_web_vitals.ejs +27 -0
- package/src/views/resources/_shared/_quick_insights.ejs +64 -0
- package/src/views/resources/_shared/_scheduled_revisions.ejs +88 -0
- package/src/views/resources/_shared/_title.ejs +16 -12
- package/src/views/resources/_shared/_toolbar.ejs +11 -21
- package/src/views/resources/_shared/_traffic_chart.ejs +27 -0
- package/src/views/resources/_shared/_translations_strip.ejs +13 -25
- package/src/views/resources/_shared/_vital_meter.ejs +54 -0
- package/src/views/resources/show.ejs +88 -98
- package/src/views/resources/translations/create_form.ejs +31 -1
|
@@ -5,21 +5,17 @@
|
|
|
5
5
|
!resource.activeContentTask.completedAt &&
|
|
6
6
|
!resource.activeContentTask.failedAt;
|
|
7
7
|
%>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<button type="submit" class="btn-primary">
|
|
16
|
-
Start revision
|
|
17
|
-
</button>
|
|
18
|
-
<% } %>
|
|
19
|
-
</form>
|
|
8
|
+
<% if (_context.query?.revisions_count_error) { %>
|
|
9
|
+
<div class="text-red-600">Cannot open a new revision. Current limit is <%= _context.maxOpenRevisions %>. </div>
|
|
10
|
+
<% } %>
|
|
11
|
+
|
|
12
|
+
<% if (hasActiveContentTask) { %>
|
|
13
|
+
<div class="mt-2 text-orange-700 dark:text-orange-300">Actions are disabled while a translation task is in progress.</div>
|
|
14
|
+
<% } %>
|
|
20
15
|
|
|
16
|
+
<div class="actions-toolbar">
|
|
21
17
|
<% if (hasActiveContentTask) { %>
|
|
22
|
-
<button type="button" class="btn-
|
|
18
|
+
<button type="button" class="btn-secondary has-icon" disabled style="opacity: 50%; cursor: not-allowed;">
|
|
23
19
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
|
|
24
20
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" />
|
|
25
21
|
</svg>
|
|
@@ -27,7 +23,7 @@
|
|
|
27
23
|
Change URL
|
|
28
24
|
</button>
|
|
29
25
|
<% } else { %>
|
|
30
|
-
<a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/urls/new` %>" class="btn-
|
|
26
|
+
<a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/urls/new` %>" class="btn-secondary has-icon">
|
|
31
27
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
|
|
32
28
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" />
|
|
33
29
|
</svg>
|
|
@@ -37,7 +33,7 @@
|
|
|
37
33
|
<% } %>
|
|
38
34
|
|
|
39
35
|
<form action="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/clones` %>" method="post" class="inline-block">
|
|
40
|
-
<button type="submit" class="btn-
|
|
36
|
+
<button type="submit" class="btn-secondary has-icon" <%= hasActiveContentTask ? 'disabled style="opacity: 50%;"' : '' %>>
|
|
41
37
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
|
|
42
38
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75" />
|
|
43
39
|
</svg>
|
|
@@ -65,11 +61,5 @@
|
|
|
65
61
|
<% } %>
|
|
66
62
|
</div>
|
|
67
63
|
|
|
68
|
-
<% if (_context.query?.revisions_count_error) { %>
|
|
69
|
-
<div class="text-red-600">Cannot open a new revision. Current limit is <%= _context.maxOpenRevisions %>. </div>
|
|
70
|
-
<% } %>
|
|
71
64
|
|
|
72
|
-
<% if (hasActiveContentTask) { %>
|
|
73
|
-
<div class="text-orange-700 mt-2 dark:text-orange-300">Actions are disabled while a translation task is in progress.</div>
|
|
74
|
-
<% } %>
|
|
75
65
|
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<div class="pb-8">
|
|
2
|
+
<div class="p-6 transition-all border rounded-xl border-neutral-200 dark:border-neutral-700" data-report="chart-card">
|
|
3
|
+
<div class="flex flex-wrap items-center justify-between gap-4 mb-6">
|
|
4
|
+
<h3 class="heading-3">Traffic Trends</h3>
|
|
5
|
+
|
|
6
|
+
<div class="flex flex-wrap items-center gap-4">
|
|
7
|
+
<div class="flex items-center gap-2">
|
|
8
|
+
<span class="inline-block rounded-full size-3 bg-raketa-primary"></span>
|
|
9
|
+
<span class="body-3 text-raketa-foreground/50">Page Views</span>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div class="flex items-center gap-2">
|
|
13
|
+
<span class="inline-block bg-yellow-400 border-2 border-yellow-500 rounded-full size-3"></span>
|
|
14
|
+
<span class="body-3 text-raketa-foreground/50">Published revision</span>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div class="relative w-full h-[320px]">
|
|
20
|
+
<canvas id="ga-traffic-chart"></canvas>
|
|
21
|
+
|
|
22
|
+
<div class="absolute inset-0 flex items-center justify-center" data-report="chart-loader">
|
|
23
|
+
<span data-loader class="inline-block border-2 rounded-full size-8 border-raketa-primary/20 border-t-raketa-primary animate-spin"></span>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<div class="flex flex-wrap items-center gap-1
|
|
1
|
+
<div class="flex flex-wrap items-center gap-1">
|
|
2
2
|
<%
|
|
3
3
|
const availableLocales = Object.keys(_context.locales);
|
|
4
4
|
const totalPossibleTranslations = availableLocales.length - 1;
|
|
@@ -19,39 +19,25 @@
|
|
|
19
19
|
%>
|
|
20
20
|
|
|
21
21
|
<span class="relative inline-block" title="<%= currentHasActiveTask ? contentTaskMessage : "" %>">
|
|
22
|
-
<img
|
|
23
|
-
title="<%= currentHasActiveTask ? contentTaskMessage : name %>"
|
|
24
|
-
src="<%= flag %>"
|
|
25
|
-
alt="<%= name %>"
|
|
26
|
-
class="border rounded-full size-6 dark:border-neutral-700"
|
|
27
|
-
/>
|
|
22
|
+
<img title="<%= currentHasActiveTask ? contentTaskMessage : name %>" src="<%= flag %>" alt="<%= name %>" class="border rounded-full size-6 dark:border-neutral-700" />
|
|
28
23
|
|
|
29
24
|
<% if (currentHasActiveTask) { %>
|
|
30
25
|
<span class="absolute -top-0.5 -right-0.5 flex h-3 w-3">
|
|
31
|
-
<span class="
|
|
32
|
-
<span class="relative inline-flex
|
|
26
|
+
<span class="absolute inline-flex w-full h-full rounded-full opacity-75 animate-ping bg-raketa-primary"></span>
|
|
27
|
+
<span class="relative inline-flex w-3 h-3 rounded-full bg-raketa-primary"></span>
|
|
33
28
|
</span>
|
|
34
29
|
<% } %>
|
|
35
30
|
</span>
|
|
36
31
|
<% } else if (resource.translations[key]) { %>
|
|
37
32
|
<% const hasActiveTask = resource.translations[key].active_content_task; %>
|
|
38
33
|
<% const contentTaskMessage = hasActiveTask ? `${name}: ${Inflector.capitalize(resource.translations[key].active_content_task.workflow)} task in progress` : ""; %>
|
|
39
|
-
<a
|
|
40
|
-
|
|
41
|
-
class="relative inline-block"
|
|
42
|
-
title="<%= hasActiveTask ? contentTaskMessage : "" %>"
|
|
43
|
-
>
|
|
44
|
-
<img
|
|
45
|
-
title="<%= hasActiveTask ? contentTaskMessage : name %>"
|
|
46
|
-
src="<%= flag %>"
|
|
47
|
-
alt="<%= name %>"
|
|
48
|
-
class="border rounded-full size-6 dark:border-neutral-700"
|
|
49
|
-
/>
|
|
34
|
+
<a href="<%= `/${key}/${_context.resourceConfig.resourceTypePlural}/${resource.translations[key].id}` %>" class="relative inline-block" title="<%= hasActiveTask ? contentTaskMessage : "" %>">
|
|
35
|
+
<img title="<%= hasActiveTask ? contentTaskMessage : name %>" src="<%= flag %>" alt="<%= name %>" class="border rounded-full size-6 dark:border-neutral-700" />
|
|
50
36
|
|
|
51
37
|
<% if (hasActiveTask) { %>
|
|
52
38
|
<span class="absolute -top-0.5 -right-0.5 flex h-3 w-3">
|
|
53
|
-
<span class="
|
|
54
|
-
<span class="relative inline-flex
|
|
39
|
+
<span class="absolute inline-flex w-full h-full rounded-full opacity-75 animate-ping bg-raketa-primary"></span>
|
|
40
|
+
<span class="relative inline-flex w-3 h-3 rounded-full bg-raketa-primary"></span>
|
|
55
41
|
</span>
|
|
56
42
|
<% } %>
|
|
57
43
|
</a>
|
|
@@ -63,8 +49,10 @@
|
|
|
63
49
|
<% }); %>
|
|
64
50
|
|
|
65
51
|
<% if (canBeTranslated) { %>
|
|
66
|
-
<a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/translations/new` %>" class="
|
|
67
|
-
|
|
52
|
+
<a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/translations/new` %>" title="Translate" aria-label="Translate" class="flex items-center justify-center transition-all duration-300 ease-in-out rounded-full size-6 text-raketa-primary bg-raketa-primary/10 hover:bg-raketa-primary/20">
|
|
53
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="size-3.5">
|
|
54
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
|
55
|
+
</svg>
|
|
68
56
|
</a>
|
|
69
57
|
<% } %>
|
|
70
|
-
</div>
|
|
58
|
+
</div>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<%
|
|
2
|
+
// One Core Web Vitals metric as a banded gauge: green up to the "good" bound,
|
|
3
|
+
// amber up to the "poor" bound, red beyond it. Expects `metric` metadata only
|
|
4
|
+
// (key, label, title, unit, thresholds) — bands and bounds need no
|
|
5
|
+
// measurement, so they render at first paint.
|
|
6
|
+
//
|
|
7
|
+
// /report/reports.js positions the arrow, writes the p75 value and colours
|
|
8
|
+
// both once the JSON feed lands; data-* below is what it reads.
|
|
9
|
+
const vital = locals.metric;
|
|
10
|
+
|
|
11
|
+
// Milliseconds read as seconds past 1s; CLS is unitless.
|
|
12
|
+
const vValue = (value, unit) =>
|
|
13
|
+
unit === 'ms'
|
|
14
|
+
? (value >= 1000 ? `${(value / 1000).toFixed(2)}s` : `${Math.round(value)}ms`)
|
|
15
|
+
: Number(value).toFixed(2);
|
|
16
|
+
|
|
17
|
+
const goodBound = vital.thresholds?.good ?? 0;
|
|
18
|
+
const poorBound = vital.thresholds?.poor ?? 0;
|
|
19
|
+
|
|
20
|
+
// The track runs past the poor bound so the red band is visible rather than a
|
|
21
|
+
// hairline at the far edge.
|
|
22
|
+
const scaleMax = poorBound ? poorBound * 1.5 : 1;
|
|
23
|
+
const asPct = (value) => `${((value / scaleMax) * 100).toFixed(2)}%`;
|
|
24
|
+
%>
|
|
25
|
+
|
|
26
|
+
<div class="lg:px-5 lg:first:pl-0 lg:last:pr-0" data-report="vital" data-metric="<%= vital.key %>" data-scale-max="<%= scaleMax %>" data-unit="<%= vital.unit %>">
|
|
27
|
+
<div class="text-sm font-bold leading-tight text-raketa-foreground">
|
|
28
|
+
<%= vital.title %> (<%= vital.label %>)
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div class="relative pt-6 mt-4">
|
|
32
|
+
<div class="absolute top-0 flex flex-col items-center invisible -translate-x-1/2" style="left: 0%" data-report="marker">
|
|
33
|
+
<span class="text-[11px] font-bold whitespace-nowrap" data-report="vital-value"></span>
|
|
34
|
+
|
|
35
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 8" fill="currentColor" class="w-2.5" aria-hidden="true" data-report="vital-arrow">
|
|
36
|
+
<path d="M6 8 0 0h12Z" />
|
|
37
|
+
</svg>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<span class="absolute top-0 left-0 inline-block border-2 rounded-full size-3 border-raketa-primary/20 border-t-raketa-primary animate-spin" data-loader data-report="vital-loader"></span>
|
|
41
|
+
|
|
42
|
+
<div class="flex w-full h-2 overflow-hidden rounded-full bg-mono-25 dark:bg-neutral-800">
|
|
43
|
+
<div class="h-full bg-emerald-500" style="width: <%= asPct(goodBound) %>"></div>
|
|
44
|
+
<div class="h-full bg-amber-500" style="width: <%= asPct(poorBound - goodBound) %>"></div>
|
|
45
|
+
<div class="h-full bg-red-500" style="width: <%= asPct(scaleMax - poorBound) %>"></div>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div class="relative h-4 mt-1 text-[10px] font-medium text-raketa-foreground/50">
|
|
49
|
+
<span class="absolute left-0">0</span>
|
|
50
|
+
<span class="absolute -translate-x-1/2 whitespace-nowrap" style="left: <%= asPct(goodBound) %>"><%= vValue(goodBound, vital.unit) %></span>
|
|
51
|
+
<span class="absolute -translate-x-1/2 whitespace-nowrap" style="left: <%= asPct(poorBound) %>"><%= vValue(poorBound, vital.unit) %></span>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
<div class="page-wrapper">
|
|
2
2
|
<div class="page-title">
|
|
3
|
-
<%- render_partial('./_shared/_title.ejs') %>
|
|
4
|
-
<%- render_partial('./_shared/_toolbar.ejs') %>
|
|
3
|
+
<%- render_partial('./_shared/_title.ejs', { withTranslations: true, render_partial }) %>
|
|
5
4
|
</div>
|
|
6
5
|
|
|
7
|
-
<%- render_partial('./_shared/_translations_strip.ejs') %>
|
|
8
|
-
|
|
9
6
|
<%
|
|
10
7
|
const openedRevisions = []
|
|
11
8
|
const scheduledRevisions = []
|
|
@@ -19,7 +16,15 @@
|
|
|
19
16
|
})
|
|
20
17
|
%>
|
|
21
18
|
|
|
22
|
-
<%
|
|
19
|
+
<%
|
|
20
|
+
const hasActiveContentTask = utils.feature("contentTasks", _context) &&
|
|
21
|
+
resource.activeContentTask &&
|
|
22
|
+
!resource.activeContentTask.completedAt &&
|
|
23
|
+
!resource.activeContentTask.failedAt;
|
|
24
|
+
%>
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
23
28
|
<div class="pb-8">
|
|
24
29
|
<h4 class="flex items-center gap-2 pb-4 heading-3">
|
|
25
30
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4 text-raketa-primary">
|
|
@@ -27,9 +32,32 @@
|
|
|
27
32
|
<path d="M12.971 1.816A5.23 5.23 0 0 1 14.25 5.25v1.875c0 .207.168.375.375.375H16.5a5.23 5.23 0 0 1 3.434 1.279 9.768 9.768 0 0 0-6.963-6.963Z" />
|
|
28
33
|
</svg>
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
Revisions
|
|
31
36
|
</h4>
|
|
32
37
|
|
|
38
|
+
<%
|
|
39
|
+
const atRevisionLimit =
|
|
40
|
+
resource.revisionsCount >= _context?.maxOpenRevisions;
|
|
41
|
+
const canStartRevision = !atRevisionLimit && !hasActiveContentTask;
|
|
42
|
+
%>
|
|
43
|
+
|
|
44
|
+
<div class="pb-4">
|
|
45
|
+
<% if (_context.query?.revisions_count_error) { %>
|
|
46
|
+
<div class="text-red-600">Cannot open a new revision. Current limit is <%= _context.maxOpenRevisions %>. </div>
|
|
47
|
+
<% } %>
|
|
48
|
+
|
|
49
|
+
<% if (hasActiveContentTask) { %>
|
|
50
|
+
<div class="mb-2 text-orange-700 dark:text-orange-300">Actions are disabled while a translation task is in progress.</div>
|
|
51
|
+
<% } %>
|
|
52
|
+
|
|
53
|
+
<form method="POST" action="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/${_context.resourceConfig.resourceType}_revisions` %>" class="inline-block">
|
|
54
|
+
<button type="submit" class="btn-primary" <%- canStartRevision ? '' : 'disabled style="opacity: 50%;"' %> <% if (atRevisionLimit && !hasActiveContentTask) { %> title="Open revision limit reached (<%= _context.maxOpenRevisions %>)" <% } %>>
|
|
55
|
+
Start revision
|
|
56
|
+
</button>
|
|
57
|
+
</form>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<% if (openedRevisions.length) { %>
|
|
33
61
|
<table class="data-grid alt">
|
|
34
62
|
<thead>
|
|
35
63
|
<tr>
|
|
@@ -80,109 +108,46 @@
|
|
|
80
108
|
<% }); %>
|
|
81
109
|
</tbody>
|
|
82
110
|
</table>
|
|
111
|
+
<% } else { %>
|
|
112
|
+
<span>There are no open revisions.</span>
|
|
113
|
+
<% } %>
|
|
83
114
|
</div>
|
|
84
|
-
<% } %>
|
|
85
|
-
|
|
86
|
-
<% if (scheduledRevisions.length) { %>
|
|
87
|
-
<div class="pb-8">
|
|
88
|
-
<h4 class="flex items-center gap-2 pb-4 heading-3">
|
|
89
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4 text-raketa-primary">
|
|
90
|
-
<path fill-rule="evenodd" d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0 0 16.5 9h-1.875a1.875 1.875 0 0 1-1.875-1.875V5.25A3.75 3.75 0 0 0 9 1.5H5.625ZM7.5 15a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 7.5 15Zm.75 2.25a.75.75 0 0 0 0 1.5H12a.75.75 0 0 0 0-1.5H8.25Z" clip-rule="evenodd" />
|
|
91
|
-
<path d="M12.971 1.816A5.23 5.23 0 0 1 14.25 5.25v1.875c0 .207.168.375.375.375H16.5a5.23 5.23 0 0 1 3.434 1.279 9.768 9.768 0 0 0-6.963-6.963Z" />
|
|
92
|
-
</svg>
|
|
93
|
-
|
|
94
|
-
Scheduled for publication
|
|
95
|
-
</h4>
|
|
96
|
-
|
|
97
|
-
<table class="data-grid alt">
|
|
98
|
-
<thead>
|
|
99
|
-
<tr>
|
|
100
|
-
<th>Title</th>
|
|
101
|
-
<th>Created by</th>
|
|
102
|
-
<th>Scheduled by</th>
|
|
103
|
-
<th>Publish on</th>
|
|
104
|
-
<th> </th>
|
|
105
|
-
</tr>
|
|
106
|
-
</thead>
|
|
107
|
-
|
|
108
|
-
<tbody>
|
|
109
|
-
<% scheduledRevisions.forEach((revision, idx)=> { %>
|
|
110
|
-
<tr class="border-b border-mono-25">
|
|
111
|
-
<td class="w-1/2 py-4 pl-2">
|
|
112
|
-
<div class="flex items-center gap-1">
|
|
113
|
-
<%= revision.title %>
|
|
114
|
-
</div>
|
|
115
|
-
</td>
|
|
116
|
-
|
|
117
|
-
<td class="whitespace-nowrap">
|
|
118
|
-
<%- render_partial('./_shared/_revision_operator.ejs', { revision }) %>
|
|
119
|
-
</td>
|
|
115
|
+
<% const reports = locals.reports || {}; %>
|
|
120
116
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
<img src="<%= revision.schedule.operatorMeta.avatar %>" class="rounded-full size-4">
|
|
126
|
-
<% } %>
|
|
127
|
-
<%= revision.schedule.operatorMeta.name %>
|
|
128
|
-
</div>
|
|
129
|
-
</div>
|
|
130
|
-
</td>
|
|
131
|
-
|
|
132
|
-
<td class="whitespace-nowrap">
|
|
133
|
-
<div class="body-3 text-raketa-foreground/50">
|
|
134
|
-
<div class="flex items-center gap-1">
|
|
135
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="size-4 text-raketa-foreground" viewBox="0 0 512 512">
|
|
136
|
-
<path d="M112.91 128A191.85 191.85 0 0064 254c-1.18 106.35 85.65 193.8 192 194 106.2.2 192-85.83 192-192 0-104.54-83.55-189.61-187.5-192a4.36 4.36 0 00-4.5 4.37V152" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" />
|
|
137
|
-
<path d="M233.38 278.63l-79-113a8.13 8.13 0 0111.32-11.32l113 79a32.5 32.5 0 01-37.25 53.26 33.21 33.21 0 01-8.07-7.94z" />
|
|
138
|
-
</svg>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
<time data-pretty-expiration-time datetime="<%= revision.schedule.mergeAt %>"><%= revision.schedule.mergeAt %></time>
|
|
142
|
-
</div>
|
|
143
|
-
</div>
|
|
144
|
-
</td>
|
|
145
|
-
|
|
146
|
-
<td class="whitespace-nowrap">
|
|
147
|
-
<div class="justify-end actions-toolbar">
|
|
148
|
-
<form action="<%= `/${_context.locale}/${_context.resourceConfig.resourceType}_revisions/${revision.id}/cancel_schedules` %>" method="post" class="inline-flex items-center gap-2">
|
|
149
|
-
<%- f.submit('Remove schedule', { class: 'btn-text' }) %>
|
|
150
|
-
</form>
|
|
151
|
-
|
|
152
|
-
<a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.resourceType %>-revisions/<%= revision.id %>/preview" target="_blank" class="btn-text has-icon">
|
|
153
|
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
|
|
154
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
|
|
155
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
|
156
|
-
</svg>
|
|
117
|
+
<% if (reports.insights) { %>
|
|
118
|
+
<%- render_partial('./_shared/_quick_insights.ejs') %>
|
|
119
|
+
<%- render_partial('./_shared/_traffic_chart.ejs') %>
|
|
120
|
+
<% } %>
|
|
157
121
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
<% }); %>
|
|
164
|
-
</tbody>
|
|
165
|
-
</table>
|
|
166
|
-
</div>
|
|
122
|
+
<% if (reports.webVitals) { %>
|
|
123
|
+
<%- render_partial('./_shared/_core_web_vitals.ejs', {
|
|
124
|
+
vitalsMeta: reports.vitalsMeta,
|
|
125
|
+
render_partial,
|
|
126
|
+
}) %>
|
|
167
127
|
<% } %>
|
|
168
128
|
|
|
169
129
|
<% if (utils.feature("contentTasks", _context) && resource.activeContentTask) { %>
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
130
|
+
<div class="mb-4">
|
|
131
|
+
<h4 class="flex items-center gap-2 pb-4 heading-3">
|
|
132
|
+
<svg class="size-4 text-raketa-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
133
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
134
|
+
</svg>
|
|
175
135
|
|
|
176
|
-
|
|
177
|
-
|
|
136
|
+
Active tasks
|
|
137
|
+
</h4>
|
|
178
138
|
|
|
179
|
-
|
|
139
|
+
<%- render_partial('../_shared/_content_tasks.ejs', {
|
|
180
140
|
tasks: [{...resource.activeContentTask, resource: resource}],
|
|
181
141
|
showAllDetails: false }
|
|
182
142
|
) %>
|
|
183
|
-
|
|
143
|
+
</div>
|
|
184
144
|
<% } %>
|
|
185
145
|
|
|
146
|
+
<%- render_partial('./_shared/_scheduled_revisions.ejs', {
|
|
147
|
+
scheduledRevisions,
|
|
148
|
+
render_partial,
|
|
149
|
+
}) %>
|
|
150
|
+
|
|
186
151
|
<%- render_partial('./_shared/_addons.ejs') %>
|
|
187
152
|
|
|
188
153
|
<div class="mb-4">
|
|
@@ -204,8 +169,33 @@
|
|
|
204
169
|
toolbarPath: './_shared/_history_toolbar.ejs'
|
|
205
170
|
}) %>
|
|
206
171
|
|
|
207
|
-
<a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/history` %>" class="
|
|
172
|
+
<a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/history` %>" class="mt-2 mb-4 ml-2 btn-text">
|
|
208
173
|
Full page history
|
|
209
174
|
</a>
|
|
210
175
|
</div>
|
|
211
|
-
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
<div class="pb-8">
|
|
179
|
+
|
|
180
|
+
<h4 class="flex items-center gap-2 pb-4 heading-3">
|
|
181
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-5 text-raketa-primary">
|
|
182
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28ZM15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
|
183
|
+
</svg>
|
|
184
|
+
|
|
185
|
+
Actions
|
|
186
|
+
</h4>
|
|
187
|
+
|
|
188
|
+
<%- render_partial('./_shared/_toolbar.ejs') %>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<% if (reports.path) { %>
|
|
193
|
+
<script>
|
|
194
|
+
window.RAKETA_REPORTS = {
|
|
195
|
+
path: '<%= reports.path %>'
|
|
196
|
+
};
|
|
197
|
+
</script>
|
|
198
|
+
<script src="/report/chart.js"></script>
|
|
199
|
+
<script src="/report/analytics.js"></script>
|
|
200
|
+
<script src="/report/reports.js"></script>
|
|
201
|
+
<% } %>
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<% if (utils.feature("contentTasks", _context) && _context.locale === _context.defaultLocale) { %>
|
|
34
34
|
<div class="mb-4">
|
|
35
35
|
<label for="workflow" class="font-semibold hover:cursor-pointer body-3">Translation workflow</label>
|
|
36
|
-
<select name="resource[workflow]" id="workflow">
|
|
36
|
+
<select name="resource[workflow][type]" id="workflow">
|
|
37
37
|
<option value="">Default (no workflow)</option>
|
|
38
38
|
|
|
39
39
|
<option value="LOKALISE_TO_AI_RT_HUM" <%= resource.workflow === 'LOKALISE_TO_AI_RT_HUM' ? 'selected' : '' %>>
|
|
@@ -52,6 +52,36 @@
|
|
|
52
52
|
Select a workflow for the translation process. Lokalise workflow initiates a translation task for external translation.
|
|
53
53
|
</p>
|
|
54
54
|
</div>
|
|
55
|
+
|
|
56
|
+
<div class="mb-4" id="due_date_wrapper">
|
|
57
|
+
<label for="due_date" class="font-semibold hover:cursor-pointer body-3">Due date (UTC)</label>
|
|
58
|
+
<input type="datetime-local" name="resource[workflow][due_date]" id="due_date" />
|
|
59
|
+
<p class="text-sm text-raketa-foreground/50 mt-1">
|
|
60
|
+
Select a workflow for the translation process. Lokalise workflow initiates a translation task for external translation.
|
|
61
|
+
</p>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<script>
|
|
65
|
+
(function () {
|
|
66
|
+
const workflowSelect = document.getElementById("workflow");
|
|
67
|
+
const dueDateWrapper = document.getElementById("due_date_wrapper");
|
|
68
|
+
const dueDateInput = document.getElementById("due_date");
|
|
69
|
+
|
|
70
|
+
function toggleDueDate() {
|
|
71
|
+
if (!workflowSelect || !dueDateWrapper || !dueDateInput) return;
|
|
72
|
+
const isDefault = !workflowSelect.value;
|
|
73
|
+
dueDateWrapper.style.display = isDefault ? "none" : "block";
|
|
74
|
+
if (isDefault) {
|
|
75
|
+
dueDateInput.value = "";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (workflowSelect) {
|
|
80
|
+
workflowSelect.addEventListener("change", toggleDueDate);
|
|
81
|
+
toggleDueDate();
|
|
82
|
+
}
|
|
83
|
+
})();
|
|
84
|
+
</script>
|
|
55
85
|
<% } %>
|
|
56
86
|
|
|
57
87
|
<% if (errors?.resource && targetLocale) { %>
|