@crowdin/app-project-module 0.10.1 → 0.11.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.
@@ -49,6 +49,8 @@ function handle(config, integration) {
49
49
  options.config = JSON.stringify(req.integrationSettings || {});
50
50
  }
51
51
  options.infoModal = integration.infoModal;
52
+ options.withCronSync = integration.withCronSync;
53
+ options.withWebhookSync = integration.withWebhookSync;
52
54
  return res.render(view, options);
53
55
  }));
54
56
  }
@@ -0,0 +1,3 @@
1
+ /// <reference types="qs" />
2
+ import { Response } from 'express';
3
+ export default function handle(): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const util_1 = require("../util");
13
+ const storage_1 = require("../storage");
14
+ function handle() {
15
+ return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
+ const { files, type, provider } = req.body;
17
+ const existingSettings = yield (0, storage_1.getSyncSettings)(req.crowdinContext.clientId, req.crowdinContext.crowdinId, type, provider);
18
+ if (existingSettings) {
19
+ yield (0, storage_1.updateSyncSettings)(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, type, provider);
20
+ }
21
+ else {
22
+ yield (0, storage_1.saveSyncSettings)(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, type, provider);
23
+ }
24
+ res.status(204).end();
25
+ }));
26
+ }
27
+ exports.default = handle;
@@ -0,0 +1,3 @@
1
+ /// <reference types="qs" />
2
+ import { Response } from 'express';
3
+ export default function handle(): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const util_1 = require("../util");
13
+ const storage_1 = require("../storage");
14
+ function handle() {
15
+ return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
+ let files = {};
17
+ const provider = req.params.provider;
18
+ const syncSettings = yield (0, storage_1.getSyncSettingsByProvider)(req.crowdinContext.clientId, provider);
19
+ if (syncSettings) {
20
+ files = JSON.parse(syncSettings.files) || [];
21
+ }
22
+ res.send(files);
23
+ }));
24
+ }
25
+ exports.default = handle;
package/out/index.js CHANGED
@@ -48,6 +48,8 @@ const integration_data_1 = __importDefault(require("./handlers/integration-data"
48
48
  const integration_login_1 = __importDefault(require("./handlers/integration-login"));
49
49
  const integration_logout_1 = __importDefault(require("./handlers/integration-logout"));
50
50
  const integration_update_1 = __importDefault(require("./handlers/integration-update"));
51
+ const sync_settings_save_1 = __importDefault(require("./handlers/sync-settings-save"));
52
+ const sync_settings_1 = __importDefault(require("./handlers/sync-settings"));
51
53
  const main_1 = __importDefault(require("./handlers/main"));
52
54
  const manifest_1 = __importDefault(require("./handlers/manifest"));
53
55
  const oauth_login_1 = __importDefault(require("./handlers/oauth-login"));
@@ -93,6 +95,8 @@ function addCrowdinEndpoints(app, config) {
93
95
  app.get('/api/integration/data', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_data_1.default)(integrationLogic));
94
96
  app.post('/api/crowdin/update', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, crowdin_update_1.default)(config, integrationLogic));
95
97
  app.post('/api/integration/update', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_update_1.default)(config, integrationLogic));
98
+ app.get('/api/sync-settings/:provider', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, sync_settings_1.default)());
99
+ app.post('/api/sync-settings', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, sync_settings_save_1.default)());
96
100
  if (integrationLogic.oauthLogin) {
97
101
  app.get((0, util_1.getOauthRoute)(integrationLogic), (0, oauth_login_1.default)(config, integrationLogic));
98
102
  }
@@ -101,6 +105,13 @@ function addCrowdinEndpoints(app, config) {
101
105
  cron.schedule(job.expression, () => (0, util_1.runJob)(config, integrationLogic, job).catch(console.error));
102
106
  });
103
107
  }
108
+ if (integrationLogic.withCronSync) {
109
+ cron.schedule('0 * * * *', () => (0, util_1.filesCron)(config, integrationLogic, '1').catch(console.error));
110
+ cron.schedule('0 */3 * * *', () => (0, util_1.filesCron)(config, integrationLogic, '3').catch(console.error));
111
+ cron.schedule('0 */6 * * *', () => (0, util_1.filesCron)(config, integrationLogic, '6').catch(console.error));
112
+ cron.schedule('0 */12 * * *', () => (0, util_1.filesCron)(config, integrationLogic, '12').catch(console.error));
113
+ cron.schedule('0 0 * * *', () => (0, util_1.filesCron)(config, integrationLogic, '24').catch(console.error));
114
+ }
104
115
  }
105
116
  if (config.customFileFormat) {
106
117
  app.post('/process', (0, process_1.default)(config.baseUrl, config.customFileFormat.filesFolder || config.dbFolder, config.customFileFormat));
@@ -127,6 +127,14 @@ export interface IntegrationLogic {
127
127
  * background jobs that will be executed for each crowdin project and user
128
128
  */
129
129
  cronJobs?: CronJob[];
130
+ withCronSync?: {
131
+ crowdin: boolean;
132
+ integration: boolean;
133
+ };
134
+ withWebhookSync?: {
135
+ crowdin: boolean;
136
+ integration: boolean;
137
+ };
130
138
  }
131
139
  export interface ConfigurationField {
132
140
  key: string;
@@ -411,3 +419,10 @@ export interface CrowdinAppUtilities {
411
419
  client?: Crowdin;
412
420
  }>;
413
421
  }
422
+ export interface IntegrationSyncSettings {
423
+ id: string;
424
+ files?: any;
425
+ integrationId: string;
426
+ crowdinId: string;
427
+ provider: string;
428
+ }
@@ -1,4 +1,4 @@
1
- import { CrowdinCredentials, IntegrationCredentials } from '../models';
1
+ import { CrowdinCredentials, IntegrationCredentials, IntegrationSyncSettings } from '../models';
2
2
  export declare function connect(folder: string): Promise<void>;
3
3
  export declare function saveCrowdinCredentials(credentials: CrowdinCredentials): Promise<void>;
4
4
  export declare function updateCrowdinCredentials(credentials: CrowdinCredentials): Promise<void>;
@@ -15,3 +15,8 @@ export declare function saveMetadata(id: string, metadata: any): Promise<void>;
15
15
  export declare function updateMetadata(id: string, metadata: any): Promise<void>;
16
16
  export declare function getMetadata(id: string): Promise<any | undefined>;
17
17
  export declare function deleteMetadata(id: string): Promise<void>;
18
+ export declare function getSyncSettingsByProvider(integrationId: string, provider: string): Promise<IntegrationSyncSettings | undefined>;
19
+ export declare function getAllSyncSettingsByType(type: string): Promise<IntegrationSyncSettings[]>;
20
+ export declare function saveSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
21
+ export declare function updateSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
22
+ export declare function getSyncSettings(integrationId: string, crowdinId: string, type: string, provider: string): Promise<IntegrationSyncSettings | undefined>;
@@ -13,7 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  return (mod && mod.__esModule) ? mod : { "default": mod };
14
14
  };
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.deleteMetadata = exports.getMetadata = exports.updateMetadata = exports.saveMetadata = exports.deleteIntegrationCredentials = exports.getAllIntegrationCredentials = exports.getIntegrationCredentials = exports.updateIntegrationConfig = exports.updateIntegrationCredentials = exports.saveIntegrationCredentials = exports.deleteCrowdinCredentials = exports.getAllCrowdinCredentials = exports.getCrowdinCredentials = exports.updateCrowdinCredentials = exports.saveCrowdinCredentials = exports.connect = void 0;
16
+ exports.getSyncSettings = exports.updateSyncSettings = exports.saveSyncSettings = exports.getAllSyncSettingsByType = exports.getSyncSettingsByProvider = exports.deleteMetadata = exports.getMetadata = exports.updateMetadata = exports.saveMetadata = exports.deleteIntegrationCredentials = exports.getAllIntegrationCredentials = exports.getIntegrationCredentials = exports.updateIntegrationConfig = exports.updateIntegrationCredentials = exports.saveIntegrationCredentials = exports.deleteCrowdinCredentials = exports.getAllCrowdinCredentials = exports.getCrowdinCredentials = exports.updateCrowdinCredentials = exports.saveCrowdinCredentials = exports.connect = void 0;
17
17
  const path_1 = require("path");
18
18
  const sqlite3_1 = __importDefault(require("sqlite3"));
19
19
  let _res;
@@ -75,6 +75,17 @@ function connect(folder) {
75
75
  );
76
76
  `, []);
77
77
  yield _run(`
78
+ create table if not exists sync_settings
79
+ (
80
+ id integer not null primary key autoincrement,
81
+ files varchar null,
82
+ integration_id varchar not null,
83
+ crowdin_id varchar not null,
84
+ type varchar not null,
85
+ provider varchar not null
86
+ );
87
+ `, []);
88
+ yield _run(`
78
89
  create table if not exists app_metadata
79
90
  (
80
91
  id varchar not null primary key,
@@ -167,6 +178,7 @@ function deleteCrowdinCredentials(id) {
167
178
  return __awaiter(this, void 0, void 0, function* () {
168
179
  yield run('DELETE FROM crowdin_credentials where id = ?', [id]);
169
180
  yield run('DELETE FROM integration_credentials where crowdin_id = ?', [id]);
181
+ yield run('DELETE FROM sync_settings WHERE crowdin_id = ?', [id]);
170
182
  });
171
183
  }
172
184
  exports.deleteCrowdinCredentials = deleteCrowdinCredentials;
@@ -203,6 +215,7 @@ function getAllIntegrationCredentials(crowdinId) {
203
215
  exports.getAllIntegrationCredentials = getAllIntegrationCredentials;
204
216
  function deleteIntegrationCredentials(id) {
205
217
  return run('DELETE FROM integration_credentials where id = ?', [id]);
218
+ return run('DELETE FROM sync_settings where integration_id = ?', [id]);
206
219
  }
207
220
  exports.deleteIntegrationCredentials = deleteIntegrationCredentials;
208
221
  function saveMetadata(id, metadata) {
@@ -228,3 +241,41 @@ function deleteMetadata(id) {
228
241
  });
229
242
  }
230
243
  exports.deleteMetadata = deleteMetadata;
244
+ function getSyncSettingsByProvider(integrationId, provider) {
245
+ return __awaiter(this, void 0, void 0, function* () {
246
+ const row = yield get('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, type, provider FROM sync_settings WHERE integration_id = ? AND provider = ?', [integrationId, provider]);
247
+ if (row) {
248
+ return row;
249
+ }
250
+ });
251
+ }
252
+ exports.getSyncSettingsByProvider = getSyncSettingsByProvider;
253
+ function getAllSyncSettingsByType(type) {
254
+ return __awaiter(this, void 0, void 0, function* () {
255
+ return each('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, type, provider FROM sync_settings WHERE type = ?', [type]);
256
+ });
257
+ }
258
+ exports.getAllSyncSettingsByType = getAllSyncSettingsByType;
259
+ function saveSyncSettings(files, integrationId, crowdinId, type, provider) {
260
+ return run('INSERT INTO sync_settings(files, integration_id, crowdin_id, type, provider) VALUES (?, ?, ?, ?, ?)', [
261
+ files,
262
+ integrationId,
263
+ crowdinId,
264
+ type,
265
+ provider,
266
+ ]);
267
+ }
268
+ exports.saveSyncSettings = saveSyncSettings;
269
+ function updateSyncSettings(files, integrationId, crowdinId, type, provider) {
270
+ return run('UPDATE sync_settings SET files = ? WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [files, integrationId, crowdinId, type, provider]);
271
+ }
272
+ exports.updateSyncSettings = updateSyncSettings;
273
+ function getSyncSettings(integrationId, crowdinId, type, provider) {
274
+ return __awaiter(this, void 0, void 0, function* () {
275
+ const row = yield get('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, type FROM sync_settings WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [integrationId, crowdinId, type, provider]);
276
+ if (row) {
277
+ return row;
278
+ }
279
+ });
280
+ }
281
+ exports.getSyncSettings = getSyncSettings;
@@ -14,3 +14,4 @@ export declare function applyDefaults(config: Config, integration: IntegrationLo
14
14
  export declare function prepareCrowdinClient(config: Config, credentials: CrowdinCredentials): Promise<Crowdin>;
15
15
  export declare function prepareIntegrationCredentials(config: Config, integration: IntegrationLogic, integrationCredentials: IntegrationCredentials): Promise<any>;
16
16
  export declare function runJob(config: Config, integration: IntegrationLogic, job: CronJob): Promise<void>;
17
+ export declare function filesCron(config: Config, integration: IntegrationLogic, period: string): Promise<void>;
package/out/util/index.js CHANGED
@@ -31,7 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
31
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
32
32
  };
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
- exports.runJob = exports.prepareIntegrationCredentials = exports.prepareCrowdinClient = exports.applyDefaults = exports.getRootFolder = exports.getOauthRoute = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
34
+ exports.filesCron = exports.runJob = exports.prepareIntegrationCredentials = exports.prepareCrowdinClient = exports.applyDefaults = exports.getRootFolder = exports.getOauthRoute = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
35
35
  const crowdin_api_client_1 = __importDefault(require("@crowdin/crowdin-api-client"));
36
36
  const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
37
37
  const axios_1 = __importDefault(require("axios"));
@@ -59,10 +59,17 @@ function handleError(err, req, res) {
59
59
  res.redirect('/');
60
60
  return;
61
61
  }
62
- res.status(code).send({
63
- message: err.message ? err.message : JSON.stringify(err),
64
- code,
65
- });
62
+ let message;
63
+ if (typeof err === 'string') {
64
+ message = err;
65
+ }
66
+ else if (err.message) {
67
+ message = err.message;
68
+ }
69
+ else {
70
+ message = JSON.stringify(err);
71
+ }
72
+ res.status(code).send({ message, code });
66
73
  });
67
74
  }
68
75
  function runAsyncWrapper(callback) {
@@ -149,6 +156,46 @@ function applyDefaults(config, integration) {
149
156
  ],
150
157
  };
151
158
  }
159
+ if (integration.withCronSync) {
160
+ const getUserSettings = integration.getConfiguration;
161
+ integration.getConfiguration = (projectId, crowdinClient, integrationCredentials) => __awaiter(this, void 0, void 0, function* () {
162
+ let fields = [];
163
+ if (getUserSettings) {
164
+ fields = yield getUserSettings(projectId, crowdinClient, integrationCredentials);
165
+ }
166
+ return [
167
+ {
168
+ key: 'schedule',
169
+ label: 'Sync schedule',
170
+ helpText: 'Set the frequency for pushing sources and translations',
171
+ type: 'select',
172
+ options: [
173
+ {
174
+ value: '1',
175
+ label: '1 hour',
176
+ },
177
+ {
178
+ value: '3',
179
+ label: '3 hours',
180
+ },
181
+ {
182
+ value: '6',
183
+ label: '6 hours',
184
+ },
185
+ {
186
+ value: '12',
187
+ label: '12 hours',
188
+ },
189
+ {
190
+ value: '24',
191
+ label: '24 hours',
192
+ },
193
+ ],
194
+ },
195
+ ...fields,
196
+ ];
197
+ });
198
+ }
152
199
  }
153
200
  exports.applyDefaults = applyDefaults;
154
201
  function prepareCrowdinClient(config, credentials) {
@@ -237,3 +284,31 @@ function runJob(config, integration, job) {
237
284
  });
238
285
  }
239
286
  exports.runJob = runJob;
287
+ function filesCron(config, integration, period) {
288
+ return __awaiter(this, void 0, void 0, function* () {
289
+ const syncSettingsList = yield (0, storage_1.getAllSyncSettingsByType)('schedule');
290
+ yield Promise.all(syncSettingsList.map((syncSettings) => __awaiter(this, void 0, void 0, function* () {
291
+ const files = JSON.parse(syncSettings.files);
292
+ const crowdinCredentials = yield (0, storage_1.getCrowdinCredentials)(syncSettings.crowdinId);
293
+ const integrationCredentials = yield (0, storage_1.getIntegrationCredentials)(syncSettings.integrationId);
294
+ if (crowdinCredentials && integrationCredentials) {
295
+ const intConfig = integrationCredentials.config
296
+ ? JSON.parse(integrationCredentials.config)
297
+ : { schedule: 24 };
298
+ if (period === intConfig.schedule) {
299
+ const projectId = crowdinAppFunctions.getProjectId(integrationCredentials.id);
300
+ const crowdinClient = yield prepareCrowdinClient(config, crowdinCredentials);
301
+ const apiCredentials = yield prepareIntegrationCredentials(config, integration, integrationCredentials);
302
+ const rootFolder = yield getRootFolder(config, integration, crowdinClient, projectId);
303
+ if (syncSettings.provider === 'crowdin') {
304
+ yield integration.updateIntegration(projectId, crowdinClient, apiCredentials, files, rootFolder, intConfig);
305
+ }
306
+ else {
307
+ yield integration.updateCrowdin(projectId, crowdinClient, apiCredentials, files, rootFolder, intConfig);
308
+ }
309
+ }
310
+ }
311
+ })));
312
+ });
313
+ }
314
+ exports.filesCron = filesCron;
@@ -13,7 +13,22 @@
13
13
  {{/if}}
14
14
  <crowdin-button icon-before="account_circle" onclick="integrationLogout()">Log out</crowdin-button>
15
15
  </div>
16
- <crowdin-simple-integration integration-name="{{name}}" integration-logo="logo.png">
16
+ <crowdin-simple-integration
17
+ {{#if withWebhookSync.crowdin}}
18
+ crowdin-sync="true"
19
+ {{/if}}
20
+ {{#if withWebhookSync.integration}}
21
+ integration-sync="true"
22
+ {{/if}}
23
+ {{#if withCronSync.crowdin}}
24
+ crowdin-schedule="true"
25
+ {{/if}}
26
+ {{#if withCronSync.integration}}
27
+ integration-schedule="true"
28
+ {{/if}}
29
+ integration-name="{{name}}"
30
+ integration-logo="logo.png"
31
+ >
17
32
  </crowdin-simple-integration>
18
33
  </div>
19
34
  <crowdin-toasts></crowdin-toasts>
@@ -25,7 +40,7 @@
25
40
  </crowdin-modal>
26
41
  {{/if}}
27
42
  {{#if configurationFields}}
28
- <crowdin-modal id="settings-modal" modal-width="50" modal-title="Settings" close-button-title="Close">
43
+ <crowdin-modal id="settings-modal" body-overflow-unset modal-width="50" modal-title="Settings" close-button-title="Close">
29
44
  <div id="modal-content">
30
45
  {{#each configurationFields}}
31
46
  {{#ifeq type "checkbox"}}
@@ -82,7 +97,6 @@
82
97
  {{/if}}
83
98
  </body>
84
99
  <script type="text/javascript">
85
-
86
100
  document.body.addEventListener('refreshFilesList', (e) => {
87
101
  if (e.detail.refreshIntegration) {
88
102
  getIntegrationData();
@@ -146,6 +160,9 @@
146
160
  .then((res) => {
147
161
  project = res;
148
162
  appComponent.setCrowdinLanguagesData(project.targetLanguages)
163
+ {{#if withCronSync}}
164
+ getSyncSettings('crowdin');
165
+ {{/if}}
149
166
  })
150
167
  .catch(e => catchRejection(e, 'Can\'t fetch Crowdin data'))
151
168
  .finally(() => (appComponent.setAttribute('is-crowdin-loading', false)));
@@ -173,10 +190,22 @@
173
190
  });
174
191
  appComponent.setIntegrationFilesData(tree);
175
192
  })
193
+ {{#if withCronSync}}
194
+ .then(() => getSyncSettings('integration'))
195
+ {{/if}}
176
196
  .catch(e => catchRejection(e, 'Can\'t fetch {{name}} templates'))
177
197
  .finally(() => (appComponent.setAttribute('is-integration-loading', false)));
178
198
  }
179
199
 
200
+ function getSyncSettings(provider) {
201
+ const filesComponent = appComponent.querySelector(`#${provider}-files`);
202
+ checkOrigin()
203
+ .then(restParams => fetch(`/api/sync-settings/${provider}` + restParams))
204
+ .then(checkResponse)
205
+ .then((res) => filesComponent.addScheduledFiles(res))
206
+ .catch(e => catchRejection(e, 'Can\'t fetch file progress'));
207
+ }
208
+
180
209
  function getFileProgress(fileId) {
181
210
  checkOrigin()
182
211
  .then(restParams => fetch(`api/crowdin/file-progress/${fileId}` + restParams))
@@ -311,6 +340,69 @@
311
340
  }
312
341
  }
313
342
  });
343
+
344
+ {{#if withCronSync}}
345
+ document.body.addEventListener('integrationScheduleSync', setIntegrationScheduleSync);
346
+ document.body.addEventListener('crowdinScheduleSync', setCrowdinScheduleSync);
347
+ document.body.addEventListener('crowdinDisableSync', disableCrowdinSync);
348
+ document.body.addEventListener('integrationDisableSync', disableIntegrationSync);
349
+
350
+ async function setIntegrationScheduleSync(e) {
351
+ if (e.detail.length === 0) {
352
+ showToast('Select templates which will be pushed to Crowdin');
353
+ return;
354
+ }
355
+ appComponent.setAttribute('is-integration-loading', true);
356
+ const syncedFiles = await appComponent.getIntegrationScheduleSync();
357
+
358
+ updateSyncSettings(syncedFiles, 'schedule', 'integration');
359
+ }
360
+
361
+ async function setCrowdinScheduleSync(e) {
362
+ if (e.detail.length === 0) {
363
+ showToast('Select templates which will be pushed to Crowdin');
364
+ return;
365
+ }
366
+ appComponent.setAttribute('is-crowdin-loading', true);
367
+ const syncedFiles = await appComponent.getCrowdinScheduleSync();
368
+
369
+ updateSyncSettings(syncedFiles, 'schedule', 'crowdin');
370
+ }
371
+
372
+ async function disableIntegrationSync(e) {
373
+ if (e.detail.length === 0) {
374
+ showToast('Select templates which will be pushed to Crowdin');
375
+ return;
376
+ }
377
+ appComponent.setAttribute('is-integration-loading', true);
378
+ const syncedFiles = await appComponent.getIntegrationScheduleSync();
379
+
380
+ updateSyncSettings(syncedFiles, 'schedule', 'integration');
381
+ }
382
+
383
+ async function disableCrowdinSync(e) {
384
+ if (e.detail.length === 0) {
385
+ showToast('Select templates which will be pushed to Crowdin');
386
+ return;
387
+ }
388
+ appComponent.setAttribute('is-crowdin-loading', true);
389
+ const syncedFiles = await appComponent.getCrowdinScheduleSync();
390
+
391
+ updateSyncSettings(syncedFiles, 'schedule', 'crowdin');
392
+ }
393
+
394
+ function updateSyncSettings(files, type, provider) {
395
+ checkOrigin()
396
+ .then(restParams => fetch('api/sync-settings' + restParams, {
397
+ method: 'POST',
398
+ headers: { 'Content-Type': 'application/json' },
399
+ body: JSON.stringify({ files, type, provider })
400
+ }))
401
+ .then(checkResponse)
402
+ .catch(e => catchRejection(e, 'Can\'t save schedule sync settings'))
403
+ .finally(() => (appComponent.setAttribute(`is-${provider}-loading`, false)));
404
+ }
405
+ {{/if}}
314
406
  </script>
315
407
 
316
408
  </html>
@@ -4,7 +4,10 @@
4
4
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
5
5
  <title></title>
6
6
  <link rel="stylesheet" href="assets/css/styles.css">
7
- <script src="https://crowdin-web-components.s3.amazonaws.com/crowdin-web-components.js"></script>
7
+ <script type="module"
8
+ src="https://crowdin-web-components.s3.amazonaws.com/crowdin-web-components/crowdin-web-components.esm.js"></script>
9
+ <script nomodule=""
10
+ src="https://crowdin-web-components.s3.amazonaws.com/crowdin-web-components/crowdin-web-components.js"></script>
8
11
  <script type="text/javascript" src="https://cdn.crowdin.com/apps/dist/iframe.js"></script>
9
12
  <script type="text/javascript" src="assets/js/polyfills/promise.js"></script>
10
13
  <script type="text/javascript" src="assets/js/polyfills/fetch.js"></script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
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",