@crowdin/app-project-module 0.25.1 → 0.26.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/README.md CHANGED
@@ -89,9 +89,10 @@ const configuration = {
89
89
  crowdin: true,
90
90
  integration: true,
91
91
  },
92
+ integrationPagination: true, //enable pagination on integration files list
92
93
  integrationOneLevelFetching: true, //turn on request when opening a directory and pass its id
93
94
  integrationSearchListener: true, //turn on search listener and pass search string
94
- getIntegrationFiles: async (credentials, appSettings, parentId, search) => {
95
+ getIntegrationFiles: async (credentials, appSettings, parentId, search, page) => {
95
96
  //here you need to fetch files/objects from integration
96
97
  const res = [
97
98
  {
@@ -125,6 +126,7 @@ const configuration = {
125
126
  return {
126
127
  data: res,
127
128
  message: 'Test',
129
+ stopPagination: true, //send if no next files page
128
130
  };
129
131
  },
130
132
  updateCrowdin: async (projectId, client, credentials, request, rootFolder, appSettings) => {
@@ -21,7 +21,7 @@ function handle(config, integration) {
21
21
  }
22
22
  const result = yield integration.updateCrowdin(projectId, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
23
23
  let message;
24
- if ((0, util_1.isMessageResultType)(result)) {
24
+ if ((0, util_1.isExtendedResultType)(result)) {
25
25
  message = result.message;
26
26
  }
27
27
  res.send({ message });
@@ -12,20 +12,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const util_1 = require("../util");
13
13
  function handle(config, integration) {
14
14
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
15
- const { parent_id: parentId, search } = req.query;
15
+ const { parent_id: parentId, search, page } = req.query;
16
16
  (0, util_1.log)('Recieved request to get integration data', config.logger);
17
- const result = yield integration.getIntegrationFiles(req.integrationCredentials, req.integrationSettings, parentId, search);
17
+ const result = yield integration.getIntegrationFiles(req.integrationCredentials, req.integrationSettings, parentId, search, page);
18
18
  let message;
19
+ let stopPagination;
19
20
  let files;
20
- if ((0, util_1.isMessageResultType)(result)) {
21
+ if ((0, util_1.isExtendedResultType)(result)) {
21
22
  files = result.data;
22
23
  message = result.message;
24
+ stopPagination = result.stopPagination;
23
25
  }
24
26
  else {
25
27
  files = result;
26
28
  }
27
29
  (0, util_1.log)(`Integration data response ${JSON.stringify(files, null, 2)}`, config.logger);
28
- res.send({ data: files, message });
30
+ res.send({ data: files, message, stopPagination });
29
31
  }), config.onError);
30
32
  }
31
33
  exports.default = handle;
@@ -20,7 +20,7 @@ function handle(config, integration) {
20
20
  }
21
21
  const result = yield integration.updateIntegration(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
22
22
  let message;
23
- if ((0, util_1.isMessageResultType)(result)) {
23
+ if ((0, util_1.isExtendedResultType)(result)) {
24
24
  message = result.message;
25
25
  }
26
26
  res.send({ message });
@@ -40,6 +40,7 @@ function handle(config, integration) {
40
40
  options.configurationFields = configurationFields;
41
41
  options.config = JSON.stringify(req.integrationSettings || {});
42
42
  options.reloadOnConfigSave = !!integration.reloadOnConfigSave;
43
+ options.integrationPagination = integration.integrationPagination;
43
44
  (0, util_1.log)(`Adding configuration fields ${JSON.stringify(configurationFields, null, 2)}`, config.logger);
44
45
  }
45
46
  options.infoModal = integration.infoModal;
@@ -179,15 +179,15 @@ export interface IntegrationLogic {
179
179
  /**
180
180
  * function to get data from integration
181
181
  */
182
- getIntegrationFiles: (apiCredentials: any, config?: any, parentId?: any, search?: any) => Promise<TreeItem[] | MessageResult<TreeItem[]>>;
182
+ getIntegrationFiles: (apiCredentials: any, config?: any, parentId?: any, search?: any, page?: any) => Promise<TreeItem[] | ExtendedResult<TreeItem[]>>;
183
183
  /**
184
184
  * function to update crowdin files (e.g. pull integration data to crowdin source files)
185
185
  */
186
- updateCrowdin: (projectId: number, client: Crowdin, apiCredentials: any, request: IntegrationFile[], appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void | MessageResult<void>>;
186
+ updateCrowdin: (projectId: number, client: Crowdin, apiCredentials: any, request: IntegrationFile[], appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void | ExtendedResult<void>>;
187
187
  /**
188
188
  * function to update integration content (e.g. load crowdin translations and push them to integration service)
189
189
  */
190
- updateIntegration: (projectId: number, client: Crowdin, apiCredentials: any, request: UpdateIntegrationRequest, appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void | MessageResult<void>>;
190
+ updateIntegration: (projectId: number, client: Crowdin, apiCredentials: any, request: UpdateIntegrationRequest, appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void | ExtendedResult<void>>;
191
191
  /**
192
192
  * function to define configuration(settings) modal for you app (by default app will not have any custom settings)
193
193
  */
@@ -227,6 +227,10 @@ export interface IntegrationLogic {
227
227
  * Enable integration search event
228
228
  */
229
229
  integrationSearchListener?: boolean;
230
+ /**
231
+ * Enable integration next page event
232
+ */
233
+ integrationPagination?: boolean;
230
234
  }
231
235
  export declare type ConfigurationModalEntity = FormField | ConfigurationDelimeter;
232
236
  export interface ConfigurationDelimeter {
@@ -365,9 +369,10 @@ export interface FormField {
365
369
  value: string;
366
370
  }[];
367
371
  }
368
- export interface MessageResult<T> {
372
+ export interface ExtendedResult<T> {
369
373
  data?: T;
370
374
  message?: string;
375
+ stopPagination?: boolean;
371
376
  }
372
377
  export declare type TreeItem = File | Folder;
373
378
  /**
@@ -1,5 +1,5 @@
1
1
  import { Request, Response } from 'express';
2
- import { Config, Logger, MessageResult } from '../models';
2
+ import { Config, Logger, ExtendedResult } from '../models';
3
3
  export declare class CodeError extends Error {
4
4
  code: number | undefined;
5
5
  constructor(message: string, code?: number);
@@ -10,4 +10,4 @@ export declare function runAsyncWrapper(callback: Function, onError?: (e: any) =
10
10
  export declare function encryptData(config: Config, data: string): string;
11
11
  export declare function decryptData(config: Config, data: string): string;
12
12
  export declare function executeWithRetry<T>(func: () => Promise<T>, numOfRetries?: number): Promise<T>;
13
- export declare function isMessageResultType<T>(data?: T | MessageResult<T>): data is MessageResult<T>;
13
+ export declare function isExtendedResultType<T>(data?: T | ExtendedResult<T>): data is ExtendedResult<T>;
package/out/util/index.js CHANGED
@@ -28,7 +28,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
28
28
  });
29
29
  };
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.isMessageResultType = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.getMessage = exports.log = exports.CodeError = void 0;
31
+ exports.isExtendedResultType = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.getMessage = exports.log = exports.CodeError = void 0;
32
32
  const crypto = __importStar(require("crypto-js"));
33
33
  const storage_1 = require("../storage");
34
34
  class CodeError extends Error {
@@ -120,8 +120,8 @@ function executeWithRetry(func, numOfRetries = 2) {
120
120
  });
121
121
  }
122
122
  exports.executeWithRetry = executeWithRetry;
123
- function isMessageResultType(data) {
123
+ function isExtendedResultType(data) {
124
124
  const dataTyped = data;
125
- return !!(dataTyped === null || dataTyped === void 0 ? void 0 : dataTyped.data) || !!(dataTyped === null || dataTyped === void 0 ? void 0 : dataTyped.message);
125
+ return !!dataTyped && !Array.isArray(dataTyped);
126
126
  }
127
- exports.isMessageResultType = isMessageResultType;
127
+ exports.isExtendedResultType = isExtendedResultType;
@@ -40,6 +40,9 @@
40
40
  {{#if integrationSearchListener}}
41
41
  allow-filter-change-listener="true"
42
42
  {{/if}}
43
+ {{#if integrationPagination}}
44
+ integration-load-more-files="true"
45
+ {{/if}}
43
46
  integration-name="{{name}}"
44
47
  integration-logo="logo.png"
45
48
  >
@@ -229,13 +232,14 @@
229
232
  .finally(() => (appComponent.setAttribute('is-crowdin-loading', false)));
230
233
  }
231
234
 
232
- function getIntegrationData(hardReload = false, parentId = '', search = '',) {
235
+ function getIntegrationData(hardReload = false, parentId = '', search = '', page = 0) {
233
236
  appComponent.setAttribute('is-integration-loading', true);
234
237
  checkOrigin()
235
- .then(restParams => fetch(`api/integration/data${restParams}&parent_id=${parentId}&search=${search}`))
238
+ .then(restParams => fetch(`api/integration/data${restParams}&parent_id=${parentId}&search=${search}&page=${page}`))
236
239
  .then(checkResponse)
237
240
  .then((res) => {
238
241
  const files = res.data;
242
+ const stopPagination = res.stopPagination;
239
243
  const tree = files.map(e => {
240
244
  const item = {
241
245
  parent_id: e.parentId ? e.parentId : '0',
@@ -256,6 +260,13 @@
256
260
  } else {
257
261
  appComponent.pushIntegrationFilesData(tree);
258
262
  }
263
+ {{#if integrationPagination}}
264
+ if (stopPagination) {
265
+ appComponent.querySelector('#integration-files').setAttribute('load-more-disabled', true);
266
+ } else {
267
+ appComponent.querySelector('#integration-files').setAttribute('load-more-disabled', false);
268
+ }
269
+ {{/if}}
259
270
  if (search) {
260
271
  const openIds = files.filter(e => !e.type).map(e => e.id);
261
272
  appComponent.setIntegrationOpenedFolders(openIds);
@@ -422,6 +433,7 @@
422
433
 
423
434
  document.addEventListener('keydown', (event) => {
424
435
  if (event.keyCode == 27) {
436
+
425
437
  if (infoModal) {
426
438
  infoModal.close();
427
439
  }
@@ -431,6 +443,12 @@
431
443
  }
432
444
  });
433
445
 
446
+ {{#if integrationPagination}}
447
+ document.body.addEventListener('fileListEnd', (e) => {
448
+ getIntegrationData(false, 0, '', e.detail.page)
449
+ })
450
+ {{/if}}
451
+
434
452
  {{#if withCronSync}}
435
453
  document.body.addEventListener('integrationScheduleSync', setIntegrationScheduleSync);
436
454
  document.body.addEventListener('crowdinScheduleSync', setCrowdinScheduleSync);
@@ -5,9 +5,9 @@
5
5
  <title></title>
6
6
  <link rel="stylesheet" href="assets/css/styles.css">
7
7
  <script type="module"
8
- src="https://crowdin-web-components.s3.amazonaws.com/crowdin-web-components/crowdin-web-components.esm.js"></script>
8
+ src="https://crowdin-web-components.s3.amazonaws.com/crowdin-web-components/crowdin-web-components.esm.js"></script>
9
9
  <script nomodule=""
10
- src="https://crowdin-web-components.s3.amazonaws.com/crowdin-web-components/crowdin-web-components.js"></script>
10
+ src="https://crowdin-web-components.s3.amazonaws.com/crowdin-web-components/crowdin-web-components.js"></script>
11
11
  <script type="text/javascript" src="https://cdn.crowdin.com/apps/dist/iframe.js"></script>
12
12
  <script type="text/javascript" src="assets/js/polyfills/promise.js"></script>
13
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.25.1",
3
+ "version": "0.26.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",