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