@nocobase/plugin-localization 2.1.0-beta.30 → 2.1.0-beta.32
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/client-v2.d.ts +2 -0
- package/client-v2.js +1 -0
- package/dist/ai/ai-employees/lina.d.ts +10 -0
- package/dist/ai/ai-employees/lina.js +60 -0
- package/dist/client/300.3a4b9b688d36da96.js +10 -0
- package/dist/client/i18n-missing-handler.d.ts +1 -17
- package/dist/client/index.js +1 -1
- package/dist/client-v2/796.b9d793cda3c8b932.js +10 -0
- package/dist/client-v2/common/constants.d.ts +13 -0
- package/dist/client-v2/common/i18n-missing-handler.d.ts +23 -0
- package/dist/{client/Localization.d.ts → client-v2/i18n-missing-handler.d.ts} +1 -2
- package/dist/client-v2/index.d.ts +9 -0
- package/dist/client-v2/index.js +10 -0
- package/dist/client-v2/locale.d.ts +11 -0
- package/dist/client-v2/pages/LocalizationPage.d.ts +11 -0
- package/dist/client-v2/plugin.d.ts +13 -0
- package/dist/externalVersion.js +16 -12
- package/dist/locale/en-US.json +15 -1
- package/dist/locale/zh-CN.json +15 -1
- package/dist/server/actions/aiTranslate.d.ts +14 -0
- package/dist/server/actions/aiTranslate.js +127 -0
- package/dist/server/actions/localization.js +30 -15
- package/dist/server/actions/localizationTexts.js +8 -9
- package/dist/server/migrations/20260511230000-delete-official-plugin-package-resource-modules.d.ts +14 -0
- package/dist/server/migrations/20260511230000-delete-official-plugin-package-resource-modules.js +64 -0
- package/dist/server/plugin.d.ts +5 -2
- package/dist/server/plugin.js +72 -14
- package/dist/server/tasks/localization-ai-translate.d.ts +31 -0
- package/dist/server/tasks/localization-ai-translate.js +596 -0
- package/package.json +7 -2
- package/dist/client/304.6a0dd0c975aa0b7c.js +0 -10
- package/dist/server/source-manager.d.ts +0 -35
- package/dist/server/source-manager.js +0 -77
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var localization_ai_translate_exports = {};
|
|
28
|
+
__export(localization_ai_translate_exports, {
|
|
29
|
+
LOCALIZATION_AI_TRANSLATE_TASK_TYPE: () => LOCALIZATION_AI_TRANSLATE_TASK_TYPE,
|
|
30
|
+
LocalizationAITranslateTask: () => LocalizationAITranslateTask
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(localization_ai_translate_exports);
|
|
33
|
+
var import_plugin_async_task_manager = require("@nocobase/plugin-async-task-manager");
|
|
34
|
+
var import_messages = require("@langchain/core/messages");
|
|
35
|
+
const LOCALIZATION_AI_TRANSLATE_TASK_TYPE = "localization:ai-translate";
|
|
36
|
+
const TRANSLATION_BATCH_SIZE = 10;
|
|
37
|
+
const DEFAULT_TRANSLATION_WORKER_COUNT = 10;
|
|
38
|
+
const MIN_TRANSLATION_WORKER_COUNT = 1;
|
|
39
|
+
const MAX_TRANSLATION_WORKER_COUNT = 20;
|
|
40
|
+
const MAX_TRANSLATION_QUEUE_SIZE = TRANSLATION_BATCH_SIZE * 2;
|
|
41
|
+
const elapsed = (start) => Date.now() - start;
|
|
42
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
43
|
+
const truncateForLog = (value, maxLength = 500) => value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;
|
|
44
|
+
const LEGACY_SYMBOL_TRANSLATIONS = /* @__PURE__ */ new Set(["<", "=", ">"]);
|
|
45
|
+
const getTranslationWorkerCount = () => {
|
|
46
|
+
const value = Number.parseInt(process.env.AI_LOCALIZATION_CONCURRENCY || "", 10);
|
|
47
|
+
if (Number.isInteger(value) && value >= MIN_TRANSLATION_WORKER_COUNT && value <= MAX_TRANSLATION_WORKER_COUNT) {
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
return DEFAULT_TRANSLATION_WORKER_COUNT;
|
|
51
|
+
};
|
|
52
|
+
class LocalizationAITranslationError extends Error {
|
|
53
|
+
constructor(message, details) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.details = details;
|
|
56
|
+
this.name = "LocalizationAITranslationError";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
class LocalizationAITranslateTask extends import_plugin_async_task_manager.TaskType {
|
|
60
|
+
static type = LOCALIZATION_AI_TRANSLATE_TASK_TYPE;
|
|
61
|
+
async execute() {
|
|
62
|
+
var _a, _b;
|
|
63
|
+
const params = this.record.params;
|
|
64
|
+
const locale = params.locale || "en-US";
|
|
65
|
+
const employeeUsername = params.employeeUsername || "lina";
|
|
66
|
+
const aiPlugin = this.app.pm.get("ai");
|
|
67
|
+
if (!(aiPlugin == null ? void 0 : aiPlugin.aiConversationsManager) || !(aiPlugin == null ? void 0 : aiPlugin.aiEmployeesManager)) {
|
|
68
|
+
throw new Error("AI plugin is not available");
|
|
69
|
+
}
|
|
70
|
+
const employee = await aiPlugin.aiEmployeesManager.getEmployee(employeeUsername);
|
|
71
|
+
if (!employee) {
|
|
72
|
+
throw new Error(`AI employee "${employeeUsername}" not found`);
|
|
73
|
+
}
|
|
74
|
+
const resolvedModel = await aiPlugin.aiEmployeesManager.resolveModel(employee, params.model);
|
|
75
|
+
const { provider, model, service } = await aiPlugin.aiManager.getLLMService(resolvedModel);
|
|
76
|
+
const defaultReferenceLocale = await this.getSystemDefaultLocale();
|
|
77
|
+
const builtInReferenceResources = await this.app.localeManager.getBuiltInResources("zh-CN");
|
|
78
|
+
const builtInMatchResources = await this.app.localeManager.getBuiltInResources("en-US");
|
|
79
|
+
const workerCount = getTranslationWorkerCount();
|
|
80
|
+
const countStart = Date.now();
|
|
81
|
+
const total = await this.countTexts(params.mode, locale, params.textIds);
|
|
82
|
+
(_a = this.logger) == null ? void 0 : _a.debug("Localization AI translation task started", {
|
|
83
|
+
taskId: this.record.id,
|
|
84
|
+
mode: params.mode,
|
|
85
|
+
locale,
|
|
86
|
+
total,
|
|
87
|
+
countElapsedMs: elapsed(countStart),
|
|
88
|
+
workerCount,
|
|
89
|
+
queueLimit: MAX_TRANSLATION_QUEUE_SIZE,
|
|
90
|
+
defaultReferenceLocale,
|
|
91
|
+
provider: service == null ? void 0 : service.provider,
|
|
92
|
+
llmService: service == null ? void 0 : service.name,
|
|
93
|
+
model
|
|
94
|
+
});
|
|
95
|
+
let translated = 0;
|
|
96
|
+
let chunkIndex = 0;
|
|
97
|
+
let producerDone = false;
|
|
98
|
+
let firstError;
|
|
99
|
+
const queue = [];
|
|
100
|
+
this.reportProgress({ total, current: 0 });
|
|
101
|
+
const workers = Array.from(
|
|
102
|
+
{ length: workerCount },
|
|
103
|
+
(_, workerIndex) => this.runTranslationWorker({
|
|
104
|
+
workerIndex: workerIndex + 1,
|
|
105
|
+
queue,
|
|
106
|
+
isDone: () => producerDone,
|
|
107
|
+
getError: () => firstError,
|
|
108
|
+
setError: (error) => {
|
|
109
|
+
firstError = firstError ?? error;
|
|
110
|
+
},
|
|
111
|
+
total,
|
|
112
|
+
getTranslated: () => translated,
|
|
113
|
+
incrementTranslated: () => {
|
|
114
|
+
translated += 1;
|
|
115
|
+
return translated;
|
|
116
|
+
},
|
|
117
|
+
locale,
|
|
118
|
+
employeeUsername,
|
|
119
|
+
employee,
|
|
120
|
+
provider,
|
|
121
|
+
service,
|
|
122
|
+
model
|
|
123
|
+
})
|
|
124
|
+
);
|
|
125
|
+
try {
|
|
126
|
+
await this.app.db.getRepository("localizationTexts").chunkWithCursor({
|
|
127
|
+
...this.buildFindTextsOptions(params.mode, locale, params.textIds),
|
|
128
|
+
chunkSize: TRANSLATION_BATCH_SIZE,
|
|
129
|
+
beforeFind: async () => {
|
|
130
|
+
while (!firstError && queue.length >= MAX_TRANSLATION_QUEUE_SIZE) {
|
|
131
|
+
await sleep(100);
|
|
132
|
+
}
|
|
133
|
+
if (firstError) {
|
|
134
|
+
throw firstError;
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
callback: async (rows) => {
|
|
138
|
+
var _a2;
|
|
139
|
+
chunkIndex += 1;
|
|
140
|
+
const chunkStart = Date.now();
|
|
141
|
+
const textRows = rows.map((row) => this.normalizeTextRecord(row)).filter(Boolean);
|
|
142
|
+
const textIds = textRows.map((row) => row.id);
|
|
143
|
+
const englishReferences = await this.getLocaleReferences(textIds, "en-US");
|
|
144
|
+
const defaultLocaleReferences = defaultReferenceLocale === "en-US" ? englishReferences : await this.getLocaleReferences(textIds, defaultReferenceLocale);
|
|
145
|
+
const queueItems = textRows.map((row) => {
|
|
146
|
+
const isBuiltIn = this.isBuiltInText(row, builtInMatchResources);
|
|
147
|
+
return {
|
|
148
|
+
row,
|
|
149
|
+
chunkIndex,
|
|
150
|
+
englishReference: englishReferences.get(String(row.id)),
|
|
151
|
+
referenceTranslation: isBuiltIn ? this.getBuiltInReference(row, builtInReferenceResources) : defaultLocaleReferences.get(String(row.id)),
|
|
152
|
+
referenceLocale: isBuiltIn ? "zh-CN" : defaultReferenceLocale,
|
|
153
|
+
isBuiltIn
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
queue.push(...queueItems);
|
|
157
|
+
(_a2 = this.logger) == null ? void 0 : _a2.debug("Localization AI translation chunk enqueued", {
|
|
158
|
+
taskId: this.record.id,
|
|
159
|
+
chunkIndex,
|
|
160
|
+
rows: textRows.length,
|
|
161
|
+
englishReferences: englishReferences.size,
|
|
162
|
+
referenceLocale: defaultReferenceLocale,
|
|
163
|
+
referenceTranslations: queueItems.filter((item) => item.referenceTranslation).length,
|
|
164
|
+
builtInReferences: queueItems.filter((item) => item.isBuiltIn && item.referenceTranslation).length,
|
|
165
|
+
queueSize: queue.length,
|
|
166
|
+
elapsedMs: elapsed(chunkStart),
|
|
167
|
+
translated,
|
|
168
|
+
total
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
} finally {
|
|
173
|
+
producerDone = true;
|
|
174
|
+
}
|
|
175
|
+
await Promise.all(workers);
|
|
176
|
+
if (firstError) {
|
|
177
|
+
throw firstError;
|
|
178
|
+
}
|
|
179
|
+
(_b = this.logger) == null ? void 0 : _b.debug("Localization AI translation task completed", {
|
|
180
|
+
taskId: this.record.id,
|
|
181
|
+
translated,
|
|
182
|
+
total
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
translated,
|
|
186
|
+
total
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
async countTexts(mode, locale, textIds) {
|
|
190
|
+
return await this.app.db.getRepository("localizationTexts").count(this.buildFindTextsOptions(mode, locale, textIds));
|
|
191
|
+
}
|
|
192
|
+
buildFindTextsOptions(mode, locale, textIds) {
|
|
193
|
+
const options = {
|
|
194
|
+
fields: ["id", "text", "module"],
|
|
195
|
+
sort: ["id"]
|
|
196
|
+
};
|
|
197
|
+
if (mode === "selected") {
|
|
198
|
+
options.filter = {
|
|
199
|
+
id: {
|
|
200
|
+
$in: textIds || []
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
if (mode === "incremental") {
|
|
205
|
+
options.include = [{ association: "translations", where: { locale }, required: false }];
|
|
206
|
+
options.where = {
|
|
207
|
+
"$translations.id$": null
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return options;
|
|
211
|
+
}
|
|
212
|
+
normalizeTextRecord(row) {
|
|
213
|
+
if (!row) {
|
|
214
|
+
return void 0;
|
|
215
|
+
}
|
|
216
|
+
return typeof row.toJSON === "function" ? row.toJSON() : row;
|
|
217
|
+
}
|
|
218
|
+
async getLocaleReferences(textIds, locale) {
|
|
219
|
+
const references = /* @__PURE__ */ new Map();
|
|
220
|
+
if (!textIds.length) {
|
|
221
|
+
return references;
|
|
222
|
+
}
|
|
223
|
+
const rows = await this.app.db.getRepository("localizationTranslations").find({
|
|
224
|
+
fields: ["textId", "translation"],
|
|
225
|
+
filter: {
|
|
226
|
+
locale,
|
|
227
|
+
textId: {
|
|
228
|
+
$in: textIds
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
for (const row of rows) {
|
|
233
|
+
const record = typeof row.toJSON === "function" ? row.toJSON() : row;
|
|
234
|
+
if ((record == null ? void 0 : record.textId) != null && record.translation) {
|
|
235
|
+
references.set(String(record.textId), record.translation);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return references;
|
|
239
|
+
}
|
|
240
|
+
async getSystemDefaultLocale() {
|
|
241
|
+
var _a;
|
|
242
|
+
const systemSetting = await ((_a = this.app.db.getRepository("systemSettings")) == null ? void 0 : _a.findOne());
|
|
243
|
+
const enabledLanguages = (systemSetting == null ? void 0 : systemSetting.get("enabledLanguages")) || [];
|
|
244
|
+
return (enabledLanguages == null ? void 0 : enabledLanguages[0]) || process.env.APP_LANG || "en-US";
|
|
245
|
+
}
|
|
246
|
+
getModuleName(row) {
|
|
247
|
+
var _a;
|
|
248
|
+
return (_a = row.module) == null ? void 0 : _a.replace("resources.", "");
|
|
249
|
+
}
|
|
250
|
+
isBuiltInText(row, resources) {
|
|
251
|
+
var _a;
|
|
252
|
+
const moduleName = this.getModuleName(row);
|
|
253
|
+
return Boolean(moduleName && ((_a = resources[moduleName]) == null ? void 0 : _a[row.text]) !== void 0);
|
|
254
|
+
}
|
|
255
|
+
getBuiltInReference(row, resources) {
|
|
256
|
+
var _a;
|
|
257
|
+
const moduleName = this.getModuleName(row);
|
|
258
|
+
return moduleName ? (_a = resources[moduleName]) == null ? void 0 : _a[row.text] : void 0;
|
|
259
|
+
}
|
|
260
|
+
async runTranslationWorker(options) {
|
|
261
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
262
|
+
const {
|
|
263
|
+
workerIndex,
|
|
264
|
+
queue,
|
|
265
|
+
isDone,
|
|
266
|
+
getError,
|
|
267
|
+
setError,
|
|
268
|
+
total,
|
|
269
|
+
getTranslated,
|
|
270
|
+
incrementTranslated,
|
|
271
|
+
locale,
|
|
272
|
+
employeeUsername,
|
|
273
|
+
employee,
|
|
274
|
+
provider,
|
|
275
|
+
service,
|
|
276
|
+
model
|
|
277
|
+
} = options;
|
|
278
|
+
while (!isDone() || queue.length > 0) {
|
|
279
|
+
if (getError()) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (this.isCanceled) {
|
|
283
|
+
throw new import_plugin_async_task_manager.CancelError();
|
|
284
|
+
}
|
|
285
|
+
const item = queue.shift();
|
|
286
|
+
if (!item) {
|
|
287
|
+
await sleep(50);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const { row, chunkIndex, englishReference, referenceTranslation, referenceLocale, isBuiltIn } = item;
|
|
291
|
+
try {
|
|
292
|
+
const textStart = Date.now();
|
|
293
|
+
(_c = (_a = this.logger) == null ? void 0 : _a.trace) == null ? void 0 : _c.call(_a, "Localization AI translation text started", {
|
|
294
|
+
taskId: this.record.id,
|
|
295
|
+
workerIndex,
|
|
296
|
+
chunkIndex,
|
|
297
|
+
textId: row.id,
|
|
298
|
+
textLength: ((_b = row.text) == null ? void 0 : _b.length) ?? 0,
|
|
299
|
+
hasEnglishReference: Boolean(englishReference),
|
|
300
|
+
hasReferenceTranslation: Boolean(referenceTranslation),
|
|
301
|
+
referenceLocale,
|
|
302
|
+
isBuiltIn,
|
|
303
|
+
queueSize: queue.length,
|
|
304
|
+
translated: getTranslated(),
|
|
305
|
+
total
|
|
306
|
+
});
|
|
307
|
+
const isLegacySymbolTranslation = LEGACY_SYMBOL_TRANSLATIONS.has(row.text);
|
|
308
|
+
if (isLegacySymbolTranslation) {
|
|
309
|
+
(_e = (_d = this.logger) == null ? void 0 : _d.trace) == null ? void 0 : _e.call(_d, "Localization AI translation legacy symbol skipped", {
|
|
310
|
+
taskId: this.record.id,
|
|
311
|
+
workerIndex,
|
|
312
|
+
chunkIndex,
|
|
313
|
+
textId: row.id,
|
|
314
|
+
text: row.text
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
const translation = isLegacySymbolTranslation ? row.text : await this.translateText({
|
|
318
|
+
text: row.text,
|
|
319
|
+
module: row.module,
|
|
320
|
+
englishReference,
|
|
321
|
+
referenceTranslation,
|
|
322
|
+
referenceLocale,
|
|
323
|
+
isBuiltIn,
|
|
324
|
+
locale,
|
|
325
|
+
employeeUsername,
|
|
326
|
+
employee,
|
|
327
|
+
provider,
|
|
328
|
+
service,
|
|
329
|
+
model
|
|
330
|
+
});
|
|
331
|
+
const aiElapsedMs = elapsed(textStart);
|
|
332
|
+
const writeStart = Date.now();
|
|
333
|
+
await this.app.db.getRepository("localizationTranslations").updateOrCreate({
|
|
334
|
+
filterKeys: ["textId", "locale"],
|
|
335
|
+
values: {
|
|
336
|
+
textId: row.id,
|
|
337
|
+
locale,
|
|
338
|
+
translation
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
const writeElapsedMs = elapsed(writeStart);
|
|
342
|
+
const translated = incrementTranslated();
|
|
343
|
+
this.reportProgress({ total, current: translated });
|
|
344
|
+
(_g = this.logger) == null ? void 0 : _g.debug("Localization AI translation text completed", {
|
|
345
|
+
taskId: this.record.id,
|
|
346
|
+
workerIndex,
|
|
347
|
+
chunkIndex,
|
|
348
|
+
textId: row.id,
|
|
349
|
+
textLength: ((_f = row.text) == null ? void 0 : _f.length) ?? 0,
|
|
350
|
+
translationLength: translation.length,
|
|
351
|
+
aiElapsedMs,
|
|
352
|
+
writeElapsedMs,
|
|
353
|
+
totalElapsedMs: elapsed(textStart),
|
|
354
|
+
translated,
|
|
355
|
+
total,
|
|
356
|
+
queueSize: queue.length
|
|
357
|
+
});
|
|
358
|
+
} catch (error) {
|
|
359
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
360
|
+
const details = {
|
|
361
|
+
id: row.id,
|
|
362
|
+
text: row.text,
|
|
363
|
+
error: message
|
|
364
|
+
};
|
|
365
|
+
(_h = this.logger) == null ? void 0 : _h.error(`Failed to translate localization text ${row.id}: ${message}`, { error });
|
|
366
|
+
if (error instanceof import_plugin_async_task_manager.CancelError) {
|
|
367
|
+
throw error;
|
|
368
|
+
}
|
|
369
|
+
setError(
|
|
370
|
+
new LocalizationAITranslationError(`Failed to translate localization text ${row.id}: ${message}`, details)
|
|
371
|
+
);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
async translateText(options) {
|
|
377
|
+
var _a, _b, _c, _d, _e, _f;
|
|
378
|
+
const {
|
|
379
|
+
text,
|
|
380
|
+
module: module2,
|
|
381
|
+
englishReference,
|
|
382
|
+
referenceTranslation,
|
|
383
|
+
referenceLocale,
|
|
384
|
+
isBuiltIn,
|
|
385
|
+
locale,
|
|
386
|
+
employeeUsername,
|
|
387
|
+
provider,
|
|
388
|
+
service,
|
|
389
|
+
model,
|
|
390
|
+
employee
|
|
391
|
+
} = options;
|
|
392
|
+
const setupStart = Date.now();
|
|
393
|
+
const sourceText = englishReference || text;
|
|
394
|
+
const sourceLang = englishReference ? "English" : "auto";
|
|
395
|
+
const targetLang = this.getLanguageName(locale);
|
|
396
|
+
const context = this.buildProviderContext({
|
|
397
|
+
sourceText,
|
|
398
|
+
targetLang,
|
|
399
|
+
referenceSourceTerm: sourceText,
|
|
400
|
+
referenceTargetTerm: referenceTranslation
|
|
401
|
+
});
|
|
402
|
+
const invokeStart = Date.now();
|
|
403
|
+
(_b = (_a = this.logger) == null ? void 0 : _a.trace) == null ? void 0 : _b.call(_a, "Localization AI translation invoke started", {
|
|
404
|
+
taskId: this.record.id,
|
|
405
|
+
textLength: (text == null ? void 0 : text.length) ?? 0,
|
|
406
|
+
sourceTextLength: (sourceText == null ? void 0 : sourceText.length) ?? 0,
|
|
407
|
+
locale,
|
|
408
|
+
sourceLang,
|
|
409
|
+
targetLang,
|
|
410
|
+
module: module2,
|
|
411
|
+
employeeUsername,
|
|
412
|
+
provider: service == null ? void 0 : service.provider,
|
|
413
|
+
llmService: service == null ? void 0 : service.name,
|
|
414
|
+
model,
|
|
415
|
+
hasEnglishReference: Boolean(englishReference),
|
|
416
|
+
hasReferenceTranslation: Boolean(referenceTranslation),
|
|
417
|
+
referenceLocale,
|
|
418
|
+
isBuiltIn
|
|
419
|
+
});
|
|
420
|
+
const result = await provider.invoke(context, {
|
|
421
|
+
modelRequestParams: {
|
|
422
|
+
sourceText,
|
|
423
|
+
sourceLang,
|
|
424
|
+
targetLang,
|
|
425
|
+
terms: this.buildTranslationTerms({
|
|
426
|
+
sourceTerm: sourceText,
|
|
427
|
+
targetTerm: referenceTranslation,
|
|
428
|
+
targetLang
|
|
429
|
+
})
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
const invokeElapsedMs = elapsed(invokeStart);
|
|
433
|
+
(_d = (_c = this.logger) == null ? void 0 : _c.trace) == null ? void 0 : _d.call(_c, "Localization AI translation invoke completed", {
|
|
434
|
+
taskId: this.record.id,
|
|
435
|
+
textLength: (text == null ? void 0 : text.length) ?? 0,
|
|
436
|
+
sourceTextLength: (sourceText == null ? void 0 : sourceText.length) ?? 0,
|
|
437
|
+
locale,
|
|
438
|
+
sourceLang,
|
|
439
|
+
targetLang,
|
|
440
|
+
module: module2,
|
|
441
|
+
employeeUsername,
|
|
442
|
+
provider: service == null ? void 0 : service.provider,
|
|
443
|
+
llmService: service == null ? void 0 : service.name,
|
|
444
|
+
model,
|
|
445
|
+
hasEnglishReference: Boolean(englishReference),
|
|
446
|
+
hasReferenceTranslation: Boolean(referenceTranslation),
|
|
447
|
+
referenceLocale,
|
|
448
|
+
isBuiltIn,
|
|
449
|
+
setupElapsedMs: elapsed(setupStart) - invokeElapsedMs,
|
|
450
|
+
invokeElapsedMs,
|
|
451
|
+
totalElapsedMs: elapsed(setupStart)
|
|
452
|
+
});
|
|
453
|
+
const translation = this.extractTextContent(result == null ? void 0 : result.content).trim();
|
|
454
|
+
if (!translation) {
|
|
455
|
+
throw new Error("LLM service returned empty translation");
|
|
456
|
+
}
|
|
457
|
+
(_f = (_e = this.logger) == null ? void 0 : _e.trace) == null ? void 0 : _f.call(_e, "Localization AI translation result extracted", {
|
|
458
|
+
taskId: this.record.id,
|
|
459
|
+
textLength: (text == null ? void 0 : text.length) ?? 0,
|
|
460
|
+
sourceTextLength: (sourceText == null ? void 0 : sourceText.length) ?? 0,
|
|
461
|
+
translationLength: translation.length,
|
|
462
|
+
locale,
|
|
463
|
+
sourceLang,
|
|
464
|
+
targetLang,
|
|
465
|
+
module: module2,
|
|
466
|
+
employeeUsername,
|
|
467
|
+
provider: service == null ? void 0 : service.provider,
|
|
468
|
+
llmService: service == null ? void 0 : service.name,
|
|
469
|
+
model,
|
|
470
|
+
hasEnglishReference: Boolean(englishReference),
|
|
471
|
+
hasReferenceTranslation: Boolean(referenceTranslation),
|
|
472
|
+
referenceLocale,
|
|
473
|
+
isBuiltIn,
|
|
474
|
+
sourceText: truncateForLog(sourceText),
|
|
475
|
+
referenceTranslation: referenceTranslation ? truncateForLog(referenceTranslation) : void 0,
|
|
476
|
+
translation: truncateForLog(translation)
|
|
477
|
+
});
|
|
478
|
+
return translation;
|
|
479
|
+
}
|
|
480
|
+
buildProviderContext(options) {
|
|
481
|
+
const { sourceText, targetLang, referenceSourceTerm, referenceTargetTerm } = options;
|
|
482
|
+
const reference = referenceSourceTerm && referenceTargetTerm ? `Refer to the following translation:
|
|
483
|
+
${referenceSourceTerm} is translated as ${referenceTargetTerm}
|
|
484
|
+
|
|
485
|
+
` : "";
|
|
486
|
+
const content = `${reference}Translate the following text into ${targetLang}. Output only the translated result without any additional explanation:
|
|
487
|
+
|
|
488
|
+
${sourceText}
|
|
489
|
+
`;
|
|
490
|
+
return {
|
|
491
|
+
messages: [new import_messages.HumanMessage(content)]
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
buildTranslationTerms(options) {
|
|
495
|
+
const { sourceTerm, targetTerm, targetLang } = options;
|
|
496
|
+
if (!sourceTerm || !targetTerm || !["Chinese", "Traditional Chinese"].includes(targetLang)) {
|
|
497
|
+
return void 0;
|
|
498
|
+
}
|
|
499
|
+
return [
|
|
500
|
+
{
|
|
501
|
+
source: sourceTerm,
|
|
502
|
+
target: targetTerm
|
|
503
|
+
}
|
|
504
|
+
];
|
|
505
|
+
}
|
|
506
|
+
getLanguageName(locale) {
|
|
507
|
+
const normalized = locale.replace("_", "-");
|
|
508
|
+
const map = {
|
|
509
|
+
"en-US": "English",
|
|
510
|
+
"zh-CN": "Chinese",
|
|
511
|
+
"zh-TW": "Traditional Chinese",
|
|
512
|
+
"ja-JP": "Japanese",
|
|
513
|
+
"ko-KR": "Korean",
|
|
514
|
+
"fr-FR": "French",
|
|
515
|
+
"de-DE": "German",
|
|
516
|
+
"es-ES": "Spanish",
|
|
517
|
+
"it-IT": "Italian",
|
|
518
|
+
"pt-PT": "Portuguese",
|
|
519
|
+
"pt-BR": "Portuguese",
|
|
520
|
+
"ru-RU": "Russian",
|
|
521
|
+
"th-TH": "Thai",
|
|
522
|
+
"vi-VN": "Vietnamese",
|
|
523
|
+
"id-ID": "Indonesian",
|
|
524
|
+
"ms-MY": "Malay",
|
|
525
|
+
"ar-SA": "Arabic",
|
|
526
|
+
"hi-IN": "Hindi",
|
|
527
|
+
"tr-TR": "Turkish",
|
|
528
|
+
"nl-NL": "Dutch",
|
|
529
|
+
"pl-PL": "Polish",
|
|
530
|
+
"sv-SE": "Swedish",
|
|
531
|
+
"da-DK": "Danish",
|
|
532
|
+
"fi-FI": "Finnish",
|
|
533
|
+
"uk-UA": "Ukrainian"
|
|
534
|
+
};
|
|
535
|
+
if (map[normalized]) {
|
|
536
|
+
return map[normalized];
|
|
537
|
+
}
|
|
538
|
+
const language = normalized.split("-")[0];
|
|
539
|
+
const languageMap = {
|
|
540
|
+
en: "English",
|
|
541
|
+
zh: "Chinese",
|
|
542
|
+
ja: "Japanese",
|
|
543
|
+
ko: "Korean",
|
|
544
|
+
fr: "French",
|
|
545
|
+
de: "German",
|
|
546
|
+
es: "Spanish",
|
|
547
|
+
it: "Italian",
|
|
548
|
+
pt: "Portuguese",
|
|
549
|
+
ru: "Russian",
|
|
550
|
+
th: "Thai",
|
|
551
|
+
vi: "Vietnamese",
|
|
552
|
+
id: "Indonesian",
|
|
553
|
+
ms: "Malay",
|
|
554
|
+
ar: "Arabic",
|
|
555
|
+
hi: "Hindi",
|
|
556
|
+
tr: "Turkish",
|
|
557
|
+
nl: "Dutch",
|
|
558
|
+
pl: "Polish",
|
|
559
|
+
sv: "Swedish",
|
|
560
|
+
da: "Danish",
|
|
561
|
+
fi: "Finnish",
|
|
562
|
+
uk: "Ukrainian"
|
|
563
|
+
};
|
|
564
|
+
return languageMap[language] || language;
|
|
565
|
+
}
|
|
566
|
+
extractTextContent(content) {
|
|
567
|
+
if (typeof content === "string") {
|
|
568
|
+
return content;
|
|
569
|
+
}
|
|
570
|
+
if (Array.isArray(content)) {
|
|
571
|
+
return content.map((item) => {
|
|
572
|
+
if (typeof item === "string") {
|
|
573
|
+
return item;
|
|
574
|
+
}
|
|
575
|
+
if (item && typeof item === "object") {
|
|
576
|
+
if ("type" in item && item.type === "text") {
|
|
577
|
+
return typeof item.text === "string" ? item.text : "";
|
|
578
|
+
}
|
|
579
|
+
if ("content" in item) {
|
|
580
|
+
return this.extractTextContent(item.content);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
return "";
|
|
584
|
+
}).join("").trim();
|
|
585
|
+
}
|
|
586
|
+
if (content && typeof content === "object" && "content" in content) {
|
|
587
|
+
return this.extractTextContent(content.content);
|
|
588
|
+
}
|
|
589
|
+
return "";
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
593
|
+
0 && (module.exports = {
|
|
594
|
+
LOCALIZATION_AI_TRANSLATE_TASK_TYPE,
|
|
595
|
+
LocalizationAITranslateTask
|
|
596
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/plugin-localization",
|
|
3
|
-
"version": "2.1.0-beta.
|
|
3
|
+
"version": "2.1.0-beta.32",
|
|
4
4
|
"main": "dist/server/index.js",
|
|
5
5
|
"homepage": "https://docs.nocobase.com/handbook/localization-management",
|
|
6
6
|
"homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/localization-management",
|
|
@@ -10,9 +10,14 @@
|
|
|
10
10
|
"deepmerge": "^4.3.1"
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
|
+
"@nocobase/ai": "2.x",
|
|
13
14
|
"@nocobase/cache": "2.x",
|
|
14
15
|
"@nocobase/client": "2.x",
|
|
16
|
+
"@nocobase/client-v2": "2.x",
|
|
15
17
|
"@nocobase/database": "2.x",
|
|
18
|
+
"@nocobase/flow-engine": "2.x",
|
|
19
|
+
"@nocobase/plugin-ai": "2.x",
|
|
20
|
+
"@nocobase/plugin-async-task-manager": "2.x",
|
|
16
21
|
"@nocobase/server": "2.x",
|
|
17
22
|
"@nocobase/test": "2.x"
|
|
18
23
|
},
|
|
@@ -25,5 +30,5 @@
|
|
|
25
30
|
"description": "Allows to manage localization resources of the application.",
|
|
26
31
|
"description.ru-RU": "Позволяет управлять ресурсами локализации приложения.",
|
|
27
32
|
"description.zh-CN": "支持管理应用程序的本地化资源。",
|
|
28
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "659c5efe992da7118d33c768bbd9e837a2c4716f"
|
|
29
34
|
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
"use strict";(self.webpackChunk_nocobase_plugin_localization=self.webpackChunk_nocobase_plugin_localization||[]).push([["304"],{339:function(e,t,n){n.r(t),n.d(t,{Localization:function(){return F}});var o=n(375),r=n(452),l=n(230),a=n(342),i=n(625),c=n(59),u=n(155),s=n.n(u),p=n(872),m={name:"localization",disableTranslation:!0,fields:[{interface:"input",type:"string",name:"text",uiSchema:{type:"string",title:'{{t("Text")}}',"x-component":"Input.TextArea",required:!0}},{interface:"input",type:"string",name:"translation",uiSchema:{type:"string",title:'{{t("Translation")}}',"x-component":"Input.TextArea"}},{interface:"select",type:"string",name:"moduleTitle",uiSchema:{type:"string",title:'{{t("Module")}}',"x-component":"Select",enum:[{value:"Menu",label:'{{t("Menu")}}'},{value:"Collections & Fields",label:'{{t("Collections & Fields", {ns:"localization"})}}'}]}}]},d={type:"void",name:"localization","x-decorator":"ResourceActionProvider","x-decorator-props":{collection:m,resourceName:"localizationTexts",request:{resource:"localizationTexts",action:"list",params:{pageSize:50}}},"x-component":"CollectionProvider_deprecated","x-component-props":{collection:m},properties:{actions:{type:"void","x-component":"ActionBar","x-component-props":{style:{marginBottom:16}},properties:{currentLang:{type:"void","x-align":"left","x-component":"CurrentLang"},filter:{type:"void",title:'{{t("Filter")}}',"x-align":"left","x-component":"Filter"},deleteTranslation:{type:"void",title:'{{t("Delete translation")}}',"x-component":"Action","x-component-props":{icon:"DeleteOutlined",useAction:"{{ useBulkDestroyTranslationAction }}",confirm:{title:"{{t('Delete translation')}}",content:"{{t('Are you sure you want to delete it?')}}"}}},sync:{type:"void",title:'{{t("Sync")}}',"x-component":"Sync"},publish:{type:"void",title:'{{t("Publish")}}',"x-component":"Action","x-component-props":{icon:"UploadOutlined",type:"primary",useAction:"{{ usePublishAction }}"}}}},table:{type:"void","x-uid":"input","x-component":"Table.Void","x-component-props":{rowKey:"id",rowSelection:{type:"checkbox",getCheckboxProps:function(e){return{disabled:!(null==e?void 0:e.translationId)}}},useDataSource:"{{ cm.useDataSourceFromRAC }}"},properties:{text:{type:"void","x-decorator":"Table.Column.Decorator","x-component":"Table.Column",properties:{text:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},translation:{type:"void","x-decorator":"Table.Column.Decorator","x-component":"Table.Column",properties:{translation:{type:"string","x-component":"CollectionField","x-component-props":{component:"TranslationField"},"x-read-pretty":!0}}},moduleTitle:{type:"void","x-decorator":"Table.Column.Decorator","x-component":"Table.Column",properties:{moduleTitle:{type:"string","x-component":"ModuleTitle"}}},actions:{type:"void",title:'{{t("Actions")}}',"x-component":"Table.Column",properties:{actions:{type:"void","x-component":"Space","x-component-props":{split:"|"},properties:{update:{type:"void",title:'{{t("Edit")}}',"x-component":"Action.Link","x-component-props":{type:"primary"},properties:{drawer:{type:"void","x-component":"Action.Drawer","x-decorator":"Form","x-decorator-props":{useValues:"{{ cm.useValuesFromRecord }}"},title:'{{t("Edit")}}',properties:{moduleTitle:{title:'{{t("Module")}}',"x-component":"ModuleTitle","x-decorator":"FormItem"},text:{"x-component":"CollectionField","x-decorator":"FormItem","x-read-pretty":!0},translation:{"x-component":"CollectionField","x-decorator":"FormItem",required:!0},footer:{type:"void","x-component":"Action.Drawer.Footer",properties:{cancel:{title:'{{t("Cancel")}}',"x-component":"Action","x-component-props":{useAction:"{{ cm.useCancelAction }}"}},submit:{title:'{{t("Submit")}}',"x-component":"Action","x-component-props":{type:"primary",useAction:"{{ useUpdateTranslationAction }}"}}}}}}}},deleteTranslation:{type:"void",title:'{{ t("Delete translation") }}',"x-component":"Action.Link","x-component-props":{confirm:{title:"{{t('Delete translation')}}",content:"{{t('Are you sure you want to delete it?')}}"},useAction:"{{useDestroyTranslationAction}}"},"x-visible":"{{useHasTranslation()}}"}}}}}}}}};function f(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=Array(t);n<t;n++)o[n]=e[n];return o}function y(e,t,n,o,r,l,a){try{var i=e[l](a),c=i.value}catch(e){n(e);return}i.done?t(c):Promise.resolve(c).then(o,r)}function h(e){return function(){var t=this,n=arguments;return new Promise(function(o,r){var l=e.apply(t,n);function a(e){y(l,o,r,a,i,"next",e)}function i(e){y(l,o,r,a,i,"throw",e)}a(void 0)})}}function b(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},o=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),o.forEach(function(t){var o;o=n[t],t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o})}return e}function v(e,t){return t=null!=t?t:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):(function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t.push.apply(t,n)}return t})(Object(t)).forEach(function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}),e}function x(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n,o,r=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var l=[],a=!0,i=!1;try{for(r=r.call(e);!(a=(n=r.next()).done)&&(l.push(n.value),!t||l.length!==t);a=!0);}catch(e){i=!0,o=e}finally{try{a||null==r.return||r.return()}finally{if(i)throw o}}return l}}(e,t)||function(e,t){if(e){if("string"==typeof e)return f(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return f(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function g(e,t){var n,o,r,l={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),i=Object.defineProperty;return i(a,"next",{value:c(0)}),i(a,"throw",{value:c(1)}),i(a,"return",{value:c(2)}),"function"==typeof Symbol&&i(a,Symbol.iterator,{value:function(){return this}}),a;function c(i){return function(c){var u=[i,c];if(n)throw TypeError("Generator is already executing.");for(;a&&(a=0,u[0]&&(l=0)),l;)try{if(n=1,o&&(r=2&u[0]?o.return:u[0]?o.throw||((r=o.return)&&r.call(o),0):o.next)&&!(r=r.call(o,u[1])).done)return r;switch(o=0,r&&(u=[2&u[0],r.value]),u[0]){case 0:case 1:r=u;break;case 4:return l.label++,{value:u[1],done:!1};case 5:l.label++,o=u[1],u=[0];continue;case 7:u=l.ops.pop(),l.trys.pop();continue;default:if(!(r=(r=l.trys).length>0&&r[r.length-1])&&(6===u[0]||2===u[0])){l=0;continue}if(3===u[0]&&(!r||u[1]>r[0]&&u[1]<r[3])){l.label=u[1];break}if(6===u[0]&&l.label<r[1]){l.label=r[1],r=u;break}if(r&&l.label<r[2]){l.label=r[2],l.ops.push(u);break}r[2]&&l.ops.pop(),l.trys.pop();continue}u=t.call(e,l)}catch(e){u=[6,e],o=0}finally{n=r=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}}}var A=c.Typography.Text,C=function(){var e=(0,l.useField)(),t=(0,l.useForm)(),n=(0,a.useActionContext)(),o=(0,a.useResourceActionContext)().refresh,r=(0,a.useResourceContext)().targetKey,i=(0,a.useRecord)()[r],c=(0,a.useAPIClient)(),u=c.auth.getLocale();return{run:function(){return h(function(){return g(this,function(r){switch(r.label){case 0:return[4,t.submit()];case 1:r.sent(),e.data=e.data||{},e.data.loading=!0,r.label=2;case 2:return r.trys.push([2,5,6,7]),[4,c.resource("localizationTranslations").updateOrCreate({filterKeys:["textId","locale"],values:{textId:i,locale:u,translation:t.values.translation}})];case 3:return r.sent(),n.setVisible(!1),[4,t.reset()];case 4:return r.sent(),o(),[3,7];case 5:return console.log(r.sent()),[3,7];case 6:return e.data.loading=!1,[7];case 7:return[2]}})})()}}},T=function(){var e=(0,a.useResourceActionContext)().refresh,t=(0,a.useAPIClient)(),n=(0,a.useRecord)().translationId;return{run:function(){return h(function(){return g(this,function(o){switch(o.label){case 0:if(!n)return[2];return[4,t.resource("localizationTranslations").destroy({filterByTk:n})];case 1:return o.sent(),e(),[2]}})})()}}},w=function(){var e=(0,a.useResourceActionContext)(),t=e.state,n=e.setState,o=e.refresh,r=e.data,l=(0,a.useAPIClient)(),i=(0,p.Q)().t;return{run:function(){return h(function(){var e,a,u,s,p;return g(this,function(m){switch(m.label){case 0:if(!(a=(null==t?void 0:t.selectedRowKeys)||[]).length||(u=(null==r||null==(e=r.data)?void 0:e.rows)||(null==r?void 0:r.data)||(null==r?void 0:r.rows)||[],s=new Set(a.map(function(e){return String(e)})),!(p=u.filter(function(e){return s.has(String(e.id))}).map(function(e){return e.translationId}).filter(Boolean)).length))return[2,c.message.error(i("Please select the records you want to delete"))];return[4,l.resource("localizationTranslations").destroy({filterByTk:p})];case 1:return m.sent(),null==n||n({selectedRowKeys:[]}),o(),[2]}})})()}}},S=function(){var e=(0,a.useAPIClient)();return{run:function(){return h(function(){return g(this,function(t){switch(t.label){case 0:return[4,e.resource("localization").publish()];case 1:return t.sent(),window.location.reload(),[2]}})})()}}},E=function(){var e=(0,p.Q)().t,t=(0,a.useResourceActionContext)().refresh,n=(0,a.useAPIClient)(),r=x((0,u.useState)(!1),2),i=r[0],m=r[1],d=x((0,u.useState)([]),2),f=d[0],y=d[1],b=x((0,u.useState)([]),2),v=b[0],A=b[1],C=x((0,u.useState)(!1),2),T=C[0],w=C[1],S=x((0,u.useState)(!0),2),E=S[0],O=S[1],P=(0,a.useRequest)(function(){return n.resource("localization").getSources().then(function(e){var t;return null==e||null==(t=e.data)?void 0:t.data})},{onSuccess:function(e){var t=e.map(function(e){return e.name});y(t),A(t)}}),k=P.data;return P.loading?null:s().createElement(a.StablePopover,{placement:"bottomRight",content:s().createElement(s().Fragment,null,s().createElement(c.Checkbox,{indeterminate:T,onChange:function(e){A(e.target.checked?f:[]),w(!1),O(e.target.checked)},checked:E},e("All")),s().createElement(c.Divider,{style:{margin:"5px 0"}}),s().createElement(c.Checkbox.Group,{onChange:function(e){A(e),w(!!e.length&&e.length<f.length),O(e.length===f.length)},value:v},s().createElement(c.Col,null,(k||[]).map(function(t){return s().createElement(c.Row,{key:t.name},s().createElement(c.Checkbox,{value:t.name},l.Schema.compile(t.title,{t:e})))}))))},s().createElement(c.Button,{icon:s().createElement(o.SyncOutlined,null),loading:i,onClick:function(){return h(function(){return g(this,function(o){switch(o.label){case 0:if(!v.length)return[2,c.message.error(e("Please select the resources you want to synchronize"))];return m(!0),[4,n.resource("localization").sync({values:{types:v}})];case 1:return o.sent(),m(!1),t(),[2]}})})()}},e("Sync")))},O=function(){var e,t=(0,p.Q)().t,n=(0,i.useMemoizedFn)(t),o=(0,a.useResourceActionContext)().data;return(0,u.useMemo)(function(){var e,t;return(null==o||null==(t=o.meta)||null==(e=t.modules)?void 0:e.map(function(e){return{value:e.value,label:l.Schema.compile(e.label,{t:n})}}))||[]},[null==o||null==(e=o.meta)?void 0:e.modules,n])},P=function(){var e=(0,p.Q)().t,t=(0,a.useResourceActionContext)().run,n=O(),o=(0,u.useMemo)(function(){return(0,r.createForm)({initialValues:{hasTranslation:!0}})},[]),i=function(e){t(b({},e||o.values))};return(0,u.useEffect)(function(){o.query("module").take().dataSource=n},[o,n]),s().createElement(a.FormProvider,{form:o},s().createElement("div",{style:{display:"flex"}},s().createElement(l.Field,{name:"module",dataSource:n,component:[a.Select,{allowClear:!0,placeholder:e("Module"),onChange:function(e){return i(v(b({},o.values),{module:e}))}}]}),s().createElement(l.Field,{name:"keyword",component:[c.Input.Search,{placeholder:e("Keyword"),allowClear:!0,style:{marginLeft:"8px",width:"fit-content"},onSearch:function(e){return i(v(b({},o.values),{keyword:e}))}}]}),s().createElement(l.Field,{name:"hasTranslation",dataSource:[{label:e("All"),value:!0},{label:e("No translation"),value:!1}],component:[a.Radio.Group,{defaultValue:!0,style:{marginLeft:"8px",width:"fit-content"},optionType:"button",onChange:function(){return i()}}]})))},k=function(){var e=(0,p.Q)().t,t=(0,a.useRecord)(),n=t.moduleTitle,o=t.module;return n?s().createElement(c.Tag,null,l.Schema.compile(n,{t:e})):s().createElement(c.Tag,null,o)},F=function(){var e,t=(0,p.Q)().t,n=(0,a.useAPIClient)().auth.getLocale(),o=(null==(e=a.locale[n])?void 0:e.label)||n;return s().createElement(c.Card,{bordered:!1},s().createElement(a.SchemaComponent,{schema:d,components:{TranslationField:function(e){return void 0!==e.value?s().createElement(a.Input.TextArea,e):s().createElement("div",null)},CurrentLang:function(){return s().createElement(c.Typography,null,s().createElement(A,{strong:!0},t("Current language")),s().createElement(c.Tag,{style:{marginLeft:"10px"}},o))},Sync:E,Filter:P,ModuleTitle:k},scope:{t:t,useDestroyTranslationAction:T,useBulkDestroyTranslationAction:w,useUpdateTranslationAction:C,usePublishAction:S,useModules:O}}))}}}]);
|