@crowdin/app-project-module 0.102.1 → 0.103.0
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/ai-prompt-provider/types.d.ts +9 -0
- package/out/modules/ai-prompt-provider/types.js +7 -0
- package/out/modules/custom-mt/handlers/translate.js +6 -6
- package/out/modules/custom-mt/types.d.ts +1 -1
- package/out/modules/integration/handlers/integration-data.js +11 -7
- package/out/modules/integration/handlers/sync-settings-save.js +7 -3
- package/out/modules/integration/types.d.ts +5 -1
- package/out/modules/integration/util/defaults.js +11 -5
- package/out/modules/integration/util/files.d.ts +1 -0
- package/out/modules/integration/util/files.js +76 -6
- package/out/modules/manifest.js +7 -3
- package/out/types.d.ts +4 -0
- package/out/views/main.handlebars +142 -23
- package/package.json +1 -1
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { CrowdinContextInfo, UiModule } from '../../types';
|
|
2
2
|
import Crowdin from '@crowdin/crowdin-api-client';
|
|
3
|
+
export declare enum PromptActions {
|
|
4
|
+
PRE_TRANSLATE = "pre_translate",
|
|
5
|
+
ASSIST = "assist",
|
|
6
|
+
QA_CHECK = "qa_check"
|
|
7
|
+
}
|
|
3
8
|
export interface AiPromptProviderModule extends UiModule {
|
|
4
9
|
/**
|
|
5
10
|
* generates prompt text based on provided options
|
|
6
11
|
*/
|
|
7
12
|
compile: (options: any, payload: any, client: Crowdin, context: CrowdinContextInfo, requestData: any) => Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Represents a collection of supported actions. If not provided, all actions are supported.
|
|
15
|
+
*/
|
|
16
|
+
actions?: PromptActions[] | `custom:${string}`[];
|
|
8
17
|
}
|
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PromptActions = void 0;
|
|
4
|
+
var PromptActions;
|
|
5
|
+
(function (PromptActions) {
|
|
6
|
+
PromptActions["PRE_TRANSLATE"] = "pre_translate";
|
|
7
|
+
PromptActions["ASSIST"] = "assist";
|
|
8
|
+
PromptActions["QA_CHECK"] = "qa_check";
|
|
9
|
+
})(PromptActions = exports.PromptActions || (exports.PromptActions = {}));
|
|
@@ -19,18 +19,18 @@ function handle(config) {
|
|
|
19
19
|
(0, logger_1.log)('Received request for custom mt');
|
|
20
20
|
(0, logger_1.log)(`Source language ${source}, target language ${target}`);
|
|
21
21
|
(0, logger_1.log)(`Payload ${JSON.stringify(body, null, 2)}`);
|
|
22
|
-
const projectId = Number(req.query.project_id);
|
|
22
|
+
const projectId = req.query.project_id ? Number(req.query.project_id) : null;
|
|
23
23
|
try {
|
|
24
|
-
|
|
24
|
+
const isValidationRequest = source === 'en' && target === 'de' && body.strings && body.strings[0] === 'validation';
|
|
25
|
+
if (isValidationRequest) {
|
|
25
26
|
if (config.validate) {
|
|
26
27
|
yield config.validate(req.crowdinApiClient);
|
|
27
28
|
}
|
|
28
29
|
res.send({ data: { translations: [] } });
|
|
30
|
+
return;
|
|
29
31
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
res.send({ data: { translations } });
|
|
33
|
-
}
|
|
32
|
+
const translations = yield config.translate(req.crowdinApiClient, req.crowdinContext, projectId, source, target, body.strings);
|
|
33
|
+
res.send({ data: { translations } });
|
|
34
34
|
}
|
|
35
35
|
catch (e) {
|
|
36
36
|
req.logError(e);
|
|
@@ -4,7 +4,7 @@ export interface CustomMTLogic extends ModuleKey {
|
|
|
4
4
|
withContext?: boolean;
|
|
5
5
|
batchSize?: number;
|
|
6
6
|
maskEntities?: boolean;
|
|
7
|
-
translate: (client: Crowdin, context: CrowdinContextInfo, projectId: number, source: string, target: string, strings: CustomMtString[]) => Promise<string[]>;
|
|
7
|
+
translate: (client: Crowdin, context: CrowdinContextInfo, projectId: number | null, source: string, target: string, strings: CustomMtString[]) => Promise<string[]>;
|
|
8
8
|
validate?: (client: Crowdin) => Promise<void>;
|
|
9
9
|
}
|
|
10
10
|
export interface CustomMTRequest {
|
|
@@ -16,8 +16,8 @@ const types_1 = require("../types");
|
|
|
16
16
|
const storage_1 = require("../../../storage");
|
|
17
17
|
function handle(integration) {
|
|
18
18
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
19
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
20
|
-
const { parent_id: parentId, search, page } = req.query;
|
|
19
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
20
|
+
const { parent_id: parentId, search, page, paginationData } = req.query;
|
|
21
21
|
req.logInfo('Received request to get integration data');
|
|
22
22
|
let message;
|
|
23
23
|
let stopPagination;
|
|
@@ -25,7 +25,8 @@ function handle(integration) {
|
|
|
25
25
|
const { crowdinId, clientId } = req.crowdinContext;
|
|
26
26
|
try {
|
|
27
27
|
const appSettings = req.integrationSettings;
|
|
28
|
-
const
|
|
28
|
+
const parsedPaginationData = paginationData ? JSON.parse(paginationData) : undefined;
|
|
29
|
+
const result = yield integration.getIntegrationFiles(req.integrationCredentials, appSettings, parentId, search, page, parsedPaginationData);
|
|
29
30
|
if ((0, files_1.isExtendedResultType)(result)) {
|
|
30
31
|
files = result.data || [];
|
|
31
32
|
message = result.message;
|
|
@@ -46,20 +47,22 @@ function handle(integration) {
|
|
|
46
47
|
const needsFileStatus = ((_e = (_d = integration.filtering) === null || _d === void 0 ? void 0 : _d.integrationFileStatus) === null || _e === void 0 ? void 0 : _e.isNew) ||
|
|
47
48
|
((_g = (_f = integration.filtering) === null || _f === void 0 ? void 0 : _f.integrationFileStatus) === null || _g === void 0 ? void 0 : _g.isUpdated) ||
|
|
48
49
|
((_j = (_h = integration.filtering) === null || _h === void 0 ? void 0 : _h.integrationFileStatus) === null || _j === void 0 ? void 0 : _j.notSynced) ||
|
|
50
|
+
((_l = (_k = integration.filtering) === null || _k === void 0 ? void 0 : _k.integrationFileStatus) === null || _l === void 0 ? void 0 : _l.synced) ||
|
|
49
51
|
integration.forcePushSources === true;
|
|
50
52
|
if (needsFileStatus) {
|
|
51
53
|
const syncedData = yield (0, storage_1.getStorage)().getSyncedData(clientId, crowdinId, types_1.Provider.INTEGRATION);
|
|
52
54
|
const syncedFiles = (syncedData === null || syncedData === void 0 ? void 0 : syncedData.files) ? JSON.parse(syncedData.files) : [];
|
|
53
55
|
const lastSyncTimestamp = (syncedData === null || syncedData === void 0 ? void 0 : syncedData.updatedAt) ? Number(syncedData.updatedAt) : null;
|
|
54
56
|
files = files.map((file) => {
|
|
55
|
-
var _a, _b, _c, _d, _e, _f;
|
|
57
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
56
58
|
if (!file.type) {
|
|
57
59
|
return file;
|
|
58
60
|
}
|
|
59
61
|
const syncedFile = syncedFiles.find((syncedItem) => syncedItem.id === file.id);
|
|
60
62
|
const notSynced = ((_b = (_a = integration.filtering) === null || _a === void 0 ? void 0 : _a.integrationFileStatus) === null || _b === void 0 ? void 0 : _b.notSynced) === true ? !syncedFile : false;
|
|
63
|
+
const synced = ((_d = (_c = integration.filtering) === null || _c === void 0 ? void 0 : _c.integrationFileStatus) === null || _d === void 0 ? void 0 : _d.synced) === true ? !!syncedFile : false;
|
|
61
64
|
const fileSyncTimestamp = (syncedFile === null || syncedFile === void 0 ? void 0 : syncedFile.syncedAt) ? Number(syncedFile.syncedAt) : lastSyncTimestamp;
|
|
62
|
-
const isNew = ((
|
|
65
|
+
const isNew = ((_f = (_e = integration.filtering) === null || _e === void 0 ? void 0 : _e.integrationFileStatus) === null || _f === void 0 ? void 0 : _f.isNew) === true
|
|
63
66
|
? !syncedFile &&
|
|
64
67
|
fileSyncTimestamp &&
|
|
65
68
|
file.createdAt &&
|
|
@@ -67,7 +70,7 @@ function handle(integration) {
|
|
|
67
70
|
? new Date(file.createdAt).getTime()
|
|
68
71
|
: file.createdAt) > fileSyncTimestamp
|
|
69
72
|
: false;
|
|
70
|
-
const shouldCalculateIsUpdated = ((
|
|
73
|
+
const shouldCalculateIsUpdated = ((_h = (_g = integration.filtering) === null || _g === void 0 ? void 0 : _g.integrationFileStatus) === null || _h === void 0 ? void 0 : _h.isUpdated) === true ||
|
|
71
74
|
integration.forcePushSources === true;
|
|
72
75
|
const isUpdated = shouldCalculateIsUpdated
|
|
73
76
|
? syncedFile &&
|
|
@@ -78,7 +81,8 @@ function handle(integration) {
|
|
|
78
81
|
: false;
|
|
79
82
|
return Object.assign(Object.assign({}, file), { isNew,
|
|
80
83
|
notSynced,
|
|
81
|
-
isUpdated
|
|
84
|
+
isUpdated,
|
|
85
|
+
synced });
|
|
82
86
|
});
|
|
83
87
|
}
|
|
84
88
|
}
|
|
@@ -26,7 +26,7 @@ function checkAutoSyncSettings(integration, appSettings, provider) {
|
|
|
26
26
|
}
|
|
27
27
|
function handle(config, integration) {
|
|
28
28
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
29
|
-
const { files, provider, expandIntegrationFolders } = req.body;
|
|
29
|
+
const { files, provider, expandIntegrationFolders, hasLoadMoreElements } = req.body;
|
|
30
30
|
if (req.isApiCall) {
|
|
31
31
|
if (!files || !provider) {
|
|
32
32
|
return res.status(400).json({
|
|
@@ -54,9 +54,12 @@ function handle(config, integration) {
|
|
|
54
54
|
client: req.crowdinApiClient,
|
|
55
55
|
jobType: types_1.JobClientType.MANUAL,
|
|
56
56
|
jobStoreType: integration.jobStoreType,
|
|
57
|
-
jobCallback: () => __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
|
|
58
58
|
if (Array.isArray(expandIntegrationFolders) && expandIntegrationFolders.length) {
|
|
59
|
-
const
|
|
59
|
+
const expandedFiles = hasLoadMoreElements
|
|
60
|
+
? yield (0, files_1.expandFilesTreeWithPagination)(expandIntegrationFolders, req, integration, job)
|
|
61
|
+
: yield (0, files_1.expandFilesTree)(expandIntegrationFolders, req, integration, job);
|
|
62
|
+
const allFiles = expandedFiles.map((node) => ({
|
|
60
63
|
id: node.id,
|
|
61
64
|
name: node.name,
|
|
62
65
|
// eslint-disable-next-line @typescript-eslint/camelcase
|
|
@@ -67,6 +70,7 @@ function handle(config, integration) {
|
|
|
67
70
|
sync: false,
|
|
68
71
|
type: node.type,
|
|
69
72
|
}));
|
|
73
|
+
req.logInfo(`Expanded ${allFiles.length} files for auto-sync`);
|
|
70
74
|
yield (0, cron_1.createOrUpdateSyncSettings)({
|
|
71
75
|
req,
|
|
72
76
|
files: (0, lodash_uniqby_1.default)([...files, ...allFiles], 'id'),
|
|
@@ -40,7 +40,7 @@ export interface IntegrationLogic extends ModuleKey {
|
|
|
40
40
|
/**
|
|
41
41
|
* function to get data from integration
|
|
42
42
|
*/
|
|
43
|
-
getIntegrationFiles: (apiCredentials: any, config?: any, parentId?: any, search?: any, page?: any) => Promise<TreeItem[] | ExtendedResult<TreeItem[]>>;
|
|
43
|
+
getIntegrationFiles: (apiCredentials: any, config?: any, parentId?: any, search?: any, page?: any, paginationData?: any) => Promise<TreeItem[] | ExtendedResult<TreeItem[]>>;
|
|
44
44
|
/**
|
|
45
45
|
* function to update crowdin files (e.g. pull integration data to crowdin source files)
|
|
46
46
|
*/
|
|
@@ -146,6 +146,10 @@ export interface IntegrationLogic extends ModuleKey {
|
|
|
146
146
|
* Enable file filtering by "notSynced" status
|
|
147
147
|
*/
|
|
148
148
|
notSynced?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Enable file filtering by "synced" status
|
|
151
|
+
*/
|
|
152
|
+
synced?: boolean;
|
|
149
153
|
};
|
|
150
154
|
};
|
|
151
155
|
/**
|
|
@@ -58,7 +58,7 @@ function getOauthRoute(integration) {
|
|
|
58
58
|
}
|
|
59
59
|
exports.getOauthRoute = getOauthRoute;
|
|
60
60
|
function applyIntegrationModuleDefaults(config, integration) {
|
|
61
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
61
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
62
62
|
if (!integration.getCrowdinFiles) {
|
|
63
63
|
integration.getCrowdinFiles = (projectId, client, rootFolder, config, mode) => __awaiter(this, void 0, void 0, function* () {
|
|
64
64
|
const allBranches = (yield client.sourceFilesApi.withFetchAll().listProjectBranches(projectId)).data.map((d) => d.data);
|
|
@@ -152,7 +152,7 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
152
152
|
}
|
|
153
153
|
const getUserSettings = integration.getConfiguration;
|
|
154
154
|
integration.getConfiguration = (projectId, crowdinClient, integrationCredentials) => __awaiter(this, void 0, void 0, function* () {
|
|
155
|
-
var
|
|
155
|
+
var _p, _q, _r;
|
|
156
156
|
let fields = [];
|
|
157
157
|
const project = (yield crowdinClient.projectsGroupsApi.getProject(projectId));
|
|
158
158
|
if (getUserSettings) {
|
|
@@ -171,7 +171,7 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
171
171
|
if (integration.withCronSync || integration.webhooks) {
|
|
172
172
|
const userSchedule = fields.find((field) => 'key' in field && field.key === 'schedule');
|
|
173
173
|
if (userSchedule) {
|
|
174
|
-
userSchedule.position = (
|
|
174
|
+
userSchedule.position = (_p = userSchedule.position) !== null && _p !== void 0 ? _p : 0;
|
|
175
175
|
userSchedule.category = types_1.DefaultCategory.SYNC;
|
|
176
176
|
}
|
|
177
177
|
else {
|
|
@@ -211,7 +211,7 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
211
211
|
],
|
|
212
212
|
});
|
|
213
213
|
}
|
|
214
|
-
if ((
|
|
214
|
+
if ((_q = integration.syncNewElements) === null || _q === void 0 ? void 0 : _q.crowdin) {
|
|
215
215
|
defaultSettings.push({
|
|
216
216
|
key: 'new-crowdin-files',
|
|
217
217
|
label: 'Automatically sync new translations from Crowdin',
|
|
@@ -221,7 +221,7 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
221
221
|
position: 1,
|
|
222
222
|
});
|
|
223
223
|
}
|
|
224
|
-
if ((
|
|
224
|
+
if ((_r = integration.syncNewElements) === null || _r === void 0 ? void 0 : _r.integration) {
|
|
225
225
|
defaultSettings.push({
|
|
226
226
|
key: 'new-integration-files',
|
|
227
227
|
label: `Automatically sync new content from ${config.name}`,
|
|
@@ -350,6 +350,12 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
350
350
|
label: 'Never Synced',
|
|
351
351
|
});
|
|
352
352
|
}
|
|
353
|
+
if ((_o = (_m = integration.filtering) === null || _m === void 0 ? void 0 : _m.integrationFileStatus) === null || _o === void 0 ? void 0 : _o.synced) {
|
|
354
|
+
filterItems.push({
|
|
355
|
+
value: 'synced',
|
|
356
|
+
label: 'Previously Synced',
|
|
357
|
+
});
|
|
358
|
+
}
|
|
353
359
|
integration.filtering = Object.assign(Object.assign({}, (integration.filtering || {})), { integrationFilterConfig: filterItems.length > 1
|
|
354
360
|
? [
|
|
355
361
|
{
|
|
@@ -5,6 +5,7 @@ import { SourceFilesModel } from '@crowdin/crowdin-api-client';
|
|
|
5
5
|
export declare function skipFilesByRegex(files: TreeItem[] | undefined, skipIntegrationNodes?: SkipIntegrationNodes): TreeItem[];
|
|
6
6
|
export declare function expandFilesTree(nodes: IntegrationFile[], req: IntegrationRequest, integration: IntegrationLogic, job?: JobClient): Promise<IntegrationFile[]>;
|
|
7
7
|
export declare function attachFileStatus(files: any[], clientId: string, crowdinId: string, integration: IntegrationLogic): Promise<any[]>;
|
|
8
|
+
export declare function expandFilesTreeWithPagination(nodes: IntegrationFile[], req: IntegrationRequest, integration: IntegrationLogic, job?: JobClient): Promise<IntegrationFile[]>;
|
|
8
9
|
export declare function isExtendedResultType<T>(data?: T | ExtendedResult<T>): data is ExtendedResult<T>;
|
|
9
10
|
export declare function markUnsyncedFiles({ integrationId, crowdinId, client, files, }: {
|
|
10
11
|
integrationId: string;
|
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.filterSyncedData = exports.updateSyncedData = exports.filterFilesByPath = exports.filterFilesByPatterns = exports.getParentFiles = exports.getParentPaths = exports.buildPath = exports.prepareSyncFiles = exports.uniqueFileLanguages = exports.filterLanguages = exports.getExcludedTargetLanguages = exports.markUnsyncedFiles = exports.isExtendedResultType = exports.attachFileStatus = exports.expandFilesTree = exports.skipFilesByRegex = void 0;
|
|
15
|
+
exports.filterSyncedData = exports.updateSyncedData = exports.filterFilesByPath = exports.filterFilesByPatterns = exports.getParentFiles = exports.getParentPaths = exports.buildPath = exports.prepareSyncFiles = exports.uniqueFileLanguages = exports.filterLanguages = exports.getExcludedTargetLanguages = exports.markUnsyncedFiles = exports.isExtendedResultType = exports.expandFilesTreeWithPagination = exports.attachFileStatus = exports.expandFilesTree = exports.skipFilesByRegex = void 0;
|
|
16
16
|
const types_1 = require("../types");
|
|
17
17
|
const types_2 = require("./types");
|
|
18
18
|
const storage_1 = require("../../../storage");
|
|
@@ -38,7 +38,7 @@ function skipFilesByRegex(files, skipIntegrationNodes) {
|
|
|
38
38
|
}
|
|
39
39
|
exports.skipFilesByRegex = skipFilesByRegex;
|
|
40
40
|
function expandFilesTree(nodes, req, integration, job) {
|
|
41
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
41
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
42
42
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43
43
|
if (job && types_2.JobStatus.CANCELED === ((_a = (yield job.get())) === null || _a === void 0 ? void 0 : _a.status)) {
|
|
44
44
|
throw new Error('Job canceled');
|
|
@@ -72,6 +72,7 @@ function expandFilesTree(nodes, req, integration, job) {
|
|
|
72
72
|
const needsFileStatus = ((_c = (_b = integration.filtering) === null || _b === void 0 ? void 0 : _b.integrationFileStatus) === null || _c === void 0 ? void 0 : _c.isNew) ||
|
|
73
73
|
((_e = (_d = integration.filtering) === null || _d === void 0 ? void 0 : _d.integrationFileStatus) === null || _e === void 0 ? void 0 : _e.isUpdated) ||
|
|
74
74
|
((_g = (_f = integration.filtering) === null || _f === void 0 ? void 0 : _f.integrationFileStatus) === null || _g === void 0 ? void 0 : _g.notSynced) ||
|
|
75
|
+
((_j = (_h = integration.filtering) === null || _h === void 0 ? void 0 : _h.integrationFileStatus) === null || _j === void 0 ? void 0 : _j.synced) ||
|
|
75
76
|
integration.forcePushSources === true;
|
|
76
77
|
if (needsFileStatus) {
|
|
77
78
|
const { crowdinId, clientId } = req.crowdinContext;
|
|
@@ -82,11 +83,12 @@ function expandFilesTree(nodes, req, integration, job) {
|
|
|
82
83
|
}
|
|
83
84
|
exports.expandFilesTree = expandFilesTree;
|
|
84
85
|
function attachFileStatus(files, clientId, crowdinId, integration) {
|
|
85
|
-
var _a, _b, _c, _d, _e, _f;
|
|
86
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
86
87
|
return __awaiter(this, void 0, void 0, function* () {
|
|
87
88
|
const needsFileStatus = ((_b = (_a = integration.filtering) === null || _a === void 0 ? void 0 : _a.integrationFileStatus) === null || _b === void 0 ? void 0 : _b.isNew) ||
|
|
88
89
|
((_d = (_c = integration.filtering) === null || _c === void 0 ? void 0 : _c.integrationFileStatus) === null || _d === void 0 ? void 0 : _d.isUpdated) ||
|
|
89
90
|
((_f = (_e = integration.filtering) === null || _e === void 0 ? void 0 : _e.integrationFileStatus) === null || _f === void 0 ? void 0 : _f.notSynced) ||
|
|
91
|
+
((_h = (_g = integration.filtering) === null || _g === void 0 ? void 0 : _g.integrationFileStatus) === null || _h === void 0 ? void 0 : _h.synced) ||
|
|
90
92
|
integration.forcePushSources === true;
|
|
91
93
|
if (!needsFileStatus) {
|
|
92
94
|
return files;
|
|
@@ -95,21 +97,22 @@ function attachFileStatus(files, clientId, crowdinId, integration) {
|
|
|
95
97
|
const syncedFiles = (syncedData === null || syncedData === void 0 ? void 0 : syncedData.files) ? JSON.parse(syncedData.files) : [];
|
|
96
98
|
const lastSyncTimestamp = (syncedData === null || syncedData === void 0 ? void 0 : syncedData.updatedAt) ? Number(syncedData.updatedAt) : null;
|
|
97
99
|
return files.map((file) => {
|
|
98
|
-
var _a, _b, _c, _d, _e, _f;
|
|
100
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
99
101
|
if (!file.type) {
|
|
100
102
|
return file;
|
|
101
103
|
}
|
|
102
104
|
const syncedFile = syncedFiles.find((syncedItem) => syncedItem.id === file.id);
|
|
103
105
|
const notSynced = ((_b = (_a = integration.filtering) === null || _a === void 0 ? void 0 : _a.integrationFileStatus) === null || _b === void 0 ? void 0 : _b.notSynced) === true ? !syncedFile : false;
|
|
106
|
+
const synced = ((_d = (_c = integration.filtering) === null || _c === void 0 ? void 0 : _c.integrationFileStatus) === null || _d === void 0 ? void 0 : _d.synced) === true ? !!syncedFile : false;
|
|
104
107
|
const fileSyncTimestamp = (syncedFile === null || syncedFile === void 0 ? void 0 : syncedFile.syncedAt) ? Number(syncedFile.syncedAt) : lastSyncTimestamp;
|
|
105
|
-
const isNew = ((
|
|
108
|
+
const isNew = ((_f = (_e = integration.filtering) === null || _e === void 0 ? void 0 : _e.integrationFileStatus) === null || _f === void 0 ? void 0 : _f.isNew) === true
|
|
106
109
|
? !syncedFile &&
|
|
107
110
|
fileSyncTimestamp &&
|
|
108
111
|
file.createdAt &&
|
|
109
112
|
(typeof file.createdAt === 'string' ? new Date(file.createdAt).getTime() : file.createdAt) >
|
|
110
113
|
fileSyncTimestamp
|
|
111
114
|
: false;
|
|
112
|
-
const shouldCalculateIsUpdated = ((
|
|
115
|
+
const shouldCalculateIsUpdated = ((_h = (_g = integration.filtering) === null || _g === void 0 ? void 0 : _g.integrationFileStatus) === null || _h === void 0 ? void 0 : _h.isUpdated) === true || integration.forcePushSources === true;
|
|
113
116
|
const isUpdated = file.isUpdated !== undefined
|
|
114
117
|
? file.isUpdated
|
|
115
118
|
: shouldCalculateIsUpdated
|
|
@@ -121,11 +124,78 @@ function attachFileStatus(files, clientId, crowdinId, integration) {
|
|
|
121
124
|
: false;
|
|
122
125
|
return Object.assign(Object.assign({}, file), { isNew,
|
|
123
126
|
notSynced,
|
|
127
|
+
synced,
|
|
124
128
|
isUpdated });
|
|
125
129
|
});
|
|
126
130
|
});
|
|
127
131
|
}
|
|
128
132
|
exports.attachFileStatus = attachFileStatus;
|
|
133
|
+
function expandFilesTreeWithPagination(nodes, req, integration, job) {
|
|
134
|
+
var _a, _b;
|
|
135
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
+
if (job && types_2.JobStatus.CANCELED === ((_a = (yield job.get())) === null || _a === void 0 ? void 0 : _a.status)) {
|
|
137
|
+
throw new Error('Job canceled');
|
|
138
|
+
}
|
|
139
|
+
const files = nodes.filter((file) => file.nodeType === undefined || file.nodeType === '1');
|
|
140
|
+
const folders = nodes.filter((folder) => folder.nodeType === '0' && !nodes.find((node) => node.parentId === folder.id));
|
|
141
|
+
for (const folder of folders) {
|
|
142
|
+
const allFolderFiles = [];
|
|
143
|
+
let paginationData = undefined;
|
|
144
|
+
let hasMore = true;
|
|
145
|
+
let pageCount = 0;
|
|
146
|
+
while (hasMore) {
|
|
147
|
+
if (job && types_2.JobStatus.CANCELED === ((_b = (yield job.get())) === null || _b === void 0 ? void 0 : _b.status)) {
|
|
148
|
+
throw new Error('Job canceled');
|
|
149
|
+
}
|
|
150
|
+
pageCount++;
|
|
151
|
+
try {
|
|
152
|
+
if (job && pageCount > 1) {
|
|
153
|
+
yield job.update({
|
|
154
|
+
info: `Loading files from ${folder.name} (page ${pageCount})`,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const result = yield integration.getIntegrationFiles(req.integrationCredentials, req.integrationSettings, folder.id, '', 0, paginationData);
|
|
158
|
+
let integrationTreeItems = [];
|
|
159
|
+
if (isExtendedResultType(result)) {
|
|
160
|
+
integrationTreeItems = result.data || [];
|
|
161
|
+
if (result.stopPagination === true) {
|
|
162
|
+
hasMore = false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
integrationTreeItems = result || [];
|
|
167
|
+
}
|
|
168
|
+
const loadMoreElement = integrationTreeItems.find((item) => item.nodeType === 'load-more');
|
|
169
|
+
const actualFiles = integrationTreeItems.filter((item) => item.nodeType !== 'load-more');
|
|
170
|
+
allFolderFiles.push(...actualFiles);
|
|
171
|
+
if (loadMoreElement && loadMoreElement.pagination) {
|
|
172
|
+
paginationData = loadMoreElement.pagination;
|
|
173
|
+
}
|
|
174
|
+
else if (!isExtendedResultType(result) || result.stopPagination !== false) {
|
|
175
|
+
hasMore = false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch (e) {
|
|
179
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
180
|
+
if (job) {
|
|
181
|
+
const currentJob = yield job.get();
|
|
182
|
+
const currentErrors = (currentJob === null || currentJob === void 0 ? void 0 : currentJob.errors) ? JSON.parse(currentJob.errors) : [];
|
|
183
|
+
yield job.update({ errors: [...currentErrors, errorMessage] });
|
|
184
|
+
}
|
|
185
|
+
req.logError(`Error loading page ${pageCount} for folder ${folder.id}: ${errorMessage}`);
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const checkNodes = allFolderFiles
|
|
190
|
+
.filter((item) => item.id !== folder.id)
|
|
191
|
+
.map((item) => (Object.assign(Object.assign({}, item), { nodeType: item.nodeType || ('type' in item ? '1' : '0') })));
|
|
192
|
+
const expandedResult = yield expandFilesTreeWithPagination(checkNodes, req, integration, job);
|
|
193
|
+
files.push(...expandedResult);
|
|
194
|
+
}
|
|
195
|
+
return files;
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
exports.expandFilesTreeWithPagination = expandFilesTreeWithPagination;
|
|
129
199
|
function isExtendedResultType(data) {
|
|
130
200
|
const dataTyped = data;
|
|
131
201
|
return !!dataTyped && !Array.isArray(dataTyped);
|
package/out/modules/manifest.js
CHANGED
|
@@ -295,7 +295,11 @@ function handle(config) {
|
|
|
295
295
|
// prevent possible overrides of the other modules
|
|
296
296
|
config.aiPromptProvider = Object.assign(Object.assign({}, config.aiPromptProvider), { key: config.identifier + '-ai-prompt-provider' });
|
|
297
297
|
modules['ai-prompt-provider'] = [
|
|
298
|
-
Object.assign({ key: config.aiPromptProvider.key, name: config.aiPromptProvider.name || config.name, logo: (0, util_1.getLogoUrl)(config.aiPromptProvider, '/ai-prompt-provider'), compileUrl: '/prompt-provider/compile' }, (config.aiPromptProvider.
|
|
298
|
+
Object.assign(Object.assign({ key: config.aiPromptProvider.key, name: config.aiPromptProvider.name || config.name, logo: (0, util_1.getLogoUrl)(config.aiPromptProvider, '/ai-prompt-provider'), compileUrl: '/prompt-provider/compile' }, (config.aiPromptProvider.actions
|
|
299
|
+
? {
|
|
300
|
+
actions: config.aiPromptProvider.actions,
|
|
301
|
+
}
|
|
302
|
+
: {})), (config.aiPromptProvider.formSchema || config.aiPromptProvider.uiPath
|
|
299
303
|
? {
|
|
300
304
|
configuratorUrl: '/prompt-provider/settings/' + (config.aiPromptProvider.fileName || 'index.html'),
|
|
301
305
|
}
|
|
@@ -415,10 +419,10 @@ function handle(config) {
|
|
|
415
419
|
events['subscription_paid'] = '/subscription-paid';
|
|
416
420
|
}
|
|
417
421
|
return (_req, res) => {
|
|
418
|
-
const manifest = Object.assign(Object.assign(Object.assign(Object.assign({ identifier: config.identifier, name: config.name, logo: (0, util_1.getLogoUrl)(), baseUrl: config.baseUrl, authentication: {
|
|
422
|
+
const manifest = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ identifier: config.identifier, name: config.name, logo: (0, util_1.getLogoUrl)(), baseUrl: config.baseUrl, authentication: {
|
|
419
423
|
type: config.authenticationType || types_1.AuthenticationType.APP,
|
|
420
424
|
clientId: config.clientId,
|
|
421
|
-
}, restrictAiToSameApp: config.restrictAiToSameApp }, (config.agent && { agent: config.agent })), { events, scopes: config.scopes ? config.scopes : [types_1.Scope.PROJECTS] }), (config.defaultPermissions && { default_permissions: config.defaultPermissions })), { modules });
|
|
425
|
+
}, restrictAiToSameApp: config.restrictAiToSameApp }, (config.stringBasedAvailable !== undefined && { stringBasedAvailable: config.stringBasedAvailable })), (config.agent && { agent: config.agent })), { events, scopes: config.scopes ? config.scopes : [types_1.Scope.PROJECTS] }), (config.defaultPermissions && { default_permissions: config.defaultPermissions })), { modules });
|
|
422
426
|
res.send(manifest);
|
|
423
427
|
};
|
|
424
428
|
}
|
package/out/types.d.ts
CHANGED
|
@@ -264,6 +264,10 @@ export interface ClientConfig extends ImagePath {
|
|
|
264
264
|
* property that tells backend that AiProvider and AiPromptProvider modules can cooperate only with each one
|
|
265
265
|
*/
|
|
266
266
|
restrictAiToSameApp?: boolean;
|
|
267
|
+
/**
|
|
268
|
+
* Flag to indicate if the app works with string-based projects
|
|
269
|
+
*/
|
|
270
|
+
stringBasedAvailable?: boolean;
|
|
267
271
|
/**
|
|
268
272
|
* Automation action module
|
|
269
273
|
*/
|
|
@@ -453,6 +453,15 @@
|
|
|
453
453
|
onchange="onChangeAutoSynchronizationOptions(this)"
|
|
454
454
|
>
|
|
455
455
|
</crowdin-checkbox>
|
|
456
|
+
<crowdin-checkbox
|
|
457
|
+
id="all-folder-files"
|
|
458
|
+
name="all-folder-files"
|
|
459
|
+
label="All files in the folder"
|
|
460
|
+
class="hydrated"
|
|
461
|
+
hidden
|
|
462
|
+
onchange="onChangeAutoSynchronizationOptions(this)"
|
|
463
|
+
>
|
|
464
|
+
</crowdin-checkbox>
|
|
456
465
|
<crowdin-checkbox
|
|
457
466
|
id="new-files"
|
|
458
467
|
name="new-files"
|
|
@@ -499,8 +508,21 @@
|
|
|
499
508
|
cancelJob(e.detail);
|
|
500
509
|
});
|
|
501
510
|
{{#if integrationSearchListener}}
|
|
502
|
-
document.body.addEventListener("integrationFilterChange", (event) => {
|
|
503
|
-
|
|
511
|
+
document.body.addEventListener("integrationFilterChange", async (event) => {
|
|
512
|
+
const isEmptySearch = !event.detail || event.detail.trim() === '';
|
|
513
|
+
|
|
514
|
+
if (isEmptySearch && savedIntegrationData && hasLoadMoreElements) {
|
|
515
|
+
appComponent.setIntegrationFilesData(savedIntegrationData);
|
|
516
|
+
appComponent.setIntegrationOpenedFolders(currentOpenedFolders);
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if (!isEmptySearch && hasLoadMoreElements) {
|
|
521
|
+
savedIntegrationData = await appComponent.getIntegrationFilesData();
|
|
522
|
+
currentOpenedFolders = await appComponent.getIntegrationOpenedFolders();
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
getIntegrationData({ search: event.detail });
|
|
504
526
|
})
|
|
505
527
|
{{/if}}
|
|
506
528
|
const appComponent = document.querySelector('crowdin-simple-integration');
|
|
@@ -535,6 +557,9 @@
|
|
|
535
557
|
let project = {};
|
|
536
558
|
let crowdinData = [];
|
|
537
559
|
let fileToSync = [];
|
|
560
|
+
let hasLoadMoreElements = false;
|
|
561
|
+
let savedIntegrationData = null;
|
|
562
|
+
let currentOpenedFolders = null;
|
|
538
563
|
|
|
539
564
|
getCrowdinData();
|
|
540
565
|
getIntegrationData({});
|
|
@@ -628,10 +653,29 @@
|
|
|
628
653
|
.finally(() => (appComponent.setAttribute('is-crowdin-loading', false)));
|
|
629
654
|
}
|
|
630
655
|
|
|
631
|
-
function getIntegrationData(
|
|
632
|
-
|
|
656
|
+
function getIntegrationData(
|
|
657
|
+
{
|
|
658
|
+
hardReload = false,
|
|
659
|
+
parentId = '',
|
|
660
|
+
search = '',
|
|
661
|
+
page = 0,
|
|
662
|
+
recursion = false,
|
|
663
|
+
paginationData,
|
|
664
|
+
} = {},
|
|
665
|
+
recursionState = null
|
|
666
|
+
) {
|
|
667
|
+
if (!paginationData) {
|
|
668
|
+
appComponent.setAttribute('is-integration-loading', true);
|
|
669
|
+
}
|
|
670
|
+
|
|
633
671
|
return checkOrigin()
|
|
634
|
-
.then(restParams =>
|
|
672
|
+
.then(restParams => {
|
|
673
|
+
let url = `api/integration/data${restParams}&parent_id=${encodeURIComponent(parentId)}&search=${encodeURIComponent(search)}&page=${page}`;
|
|
674
|
+
if (paginationData) {
|
|
675
|
+
url += `&paginationData=${encodeURIComponent(JSON.stringify(paginationData))}`;
|
|
676
|
+
}
|
|
677
|
+
return fetch(url);
|
|
678
|
+
})
|
|
635
679
|
.then(checkResponse)
|
|
636
680
|
.then(async (res) => {
|
|
637
681
|
const files = res.data;
|
|
@@ -645,11 +689,13 @@
|
|
|
645
689
|
labels: e.labels,
|
|
646
690
|
disabled: e.disabled,
|
|
647
691
|
tooltip: e.tooltip,
|
|
692
|
+
pagination: e.pagination,
|
|
648
693
|
};
|
|
649
694
|
if (e.type) {
|
|
650
695
|
item.isNew = e.isNew;
|
|
651
696
|
item.isUpdated = e.isUpdated;
|
|
652
697
|
item.notSynced = e.notSynced;
|
|
698
|
+
item.synced = e.synced;
|
|
653
699
|
item.type = e.type;
|
|
654
700
|
item.node_type = fileType;
|
|
655
701
|
} else {
|
|
@@ -658,6 +704,10 @@
|
|
|
658
704
|
return item;
|
|
659
705
|
});
|
|
660
706
|
|
|
707
|
+
if ((!paginationData && !parentId && !search) || hardReload) {
|
|
708
|
+
hasLoadMoreElements = tree.some(item => item.node_type === 'load-more');
|
|
709
|
+
}
|
|
710
|
+
|
|
661
711
|
const appIntegrationFiles = appComponent.querySelector('#integration-files');
|
|
662
712
|
if (hardReload) {
|
|
663
713
|
appComponent.setIntegrationFilesData(tree);
|
|
@@ -1496,6 +1546,18 @@
|
|
|
1496
1546
|
})
|
|
1497
1547
|
{{/if}}
|
|
1498
1548
|
|
|
1549
|
+
document.body.addEventListener('loadMoreClick', async (e) => {
|
|
1550
|
+
const loadMoreFile = e.detail;
|
|
1551
|
+
const fileComponent = document.getElementById('integration-files')
|
|
1552
|
+
|
|
1553
|
+
await fileComponent.setLoadMoreLoading(loadMoreFile.id, true);
|
|
1554
|
+
|
|
1555
|
+
getIntegrationData({ parentId: e.detail.parent_id, paginationData: e.detail.pagination })
|
|
1556
|
+
.finally(async () => {
|
|
1557
|
+
await fileComponent.setLoadMoreLoading(loadMoreFile.id, false);
|
|
1558
|
+
});
|
|
1559
|
+
});
|
|
1560
|
+
|
|
1499
1561
|
{{#or withCronSync webhooks}}
|
|
1500
1562
|
const scheduleModal = document.getElementById('confirm-schedule-modal');
|
|
1501
1563
|
let syncData;
|
|
@@ -1520,6 +1582,7 @@
|
|
|
1520
1582
|
async function saveScheduleSync() {
|
|
1521
1583
|
const newFile = scheduleModal.querySelector('#new-files').checked || false;
|
|
1522
1584
|
const selectedFiles = scheduleModal.querySelector('#selected-files').checked || false;
|
|
1585
|
+
const allFolderFiles = scheduleModal.querySelector('#all-folder-files').checked || false;
|
|
1523
1586
|
|
|
1524
1587
|
const type = scheduleModal.getAttribute('data-type');
|
|
1525
1588
|
|
|
@@ -1530,7 +1593,11 @@
|
|
|
1530
1593
|
appComponent.setAttribute('is-crowdin-sync-settings-in-progress', true);
|
|
1531
1594
|
updateSyncSettings(syncedFiles, 'schedule', 'crowdin');
|
|
1532
1595
|
} else if (type === 'integration') {
|
|
1533
|
-
|
|
1596
|
+
{{#if syncNewElements.integration}}
|
|
1597
|
+
appComponent.setIntegrationScheduleSync(syncData, newFile, selectedFiles);
|
|
1598
|
+
{{else}}
|
|
1599
|
+
appComponent.setIntegrationScheduleSync(syncData);
|
|
1600
|
+
{{/if}}
|
|
1534
1601
|
appComponent.setIntegrationFilesHasSyncOption(true);
|
|
1535
1602
|
const syncedFiles = await appComponent.getIntegrationScheduleSync(true);
|
|
1536
1603
|
appComponent.setAttribute('is-integration-sync-settings-in-progress', true);
|
|
@@ -1542,16 +1609,28 @@
|
|
|
1542
1609
|
selectedFiles ? getIntegrationFoldersToExpand(syncData, syncedFiles) : [],
|
|
1543
1610
|
);
|
|
1544
1611
|
{{else}}
|
|
1545
|
-
|
|
1612
|
+
if (allFolderFiles) {
|
|
1613
|
+
const integrationExpandedFolders = syncData.filter(file => file.node_type === folderType).map(file => ({
|
|
1614
|
+
...file,
|
|
1615
|
+
nodeType: file.node_type,
|
|
1616
|
+
parentId: file.parent_id,
|
|
1617
|
+
}));
|
|
1618
|
+
updateSyncSettings(syncedFiles, 'schedule', 'integration', integrationExpandedFolders);
|
|
1619
|
+
} else {
|
|
1620
|
+
updateSyncSettings(syncedFiles, 'schedule', 'integration');
|
|
1621
|
+
}
|
|
1546
1622
|
{{/if}}
|
|
1547
1623
|
}
|
|
1548
1624
|
|
|
1549
1625
|
closeModal(scheduleModal);
|
|
1550
1626
|
}
|
|
1551
1627
|
|
|
1552
|
-
async function openScheduleModal(type) {
|
|
1628
|
+
async function openScheduleModal(type, options = {}) {
|
|
1629
|
+
const { showAllFolderFiles = false, showNewFiles = true } = options;
|
|
1630
|
+
|
|
1553
1631
|
const newFile = scheduleModal.querySelector('#new-files')
|
|
1554
1632
|
const selectedFiles = scheduleModal.querySelector('#selected-files');
|
|
1633
|
+
const allFolderFiles = scheduleModal.querySelector('#all-folder-files');
|
|
1555
1634
|
let newFileStatus = 'unChecked';
|
|
1556
1635
|
|
|
1557
1636
|
const integrationSyncFolders = (await document.querySelector('crowdin-simple-integration').getIntegrationScheduleSync(true))
|
|
@@ -1577,18 +1656,33 @@
|
|
|
1577
1656
|
}
|
|
1578
1657
|
}
|
|
1579
1658
|
|
|
1580
|
-
if (
|
|
1581
|
-
newFile
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1659
|
+
if (showNewFiles) {
|
|
1660
|
+
newFile.removeAttribute('hidden');
|
|
1661
|
+
if (newFileStatus === 'checked') {
|
|
1662
|
+
newFile[newFileStatus] = true;
|
|
1663
|
+
newFile.value = true;
|
|
1664
|
+
newFile.removeAttribute('clear-selection');
|
|
1665
|
+
} else if (newFileStatus === 'clear-selection') {
|
|
1666
|
+
newFile.checked = false;
|
|
1667
|
+
newFile.value = false;
|
|
1668
|
+
newFile.setAttribute(newFileStatus, '');
|
|
1669
|
+
} else {
|
|
1670
|
+
newFile.checked = false;
|
|
1671
|
+
newFile.value = false;
|
|
1672
|
+
newFile.removeAttribute('clear-selection');
|
|
1673
|
+
}
|
|
1588
1674
|
} else {
|
|
1675
|
+
newFile.setAttribute('hidden', '');
|
|
1589
1676
|
newFile.checked = false;
|
|
1590
|
-
|
|
1591
|
-
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
if (showAllFolderFiles) {
|
|
1680
|
+
allFolderFiles.removeAttribute('hidden');
|
|
1681
|
+
allFolderFiles.checked = false;
|
|
1682
|
+
allFolderFiles.value = false;
|
|
1683
|
+
} else {
|
|
1684
|
+
allFolderFiles.setAttribute('hidden', '');
|
|
1685
|
+
allFolderFiles.checked = false;
|
|
1592
1686
|
}
|
|
1593
1687
|
|
|
1594
1688
|
selectedFiles.checked = true;
|
|
@@ -1604,9 +1698,10 @@
|
|
|
1604
1698
|
|
|
1605
1699
|
const newFilesStatus = newFiles.checked || false;
|
|
1606
1700
|
const selectedFiles = document.getElementById('selected-files').checked || false;
|
|
1701
|
+
const allFolderFiles = document.getElementById('all-folder-files').checked || false;
|
|
1607
1702
|
const buttonSaveScheduleSync = document.getElementById('save-schedule-sync');
|
|
1608
1703
|
|
|
1609
|
-
if (newFilesStatus || selectedFiles) {
|
|
1704
|
+
if (newFilesStatus || selectedFiles || allFolderFiles) {
|
|
1610
1705
|
buttonSaveScheduleSync.removeAttribute('disabled');
|
|
1611
1706
|
} else {
|
|
1612
1707
|
buttonSaveScheduleSync.setAttribute('disabled', true);
|
|
@@ -1635,8 +1730,13 @@
|
|
|
1635
1730
|
{{#if syncNewElements.integration}}
|
|
1636
1731
|
syncData = e.detail;
|
|
1637
1732
|
const isFolder = await hasFolder(e.detail);
|
|
1638
|
-
|
|
1639
|
-
|
|
1733
|
+
|
|
1734
|
+
const shouldShowModal = isFolder && !newIntegrationFiles;
|
|
1735
|
+
const showNewFiles = true; // завжди показуємо New files коли є syncNewElements.integration
|
|
1736
|
+
const showAllFolderFiles = hasLoadMoreElements; // показуємо All files якщо є hasLoadMoreElements
|
|
1737
|
+
|
|
1738
|
+
if (shouldShowModal) {
|
|
1739
|
+
await openScheduleModal('integration', { showNewFiles, showAllFolderFiles });
|
|
1640
1740
|
return;
|
|
1641
1741
|
}
|
|
1642
1742
|
|
|
@@ -1644,14 +1744,33 @@
|
|
|
1644
1744
|
appComponent.setIntegrationFilesHasSyncOption(true);
|
|
1645
1745
|
const syncedFiles = await appComponent.getIntegrationScheduleSync(true);
|
|
1646
1746
|
{{else}}
|
|
1747
|
+
syncData = e.detail;
|
|
1748
|
+
const isFolder = await hasFolder(e.detail);
|
|
1749
|
+
|
|
1750
|
+
if (hasLoadMoreElements && isFolder) {
|
|
1751
|
+
await openScheduleModal('integration', { showNewFiles: false, showAllFolderFiles: true });
|
|
1752
|
+
return;
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1647
1755
|
const syncedFiles = await appComponent.getIntegrationScheduleSync();
|
|
1648
1756
|
{{/if}}
|
|
1649
1757
|
|
|
1650
1758
|
appComponent.setAttribute('is-integration-sync-settings-in-progress', true);
|
|
1759
|
+
|
|
1651
1760
|
{{#if integrationOneLevelFetching}}
|
|
1652
1761
|
updateSyncSettings(syncedFiles, 'schedule', 'integration', getIntegrationFoldersToExpand(e.detail, syncedFiles));
|
|
1653
1762
|
{{else}}
|
|
1654
|
-
|
|
1763
|
+
if (hasLoadMoreElements) {
|
|
1764
|
+
const integrationExpandedFolders = e.detail.filter(file => file.node_type === folderType).map(file => ({
|
|
1765
|
+
...file,
|
|
1766
|
+
nodeType: file.node_type,
|
|
1767
|
+
parentId: file.parent_id,
|
|
1768
|
+
}));
|
|
1769
|
+
|
|
1770
|
+
updateSyncSettings(syncedFiles, 'schedule', 'integration', integrationExpandedFolders);
|
|
1771
|
+
} else {
|
|
1772
|
+
updateSyncSettings(syncedFiles, 'schedule', 'integration');
|
|
1773
|
+
}
|
|
1655
1774
|
{{/if}}
|
|
1656
1775
|
}
|
|
1657
1776
|
|
|
@@ -1714,7 +1833,7 @@
|
|
|
1714
1833
|
.then(restParams => fetch('api/sync-settings' + restParams, {
|
|
1715
1834
|
method: 'POST',
|
|
1716
1835
|
headers: { 'Content-Type': 'application/json' },
|
|
1717
|
-
body: JSON.stringify({ files, type, provider, expandIntegrationFolders })
|
|
1836
|
+
body: JSON.stringify({ files, type, provider, expandIntegrationFolders, hasLoadMoreElements }),
|
|
1718
1837
|
}))
|
|
1719
1838
|
.then(checkResponse)
|
|
1720
1839
|
.then((res) => {
|
package/package.json
CHANGED