@goenhance/strapi-plugins-translate 1.0.0 → 1.0.2
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/_chunks/{App-uB_CPrcd.mjs → App-CH4LpMAi.mjs} +131 -62
- package/dist/_chunks/{App-DvJ8tPer.js → App-COp30Bhv.js} +131 -62
- package/dist/_chunks/en-D2smyOgo.mjs +68 -0
- package/dist/_chunks/en-DUvTuZTY.js +68 -0
- package/dist/_chunks/{index-DkZZ45sW.mjs → index-NYuUIL7z.mjs} +2 -2
- package/dist/_chunks/{index-B8MBOdIV.js → index-yeAqhdmn.js} +2 -2
- package/dist/_chunks/{zh-CtGwhmjc.mjs → zh-Byx4OrFn.mjs} +3 -0
- package/dist/_chunks/{zh-DUCnaWvE.js → zh-DFUisXeH.js} +3 -0
- package/dist/_chunks/{zh-Hans-CJW3RUKL.js → zh-Hans-BroQrclN.js} +3 -0
- package/dist/_chunks/{zh-Hans-pTiPqgIS.mjs → zh-Hans-DIdLcpcG.mjs} +3 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +490 -48
- package/dist/server/index.mjs +490 -48
- package/dist/server/src/controllers/admin.controller.d.ts +5 -0
- package/dist/server/src/controllers/index.d.ts +15 -0
- package/dist/server/src/services/batch-translation-service.d.ts +4 -0
- package/dist/server/src/utils/feishu-notifier.d.ts +19 -0
- package/package.json +1 -1
- package/dist/_chunks/en-BOBGCAB6.mjs +0 -65
- package/dist/_chunks/en-BaJyCZ_c.js +0 -65
|
@@ -5,7 +5,7 @@ import { useState, useEffect, useCallback } from "react";
|
|
|
5
5
|
import { useIntl } from "react-intl";
|
|
6
6
|
import { Main, Box, Flex, Loader, Typography, Button, Field, SingleSelect, SingleSelectOption, MultiSelect, MultiSelectOption, Toggle, EmptyStateLayout, Table, Thead, Tr, Th, Checkbox, Tbody, Td, Badge, Textarea, NumberInput, TextInput } from "@strapi/design-system";
|
|
7
7
|
import { Cog, Magic, Check, Cross, ChevronLeft, ChevronRight, ArrowLeft } from "@strapi/icons";
|
|
8
|
-
import { P as PLUGIN_ID, g as getTranslation, a as PluginIcon } from "./index-
|
|
8
|
+
import { P as PLUGIN_ID, g as getTranslation, a as PluginIcon } from "./index-NYuUIL7z.mjs";
|
|
9
9
|
const BatchTranslatePage = () => {
|
|
10
10
|
const { formatMessage } = useIntl();
|
|
11
11
|
const { get, post } = useFetchClient();
|
|
@@ -22,7 +22,7 @@ const BatchTranslatePage = () => {
|
|
|
22
22
|
const [loadingEntries, setLoadingEntries] = useState(false);
|
|
23
23
|
const [pagination, setPagination] = useState({
|
|
24
24
|
page: 1,
|
|
25
|
-
pageSize:
|
|
25
|
+
pageSize: 15,
|
|
26
26
|
total: 0,
|
|
27
27
|
pageCount: 0
|
|
28
28
|
});
|
|
@@ -36,11 +36,22 @@ const BatchTranslatePage = () => {
|
|
|
36
36
|
get(`/${PLUGIN_ID}/content-types`),
|
|
37
37
|
get(`/${PLUGIN_ID}/locales`)
|
|
38
38
|
]);
|
|
39
|
+
const localesData = localesRes.data.data || [];
|
|
39
40
|
setContentTypes(contentTypesRes.data.data || []);
|
|
40
|
-
setLocales(
|
|
41
|
-
const
|
|
42
|
-
|
|
41
|
+
setLocales(localesData);
|
|
42
|
+
const englishLocale = localesData.find(
|
|
43
|
+
(l) => l.code === "en" || l.code.startsWith("en-")
|
|
44
|
+
);
|
|
45
|
+
const defaultLocale = localesData.find((l) => l.isDefault);
|
|
46
|
+
if (englishLocale) {
|
|
47
|
+
console.log("Setting default source locale to English:", englishLocale.code);
|
|
48
|
+
setSourceLocale(englishLocale.code);
|
|
49
|
+
} else if (defaultLocale) {
|
|
50
|
+
console.log("Setting default source locale to default:", defaultLocale.code);
|
|
43
51
|
setSourceLocale(defaultLocale.code);
|
|
52
|
+
} else if (localesData.length > 0) {
|
|
53
|
+
console.log("Setting default source locale to first available:", localesData[0].code);
|
|
54
|
+
setSourceLocale(localesData[0].code);
|
|
44
55
|
}
|
|
45
56
|
} catch (error) {
|
|
46
57
|
console.error("Error fetching initial data:", error);
|
|
@@ -95,9 +106,13 @@ const BatchTranslatePage = () => {
|
|
|
95
106
|
}
|
|
96
107
|
};
|
|
97
108
|
const handleSelectEntry = (documentId) => {
|
|
98
|
-
setSelectedEntries(
|
|
99
|
-
(prev
|
|
100
|
-
|
|
109
|
+
setSelectedEntries((prev) => {
|
|
110
|
+
if (prev.includes(documentId)) {
|
|
111
|
+
return prev.filter((id) => id !== documentId);
|
|
112
|
+
} else {
|
|
113
|
+
return [...prev, documentId];
|
|
114
|
+
}
|
|
115
|
+
});
|
|
101
116
|
};
|
|
102
117
|
const availableTargetLocales = locales.filter((l) => l.code !== sourceLocale);
|
|
103
118
|
const handleBatchTranslate = async () => {
|
|
@@ -112,7 +127,6 @@ const BatchTranslatePage = () => {
|
|
|
112
127
|
return;
|
|
113
128
|
}
|
|
114
129
|
setTranslating(true);
|
|
115
|
-
setResults([]);
|
|
116
130
|
try {
|
|
117
131
|
const response = await post(`/${PLUGIN_ID}/batch-translate`, {
|
|
118
132
|
contentType: selectedContentType,
|
|
@@ -121,26 +135,32 @@ const BatchTranslatePage = () => {
|
|
|
121
135
|
targetLocales,
|
|
122
136
|
publish: publishAfterTranslate
|
|
123
137
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
if (response.data.meta?.ok) {
|
|
139
|
+
toggleNotification({
|
|
140
|
+
type: "success",
|
|
141
|
+
message: response.data.meta.message || formatMessage({
|
|
142
|
+
id: getTranslation("batch.success.taskStarted"),
|
|
143
|
+
defaultMessage: "Translation task started. You will receive a Feishu notification when it completes."
|
|
144
|
+
})
|
|
145
|
+
});
|
|
146
|
+
setSelectedEntries([]);
|
|
147
|
+
setResults([]);
|
|
148
|
+
} else {
|
|
149
|
+
toggleNotification({
|
|
150
|
+
type: "danger",
|
|
151
|
+
message: response.data.meta?.message || formatMessage({
|
|
152
|
+
id: getTranslation("batch.error.translate"),
|
|
153
|
+
defaultMessage: "Failed to start translation task"
|
|
154
|
+
})
|
|
155
|
+
});
|
|
156
|
+
}
|
|
137
157
|
} catch (error) {
|
|
138
158
|
console.error("Error during batch translation:", error);
|
|
139
159
|
toggleNotification({
|
|
140
160
|
type: "danger",
|
|
141
161
|
message: formatMessage({
|
|
142
162
|
id: getTranslation("batch.error.translate"),
|
|
143
|
-
defaultMessage: "
|
|
163
|
+
defaultMessage: "Failed to start translation task"
|
|
144
164
|
})
|
|
145
165
|
});
|
|
146
166
|
} finally {
|
|
@@ -245,10 +265,33 @@ const BatchTranslatePage = () => {
|
|
|
245
265
|
)
|
|
246
266
|
] }) }),
|
|
247
267
|
/* @__PURE__ */ jsx(Box, { flex: "1", minWidth: "200px", children: /* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
248
|
-
/* @__PURE__ */
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
268
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", alignItems: "center", justifyContent: "space-between", gap: 4, children: [
|
|
269
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
|
270
|
+
id: getTranslation("batch.filters.targetLocales"),
|
|
271
|
+
defaultMessage: "Target Languages"
|
|
272
|
+
}) }),
|
|
273
|
+
/* @__PURE__ */ jsx(
|
|
274
|
+
Button,
|
|
275
|
+
{
|
|
276
|
+
variant: "secondary",
|
|
277
|
+
size: "S",
|
|
278
|
+
onClick: () => {
|
|
279
|
+
if (targetLocales.length === availableTargetLocales.length) {
|
|
280
|
+
setTargetLocales([]);
|
|
281
|
+
} else {
|
|
282
|
+
setTargetLocales(availableTargetLocales.map((l) => l.code));
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
children: targetLocales.length === availableTargetLocales.length ? formatMessage({
|
|
286
|
+
id: getTranslation("batch.filters.deselectAll"),
|
|
287
|
+
defaultMessage: "Deselect All"
|
|
288
|
+
}) : formatMessage({
|
|
289
|
+
id: getTranslation("batch.filters.selectAll"),
|
|
290
|
+
defaultMessage: "Select All"
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
)
|
|
294
|
+
] }),
|
|
252
295
|
/* @__PURE__ */ jsx(
|
|
253
296
|
MultiSelect,
|
|
254
297
|
{
|
|
@@ -335,13 +378,13 @@ const BatchTranslatePage = () => {
|
|
|
335
378
|
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
336
379
|
/* @__PURE__ */ jsxs(Table, { colCount: 6, rowCount: entries.length + 1, children: [
|
|
337
380
|
/* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
|
|
338
|
-
/* @__PURE__ */ jsx(Th, { style: { width: "40px" }, children: /* @__PURE__ */ jsx(
|
|
381
|
+
/* @__PURE__ */ jsx(Th, { style: { width: "40px" }, children: /* @__PURE__ */ jsx("div", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx(
|
|
339
382
|
Checkbox,
|
|
340
383
|
{
|
|
341
384
|
checked: selectedEntries.length === entries.length && entries.length > 0,
|
|
342
385
|
onCheckedChange: handleSelectAll
|
|
343
386
|
}
|
|
344
|
-
) }),
|
|
387
|
+
) }) }),
|
|
345
388
|
/* @__PURE__ */ jsx(Th, { style: { maxWidth: "160px" }, children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: formatMessage({
|
|
346
389
|
id: getTranslation("batch.table.id"),
|
|
347
390
|
defaultMessage: "ID"
|
|
@@ -365,40 +408,66 @@ const BatchTranslatePage = () => {
|
|
|
365
408
|
] }) }),
|
|
366
409
|
/* @__PURE__ */ jsx(Tbody, { children: entries.map((entry) => {
|
|
367
410
|
const missingLocales = getMissingLocales(entry);
|
|
368
|
-
const entryResults = results.filter(
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
{
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
}
|
|
378
|
-
) }),
|
|
379
|
-
/* @__PURE__ */ jsx(Td, { style: { maxWidth: "160px", wordBreak: "break-word" }, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "omega", style: { wordBreak: "break-word", whiteSpace: "wrap" }, children: entry.customId || entry.id }) }),
|
|
380
|
-
/* @__PURE__ */ jsx(Td, { style: { maxWidth: "200px", wordBreak: "break-word" }, children: /* @__PURE__ */ jsx(Typography, { style: { wordBreak: "break-word", whiteSpace: "wrap" }, children: entry.title }) }),
|
|
381
|
-
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { gap: 1, wrap: "wrap", children: entry.existingLocales.map((locale) => /* @__PURE__ */ jsx(Badge, { backgroundColor: "neutral150", children: getLocaleDisplay(locale) }, locale)) }) }),
|
|
382
|
-
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { gap: 1, wrap: "wrap", children: targetLocales.length > 0 ? missingLocales.length > 0 ? missingLocales.map((locale) => /* @__PURE__ */ jsx(Badge, { backgroundColor: "warning100", textColor: "warning700", children: getLocaleDisplay(locale) }, locale)) : /* @__PURE__ */ jsx(Badge, { backgroundColor: "success100", textColor: "success700", children: formatMessage({
|
|
383
|
-
id: getTranslation("batch.table.allTranslated"),
|
|
384
|
-
defaultMessage: "All translated"
|
|
385
|
-
}) }) : /* @__PURE__ */ jsx(Typography, { textColor: "neutral500", children: formatMessage({
|
|
386
|
-
id: getTranslation("batch.table.selectTargets"),
|
|
387
|
-
defaultMessage: "Select target languages"
|
|
388
|
-
}) }) }) }),
|
|
389
|
-
/* @__PURE__ */ jsx(Td, { children: entryResults.length > 0 ? /* @__PURE__ */ jsx(Flex, { gap: 1, wrap: "wrap", children: entryResults.map((result) => /* @__PURE__ */ jsx(
|
|
390
|
-
Badge,
|
|
391
|
-
{
|
|
392
|
-
backgroundColor: result.success ? "success100" : "danger100",
|
|
393
|
-
textColor: result.success ? "success700" : "danger700",
|
|
394
|
-
children: /* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", children: [
|
|
395
|
-
result.success ? /* @__PURE__ */ jsx(Check, { width: 12, height: 12 }) : /* @__PURE__ */ jsx(Cross, { width: 12, height: 12 }),
|
|
396
|
-
result.locale
|
|
397
|
-
] })
|
|
411
|
+
const entryResults = results.filter((r) => r.documentId === entry.documentId);
|
|
412
|
+
const isSelected = selectedEntries.includes(entry.documentId);
|
|
413
|
+
return /* @__PURE__ */ jsxs(
|
|
414
|
+
Tr,
|
|
415
|
+
{
|
|
416
|
+
onClick: () => handleSelectEntry(entry.documentId),
|
|
417
|
+
style: {
|
|
418
|
+
cursor: "pointer",
|
|
419
|
+
backgroundColor: isSelected ? "rgba(85, 82, 255, 0.05)" : "transparent"
|
|
398
420
|
},
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
421
|
+
children: [
|
|
422
|
+
/* @__PURE__ */ jsx(Td, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx(
|
|
423
|
+
Checkbox,
|
|
424
|
+
{
|
|
425
|
+
checked: isSelected,
|
|
426
|
+
onCheckedChange: () => handleSelectEntry(entry.documentId)
|
|
427
|
+
}
|
|
428
|
+
) }),
|
|
429
|
+
/* @__PURE__ */ jsx(Td, { style: { maxWidth: "160px", wordBreak: "break-word" }, children: /* @__PURE__ */ jsx(
|
|
430
|
+
Typography,
|
|
431
|
+
{
|
|
432
|
+
textColor: "neutral600",
|
|
433
|
+
variant: "omega",
|
|
434
|
+
style: { wordBreak: "break-word", whiteSpace: "wrap" },
|
|
435
|
+
children: entry.customId || entry.id
|
|
436
|
+
}
|
|
437
|
+
) }),
|
|
438
|
+
/* @__PURE__ */ jsx(Td, { style: { maxWidth: "200px", wordBreak: "break-word" }, children: /* @__PURE__ */ jsx(Typography, { style: { wordBreak: "break-word", whiteSpace: "wrap" }, children: entry.title }) }),
|
|
439
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { gap: 1, wrap: "wrap", children: entry.existingLocales.map((locale) => /* @__PURE__ */ jsx(Badge, { backgroundColor: "neutral150", children: getLocaleDisplay(locale) }, locale)) }) }),
|
|
440
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { gap: 1, wrap: "wrap", children: targetLocales.length > 0 ? missingLocales.length > 0 ? missingLocales.map((locale) => /* @__PURE__ */ jsx(
|
|
441
|
+
Badge,
|
|
442
|
+
{
|
|
443
|
+
backgroundColor: "warning100",
|
|
444
|
+
textColor: "warning700",
|
|
445
|
+
children: getLocaleDisplay(locale)
|
|
446
|
+
},
|
|
447
|
+
locale
|
|
448
|
+
)) : /* @__PURE__ */ jsx(Badge, { backgroundColor: "success100", textColor: "success700", children: formatMessage({
|
|
449
|
+
id: getTranslation("batch.table.allTranslated"),
|
|
450
|
+
defaultMessage: "All translated"
|
|
451
|
+
}) }) : /* @__PURE__ */ jsx(Typography, { textColor: "neutral500", children: formatMessage({
|
|
452
|
+
id: getTranslation("batch.table.selectTargets"),
|
|
453
|
+
defaultMessage: "Select target languages"
|
|
454
|
+
}) }) }) }),
|
|
455
|
+
/* @__PURE__ */ jsx(Td, { children: entryResults.length > 0 ? /* @__PURE__ */ jsx(Flex, { gap: 1, wrap: "wrap", children: entryResults.map((result) => /* @__PURE__ */ jsx(
|
|
456
|
+
Badge,
|
|
457
|
+
{
|
|
458
|
+
backgroundColor: result.success ? "success100" : "danger100",
|
|
459
|
+
textColor: result.success ? "success700" : "danger700",
|
|
460
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", children: [
|
|
461
|
+
result.success ? /* @__PURE__ */ jsx(Check, { width: 12, height: 12 }) : /* @__PURE__ */ jsx(Cross, { width: 12, height: 12 }),
|
|
462
|
+
result.locale
|
|
463
|
+
] })
|
|
464
|
+
},
|
|
465
|
+
result.locale
|
|
466
|
+
)) }) : /* @__PURE__ */ jsx(Typography, { textColor: "neutral500", children: "-" }) })
|
|
467
|
+
]
|
|
468
|
+
},
|
|
469
|
+
entry.documentId
|
|
470
|
+
);
|
|
402
471
|
}) })
|
|
403
472
|
] }),
|
|
404
473
|
pagination.pageCount > 1 && /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginTop: 4, children: [
|
|
@@ -7,7 +7,7 @@ const react = require("react");
|
|
|
7
7
|
const reactIntl = require("react-intl");
|
|
8
8
|
const designSystem = require("@strapi/design-system");
|
|
9
9
|
const icons = require("@strapi/icons");
|
|
10
|
-
const index = require("./index-
|
|
10
|
+
const index = require("./index-yeAqhdmn.js");
|
|
11
11
|
const BatchTranslatePage = () => {
|
|
12
12
|
const { formatMessage } = reactIntl.useIntl();
|
|
13
13
|
const { get, post } = admin.useFetchClient();
|
|
@@ -24,7 +24,7 @@ const BatchTranslatePage = () => {
|
|
|
24
24
|
const [loadingEntries, setLoadingEntries] = react.useState(false);
|
|
25
25
|
const [pagination, setPagination] = react.useState({
|
|
26
26
|
page: 1,
|
|
27
|
-
pageSize:
|
|
27
|
+
pageSize: 15,
|
|
28
28
|
total: 0,
|
|
29
29
|
pageCount: 0
|
|
30
30
|
});
|
|
@@ -38,11 +38,22 @@ const BatchTranslatePage = () => {
|
|
|
38
38
|
get(`/${index.PLUGIN_ID}/content-types`),
|
|
39
39
|
get(`/${index.PLUGIN_ID}/locales`)
|
|
40
40
|
]);
|
|
41
|
+
const localesData = localesRes.data.data || [];
|
|
41
42
|
setContentTypes(contentTypesRes.data.data || []);
|
|
42
|
-
setLocales(
|
|
43
|
-
const
|
|
44
|
-
|
|
43
|
+
setLocales(localesData);
|
|
44
|
+
const englishLocale = localesData.find(
|
|
45
|
+
(l) => l.code === "en" || l.code.startsWith("en-")
|
|
46
|
+
);
|
|
47
|
+
const defaultLocale = localesData.find((l) => l.isDefault);
|
|
48
|
+
if (englishLocale) {
|
|
49
|
+
console.log("Setting default source locale to English:", englishLocale.code);
|
|
50
|
+
setSourceLocale(englishLocale.code);
|
|
51
|
+
} else if (defaultLocale) {
|
|
52
|
+
console.log("Setting default source locale to default:", defaultLocale.code);
|
|
45
53
|
setSourceLocale(defaultLocale.code);
|
|
54
|
+
} else if (localesData.length > 0) {
|
|
55
|
+
console.log("Setting default source locale to first available:", localesData[0].code);
|
|
56
|
+
setSourceLocale(localesData[0].code);
|
|
46
57
|
}
|
|
47
58
|
} catch (error) {
|
|
48
59
|
console.error("Error fetching initial data:", error);
|
|
@@ -97,9 +108,13 @@ const BatchTranslatePage = () => {
|
|
|
97
108
|
}
|
|
98
109
|
};
|
|
99
110
|
const handleSelectEntry = (documentId) => {
|
|
100
|
-
setSelectedEntries(
|
|
101
|
-
(prev
|
|
102
|
-
|
|
111
|
+
setSelectedEntries((prev) => {
|
|
112
|
+
if (prev.includes(documentId)) {
|
|
113
|
+
return prev.filter((id) => id !== documentId);
|
|
114
|
+
} else {
|
|
115
|
+
return [...prev, documentId];
|
|
116
|
+
}
|
|
117
|
+
});
|
|
103
118
|
};
|
|
104
119
|
const availableTargetLocales = locales.filter((l) => l.code !== sourceLocale);
|
|
105
120
|
const handleBatchTranslate = async () => {
|
|
@@ -114,7 +129,6 @@ const BatchTranslatePage = () => {
|
|
|
114
129
|
return;
|
|
115
130
|
}
|
|
116
131
|
setTranslating(true);
|
|
117
|
-
setResults([]);
|
|
118
132
|
try {
|
|
119
133
|
const response = await post(`/${index.PLUGIN_ID}/batch-translate`, {
|
|
120
134
|
contentType: selectedContentType,
|
|
@@ -123,26 +137,32 @@ const BatchTranslatePage = () => {
|
|
|
123
137
|
targetLocales,
|
|
124
138
|
publish: publishAfterTranslate
|
|
125
139
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
if (response.data.meta?.ok) {
|
|
141
|
+
toggleNotification({
|
|
142
|
+
type: "success",
|
|
143
|
+
message: response.data.meta.message || formatMessage({
|
|
144
|
+
id: index.getTranslation("batch.success.taskStarted"),
|
|
145
|
+
defaultMessage: "Translation task started. You will receive a Feishu notification when it completes."
|
|
146
|
+
})
|
|
147
|
+
});
|
|
148
|
+
setSelectedEntries([]);
|
|
149
|
+
setResults([]);
|
|
150
|
+
} else {
|
|
151
|
+
toggleNotification({
|
|
152
|
+
type: "danger",
|
|
153
|
+
message: response.data.meta?.message || formatMessage({
|
|
154
|
+
id: index.getTranslation("batch.error.translate"),
|
|
155
|
+
defaultMessage: "Failed to start translation task"
|
|
156
|
+
})
|
|
157
|
+
});
|
|
158
|
+
}
|
|
139
159
|
} catch (error) {
|
|
140
160
|
console.error("Error during batch translation:", error);
|
|
141
161
|
toggleNotification({
|
|
142
162
|
type: "danger",
|
|
143
163
|
message: formatMessage({
|
|
144
164
|
id: index.getTranslation("batch.error.translate"),
|
|
145
|
-
defaultMessage: "
|
|
165
|
+
defaultMessage: "Failed to start translation task"
|
|
146
166
|
})
|
|
147
167
|
});
|
|
148
168
|
} finally {
|
|
@@ -247,10 +267,33 @@ const BatchTranslatePage = () => {
|
|
|
247
267
|
)
|
|
248
268
|
] }) }),
|
|
249
269
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { flex: "1", minWidth: "200px", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
|
|
250
|
-
/* @__PURE__ */ jsxRuntime.
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
270
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", alignItems: "center", justifyContent: "space-between", gap: 4, children: [
|
|
271
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
|
|
272
|
+
id: index.getTranslation("batch.filters.targetLocales"),
|
|
273
|
+
defaultMessage: "Target Languages"
|
|
274
|
+
}) }),
|
|
275
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
276
|
+
designSystem.Button,
|
|
277
|
+
{
|
|
278
|
+
variant: "secondary",
|
|
279
|
+
size: "S",
|
|
280
|
+
onClick: () => {
|
|
281
|
+
if (targetLocales.length === availableTargetLocales.length) {
|
|
282
|
+
setTargetLocales([]);
|
|
283
|
+
} else {
|
|
284
|
+
setTargetLocales(availableTargetLocales.map((l) => l.code));
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
children: targetLocales.length === availableTargetLocales.length ? formatMessage({
|
|
288
|
+
id: index.getTranslation("batch.filters.deselectAll"),
|
|
289
|
+
defaultMessage: "Deselect All"
|
|
290
|
+
}) : formatMessage({
|
|
291
|
+
id: index.getTranslation("batch.filters.selectAll"),
|
|
292
|
+
defaultMessage: "Select All"
|
|
293
|
+
})
|
|
294
|
+
}
|
|
295
|
+
)
|
|
296
|
+
] }),
|
|
254
297
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
255
298
|
designSystem.MultiSelect,
|
|
256
299
|
{
|
|
@@ -337,13 +380,13 @@ const BatchTranslatePage = () => {
|
|
|
337
380
|
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
338
381
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { colCount: 6, rowCount: entries.length + 1, children: [
|
|
339
382
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
|
|
340
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { style: { width: "40px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
383
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { style: { width: "40px" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
341
384
|
designSystem.Checkbox,
|
|
342
385
|
{
|
|
343
386
|
checked: selectedEntries.length === entries.length && entries.length > 0,
|
|
344
387
|
onCheckedChange: handleSelectAll
|
|
345
388
|
}
|
|
346
|
-
) }),
|
|
389
|
+
) }) }),
|
|
347
390
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { style: { maxWidth: "160px" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: formatMessage({
|
|
348
391
|
id: index.getTranslation("batch.table.id"),
|
|
349
392
|
defaultMessage: "ID"
|
|
@@ -367,40 +410,66 @@ const BatchTranslatePage = () => {
|
|
|
367
410
|
] }) }),
|
|
368
411
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: entries.map((entry) => {
|
|
369
412
|
const missingLocales = getMissingLocales(entry);
|
|
370
|
-
const entryResults = results.filter(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
{
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
) }),
|
|
381
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { maxWidth: "160px", wordBreak: "break-word" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "omega", style: { wordBreak: "break-word", whiteSpace: "wrap" }, children: entry.customId || entry.id }) }),
|
|
382
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { maxWidth: "200px", wordBreak: "break-word" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { style: { wordBreak: "break-word", whiteSpace: "wrap" }, children: entry.title }) }),
|
|
383
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, wrap: "wrap", children: entry.existingLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "neutral150", children: getLocaleDisplay(locale) }, locale)) }) }),
|
|
384
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, wrap: "wrap", children: targetLocales.length > 0 ? missingLocales.length > 0 ? missingLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "warning100", textColor: "warning700", children: getLocaleDisplay(locale) }, locale)) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", children: formatMessage({
|
|
385
|
-
id: index.getTranslation("batch.table.allTranslated"),
|
|
386
|
-
defaultMessage: "All translated"
|
|
387
|
-
}) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral500", children: formatMessage({
|
|
388
|
-
id: index.getTranslation("batch.table.selectTargets"),
|
|
389
|
-
defaultMessage: "Select target languages"
|
|
390
|
-
}) }) }) }),
|
|
391
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: entryResults.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, wrap: "wrap", children: entryResults.map((result) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
392
|
-
designSystem.Badge,
|
|
393
|
-
{
|
|
394
|
-
backgroundColor: result.success ? "success100" : "danger100",
|
|
395
|
-
textColor: result.success ? "success700" : "danger700",
|
|
396
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, alignItems: "center", children: [
|
|
397
|
-
result.success ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, { width: 12, height: 12 }) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, { width: 12, height: 12 }),
|
|
398
|
-
result.locale
|
|
399
|
-
] })
|
|
413
|
+
const entryResults = results.filter((r) => r.documentId === entry.documentId);
|
|
414
|
+
const isSelected = selectedEntries.includes(entry.documentId);
|
|
415
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
416
|
+
designSystem.Tr,
|
|
417
|
+
{
|
|
418
|
+
onClick: () => handleSelectEntry(entry.documentId),
|
|
419
|
+
style: {
|
|
420
|
+
cursor: "pointer",
|
|
421
|
+
backgroundColor: isSelected ? "rgba(85, 82, 255, 0.05)" : "transparent"
|
|
400
422
|
},
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
423
|
+
children: [
|
|
424
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
425
|
+
designSystem.Checkbox,
|
|
426
|
+
{
|
|
427
|
+
checked: isSelected,
|
|
428
|
+
onCheckedChange: () => handleSelectEntry(entry.documentId)
|
|
429
|
+
}
|
|
430
|
+
) }),
|
|
431
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { maxWidth: "160px", wordBreak: "break-word" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
432
|
+
designSystem.Typography,
|
|
433
|
+
{
|
|
434
|
+
textColor: "neutral600",
|
|
435
|
+
variant: "omega",
|
|
436
|
+
style: { wordBreak: "break-word", whiteSpace: "wrap" },
|
|
437
|
+
children: entry.customId || entry.id
|
|
438
|
+
}
|
|
439
|
+
) }),
|
|
440
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { maxWidth: "200px", wordBreak: "break-word" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { style: { wordBreak: "break-word", whiteSpace: "wrap" }, children: entry.title }) }),
|
|
441
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, wrap: "wrap", children: entry.existingLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "neutral150", children: getLocaleDisplay(locale) }, locale)) }) }),
|
|
442
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, wrap: "wrap", children: targetLocales.length > 0 ? missingLocales.length > 0 ? missingLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
443
|
+
designSystem.Badge,
|
|
444
|
+
{
|
|
445
|
+
backgroundColor: "warning100",
|
|
446
|
+
textColor: "warning700",
|
|
447
|
+
children: getLocaleDisplay(locale)
|
|
448
|
+
},
|
|
449
|
+
locale
|
|
450
|
+
)) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", children: formatMessage({
|
|
451
|
+
id: index.getTranslation("batch.table.allTranslated"),
|
|
452
|
+
defaultMessage: "All translated"
|
|
453
|
+
}) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral500", children: formatMessage({
|
|
454
|
+
id: index.getTranslation("batch.table.selectTargets"),
|
|
455
|
+
defaultMessage: "Select target languages"
|
|
456
|
+
}) }) }) }),
|
|
457
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: entryResults.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, wrap: "wrap", children: entryResults.map((result) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
458
|
+
designSystem.Badge,
|
|
459
|
+
{
|
|
460
|
+
backgroundColor: result.success ? "success100" : "danger100",
|
|
461
|
+
textColor: result.success ? "success700" : "danger700",
|
|
462
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, alignItems: "center", children: [
|
|
463
|
+
result.success ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, { width: 12, height: 12 }) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, { width: 12, height: 12 }),
|
|
464
|
+
result.locale
|
|
465
|
+
] })
|
|
466
|
+
},
|
|
467
|
+
result.locale
|
|
468
|
+
)) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral500", children: "-" }) })
|
|
469
|
+
]
|
|
470
|
+
},
|
|
471
|
+
entry.documentId
|
|
472
|
+
);
|
|
404
473
|
}) })
|
|
405
474
|
] }),
|
|
406
475
|
pagination.pageCount > 1 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", marginTop: 4, children: [
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const en = {
|
|
2
|
+
"strapi-plugins-translate.button.label.error": "翻译失败",
|
|
3
|
+
"strapi-plugins-translate.button.label.idle": "使用 AI 翻译",
|
|
4
|
+
"strapi-plugins-translate.button.label.loading": "正在翻译内容...",
|
|
5
|
+
"strapi-plugins-translate.button.label.success": "翻译已完成",
|
|
6
|
+
"strapi-plugins-translate.button.tooltip.disabled": "翻译功能仅适用于已启用国际化(Localized)的内容类型",
|
|
7
|
+
"strapi-plugins-translate.button.tooltip.error": "翻译失败。点击重试",
|
|
8
|
+
"strapi-plugins-translate.button.tooltip.idle": "使用 AI 翻译内容",
|
|
9
|
+
"strapi-plugins-translate.button.tooltip.loading": "内容正在翻译中",
|
|
10
|
+
"strapi-plugins-translate.button.tooltip.success": "内容已成功翻译",
|
|
11
|
+
"strapi-plugins-translate.notification.error": "翻译失败。错误:",
|
|
12
|
+
"strapi-plugins-translate.notification.success": "翻译成功完成。",
|
|
13
|
+
"strapi-plugins-translate.plugin.name": "LLM 翻译器",
|
|
14
|
+
"strapi-plugins-translate.plugin.page.description": "配置 LLM 翻译器插件设置。请注意,基础模型、API 密钥和 LLM 基础 URL 需要设置为环境变量。",
|
|
15
|
+
"strapi-plugins-translate.plugin.page.form.llm_base_url": "LLM 基础 URL",
|
|
16
|
+
"strapi-plugins-translate.plugin.page.form.llm_base_url_hint": "LLM API 的基础 URL。需要设置为环境变量。",
|
|
17
|
+
"strapi-plugins-translate.plugin.page.form.llm_model": "LLM 模型",
|
|
18
|
+
"strapi-plugins-translate.plugin.page.form.llm_model_hint": "将用于生成翻译的模型。需要设置为环境变量。",
|
|
19
|
+
"strapi-plugins-translate.plugin.page.form.llm_temperature": "LLM 温度 (Temperature)",
|
|
20
|
+
"strapi-plugins-translate.plugin.page.form.llm_temperature_hint": "数值越高,输出越随机;数值越低,输出越专注和确定。",
|
|
21
|
+
"strapi-plugins-translate.plugin.page.form.restore": "恢复默认设置",
|
|
22
|
+
"strapi-plugins-translate.plugin.page.form.save": "保存更改",
|
|
23
|
+
"strapi-plugins-translate.plugin.page.form.system_prompt": "系统提示词",
|
|
24
|
+
"strapi-plugins-translate.plugin.page.form.system_prompt_hint": "这是用于指令 LLM 的提示词(部分)。应当清晰简洁。",
|
|
25
|
+
"strapi-plugins-translate.plugin.page.title": "LLM 翻译器(配置)",
|
|
26
|
+
"strapi-plugins-translate.plugin.page.batchTranslate": "批量翻译",
|
|
27
|
+
"strapi-plugins-translate.batch.title": "批量翻译",
|
|
28
|
+
"strapi-plugins-translate.batch.description": "选择内容类型和条目,一次将其翻译为多种语言。翻译后的内容将保存为草稿。",
|
|
29
|
+
"strapi-plugins-translate.batch.settings": "设置",
|
|
30
|
+
"strapi-plugins-translate.settings.back": "返回",
|
|
31
|
+
"strapi-plugins-translate.batch.filters.title": "翻译设置",
|
|
32
|
+
"strapi-plugins-translate.batch.filters.contentType": "内容类型",
|
|
33
|
+
"strapi-plugins-translate.batch.filters.contentTypePlaceholder": "选择一个内容类型",
|
|
34
|
+
"strapi-plugins-translate.batch.filters.sourceLocale": "源语言",
|
|
35
|
+
"strapi-plugins-translate.batch.filters.sourceLocalePlaceholder": "选择源语言",
|
|
36
|
+
"strapi-plugins-translate.batch.filters.targetLocales": "目标语言",
|
|
37
|
+
"strapi-plugins-translate.batch.filters.targetLocalesPlaceholder": "选择目标语言",
|
|
38
|
+
"strapi-plugins-translate.batch.filters.selectAll": "全选",
|
|
39
|
+
"strapi-plugins-translate.batch.filters.deselectAll": "取消全选",
|
|
40
|
+
"strapi-plugins-translate.batch.filters.publishAfterTranslate": "翻译后发布",
|
|
41
|
+
"strapi-plugins-translate.batch.filters.publishAfterTranslateHint": "启用后,翻译的内容将立即发布。否则,将被保存为草稿。",
|
|
42
|
+
"strapi-plugins-translate.batch.filters.publishOn": "开启",
|
|
43
|
+
"strapi-plugins-translate.batch.filters.publishOff": "关闭",
|
|
44
|
+
"strapi-plugins-translate.batch.entries.title": "条目 ({count})",
|
|
45
|
+
"strapi-plugins-translate.batch.entries.empty": "未找到该内容类型和语言的条目",
|
|
46
|
+
"strapi-plugins-translate.batch.entries.selectContentType": "请选择内容类型和源语言以查看条目",
|
|
47
|
+
"strapi-plugins-translate.batch.table.id": "ID",
|
|
48
|
+
"strapi-plugins-translate.batch.table.title": "标题",
|
|
49
|
+
"strapi-plugins-translate.batch.table.existingLocales": "已有翻译",
|
|
50
|
+
"strapi-plugins-translate.batch.table.missingLocales": "缺失翻译",
|
|
51
|
+
"strapi-plugins-translate.batch.table.status": "状态",
|
|
52
|
+
"strapi-plugins-translate.batch.table.allTranslated": "已全部翻译",
|
|
53
|
+
"strapi-plugins-translate.batch.table.selectTargets": "选择目标语言",
|
|
54
|
+
"strapi-plugins-translate.batch.button.translate": "翻译选中项 ({count})",
|
|
55
|
+
"strapi-plugins-translate.batch.button.translating": "正在翻译...",
|
|
56
|
+
"strapi-plugins-translate.batch.error.fetchInitial": "加载初始化数据失败",
|
|
57
|
+
"strapi-plugins-translate.batch.error.fetchEntries": "加载条目失败",
|
|
58
|
+
"strapi-plugins-translate.batch.error.missingSelection": "请选择内容类型、语言和要翻译的条目",
|
|
59
|
+
"strapi-plugins-translate.batch.error.translate": "批量翻译失败",
|
|
60
|
+
"strapi-plugins-translate.batch.success.taskStarted": "翻译任务已开始。完成后您将收到飞书通知。",
|
|
61
|
+
"strapi-plugins-translate.batch.result.summary": "翻译完成:{successCount} 个成功,{failureCount} 个失败",
|
|
62
|
+
"strapi-plugins-translate.batch.pagination.info": "第 {page} 页 / 共 {pageCount} 页",
|
|
63
|
+
"strapi-plugins-translate.batch.pagination.prev": "上一页",
|
|
64
|
+
"strapi-plugins-translate.batch.pagination.next": "下一页"
|
|
65
|
+
};
|
|
66
|
+
export {
|
|
67
|
+
en as default
|
|
68
|
+
};
|