@translationstudio/translationstudio-strapi-extension 4.3.0 → 5.0.1
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/Types.d.ts +11 -1
- package/dist/_chunks/{App-C2A-alX9.js → App-CDI8iUHL.js} +26 -29
- package/dist/_chunks/{App-CUYIBOWI.mjs → App-Dw8LkiAx.mjs} +27 -30
- package/dist/_chunks/{HistoryPage-AhmPF4m4.mjs → HistoryPage-Do_yIUdx.mjs} +232 -211
- package/dist/_chunks/{HistoryPage-C77OaOGZ.js → HistoryPage-VqkbaIHn.js} +231 -210
- package/dist/_chunks/{index-Dgpsawos.js → index-CgX-X1nF.js} +6 -17
- package/dist/_chunks/{index-Csx0xlBL.mjs → index-DKeIuEy_.mjs} +19 -30
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/admin/src/components/BulkTranslationMenu.d.ts +1 -1
- package/dist/admin/src/components/BulkTranslationPanel.d.ts +1 -1
- package/dist/admin/src/components/DeleteHistoryEntryRequest.d.ts +1 -1
- package/dist/admin/src/components/HistoryMenu.d.ts +5 -1
- package/dist/admin/src/components/utils/historyDataUtils.d.ts +1 -10
- package/dist/admin/src/components/utils/historyStatusUtils.d.ts +2 -2
- package/dist/admin/src/components/utils/statusHelper.d.ts +1 -2
- package/dist/server/index.js +4 -4
- package/dist/server/index.mjs +4 -4
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
4
4
|
const designSystem = require("@strapi/design-system");
|
|
5
5
|
const react = require("react");
|
|
6
6
|
const admin = require("@strapi/strapi/admin");
|
|
7
|
-
const index = require("./index-
|
|
7
|
+
const index = require("./index-CgX-X1nF.js");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
9
|
const getSearchableText = (item) => {
|
|
10
10
|
return `${item["project-name"]} ${item["element-name"]} ${item["element-uid"]} ${item.targetLanguages.join(" ")} ${item.combinedStatus.text}`.toLowerCase();
|
|
@@ -90,7 +90,6 @@ function DeleteHistoryEntryRequest({ item, onDeleted, onClose }) {
|
|
|
90
90
|
] }) });
|
|
91
91
|
}
|
|
92
92
|
const DEBOUNCE_DELAY = 500;
|
|
93
|
-
const LoadingState = () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: "Loading history..." }) });
|
|
94
93
|
const EmptyState = ({ hasSearchTerm }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", style: { color: "#666" }, children: hasSearchTerm ? "No matching translation history found." : "No translation history available." }) });
|
|
95
94
|
const SearchInput = ({ value, onChange }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
96
95
|
designSystem.TextInput,
|
|
@@ -180,10 +179,7 @@ const HistoryRow = ({ item, onDelete, secondaryColor }) => /* @__PURE__ */ jsxRu
|
|
|
180
179
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: index.formatDate(item.timeUpdated) }) }),
|
|
181
180
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.SimpleMenu, { label: "Actions", tag: designSystem.IconButton, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {}), children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Bell, {}), variant: "danger", onSelect: () => onDelete(item), children: "Delete history entry" }) }) })
|
|
182
181
|
] });
|
|
183
|
-
const HistoryMenu = () => {
|
|
184
|
-
const [historyData, setHistoryData] = react.useState([]);
|
|
185
|
-
const [isLoading, setIsLoading] = react.useState(true);
|
|
186
|
-
const [error, setError] = react.useState(null);
|
|
182
|
+
const HistoryMenu = ({ groupedHistoryData, onRemoveHistoryItem }) => {
|
|
187
183
|
const [errorMessage, setErrorMessage] = react.useState("");
|
|
188
184
|
const [succcessMessage, setSucccessMessage] = react.useState("");
|
|
189
185
|
const [searchTerm, setSearchTerm] = react.useState("");
|
|
@@ -192,67 +188,19 @@ const HistoryMenu = () => {
|
|
|
192
188
|
field: "time-imported",
|
|
193
189
|
direction: "desc"
|
|
194
190
|
});
|
|
195
|
-
const {
|
|
191
|
+
const { post } = admin.getFetchClient();
|
|
196
192
|
const themeColors = index.getThemeColors();
|
|
197
193
|
const debouncedSearchTerm = useDebounce(searchTerm, DEBOUNCE_DELAY);
|
|
198
|
-
react.useEffect(() => {
|
|
199
|
-
const fetchHistory = async () => {
|
|
200
|
-
setIsLoading(true);
|
|
201
|
-
setError(null);
|
|
202
|
-
try {
|
|
203
|
-
const response = await get("/translationstudio/history");
|
|
204
|
-
const result = index.handleHistoryResponse(response.data);
|
|
205
|
-
if (result.isError) {
|
|
206
|
-
setError(result.errorMessage || "Failed to fetch translation history.");
|
|
207
|
-
} else if (result.historyData && Array.isArray(result.historyData) && result.historyData.length > 0) {
|
|
208
|
-
const res = result.historyData;
|
|
209
|
-
res.sort((a, b) => a["time-updated"] - b["time-updated"]);
|
|
210
|
-
setHistoryData(res);
|
|
211
|
-
}
|
|
212
|
-
} catch (error2) {
|
|
213
|
-
console.error("Failed to fetch history:", error2);
|
|
214
|
-
setError("Failed to fetch translation history.");
|
|
215
|
-
setHistoryData([]);
|
|
216
|
-
} finally {
|
|
217
|
-
setIsLoading(false);
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
fetchHistory();
|
|
221
|
-
}, [setIsLoading, setError, setHistoryData]);
|
|
222
194
|
const processedData = react.useMemo(() => {
|
|
223
|
-
const
|
|
224
|
-
const filtered = filterBySearchTerm(grouped, debouncedSearchTerm, getSearchableText);
|
|
195
|
+
const filtered = filterBySearchTerm(groupedHistoryData, debouncedSearchTerm, getSearchableText);
|
|
225
196
|
return sortItems(filtered, sortState);
|
|
226
|
-
}, [
|
|
197
|
+
}, [groupedHistoryData, debouncedSearchTerm, sortState]);
|
|
227
198
|
const handleSort = (field) => {
|
|
228
199
|
setSortState((currentState) => getNextSortState(currentState, field));
|
|
229
200
|
};
|
|
230
201
|
const handleSearchChange = (e) => {
|
|
231
202
|
setSearchTerm(e.target.value);
|
|
232
203
|
};
|
|
233
|
-
if (isLoading) {
|
|
234
|
-
return /* @__PURE__ */ jsxRuntime.jsx(LoadingState, {});
|
|
235
|
-
}
|
|
236
|
-
if (error) {
|
|
237
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", textColor: "danger600", children: error }) });
|
|
238
|
-
}
|
|
239
|
-
const removeHistoryEntry = function(item) {
|
|
240
|
-
if (!item || historyData.length === 0)
|
|
241
|
-
return;
|
|
242
|
-
if (historyData.length === 1) {
|
|
243
|
-
setHistoryData([]);
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
let index2 = -1;
|
|
247
|
-
for (let i = 0; i < historyData.length && index2 === -1; i++) {
|
|
248
|
-
if (historyData[i].id === item.id)
|
|
249
|
-
index2 = i;
|
|
250
|
-
}
|
|
251
|
-
if (index2 === -1)
|
|
252
|
-
return;
|
|
253
|
-
historyData.splice(index2, 1);
|
|
254
|
-
setHistoryData([...historyData]);
|
|
255
|
-
};
|
|
256
204
|
const onDeleteHistoyInfo = function(elem) {
|
|
257
205
|
if (!errorMessage)
|
|
258
206
|
setErrorMessage("");
|
|
@@ -265,14 +213,14 @@ const HistoryMenu = () => {
|
|
|
265
213
|
}).then((res) => {
|
|
266
214
|
if (res.status !== 204)
|
|
267
215
|
throw new Error("Could not delete entry");
|
|
268
|
-
|
|
216
|
+
onRemoveHistoryItem(deleteItem.id);
|
|
269
217
|
setSucccessMessage("Successfully removed history entry.");
|
|
270
218
|
}).catch(() => setErrorMessage("Could not delete history entry " + deleteItem["element-name"])).finally(() => setDeleteItem(null));
|
|
271
219
|
};
|
|
272
220
|
const hasData = processedData.length > 0;
|
|
273
221
|
const hasSearchTerm = Boolean(debouncedSearchTerm.trim());
|
|
274
222
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 4, paddingBottom: 4, style: { width: "100%" }, children: !hasData && !hasSearchTerm ? /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { hasSearchTerm: false }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
275
|
-
|
|
223
|
+
groupedHistoryData.length > 10 && /* @__PURE__ */ jsxRuntime.jsx(SearchInput, { value: searchTerm, onChange: handleSearchChange }),
|
|
276
224
|
errorMessage && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { title: errorMessage, variant: "danger", style: { marginBottom: "2em" }, children: errorMessage }),
|
|
277
225
|
succcessMessage && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { title: succcessMessage, variant: "success", style: { marginBottom: "2em" }, children: succcessMessage }),
|
|
278
226
|
hasData ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -317,16 +265,7 @@ const LanguageSelector = ({
|
|
|
317
265
|
name: "languages",
|
|
318
266
|
"aria-label": "translationstudio settings",
|
|
319
267
|
children: [
|
|
320
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
321
|
-
designSystem.Typography,
|
|
322
|
-
{
|
|
323
|
-
variant: "omega",
|
|
324
|
-
tag: "label",
|
|
325
|
-
paddingBottom: 2,
|
|
326
|
-
style: { color: themeColors.primaryText },
|
|
327
|
-
children: "Translation Options"
|
|
328
|
-
}
|
|
329
|
-
),
|
|
268
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", tag: "label", paddingBottom: 2, style: { color: themeColors.primaryText }, children: "Available translation options:" }),
|
|
330
269
|
languages.map((lang) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { value: lang.name, children: lang.name }, lang.id))
|
|
331
270
|
]
|
|
332
271
|
}
|
|
@@ -404,6 +343,7 @@ const AlertMessage = ({
|
|
|
404
343
|
const BulkTranslationPanel = ({
|
|
405
344
|
contentType,
|
|
406
345
|
selectedEntries,
|
|
346
|
+
onClose,
|
|
407
347
|
onTranslationComplete
|
|
408
348
|
}) => {
|
|
409
349
|
const [languages, setLanguages] = react.useState([]);
|
|
@@ -420,20 +360,16 @@ const BulkTranslationPanel = ({
|
|
|
420
360
|
const [tsIsAvailable, setTsIsAvailable] = react.useState(true);
|
|
421
361
|
const [isProcessing, setIsProcessing] = react.useState(false);
|
|
422
362
|
const [progress, setProgress] = react.useState(0);
|
|
423
|
-
const [isLoadingMappings, setIsLoadingMappings] = react.useState(
|
|
363
|
+
const [isLoadingMappings, setIsLoadingMappings] = react.useState(true);
|
|
424
364
|
const [mappingsError, setMappingsError] = react.useState(false);
|
|
425
365
|
const themeColors = index.getThemeColors();
|
|
426
|
-
index.useThemeMode();
|
|
427
366
|
const { get, post } = admin.getFetchClient();
|
|
428
367
|
const selectedLang = languages.find((lang) => lang.name === selectedOption);
|
|
429
368
|
const isMachineTranslation = selectedLang?.machine ?? false;
|
|
430
369
|
react.useEffect(() => {
|
|
431
370
|
if (!contentType) return;
|
|
432
|
-
setIsLoadingMappings(true);
|
|
433
|
-
setMappingsError(false);
|
|
434
371
|
get("/translationstudio/getLicense").then((response) => {
|
|
435
|
-
|
|
436
|
-
return response.data.license !== "";
|
|
372
|
+
return response.status === 204;
|
|
437
373
|
}).then((hasLicense) => {
|
|
438
374
|
setLicenseValid(hasLicense);
|
|
439
375
|
if (!hasLicense) throw new Error("No license set");
|
|
@@ -454,14 +390,15 @@ const BulkTranslationPanel = ({
|
|
|
454
390
|
}).finally(() => {
|
|
455
391
|
setIsLoadingMappings(false);
|
|
456
392
|
});
|
|
457
|
-
}, [contentType]);
|
|
393
|
+
}, [contentType, setLicenseValid, setTsIsAvailable, setLanguages, setMappingsError, setIsLoadingMappings]);
|
|
458
394
|
react.useEffect(() => {
|
|
459
|
-
if (!contentType || !isEmail)
|
|
395
|
+
if (!contentType || !isEmail)
|
|
396
|
+
return;
|
|
460
397
|
const savedEmail = index.getStoredEmail();
|
|
461
398
|
if (savedEmail) {
|
|
462
399
|
setEmail(savedEmail);
|
|
463
400
|
}
|
|
464
|
-
}, [isEmail]);
|
|
401
|
+
}, [contentType, isEmail, setEmail]);
|
|
465
402
|
const handleUrgentChange = () => {
|
|
466
403
|
if (isUrgent) {
|
|
467
404
|
setIsUrgent(false);
|
|
@@ -588,76 +525,70 @@ const BulkTranslationPanel = ({
|
|
|
588
525
|
const pluginIsAvailable = () => {
|
|
589
526
|
return !isLoadingMappings && licenseValid !== null && tsIsAvailable === true && !mappingsError;
|
|
590
527
|
};
|
|
591
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
592
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
}
|
|
656
|
-
)
|
|
657
|
-
] })
|
|
658
|
-
}
|
|
659
|
-
)
|
|
660
|
-
] });
|
|
528
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: true, onOpenChange: () => onClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
|
529
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: "Translation request" }) }),
|
|
530
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
|
|
531
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
532
|
+
AlertMessage,
|
|
533
|
+
{
|
|
534
|
+
show: showAlert,
|
|
535
|
+
type: alertType,
|
|
536
|
+
message: alertMessage,
|
|
537
|
+
onClose: () => setShowAlert(false)
|
|
538
|
+
}
|
|
539
|
+
),
|
|
540
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
541
|
+
designSystem.Box,
|
|
542
|
+
{
|
|
543
|
+
padding: 4,
|
|
544
|
+
style: {
|
|
545
|
+
width: "100%",
|
|
546
|
+
backgroundColor: themeColors.cardBackground,
|
|
547
|
+
borderRadius: "4px"
|
|
548
|
+
},
|
|
549
|
+
children: !pluginIsAvailable() ? renderNotAvailable() : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
550
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
551
|
+
LanguageSelector,
|
|
552
|
+
{
|
|
553
|
+
languages,
|
|
554
|
+
selectedOption,
|
|
555
|
+
onSelectionChange: handleRadioSelection,
|
|
556
|
+
themeColors
|
|
557
|
+
}
|
|
558
|
+
),
|
|
559
|
+
!isMachineTranslation && selectedOption !== "" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
560
|
+
AdditionalSettings,
|
|
561
|
+
{
|
|
562
|
+
isUrgent,
|
|
563
|
+
isEmail,
|
|
564
|
+
email,
|
|
565
|
+
dueDate,
|
|
566
|
+
onUrgentChange: handleUrgentChange,
|
|
567
|
+
onEmailChange: handleEmailChange,
|
|
568
|
+
onEmailInputChange: handleEmailInputChange,
|
|
569
|
+
onDueDateChange: handleDueDateChange,
|
|
570
|
+
themeColors
|
|
571
|
+
}
|
|
572
|
+
),
|
|
573
|
+
isProcessing && /* @__PURE__ */ jsxRuntime.jsx(ProgressIndicator, { progress })
|
|
574
|
+
] })
|
|
575
|
+
}
|
|
576
|
+
)
|
|
577
|
+
] }),
|
|
578
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
|
579
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: "Cancel" }),
|
|
580
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
581
|
+
designSystem.Button,
|
|
582
|
+
{
|
|
583
|
+
onClick: handleBulkTranslationRequest,
|
|
584
|
+
disabled: !selectedOption || isProcessing,
|
|
585
|
+
loading: isProcessing,
|
|
586
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}),
|
|
587
|
+
children: index.getSubmitLabel(selectedEntries.length, isUrgent, isMachineTranslation)
|
|
588
|
+
}
|
|
589
|
+
)
|
|
590
|
+
] })
|
|
591
|
+
] }) });
|
|
661
592
|
};
|
|
662
593
|
const filterAndTransformContentTypes = (data) => {
|
|
663
594
|
return data.filter((type) => type.kind === "collectionType" || type.kind === "singleType").filter((type) => !type.uid.startsWith("admin::") && !type.uid.startsWith("plugin::")).map((type) => ({
|
|
@@ -817,14 +748,19 @@ const EntriesTable = ({
|
|
|
817
748
|
}
|
|
818
749
|
);
|
|
819
750
|
};
|
|
820
|
-
const getLangQueued = function(
|
|
821
|
-
return
|
|
751
|
+
const getLangQueued = function(e) {
|
|
752
|
+
return e.queued.sort().join(", ");
|
|
822
753
|
};
|
|
823
|
-
const getLangInTranslation = function(
|
|
824
|
-
return
|
|
754
|
+
const getLangInTranslation = function(e) {
|
|
755
|
+
return e.intranslation.sort().join(", ");
|
|
825
756
|
};
|
|
826
|
-
const getLangTranslated = function(
|
|
827
|
-
return
|
|
757
|
+
const getLangTranslated = function(e) {
|
|
758
|
+
return e.translated.sort().join(", ");
|
|
759
|
+
};
|
|
760
|
+
const EmptyHistoryDataLanguageMapItem = {
|
|
761
|
+
queued: [],
|
|
762
|
+
intranslation: [],
|
|
763
|
+
translated: []
|
|
828
764
|
};
|
|
829
765
|
const EntryRow = ({
|
|
830
766
|
entry,
|
|
@@ -835,7 +771,7 @@ const EntryRow = ({
|
|
|
835
771
|
themeColors
|
|
836
772
|
}) => {
|
|
837
773
|
const entryId = getEntryId(entry);
|
|
838
|
-
const history = historyData[entryId] ??
|
|
774
|
+
const history = historyData[entryId] ?? EmptyHistoryDataLanguageMapItem;
|
|
839
775
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
|
|
840
776
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
841
777
|
designSystem.Checkbox,
|
|
@@ -868,8 +804,45 @@ const fetchContentEntriesData = async function(selectedContentType) {
|
|
|
868
804
|
}
|
|
869
805
|
return [];
|
|
870
806
|
};
|
|
807
|
+
const extractDocumentId = function(id) {
|
|
808
|
+
const pos = id.lastIndexOf("#");
|
|
809
|
+
return pos === -1 ? id : id.substring(pos + 1);
|
|
810
|
+
};
|
|
811
|
+
const groupHistory = function(history) {
|
|
812
|
+
const map = {};
|
|
813
|
+
for (const e of history) {
|
|
814
|
+
const id = extractDocumentId(e["element-uid"]);
|
|
815
|
+
if (!map[id]) {
|
|
816
|
+
const data = {
|
|
817
|
+
queued: [],
|
|
818
|
+
intranslation: [],
|
|
819
|
+
translated: []
|
|
820
|
+
};
|
|
821
|
+
map[id] = data;
|
|
822
|
+
}
|
|
823
|
+
const entry = map[id];
|
|
824
|
+
switch (e.status) {
|
|
825
|
+
case "intranslation":
|
|
826
|
+
entry.intranslation.push(e.targetLanguage);
|
|
827
|
+
break;
|
|
828
|
+
case "translated":
|
|
829
|
+
entry.translated.push(e.targetLanguage);
|
|
830
|
+
break;
|
|
831
|
+
default:
|
|
832
|
+
entry.queued.push(e.targetLanguage);
|
|
833
|
+
break;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
for (const key in map) {
|
|
837
|
+
const data = map[key];
|
|
838
|
+
data.intranslation.sort();
|
|
839
|
+
data.queued.sort();
|
|
840
|
+
data.translated.sort();
|
|
841
|
+
}
|
|
842
|
+
return map;
|
|
843
|
+
};
|
|
871
844
|
const BulkTranslationMenu = ({
|
|
872
|
-
|
|
845
|
+
groupedHistoryData,
|
|
873
846
|
isLoadingHistory,
|
|
874
847
|
onTranslationComplete
|
|
875
848
|
}) => {
|
|
@@ -879,7 +852,9 @@ const BulkTranslationMenu = ({
|
|
|
879
852
|
const [selectedEntries, setSelectedEntries] = react.useState(/* @__PURE__ */ new Set());
|
|
880
853
|
const [isLoadingContentTypes, setIsLoadingContentTypes] = react.useState(false);
|
|
881
854
|
const [isLoadingEntries, setIsLoadingEntries] = react.useState(false);
|
|
855
|
+
const [showTranslation, setShowTranslation] = react.useState(false);
|
|
882
856
|
const themeColors = index.getThemeColors();
|
|
857
|
+
const historyItemMap = react.useMemo(() => groupHistory(groupedHistoryData), [groupedHistoryData]);
|
|
883
858
|
const { get } = admin.getFetchClient();
|
|
884
859
|
react.useEffect(() => {
|
|
885
860
|
const fetchContentTypes = async () => {
|
|
@@ -945,7 +920,7 @@ const BulkTranslationMenu = ({
|
|
|
945
920
|
if (contentTypes.length === 0) {
|
|
946
921
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 4, paddingBottom: 4, style: { overflow: "hidden", display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", paddingBottom: 3, style: { fontWeight: "bold" }, children: "No content types available." }) });
|
|
947
922
|
}
|
|
948
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 4, paddingBottom: 4, style: {
|
|
923
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 4, paddingBottom: 4, style: { display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: 1, display: "flex", gap: "16px" }, children: [
|
|
949
924
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
950
925
|
ContentTypesList,
|
|
951
926
|
{
|
|
@@ -962,9 +937,7 @@ const BulkTranslationMenu = ({
|
|
|
962
937
|
style: {
|
|
963
938
|
flex: 1,
|
|
964
939
|
display: "flex",
|
|
965
|
-
flexDirection: "column"
|
|
966
|
-
minWidth: "400px",
|
|
967
|
-
width: "60vw"
|
|
940
|
+
flexDirection: "column"
|
|
968
941
|
},
|
|
969
942
|
children: [
|
|
970
943
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", paddingBottom: 3, style: { fontWeight: "bold" }, children: "Entries" }),
|
|
@@ -974,7 +947,7 @@ const BulkTranslationMenu = ({
|
|
|
974
947
|
entries,
|
|
975
948
|
isLoading: isLoadingEntries,
|
|
976
949
|
selectedEntries,
|
|
977
|
-
historyData,
|
|
950
|
+
historyData: historyItemMap,
|
|
978
951
|
isLoadingHistory,
|
|
979
952
|
onEntrySelection: handleEntrySelection,
|
|
980
953
|
onSelectAll: handleSelectAll,
|
|
@@ -984,34 +957,55 @@ const BulkTranslationMenu = ({
|
|
|
984
957
|
]
|
|
985
958
|
}
|
|
986
959
|
),
|
|
987
|
-
/* @__PURE__ */ jsxRuntime.
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
{
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
960
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
961
|
+
designSystem.Button,
|
|
962
|
+
{
|
|
963
|
+
disabled: selectedEntries.size === 0,
|
|
964
|
+
style: { position: "fixed", right: "5%", bottom: "5%" },
|
|
965
|
+
size: "L",
|
|
966
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Earth, {}),
|
|
967
|
+
onClick: () => {
|
|
968
|
+
setShowTranslation(true);
|
|
969
|
+
},
|
|
970
|
+
children: [
|
|
971
|
+
"Translate ",
|
|
972
|
+
selectedEntries.size,
|
|
973
|
+
" ",
|
|
974
|
+
selectedEntries.size === 1 ? "entry" : "entries"
|
|
975
|
+
]
|
|
976
|
+
}
|
|
977
|
+
),
|
|
978
|
+
showTranslation && /* @__PURE__ */ jsxRuntime.jsx(
|
|
979
|
+
BulkTranslationPanel,
|
|
980
|
+
{
|
|
981
|
+
contentType: selectedContentTypeData,
|
|
982
|
+
selectedEntries: Array.from(selectedEntries),
|
|
983
|
+
onClose: () => setShowTranslation(false),
|
|
984
|
+
onTranslationComplete: () => {
|
|
985
|
+
handleTranslationComplete();
|
|
986
|
+
setShowTranslation(false);
|
|
995
987
|
}
|
|
996
|
-
|
|
997
|
-
|
|
988
|
+
}
|
|
989
|
+
)
|
|
998
990
|
] }) });
|
|
999
991
|
};
|
|
1000
|
-
const
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
992
|
+
const TranslationstudioLogoBox = function() {
|
|
993
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { textAlign: "right", width: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
994
|
+
"picture",
|
|
995
|
+
{
|
|
996
|
+
style: {
|
|
997
|
+
width: "150px",
|
|
998
|
+
height: "auto",
|
|
999
|
+
display: "inline-block"
|
|
1000
|
+
},
|
|
1001
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(index.TranslationstudioLogo, {})
|
|
1002
|
+
}
|
|
1003
|
+
) });
|
|
1012
1004
|
};
|
|
1013
1005
|
const HistoryPage = () => {
|
|
1014
|
-
const [historyData, setHistoryData] = react.useState(
|
|
1006
|
+
const [historyData, setHistoryData] = react.useState([]);
|
|
1007
|
+
const [groupedHistoryData, setGroupedHistoryData] = react.useState([]);
|
|
1008
|
+
const [lastUpdated, setLastUpdated] = react.useState(0);
|
|
1015
1009
|
const [isLoadingHistory, setIsLoadingHistory] = react.useState(true);
|
|
1016
1010
|
const [activeTab, setActiveTab] = react.useState("history");
|
|
1017
1011
|
const { get } = admin.getFetchClient();
|
|
@@ -1022,50 +1016,77 @@ const HistoryPage = () => {
|
|
|
1022
1016
|
const result = index.handleHistoryResponse(response.data);
|
|
1023
1017
|
if (result.isError)
|
|
1024
1018
|
throw new Error("Cold not fetch data");
|
|
1025
|
-
if (result.historyData && Array.isArray(result.historyData))
|
|
1026
|
-
setHistoryData(
|
|
1019
|
+
if (result.historyData && Array.isArray(result.historyData)) {
|
|
1020
|
+
setHistoryData(result.historyData);
|
|
1021
|
+
setGroupedHistoryData(index.groupHistoryData(result.historyData));
|
|
1022
|
+
setLastUpdated(Date.now());
|
|
1023
|
+
}
|
|
1027
1024
|
} catch (error) {
|
|
1028
1025
|
console.error("Failed to fetch history:", error);
|
|
1029
|
-
setHistoryData(
|
|
1026
|
+
setHistoryData([]);
|
|
1027
|
+
setGroupedHistoryData([]);
|
|
1030
1028
|
} finally {
|
|
1031
1029
|
setIsLoadingHistory(false);
|
|
1032
1030
|
}
|
|
1033
1031
|
};
|
|
1034
1032
|
fetchHistory();
|
|
1035
|
-
}, [setHistoryData, setIsLoadingHistory]);
|
|
1033
|
+
}, [setHistoryData, setIsLoadingHistory, setGroupedHistoryData, setLastUpdated]);
|
|
1036
1034
|
const refreshHistoryData = async () => {
|
|
1037
1035
|
setIsLoadingHistory(true);
|
|
1038
1036
|
try {
|
|
1039
1037
|
const response = await get("/translationstudio/history");
|
|
1040
1038
|
const result = index.handleHistoryResponse(response.data);
|
|
1041
|
-
if (result.isError)
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1039
|
+
if (result.isError) {
|
|
1040
|
+
setGroupedHistoryData([]);
|
|
1041
|
+
setHistoryData([]);
|
|
1042
|
+
} else if (result.historyData && Array.isArray(result.historyData)) {
|
|
1043
|
+
setHistoryData(result.historyData);
|
|
1044
|
+
setGroupedHistoryData(index.groupHistoryData(result.historyData));
|
|
1045
|
+
setLastUpdated(Date.now());
|
|
1046
|
+
}
|
|
1045
1047
|
} catch (error) {
|
|
1046
|
-
setHistoryData(
|
|
1048
|
+
setHistoryData([]);
|
|
1049
|
+
setGroupedHistoryData([]);
|
|
1047
1050
|
} finally {
|
|
1048
1051
|
setIsLoadingHistory(false);
|
|
1049
1052
|
}
|
|
1050
1053
|
};
|
|
1054
|
+
const onRefreshHistoryClick = function() {
|
|
1055
|
+
if (Date.now() - lastUpdated > 1e3 * 60 * 5)
|
|
1056
|
+
refreshHistoryData();
|
|
1057
|
+
};
|
|
1058
|
+
const onChangePage = function(input) {
|
|
1059
|
+
onRefreshHistoryClick();
|
|
1060
|
+
setActiveTab(input);
|
|
1061
|
+
};
|
|
1062
|
+
const removeHistoryEntry = function(id) {
|
|
1063
|
+
if (!id || historyData.length === 0)
|
|
1064
|
+
return;
|
|
1065
|
+
if (historyData.length === 1) {
|
|
1066
|
+
setHistoryData([]);
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
let index$1 = -1;
|
|
1070
|
+
for (let i = 0; i < historyData.length && index$1 === -1; i++) {
|
|
1071
|
+
if (historyData[i].id === id)
|
|
1072
|
+
index$1 = i;
|
|
1073
|
+
}
|
|
1074
|
+
if (index$1 === -1)
|
|
1075
|
+
return;
|
|
1076
|
+
historyData.splice(index$1, 1);
|
|
1077
|
+
const res = [...historyData];
|
|
1078
|
+
setHistoryData(res);
|
|
1079
|
+
setGroupedHistoryData(index.groupHistoryData(res));
|
|
1080
|
+
};
|
|
1051
1081
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 10, style: { minHeight: "90vh", marginTop: "5vh" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { children: [
|
|
1052
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { xs: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1053
|
-
"picture",
|
|
1054
|
-
{
|
|
1055
|
-
style: {
|
|
1056
|
-
width: "150px",
|
|
1057
|
-
height: "auto",
|
|
1058
|
-
display: "inline-block"
|
|
1059
|
-
},
|
|
1060
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(index.TranslationstudioLogo, {})
|
|
1061
|
-
}
|
|
1062
|
-
) }) }),
|
|
1082
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { xs: 12, children: /* @__PURE__ */ jsxRuntime.jsx(TranslationstudioLogoBox, {}) }),
|
|
1063
1083
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { xs: 12, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
|
1064
1084
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1065
1085
|
designSystem.Button,
|
|
1066
1086
|
{
|
|
1067
1087
|
variant: activeTab === "history" ? "default" : "tertiary",
|
|
1068
|
-
|
|
1088
|
+
disabled: isLoadingHistory,
|
|
1089
|
+
onClick: () => onChangePage("history"),
|
|
1069
1090
|
children: "Translation History"
|
|
1070
1091
|
}
|
|
1071
1092
|
),
|
|
@@ -1073,7 +1094,8 @@ const HistoryPage = () => {
|
|
|
1073
1094
|
designSystem.Button,
|
|
1074
1095
|
{
|
|
1075
1096
|
variant: activeTab === "bulk" ? "default" : "tertiary",
|
|
1076
|
-
|
|
1097
|
+
disabled: isLoadingHistory,
|
|
1098
|
+
onClick: () => onChangePage("bulk"),
|
|
1077
1099
|
children: "Translate multiple entries"
|
|
1078
1100
|
}
|
|
1079
1101
|
)
|
|
@@ -1082,7 +1104,7 @@ const HistoryPage = () => {
|
|
|
1082
1104
|
activeTab === "bulk" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1083
1105
|
BulkTranslationMenu,
|
|
1084
1106
|
{
|
|
1085
|
-
|
|
1107
|
+
groupedHistoryData,
|
|
1086
1108
|
isLoadingHistory,
|
|
1087
1109
|
onTranslationComplete: refreshHistoryData
|
|
1088
1110
|
}
|
|
@@ -1090,9 +1112,8 @@ const HistoryPage = () => {
|
|
|
1090
1112
|
activeTab === "history" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1091
1113
|
HistoryMenu,
|
|
1092
1114
|
{
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
onRefresh: refreshHistoryData
|
|
1115
|
+
groupedHistoryData,
|
|
1116
|
+
onRemoveHistoryItem: (id) => removeHistoryEntry(id)
|
|
1096
1117
|
}
|
|
1097
1118
|
)
|
|
1098
1119
|
] })
|