@crowdin/app-project-module 0.77.0 → 0.78.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/out/modules/integration/handlers/crowdin-update.js +10 -4
- package/out/modules/integration/handlers/integration-update.js +21 -7
- package/out/modules/integration/handlers/main.js +1 -0
- package/out/modules/integration/types.d.ts +7 -1
- package/out/modules/integration/util/defaults.js +1 -0
- package/out/modules/integration/util/files.d.ts +8 -1
- package/out/modules/integration/util/files.js +24 -1
- package/out/storage/mysql.js +8 -8
- package/out/storage/postgre.js +9 -9
- package/out/views/main.handlebars +89 -5
- package/package.json +2 -2
|
@@ -21,7 +21,7 @@ const job_1 = require("../util/job");
|
|
|
21
21
|
const files_1 = require("../util/files");
|
|
22
22
|
function handle(config, integration) {
|
|
23
23
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
24
|
-
var _a, _b;
|
|
24
|
+
var _a, _b, _c;
|
|
25
25
|
const projectId = req.crowdinContext.jwtPayload.context.project_id || (req === null || req === void 0 ? void 0 : req.body.projectId);
|
|
26
26
|
const uploadTranslations = req.query.uploadTranslations === 'true' || ((_a = req.body) === null || _a === void 0 ? void 0 : _a.uploadTranslations);
|
|
27
27
|
req.logInfo(`Updating crowdin project ${projectId}`);
|
|
@@ -33,6 +33,11 @@ function handle(config, integration) {
|
|
|
33
33
|
if (((_b = config.api) === null || _b === void 0 ? void 0 : _b.default) && req.body.files) {
|
|
34
34
|
req.body = req.body.files;
|
|
35
35
|
}
|
|
36
|
+
const excludedTargetLanguages = yield (0, files_1.getExcludedTargetLanguages)({
|
|
37
|
+
client: req.crowdinApiClient,
|
|
38
|
+
projectId,
|
|
39
|
+
languages: ((_c = req.query.languages) === null || _c === void 0 ? void 0 : _c.split(',')) || [],
|
|
40
|
+
});
|
|
36
41
|
yield (0, job_1.runAsJob)({
|
|
37
42
|
integrationId: req.crowdinContext.clientId,
|
|
38
43
|
crowdinId: req.crowdinContext.crowdinId,
|
|
@@ -40,13 +45,13 @@ function handle(config, integration) {
|
|
|
40
45
|
title: 'Sync files to Crowdin',
|
|
41
46
|
payload: req.body,
|
|
42
47
|
res,
|
|
43
|
-
projectId
|
|
48
|
+
projectId,
|
|
44
49
|
client: req.crowdinApiClient,
|
|
45
50
|
jobType: types_1.JobClientType.MANUAL,
|
|
46
51
|
jobStoreType: integration.jobStoreType,
|
|
47
52
|
jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
var
|
|
49
|
-
if (req.body && ((
|
|
53
|
+
var _d;
|
|
54
|
+
if (req.body && ((_d = req.body) === null || _d === void 0 ? void 0 : _d.length)) {
|
|
50
55
|
req.body = yield (0, files_1.expandFilesTree)(req.body, req, integration, job);
|
|
51
56
|
req.body = (0, lodash_uniqby_1.default)(req.body, 'id');
|
|
52
57
|
}
|
|
@@ -59,6 +64,7 @@ function handle(config, integration) {
|
|
|
59
64
|
appSettings: req.integrationSettings,
|
|
60
65
|
uploadTranslations,
|
|
61
66
|
job,
|
|
67
|
+
excludedTargetLanguages: req.query.languages ? excludedTargetLanguages : undefined,
|
|
62
68
|
});
|
|
63
69
|
let message;
|
|
64
70
|
if ((0, files_1.isExtendedResultType)(result)) {
|
|
@@ -19,7 +19,9 @@ function handle(config, integration) {
|
|
|
19
19
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
20
20
|
var _a;
|
|
21
21
|
req.logInfo('Updating integration data');
|
|
22
|
-
const
|
|
22
|
+
const client = req.crowdinApiClient;
|
|
23
|
+
const projectId = req.crowdinContext.jwtPayload.context.project_id;
|
|
24
|
+
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, req.crowdinApiClient, projectId);
|
|
23
25
|
if (rootFolder) {
|
|
24
26
|
req.logInfo(`Updating integration data for crowding root folder ${rootFolder.id}`);
|
|
25
27
|
}
|
|
@@ -27,23 +29,35 @@ function handle(config, integration) {
|
|
|
27
29
|
if (((_a = config.api) === null || _a === void 0 ? void 0 : _a.default) && req.body.files) {
|
|
28
30
|
req.body = req.body.files;
|
|
29
31
|
}
|
|
32
|
+
let payload = req.body;
|
|
33
|
+
if (integration.excludedTargetLanguages) {
|
|
34
|
+
let options = {};
|
|
35
|
+
if (rootFolder) {
|
|
36
|
+
options = {
|
|
37
|
+
directoryId: rootFolder.id,
|
|
38
|
+
recursion: 'true',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const files = (yield client.sourceFilesApi.withFetchAll().listProjectFiles(projectId, options)).data.map((d) => d.data);
|
|
42
|
+
payload = (0, files_1.filterLanguages)(payload, files);
|
|
43
|
+
}
|
|
30
44
|
yield (0, job_1.runAsJob)({
|
|
31
45
|
integrationId: req.crowdinContext.clientId,
|
|
32
46
|
crowdinId: req.crowdinContext.crowdinId,
|
|
33
47
|
type: types_1.JobType.UPDATE_TO_INTEGRATION,
|
|
34
48
|
title: 'Sync files to ' + config.name,
|
|
35
|
-
payload
|
|
49
|
+
payload,
|
|
36
50
|
res,
|
|
37
|
-
projectId
|
|
38
|
-
client
|
|
51
|
+
projectId,
|
|
52
|
+
client,
|
|
39
53
|
jobType: types_1.JobClientType.MANUAL,
|
|
40
54
|
jobStoreType: integration.jobStoreType,
|
|
41
55
|
jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
|
|
42
56
|
const result = yield integration.updateIntegration({
|
|
43
|
-
projectId
|
|
44
|
-
client
|
|
57
|
+
projectId,
|
|
58
|
+
client,
|
|
45
59
|
credentials: req.integrationCredentials,
|
|
46
|
-
request:
|
|
60
|
+
request: payload,
|
|
47
61
|
rootFolder,
|
|
48
62
|
appSettings: req.integrationSettings,
|
|
49
63
|
job,
|
|
@@ -94,6 +94,7 @@ function handle(config, integration) {
|
|
|
94
94
|
options.integrationSearchListener = integration.integrationSearchListener;
|
|
95
95
|
options.checkSubscription = !(0, subscription_1.isAppFree)(config);
|
|
96
96
|
options.uploadTranslations = integration.uploadTranslations;
|
|
97
|
+
options.excludedTargetLanguages = integration.excludedTargetLanguages;
|
|
97
98
|
options.sentryData = process.env.SENTRY_DSN
|
|
98
99
|
? {
|
|
99
100
|
dsn: process.env.SENTRY_DSN,
|
|
@@ -34,7 +34,7 @@ export interface IntegrationLogic extends ModuleKey {
|
|
|
34
34
|
/**
|
|
35
35
|
* function to update crowdin files (e.g. pull integration data to crowdin source files)
|
|
36
36
|
*/
|
|
37
|
-
updateCrowdin: ({ projectId, client, credentials, request, rootFolder, appSettings, uploadTranslations, job, }: {
|
|
37
|
+
updateCrowdin: ({ projectId, client, credentials, request, rootFolder, appSettings, uploadTranslations, job, excludedTargetLanguages, }: {
|
|
38
38
|
projectId: number;
|
|
39
39
|
client: Crowdin;
|
|
40
40
|
credentials: any;
|
|
@@ -43,6 +43,7 @@ export interface IntegrationLogic extends ModuleKey {
|
|
|
43
43
|
appSettings?: any;
|
|
44
44
|
uploadTranslations?: boolean;
|
|
45
45
|
job: JobClient;
|
|
46
|
+
excludedTargetLanguages?: string[];
|
|
46
47
|
}) => Promise<void | ExtendedResult<void>>;
|
|
47
48
|
/**
|
|
48
49
|
* function to update integration content (e.g. load crowdin translations and push them to integration service)
|
|
@@ -125,6 +126,10 @@ export interface IntegrationLogic extends ModuleKey {
|
|
|
125
126
|
* Enable the option to upload translations to crowdin that are already present in the integration.
|
|
126
127
|
*/
|
|
127
128
|
uploadTranslations?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Enable the option to upload file for translation into selected languages.
|
|
131
|
+
*/
|
|
132
|
+
excludedTargetLanguages?: boolean;
|
|
128
133
|
/**
|
|
129
134
|
* function to get crowdin file translation progress
|
|
130
135
|
*/
|
|
@@ -299,6 +304,7 @@ export interface File {
|
|
|
299
304
|
customContent?: string;
|
|
300
305
|
labels?: LabelTreeElement[];
|
|
301
306
|
failed?: boolean;
|
|
307
|
+
excludedTargetLanguages?: string[];
|
|
302
308
|
}
|
|
303
309
|
export interface Folder {
|
|
304
310
|
id: string;
|
|
@@ -116,6 +116,7 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
116
116
|
parentId: parentId ? parentId.toString() : undefined,
|
|
117
117
|
name: e.title || e.name,
|
|
118
118
|
type: e.type,
|
|
119
|
+
excludedTargetLanguages: e.excludedTargetLanguages,
|
|
119
120
|
});
|
|
120
121
|
});
|
|
121
122
|
return res;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ExtendedResult, IntegrationFile, IntegrationLogic, IntegrationRequest, SkipIntegrationNodes, TreeItem } from '../types';
|
|
1
|
+
import { ExtendedResult, IntegrationFile, IntegrationLogic, IntegrationRequest, SkipIntegrationNodes, TreeItem, UpdateIntegrationRequest } from '../types';
|
|
2
2
|
import { JobClient } from './types';
|
|
3
3
|
import Crowdin from '@crowdin/crowdin-api-client';
|
|
4
|
+
import { SourceFilesModel } from '@crowdin/crowdin-api-client';
|
|
4
5
|
export declare function skipFilesByRegex(files: TreeItem[] | undefined, skipIntegrationNodes?: SkipIntegrationNodes): TreeItem[];
|
|
5
6
|
export declare function expandFilesTree(nodes: IntegrationFile[], req: IntegrationRequest, integration: IntegrationLogic, job?: JobClient): Promise<IntegrationFile[]>;
|
|
6
7
|
export declare function isExtendedResultType<T>(data?: T | ExtendedResult<T>): data is ExtendedResult<T>;
|
|
@@ -10,3 +11,9 @@ export declare function markUnsyncedFiles({ integrationId, crowdinId, client, fi
|
|
|
10
11
|
client: Crowdin;
|
|
11
12
|
files?: TreeItem[];
|
|
12
13
|
}): Promise<TreeItem[]>;
|
|
14
|
+
export declare function getExcludedTargetLanguages({ client, projectId, languages, }: {
|
|
15
|
+
client: Crowdin;
|
|
16
|
+
projectId: number;
|
|
17
|
+
languages: string[];
|
|
18
|
+
}): Promise<string[]>;
|
|
19
|
+
export declare function filterLanguages(request: UpdateIntegrationRequest, files: SourceFilesModel.File[]): UpdateIntegrationRequest;
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.markUnsyncedFiles = exports.isExtendedResultType = exports.expandFilesTree = exports.skipFilesByRegex = void 0;
|
|
12
|
+
exports.filterLanguages = exports.getExcludedTargetLanguages = exports.markUnsyncedFiles = exports.isExtendedResultType = exports.expandFilesTree = exports.skipFilesByRegex = void 0;
|
|
13
13
|
const types_1 = require("./types");
|
|
14
14
|
const storage_1 = require("../../../storage");
|
|
15
15
|
const util_1 = require("../../../util");
|
|
@@ -98,3 +98,26 @@ function markUnsyncedFiles({ integrationId, crowdinId, client, files, }) {
|
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
100
|
exports.markUnsyncedFiles = markUnsyncedFiles;
|
|
101
|
+
function getExcludedTargetLanguages({ client, projectId, languages, }) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const projectData = yield client.projectsGroupsApi.getProject(projectId);
|
|
104
|
+
const targetLanguages = projectData.data.targetLanguageIds;
|
|
105
|
+
return targetLanguages.filter((language) => !languages.includes(language));
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
exports.getExcludedTargetLanguages = getExcludedTargetLanguages;
|
|
109
|
+
function filterLanguages(request, files) {
|
|
110
|
+
const result = {};
|
|
111
|
+
for (const fileId in request) {
|
|
112
|
+
const file = files.find((f) => f.id === parseInt(fileId, 10));
|
|
113
|
+
if (file) {
|
|
114
|
+
const excludedLanguages = new Set((file === null || file === void 0 ? void 0 : file.excludedTargetLanguages) || []);
|
|
115
|
+
result[fileId] = request[fileId].filter((lang) => !excludedLanguages.has(lang));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
result[fileId] = request[fileId];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
exports.filterLanguages = filterLanguages;
|
package/out/storage/mysql.js
CHANGED
|
@@ -572,8 +572,8 @@ class MySQLStorage {
|
|
|
572
572
|
yield this.dbPromise;
|
|
573
573
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
574
574
|
const [rows] = yield connection.execute(`
|
|
575
|
-
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
576
|
-
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
575
|
+
SELECT id, integration_id as "integrationId", crowdin_id as "crowdinId", type, payload, progress, status,
|
|
576
|
+
title, info, data, attempt, created_at as "createdAt", updated_at as "updatedAt", finished_at as "finishedAt"
|
|
577
577
|
FROM job
|
|
578
578
|
WHERE id = ?
|
|
579
579
|
`, [id]);
|
|
@@ -586,8 +586,8 @@ class MySQLStorage {
|
|
|
586
586
|
yield this.dbPromise;
|
|
587
587
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
588
588
|
const [rows] = yield connection.execute(`
|
|
589
|
-
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
590
|
-
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
589
|
+
SELECT id, integration_id as "integrationId", crowdin_id as "crowdinId", type, payload, progress, status,
|
|
590
|
+
title, info, data, attempt, created_at as "createdAt", updated_at as "updatedAt", finished_at as "finishedAt"
|
|
591
591
|
FROM job
|
|
592
592
|
WHERE integration_id = ? AND crowdin_id = ? AND finished_at is NULL
|
|
593
593
|
`, [integrationId, crowdinId]);
|
|
@@ -606,8 +606,8 @@ class MySQLStorage {
|
|
|
606
606
|
yield this.dbPromise;
|
|
607
607
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
608
608
|
const [rows] = yield connection.execute(`
|
|
609
|
-
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
610
|
-
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
609
|
+
SELECT id, integration_id as "integrationId", crowdin_id as "crowdinId", type, payload, progress, status,
|
|
610
|
+
title, info, data, attempt, created_at as "createdAt", updated_at as "updatedAt", finished_at as "finishedAt"
|
|
611
611
|
FROM job
|
|
612
612
|
WHERE status IN (?, ?) AND finished_at is NULL
|
|
613
613
|
`, [types_1.JobStatus.IN_PROGRESS, types_1.JobStatus.CREATED]);
|
|
@@ -629,7 +629,7 @@ class MySQLStorage {
|
|
|
629
629
|
yield this.dbPromise;
|
|
630
630
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
631
631
|
const [rows] = yield connection.execute(`
|
|
632
|
-
SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
|
|
632
|
+
SELECT integration_id as "integrationId", crowdin_id as "crowdinId", file_id as "fileId", language_id as "languageId", etag
|
|
633
633
|
FROM translation_file_cache
|
|
634
634
|
WHERE integration_id = ? AND crowdin_id = ? AND file_id = ?
|
|
635
635
|
`, [integrationId, crowdinId, fileId]);
|
|
@@ -642,7 +642,7 @@ class MySQLStorage {
|
|
|
642
642
|
yield this.dbPromise;
|
|
643
643
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
644
644
|
const [rows] = yield connection.execute(`
|
|
645
|
-
SELECT integration_id as integrationId, crowdin_id as
|
|
645
|
+
SELECT integration_id as "integrationId", crowdin_id as "crowdinId", file_id as "fileId", language_id as "languageId", etag
|
|
646
646
|
FROM translation_file_cache
|
|
647
647
|
WHERE integration_id = ? AND crowdin_id = ? AND file_id = ? AND language_id = ?
|
|
648
648
|
`, [integrationId, crowdinId, fileId, languageId]);
|
package/out/storage/postgre.js
CHANGED
|
@@ -624,8 +624,8 @@ class PostgreStorage {
|
|
|
624
624
|
yield this.dbPromise;
|
|
625
625
|
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
626
626
|
const res = yield client.query(`
|
|
627
|
-
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
628
|
-
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
627
|
+
SELECT id, integration_id as "integrationId", crowdin_id as "crowdinId", type, payload, progress, status,
|
|
628
|
+
title, info, data, attempt, created_at as "createdAt", updated_at as "updatedAt", finished_at as "finishedAt"
|
|
629
629
|
FROM job
|
|
630
630
|
WHERE id = $1
|
|
631
631
|
`, [id]);
|
|
@@ -638,8 +638,8 @@ class PostgreStorage {
|
|
|
638
638
|
yield this.dbPromise;
|
|
639
639
|
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
640
640
|
const res = yield client.query(`
|
|
641
|
-
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
642
|
-
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
641
|
+
SELECT id, integration_id as "integrationId", crowdin_id as "crowdinId", type, payload, progress, status,
|
|
642
|
+
title, info, data, attempt, created_at as "createdAt", updated_at as "updatedAt", finished_at as "finishedAt"
|
|
643
643
|
FROM job
|
|
644
644
|
WHERE integration_id = $1 AND crowdin_id = $2 AND finished_at is NULL
|
|
645
645
|
`, [integrationId, crowdinId]);
|
|
@@ -658,8 +658,8 @@ class PostgreStorage {
|
|
|
658
658
|
yield this.dbPromise;
|
|
659
659
|
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
660
660
|
const res = yield client.query(`
|
|
661
|
-
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
662
|
-
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
661
|
+
SELECT id, integration_id as "integrationId", crowdin_id as "crowdinId", type, payload, progress, status,
|
|
662
|
+
title, info, data, attempt, created_at as "createdAt", updated_at as "updatedAt", finished_at as "finishedAt"
|
|
663
663
|
FROM job
|
|
664
664
|
WHERE status IN ($1, $2) AND finished_at is NULL
|
|
665
665
|
`, [types_2.JobStatus.IN_PROGRESS, types_2.JobStatus.CREATED]);
|
|
@@ -673,7 +673,7 @@ class PostgreStorage {
|
|
|
673
673
|
yield this.executeQuery((client) => client.query(`
|
|
674
674
|
INSERT
|
|
675
675
|
INTO translation_file_cache(integration_id, crowdin_id, file_id, language_id, etag)
|
|
676
|
-
VALUES ($1, $2, $3, $4, $
|
|
676
|
+
VALUES ($1, $2, $3, $4, $5)
|
|
677
677
|
`, [integrationId, crowdinId, fileId, languageId, etag]));
|
|
678
678
|
});
|
|
679
679
|
}
|
|
@@ -682,7 +682,7 @@ class PostgreStorage {
|
|
|
682
682
|
yield this.dbPromise;
|
|
683
683
|
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
684
684
|
const res = yield client.query(`
|
|
685
|
-
SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
|
|
685
|
+
SELECT integration_id as "integrationId", crowdin_id as "crowdinId", file_id as "fileId", language_id as "languageId", etag
|
|
686
686
|
FROM translation_file_cache
|
|
687
687
|
WHERE integration_id = $1 AND crowdin_id = $2 AND file_id = $3
|
|
688
688
|
`, [integrationId, crowdinId, fileId]);
|
|
@@ -695,7 +695,7 @@ class PostgreStorage {
|
|
|
695
695
|
yield this.dbPromise;
|
|
696
696
|
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
697
697
|
const res = yield client.query(`
|
|
698
|
-
SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId
|
|
698
|
+
SELECT integration_id as "integrationId", crowdin_id as "crowdinId", file_id as "fileId", language_id as "languageId", etag
|
|
699
699
|
FROM translation_file_cache
|
|
700
700
|
WHERE integration_id = $1 AND crowdin_id = $2 AND file_id = $3 AND language_id = $4
|
|
701
701
|
`, [integrationId, crowdinId, fileId, languageId]);
|
|
@@ -79,7 +79,15 @@
|
|
|
79
79
|
integration-name="{{name}}"
|
|
80
80
|
integration-logo="logo.png"
|
|
81
81
|
{{#if uploadTranslations}}
|
|
82
|
-
|
|
82
|
+
{{#if excludedTargetLanguages}}
|
|
83
|
+
integration-button-menu-items='[{"label":"Sync translations", "title":"Sync translations to Crowdin", "action":"uploadTranslations"}, {"label":"Select target languages", "title":"Upload file for translation into selected languages", "action":"excludedTargetLanguages"}]'
|
|
84
|
+
{{else}}
|
|
85
|
+
integration-button-menu-items='[{"label":"Sync translations", "title":"Sync translations to Crowdin", "action":"uploadTranslations"}]'
|
|
86
|
+
{{/if}}
|
|
87
|
+
{{else}}
|
|
88
|
+
{{#if excludedTargetLanguages}}
|
|
89
|
+
integration-button-menu-items='[{"label":"Select target languages", "title":"Upload file for translation into selected languages", "action":"excludedTargetLanguages"}]'
|
|
90
|
+
{{/if}}
|
|
83
91
|
{{/if}}
|
|
84
92
|
{{#if filtering.crowdinLanguages}}
|
|
85
93
|
crowdin-filter
|
|
@@ -209,6 +217,15 @@
|
|
|
209
217
|
</div>
|
|
210
218
|
</crowdin-modal>
|
|
211
219
|
|
|
220
|
+
{{#if excludedTargetLanguages}}
|
|
221
|
+
<crowdin-modal
|
|
222
|
+
modal-width="50"
|
|
223
|
+
modal-title="Select Target Languages for Translation"
|
|
224
|
+
id="excluded-languages"
|
|
225
|
+
>
|
|
226
|
+
</crowdin-modal>
|
|
227
|
+
{{/if}}
|
|
228
|
+
|
|
212
229
|
{{#if infoModal}}
|
|
213
230
|
<crowdin-modal
|
|
214
231
|
style="display: none;"
|
|
@@ -479,6 +496,7 @@
|
|
|
479
496
|
|
|
480
497
|
let project = {};
|
|
481
498
|
let crowdinData = [];
|
|
499
|
+
let fileToSync = [];
|
|
482
500
|
|
|
483
501
|
getCrowdinData();
|
|
484
502
|
getIntegrationData();
|
|
@@ -511,6 +529,7 @@
|
|
|
511
529
|
item.type = e.type;
|
|
512
530
|
item.node_type = fileType;
|
|
513
531
|
item.failed = e.failed;
|
|
532
|
+
item.excludedTargetLanguages = e.excludedTargetLanguages;
|
|
514
533
|
} else {
|
|
515
534
|
item.node_type = e.nodeType || folderType;
|
|
516
535
|
}
|
|
@@ -534,6 +553,8 @@
|
|
|
534
553
|
languagesSorted.push({...project.inContextPseudoLanguage, inContext: true});
|
|
535
554
|
}
|
|
536
555
|
|
|
556
|
+
setLanguagesForTranslation(languagesSorted);
|
|
557
|
+
|
|
537
558
|
appComponent.setCrowdinLanguagesData(languagesSorted)
|
|
538
559
|
})
|
|
539
560
|
{{#or withCronSync webhooks}}
|
|
@@ -636,17 +657,21 @@
|
|
|
636
657
|
.catch(e => catchRejection(e, 'Can\'t fetch file progress'));
|
|
637
658
|
}
|
|
638
659
|
|
|
639
|
-
function uploadFilesToCrowdin(event) {
|
|
660
|
+
function uploadFilesToCrowdin(event, languages = []) {
|
|
640
661
|
let files = [];
|
|
641
662
|
let uploadTranslations = false;
|
|
642
|
-
if (event.detail
|
|
663
|
+
if (event.detail?.action === 'uploadTranslations') {
|
|
643
664
|
files = event.detail.files;
|
|
644
665
|
uploadTranslations = true;
|
|
666
|
+
} else if (event.detail?.action === 'excludedTargetLanguages') {
|
|
667
|
+
fileToSync = event.detail.files;
|
|
668
|
+
openLanguageModal();
|
|
669
|
+
return;
|
|
645
670
|
} else {
|
|
646
671
|
files = event.detail;
|
|
647
672
|
}
|
|
648
673
|
|
|
649
|
-
if (event.detail
|
|
674
|
+
if (event.detail?.length === 0 || !event.detail) {
|
|
650
675
|
showToast('Select templates which will be pushed to Crowdin');
|
|
651
676
|
return;
|
|
652
677
|
}
|
|
@@ -669,7 +694,7 @@
|
|
|
669
694
|
}));
|
|
670
695
|
{{/if}}
|
|
671
696
|
checkOrigin()
|
|
672
|
-
.then(restParams => fetch(`api/crowdin/update${restParams}&uploadTranslations=${uploadTranslations}`, {
|
|
697
|
+
.then(restParams => fetch(`api/crowdin/update${restParams}&uploadTranslations=${uploadTranslations}&languages=${languages}`, {
|
|
673
698
|
method: 'POST',
|
|
674
699
|
headers: { 'Content-Type': 'application/json' },
|
|
675
700
|
body: JSON.stringify(req)
|
|
@@ -844,6 +869,56 @@
|
|
|
844
869
|
.catch(e => catchRejection(e, 'Can\'t upload files to {{name}}'))
|
|
845
870
|
}
|
|
846
871
|
|
|
872
|
+
function openLanguageModal() {
|
|
873
|
+
openModal(languageModal);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
async function uploadFilesToCrowdinWithExcludedLanguages() {
|
|
877
|
+
const languageSelect = document.querySelector('#language-select');
|
|
878
|
+
const selectedLanguages = await languageSelect.getValue();
|
|
879
|
+
closeModal(languageModal);
|
|
880
|
+
uploadFilesToCrowdin({ detail: fileToSync }, selectedLanguages);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
async function setLanguagesForTranslation(languages) {
|
|
884
|
+
const languageIds = languages.map(language => language.id);
|
|
885
|
+
if (languageModal) {
|
|
886
|
+
let modalContent = `
|
|
887
|
+
<div>
|
|
888
|
+
<crowdin-select
|
|
889
|
+
is-multi
|
|
890
|
+
is-searchable
|
|
891
|
+
is-position-fixed
|
|
892
|
+
close-on-select="false"
|
|
893
|
+
name="languages"
|
|
894
|
+
id="language-select"
|
|
895
|
+
label="Languages"
|
|
896
|
+
>`;
|
|
897
|
+
|
|
898
|
+
for (const language of languages) {
|
|
899
|
+
modalContent += `<option value="${language.id}">${language.name}</option>`;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
modalContent += `
|
|
903
|
+
</crowdin-select>
|
|
904
|
+
</div>
|
|
905
|
+
<div slot="footer">
|
|
906
|
+
<crowdin-button id="upload-exclude-languages" outlined onclick="uploadFilesToCrowdinWithExcludedLanguages()">
|
|
907
|
+
<div class="integration-icon-button">
|
|
908
|
+
<span>Sync to</span>
|
|
909
|
+
<crowdin-logo is-icon/>
|
|
910
|
+
</div>
|
|
911
|
+
</crowdin-button>
|
|
912
|
+
</div>
|
|
913
|
+
`;
|
|
914
|
+
|
|
915
|
+
languageModal.innerHTML = modalContent;
|
|
916
|
+
|
|
917
|
+
const select = document.querySelector('#language-select')
|
|
918
|
+
await select.setValue(languageIds);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
847
922
|
{{#if configurationFields}}
|
|
848
923
|
const settingsModal = document.getElementById('settings-modal');
|
|
849
924
|
const settingsSaveBtn = document.getElementById('settings-save-btn');
|
|
@@ -1109,6 +1184,12 @@
|
|
|
1109
1184
|
|
|
1110
1185
|
const permissions = document.getElementById('permissions-modal');
|
|
1111
1186
|
|
|
1187
|
+
{{#if excludedTargetLanguages}}
|
|
1188
|
+
const languageModal = document.getElementById('excluded-languages');
|
|
1189
|
+
{{else}}
|
|
1190
|
+
const languageModal = undefined;
|
|
1191
|
+
{{/if}}
|
|
1192
|
+
|
|
1112
1193
|
{{#if infoModal}}
|
|
1113
1194
|
const infoModal = document.getElementById('info-modal');
|
|
1114
1195
|
{{else}}
|
|
@@ -1126,6 +1207,9 @@
|
|
|
1126
1207
|
if (settingsModal) {
|
|
1127
1208
|
closeModal(settingsModal);
|
|
1128
1209
|
}
|
|
1210
|
+
if (languageModal) {
|
|
1211
|
+
closeModal(languageModal);
|
|
1212
|
+
}
|
|
1129
1213
|
}
|
|
1130
1214
|
});
|
|
1131
1215
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crowdin/app-project-module",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.78.1",
|
|
4
4
|
"description": "Module that generates for you all common endpoints for serving standalone Crowdin App",
|
|
5
5
|
"main": "out/index.js",
|
|
6
6
|
"types": "out/index.d.ts",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@aws-sdk/client-s3": "^3.744.0",
|
|
23
23
|
"@aws-sdk/s3-request-presigner": "^3.744.0",
|
|
24
|
-
"@crowdin/crowdin-apps-functions": "^0.
|
|
24
|
+
"@crowdin/crowdin-apps-functions": "^0.11.0",
|
|
25
25
|
"@crowdin/logs-formatter": "^2.1.7",
|
|
26
26
|
"@godaddy/terminus": "^4.12.1",
|
|
27
27
|
"@monaco-editor/react": "^4.6.0",
|