@crowdin/app-project-module 0.92.0 → 0.94.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/integration/handlers/integration-data.js +10 -7
- package/out/modules/integration/handlers/settings-save.js +15 -0
- package/out/modules/integration/types.d.ts +21 -0
- package/out/modules/integration/util/defaults.js +15 -6
- package/out/modules/integration/util/snapshot.js +5 -1
- package/out/static/js/form.js +1 -1
- package/out/types.d.ts +1 -1
- package/out/views/main.handlebars +98 -16
- package/out/views/partials/head.handlebars +18 -14
- package/package.json +1 -1
package/out/types.d.ts
CHANGED
|
@@ -261,7 +261,7 @@ export interface ClientConfig extends ImagePath {
|
|
|
261
261
|
/**
|
|
262
262
|
* property that tells backend that AiProvider and AiPromptProvider modules can cooperate only with each one
|
|
263
263
|
*/
|
|
264
|
-
restrictAiToSameApp
|
|
264
|
+
restrictAiToSameApp?: boolean;
|
|
265
265
|
}
|
|
266
266
|
export interface Environments {
|
|
267
267
|
environments?: Environment | Environment[];
|
|
@@ -287,6 +287,7 @@
|
|
|
287
287
|
{{#if dependencySettings}}
|
|
288
288
|
data-dependency="{{dependencySettings}}"
|
|
289
289
|
{{/if}}
|
|
290
|
+
onchange="settingsFieldChange(this)"
|
|
290
291
|
>
|
|
291
292
|
</crowdin-checkbox>
|
|
292
293
|
{{/ifeq}}
|
|
@@ -312,6 +313,7 @@
|
|
|
312
313
|
data-dependency="{{dependencySettings}}"
|
|
313
314
|
{{/if}}
|
|
314
315
|
is-position-fixed
|
|
316
|
+
onchange="settingsFieldChange(this)"
|
|
315
317
|
>
|
|
316
318
|
{{#each options}}
|
|
317
319
|
<option
|
|
@@ -340,6 +342,7 @@
|
|
|
340
342
|
data-dependency="{{dependencySettings}}"
|
|
341
343
|
{{/if}}
|
|
342
344
|
value="{{#if defaultValue}}{{defaultValue}}{{/if}}"
|
|
345
|
+
onchange="settingsFieldChange(this)"
|
|
343
346
|
>
|
|
344
347
|
</crowdin-input>
|
|
345
348
|
{{/ifeq}}
|
|
@@ -357,7 +360,9 @@
|
|
|
357
360
|
{{#if dependencySettings}}
|
|
358
361
|
data-dependency="{{dependencySettings}}"
|
|
359
362
|
{{/if}}
|
|
360
|
-
value="{{#if defaultValue}}{{defaultValue}}{{/if}}"
|
|
363
|
+
value="{{#if defaultValue}}{{defaultValue}}{{/if}}"
|
|
364
|
+
onchange="settingsFieldChange(this)"
|
|
365
|
+
>
|
|
361
366
|
</crowdin-textarea>
|
|
362
367
|
{{/ifeq}}
|
|
363
368
|
{{#ifeq type "notice"}}
|
|
@@ -457,7 +462,7 @@
|
|
|
457
462
|
<script type="text/javascript">
|
|
458
463
|
document.body.addEventListener('refreshFilesList', (e) => {
|
|
459
464
|
if (e.detail.refreshIntegration) {
|
|
460
|
-
getIntegrationData(true);
|
|
465
|
+
getIntegrationData({ hardReload: true });
|
|
461
466
|
} else if (e.detail.refreshCrowdin) {
|
|
462
467
|
getCrowdinData();
|
|
463
468
|
}
|
|
@@ -468,7 +473,7 @@
|
|
|
468
473
|
}
|
|
469
474
|
{{#if integrationOneLevelFetching}}
|
|
470
475
|
if (event.detail.componentId === 'integration-files' && event.detail.isOpen) {
|
|
471
|
-
getIntegrationData(
|
|
476
|
+
getIntegrationData({ parentId: event.detail.id, recursion: event.detail.recursion });
|
|
472
477
|
}
|
|
473
478
|
{{/if}}
|
|
474
479
|
});
|
|
@@ -479,7 +484,7 @@
|
|
|
479
484
|
});
|
|
480
485
|
{{#if integrationSearchListener}}
|
|
481
486
|
document.body.addEventListener("integrationFilterChange", (event) => {
|
|
482
|
-
getIntegrationData(
|
|
487
|
+
getIntegrationData({ search: event.detail });
|
|
483
488
|
})
|
|
484
489
|
{{/if}}
|
|
485
490
|
const appComponent = document.querySelector('crowdin-simple-integration');
|
|
@@ -516,7 +521,7 @@
|
|
|
516
521
|
let fileToSync = [];
|
|
517
522
|
|
|
518
523
|
getCrowdinData();
|
|
519
|
-
getIntegrationData();
|
|
524
|
+
getIntegrationData({});
|
|
520
525
|
getActiveJobs();
|
|
521
526
|
|
|
522
527
|
function integrationLogout() {
|
|
@@ -583,12 +588,12 @@
|
|
|
583
588
|
.finally(() => (appComponent.setAttribute('is-crowdin-loading', false)));
|
|
584
589
|
}
|
|
585
590
|
|
|
586
|
-
function getIntegrationData(hardReload = false, parentId = '', search = '', page = 0) {
|
|
591
|
+
function getIntegrationData({ hardReload = false, parentId = '', search = '', page = 0, recursion = false } = {}, recursionState = null) {
|
|
587
592
|
appComponent.setAttribute('is-integration-loading', true);
|
|
588
|
-
checkOrigin()
|
|
593
|
+
return checkOrigin()
|
|
589
594
|
.then(restParams => fetch(`api/integration/data${restParams}&parent_id=${encodeURIComponent(parentId)}&search=${encodeURIComponent(search)}&page=${page}`))
|
|
590
595
|
.then(checkResponse)
|
|
591
|
-
.then((res) => {
|
|
596
|
+
.then(async (res) => {
|
|
592
597
|
const files = res.data;
|
|
593
598
|
const stopPagination = res.stopPagination;
|
|
594
599
|
const tree = files.map(e => {
|
|
@@ -642,12 +647,61 @@
|
|
|
642
647
|
const openIds = files.filter(e => !e.type).map(e => e.id);
|
|
643
648
|
appComponent.setIntegrationOpenedFolders(openIds);
|
|
644
649
|
}
|
|
650
|
+
|
|
651
|
+
if (recursion) {
|
|
652
|
+
if (!recursionState) {
|
|
653
|
+
recursionState = {
|
|
654
|
+
openedFolders: new Set(),
|
|
655
|
+
calls: 0,
|
|
656
|
+
setLoading(isLoading) {
|
|
657
|
+
appComponent.setAttribute('is-integration-loading', isLoading);
|
|
658
|
+
},
|
|
659
|
+
};
|
|
660
|
+
recursionState.setLoading(true);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
if (parentId) {
|
|
664
|
+
recursionState.openedFolders.add(parentId);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const folderItems = files.filter(isFolder);
|
|
668
|
+
|
|
669
|
+
if (folderItems.length === 0) {
|
|
670
|
+
return Promise.resolve();
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
folderItems.forEach(folder => recursionState.openedFolders.add(folder.id));
|
|
674
|
+
|
|
675
|
+
const currentOpenedFolders = await appComponent.getIntegrationOpenedFolders();
|
|
676
|
+
appComponent.setIntegrationOpenedFolders([...currentOpenedFolders, ...recursionState.openedFolders]);
|
|
677
|
+
|
|
678
|
+
const recursivePromises = folderItems.map(async folder => {
|
|
679
|
+
recursionState.calls++;
|
|
680
|
+
|
|
681
|
+
try {
|
|
682
|
+
return getIntegrationData({ parentId: folder.id, recursion: true }, recursionState);
|
|
683
|
+
} finally {
|
|
684
|
+
recursionState.calls--;
|
|
685
|
+
if (recursionState.calls === 0) {
|
|
686
|
+
recursionState.setLoading(false);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
return Promise.all(recursivePromises);
|
|
692
|
+
}
|
|
645
693
|
})
|
|
646
694
|
{{#or withCronSync webhooks}}
|
|
647
695
|
.then(() => getSyncSettings('integration'))
|
|
648
696
|
{{/or}}
|
|
649
697
|
.catch(e => catchRejection(e, 'Can\'t fetch {{name}} templates'))
|
|
650
|
-
.finally(() =>
|
|
698
|
+
.finally(() => {
|
|
699
|
+
if (!recursionState && !recursion) {
|
|
700
|
+
appComponent.setAttribute('is-integration-loading', false);
|
|
701
|
+
} else if (recursionState && recursionState.calls === 0) {
|
|
702
|
+
appComponent.setAttribute('is-integration-loading', false);
|
|
703
|
+
}
|
|
704
|
+
});
|
|
651
705
|
}
|
|
652
706
|
|
|
653
707
|
function getSyncSettings(provider) {
|
|
@@ -1315,6 +1369,7 @@
|
|
|
1315
1369
|
});
|
|
1316
1370
|
});
|
|
1317
1371
|
|
|
1372
|
+
let isValidationError = false;
|
|
1318
1373
|
settingsSaveBtn.setAttribute('disabled', true);
|
|
1319
1374
|
checkOrigin()
|
|
1320
1375
|
.then(restParams => fetch('api/settings' + restParams, {
|
|
@@ -1327,15 +1382,33 @@
|
|
|
1327
1382
|
showToast('Settings successfully saved');
|
|
1328
1383
|
config = configReq;
|
|
1329
1384
|
})
|
|
1330
|
-
.catch(e =>
|
|
1385
|
+
.catch(e => {
|
|
1386
|
+
if (e?.error && e?.error?.type === 'validation_error') {
|
|
1387
|
+
Object.keys(e?.error?.details).forEach(key => {
|
|
1388
|
+
const el = document.getElementById(`${key}-settings`);
|
|
1389
|
+
if (el) {
|
|
1390
|
+
el.setAttribute('error', 'true');
|
|
1391
|
+
el.setAttribute('error-text', e?.error?.details[key]);
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
1394
|
+
|
|
1395
|
+
isValidationError = true;
|
|
1396
|
+
showToast(e?.error?.details?.message || 'Can\'t save settings');
|
|
1397
|
+
settingsSaveBtn.removeAttribute('disabled');
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
catchRejection(e, 'Can\'t save settings')
|
|
1401
|
+
})
|
|
1331
1402
|
.finally(() => {
|
|
1332
1403
|
unsetLoader('#settings-modal');
|
|
1333
1404
|
settingsSaveBtn.removeAttribute('disabled');
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1405
|
+
if (!isValidationError) {
|
|
1406
|
+
closeModal(settingsModal);
|
|
1407
|
+
{{#if reloadOnConfigSave}}
|
|
1408
|
+
getIntegrationData({ hardReload: true });
|
|
1409
|
+
getCrowdinData();
|
|
1410
|
+
{{/if}}
|
|
1411
|
+
}
|
|
1339
1412
|
});
|
|
1340
1413
|
}
|
|
1341
1414
|
{{else}}
|
|
@@ -1375,7 +1448,7 @@
|
|
|
1375
1448
|
|
|
1376
1449
|
{{#if integrationPagination}}
|
|
1377
1450
|
document.body.addEventListener('fileListEnd', (e) => {
|
|
1378
|
-
getIntegrationData(
|
|
1451
|
+
getIntegrationData({ page: e.detail.page });
|
|
1379
1452
|
})
|
|
1380
1453
|
{{/if}}
|
|
1381
1454
|
|
|
@@ -1770,6 +1843,15 @@
|
|
|
1770
1843
|
modal.style.display = 'none';
|
|
1771
1844
|
modal.close()
|
|
1772
1845
|
}
|
|
1846
|
+
|
|
1847
|
+
function settingsFieldChange(el) {
|
|
1848
|
+
el.removeAttribute('error');
|
|
1849
|
+
el.removeAttribute('error-text');
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
function isFolder(e) {
|
|
1853
|
+
return !e.type && (e.nodeType === undefined || e.nodeType === folderType || e.nodeType === branchType);
|
|
1854
|
+
}
|
|
1773
1855
|
</script>
|
|
1774
1856
|
|
|
1775
1857
|
</html>
|
|
@@ -26,24 +26,28 @@
|
|
|
26
26
|
crossorigin="anonymous"
|
|
27
27
|
></script>
|
|
28
28
|
<script>
|
|
29
|
-
Sentry
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
if (typeof Sentry !== 'undefined') {
|
|
30
|
+
Sentry.init({
|
|
31
|
+
dsn: "{{sentryData.dsn}}",
|
|
32
|
+
environment: "frontend",
|
|
33
|
+
replaysSessionSampleRate: 0,
|
|
34
|
+
replaysOnErrorSampleRate: 1.0,
|
|
35
|
+
integrations: [new Sentry.Replay()],
|
|
36
|
+
});
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
Sentry.configureScope(function(scope) {
|
|
39
|
+
scope.setTag("identifier", "{{sentryData.appIdentifier}}");
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
AP.getContext(contextData => {
|
|
42
|
+
const { user_id, ...rest } = contextData;
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
user_id && scope.setUser({ id: user_id });
|
|
45
|
+
scope.setTags(rest);
|
|
46
|
+
});
|
|
45
47
|
});
|
|
46
|
-
}
|
|
48
|
+
} else {
|
|
49
|
+
console.warn('Sentry is not available. This might be due to ad/tracking blockers or network issues.');
|
|
50
|
+
}
|
|
47
51
|
</script>
|
|
48
52
|
{{/if}}
|
|
49
53
|
</head>
|
package/package.json
CHANGED