@raketa-cloud/admin 1.10.4 → 1.10.6

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.
@@ -0,0 +1,72 @@
1
+ <div class="page-wrapper">
2
+ <div class="page-title flex flex-col items-start">
3
+ <h1 class="heading-1">
4
+ <span class="opacity-50">Partially translate / </span><%= resource.title %>
5
+ </h1>
6
+ </div>
7
+
8
+ <% const targetTranslations = Object.entries(resource.translations || {}).filter(([locale, translation]) => locale !== _context.locale && translation?.id); %>
9
+ <div class="grid gap-4 md:grid-cols-3">
10
+ <form action="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/partial-translations?widget_ids=${encodeURIComponent(partialTranslation.widgetIds.join(','))}` %>" method="post" class="form">
11
+ <div class="mb-4">
12
+ <h6>Current translations</h6>
13
+ <div class="checkbox-group !max-h-fit">
14
+ <% targetTranslations.forEach(([locale]) => { %>
15
+ <label>
16
+ <input type="checkbox" name="partial_translation[locales][]" value="<%= locale %>" <%= partialTranslation.locales.includes(locale) ? 'checked' : '' %>>
17
+ <%= _context.locales[locale]?.name || locale %>
18
+ </label>
19
+ <% }) %>
20
+ </div>
21
+ <% if (targetTranslations.length === 0) { %>
22
+ <p class="text-sm text-raketa-foreground/50">This resource has no translations.</p>
23
+ <% } %>
24
+ </div>
25
+
26
+ <div class="mb-4">
27
+ <label for="workflow" class="font-semibold body-3">Translation workflow</label>
28
+ <select name="partial_translation[workflow][type]" id="workflow" required>
29
+ <option value="">Select workflow</option>
30
+ <% ['LOKALISE_TT_AI_RT_HUM', 'LOKALISE_TT_HUM', 'LOKALISE_TT_AI'].forEach(workflow => { %>
31
+ <option value="<%= workflow %>" <%= partialTranslation.workflow?.type === workflow ? 'selected' : '' %>><%= content_tasks.workflowsMap(workflow.toLowerCase()) %></option>
32
+ <% }) %>
33
+ </select>
34
+ </div>
35
+
36
+ <%- render_partial('../_shared/_due_date.ejs', {
37
+ workflow: partialTranslation.workflow,
38
+ dueDateField: 'partial_translation[workflow][due_date]',
39
+ }) %>
40
+
41
+ <div class="mb-4">
42
+ <h6>Widgets selected for translation</h6>
43
+ <ul class="mt-2 space-y-1">
44
+ <% partialTranslation.widgetIds.forEach(widgetId => { const widget = (resource.widgets || []).find(item => item.widgetId === widgetId); %>
45
+ <li class="rounded border px-3 py-2 dark:border-neutral-500">
46
+ <input type="hidden" name="partial_translation[widget_ids][]" value="<%= widgetId %>">
47
+ <strong><%= widget?.component || 'Widget' %></strong>
48
+ <% if (widget?.settings?.title) { %> — <%= widget.settings.title %><% } %>
49
+ <span class="text-sm text-raketa-foreground/50">(<%= widgetId %>)</span>
50
+ </li>
51
+ <% }) %>
52
+ </ul>
53
+ </div>
54
+
55
+ <div class="mb-4">
56
+ <h6>Preview of the original page</h6>
57
+ <a href="<%= previewUrl %>" target="_blank" rel="noopener noreferrer" class="btn-text">Open preview</a>
58
+ </div>
59
+
60
+ <% Object.entries(errors?.partialTranslation || {}).forEach(([key, error]) => { %>
61
+ <p class="mb-2 text-sm font-medium text-red-600"><%= key %>: <%= error %></p>
62
+ <% }) %>
63
+
64
+ <div class="form-actions">
65
+ <div class="btn-toolbar">
66
+ <button type="submit" class="btn-primary">Initiate partial translations</button>
67
+ <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}` %>" class="btn-secondary">Cancel</a>
68
+ </div>
69
+ </div>
70
+ </form>
71
+ </div>
72
+ </div>
@@ -53,88 +53,10 @@
53
53
  </p>
54
54
  </div>
55
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" value="<%= resource.workflow?.due_date || "" %>" />
59
-
60
- <p class="text-sm text-raketa-foreground/50 mt-1">
61
- Select a due date for the translation. Weekends are not a valid choice.
62
- </p>
63
- </div>
64
-
65
- <script>
66
- window.addEventListener("load", (_event) => {
67
- (function () {
68
- const workflowSelect = document.getElementById("workflow");
69
- const dueDateWrapper = document.getElementById("due_date_wrapper");
70
- const dueDateInput = document.getElementById("due_date");
71
-
72
- function validateInputValue(dInput) {
73
- if (dInput.value === "") {
74
- dInput.setCustomValidity('');
75
- return;
76
- }
77
-
78
- const selectedDate = new Date(dInput.value);
79
- const day = selectedDate.getDay();
80
-
81
- if (day === 0 || day === 6) {
82
- dInput.setCustomValidity('Weekends are not allowed. Please select a weekday.')
83
- selectedDate.value = '';
84
- } else {
85
- dInput.setCustomValidity('');
86
- }
87
- }
88
-
89
- dueDateInput.addEventListener('change', function(e) {
90
- validateInputValue(dueDateInput);
91
- });
92
-
93
- function getTwoDaysFromNowString() {
94
- const date = new Date();
95
-
96
-
97
- date.setDate(date.getDate() + 3);
98
-
99
- // Skip weekends.
100
- while(date.getDay() === 0 || date.getDay() === 6) {
101
- date.setDate(date.getDate() + 1);
102
- }
103
-
104
- const year = date.getFullYear();
105
- const month = String(date.getMonth() + 1).padStart(2, "0");
106
- const day = String(date.getDate()).padStart(2, "0");
107
- const hours = String(date.getHours()).padStart(2, "0");
108
- const minutes = String(date.getMinutes()).padStart(2, "0");
109
- return `${year}-${month}-${day}T${hours}:${minutes}`;
110
- }
111
-
112
- function toggleDueDate() {
113
- if (!workflowSelect || !dueDateWrapper || !dueDateInput) return;
114
- const minDate = getTwoDaysFromNowString();
115
- dueDateInput.min = minDate;
116
-
117
- const isDefault = !workflowSelect.value;
118
- dueDateWrapper.style.display = isDefault ? "none" : "block";
119
-
120
- if (isDefault) {
121
- dueDateInput.value = "";
122
- } else if (!dueDateInput.value) {
123
- dueDateInput.value = minDate;
124
- }
125
-
126
- // Trigger the on change so hints are visible together with the validation.
127
- const changeEvent = new Event('change', { bubbles: true });
128
- dueDateInput.dispatchEvent(changeEvent);
129
- }
130
-
131
- if (workflowSelect) {
132
- workflowSelect.addEventListener("change", toggleDueDate);
133
- toggleDueDate();
134
- }
135
- })();
136
- })
137
- </script>
56
+ <%- render_partial('../_shared/_due_date.ejs', {
57
+ workflow: resource.workflow,
58
+ dueDateField: 'resource[workflow][due_date]',
59
+ }) %>
138
60
  <% } %>
139
61
 
140
62
  <% const currentLocaleErrors = errors?.localeErrors || []; %>