@gudhub/core 1.0.68 → 1.1.2

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.
@@ -0,0 +1,526 @@
1
+ export default class AppsTemplateService {
2
+ constructor(gudhub) {
3
+ this.gudhub = gudhub;
4
+ this.appsConnectingMap = {
5
+ apps: [],
6
+ fields: [],
7
+ items: [],
8
+ views: []
9
+ }
10
+ }
11
+
12
+ createAppsFromTemplate(pack, maxNumberOfInsstalledItems, progressCallback) {
13
+ const self = this;
14
+ return new Promise(resolve => {
15
+ const stepsCount = pack.apps.length * 6;
16
+ const stepPercents = 100 / stepsCount;
17
+ let currentStep = 0;
18
+ self.createApps(pack, (status) => {
19
+ currentStep += 1;
20
+ progressCallback.call(this, {
21
+ percent: currentStep * stepPercents,
22
+ status
23
+ })
24
+ }).then(success => {
25
+ self.createItems(success, maxNumberOfInsstalledItems, (status) => {
26
+ if(typeof status === 'string') {
27
+ currentStep += 1;
28
+ progressCallback.call(this, {
29
+ percent: currentStep * stepPercents,
30
+ status
31
+ })
32
+ } else if (typeof status === 'object') {
33
+ progressCallback.call(this, {
34
+ status: 'Done',
35
+ apps: status
36
+ })
37
+ }
38
+ }).then(() => {
39
+ resolve();
40
+ })
41
+ })
42
+ });
43
+ }
44
+
45
+ createItems(create_apps, maxNumberOfInsstalledItems, callback) {
46
+ return new Promise(resolve => {
47
+ const MAX_NUMBER_OF_INSTALLED_ITEMS = maxNumberOfInsstalledItems ? maxNumberOfInsstalledItems : 100000;
48
+ const self = this;
49
+ let createsItems = [];
50
+ let promises = [];
51
+
52
+ create_apps.forEach(app => {
53
+ promises.push(new Promise(app_resolve => {
54
+ self.gudhub.getApp(self._searchOldAppId(app.app_id, self.appsConnectingMap.apps)).then(result_app => {
55
+ callback ? callback.call(this, `GET APP: ${result_app.app_name} (Items steps)`) : null;
56
+ let source_app = JSON.parse(JSON.stringify(result_app));
57
+ let items = source_app.items_list.map(item => {
58
+ return {
59
+ index_number: item.index_number,
60
+ item_id: 0,
61
+ fields: []
62
+ }
63
+ }).filter((item, index) => index <= MAX_NUMBER_OF_INSTALLED_ITEMS);
64
+
65
+ self.gudhub.addNewItems(app.app_id, items).then(items => {
66
+ callback ? callback.call(this, `ADD NEW ITEMS: ${result_app.app_name} (Items steps)`) : null;
67
+
68
+ if(items.length === 0) {
69
+ callback ? callback.call(this, `NO ITEMS TO REPLACE VALUE: ${result_app.app_name} (Items steps)`) : null;
70
+ app_resolve();
71
+ }
72
+
73
+ app.items_list = items;
74
+ self._updateMap(app.items_list, source_app.items_list);
75
+ self._addFieldValue(source_app.items_list, app.items_list, self.appsConnectingMap);
76
+
77
+ createsItems.push(app);
78
+
79
+ if (self.appsConnectingMap.apps.length === createsItems.length) {
80
+ createsItems.forEach(app => {
81
+ app.items_list.forEach(item => {
82
+ item.fields.forEach(field_item => {
83
+ self.appsConnectingMap.fields.forEach(field_map => {
84
+ if (field_item.field_id === field_map.old_field_id) {
85
+ field_item.field_id = field_map.new_field_id;
86
+ field_item.element_id = field_map.new_field_id;
87
+ }
88
+ })
89
+ })
90
+ })
91
+ });
92
+
93
+ self.deleteField(createsItems);
94
+
95
+ self.replaceValue(createsItems, self.appsConnectingMap).then(() => {
96
+ callback ? callback.call(this, `REPLACE VALUE: ${result_app.app_name} (Items steps)`) : null;
97
+ createsItems.forEach(created_app => {
98
+ let newItems = created_app.items_list.map(item => {
99
+ item.fields.forEach(field => {
100
+ delete field.data_id;
101
+ });
102
+ return item;
103
+ });
104
+
105
+ self.gudhub.updateItems(created_app.app_id, newItems).then(() => {
106
+ app_resolve();
107
+ })
108
+ })
109
+ });
110
+ }
111
+ });
112
+ });
113
+ }));
114
+ });
115
+
116
+ Promise.all(promises).then(() => {
117
+ let apps = create_apps.map(app => {
118
+ return app.app_id;
119
+ });
120
+ callback.call(this, apps);
121
+ resolve();
122
+ })
123
+ })
124
+ }
125
+
126
+ deleteField(apps) {
127
+ apps.forEach(app => {
128
+ app.items_list.forEach(item => {
129
+ item.fields = item.fields.filter(field => {
130
+ return app.field_list.findIndex(f => f.field_id == field.field_id) > -1;
131
+ })
132
+ })
133
+ })
134
+ }
135
+
136
+ replaceValue(apps, map) {
137
+ return new Promise(async (resolve) => {
138
+ const allPromises = [];
139
+ const self = this;
140
+
141
+ apps.forEach(app => {
142
+ app.field_list.forEach(field_of_list => {
143
+ if (field_of_list.data_type === 'item_ref') {
144
+ self._replaceValueItemRef(app, field_of_list, map);
145
+ }
146
+
147
+ allPromises.push(self.gudhub.ghconstructor.getInstance(field_of_list.data_type).then(data => {
148
+ if (data.getTemplate().constructor == 'file') {
149
+ return self.gudhub.util.fileInstallerHelper(app.app_id, app.items_list, field_of_list.field_id).then(result => {
150
+ return result;
151
+ });
152
+ } else if (data.getTemplate().constructor == 'document') {
153
+ self.documentInstallerHelper(app.app_id, app.items_list, field_of_list.field_id).then(result => {
154
+ return data;
155
+ })
156
+ } else {
157
+ return data;
158
+ }
159
+ }))
160
+
161
+ })
162
+ });
163
+
164
+ if(allPromises.length > 0) {
165
+
166
+ Promise.all(allPromises).then(result => {
167
+ resolve(result);
168
+ });
169
+
170
+ } else {
171
+ resolve(result);
172
+ }
173
+
174
+ });
175
+ }
176
+
177
+ documentInstallerHelper(appId, items, elementId) {
178
+ const self = this;
179
+ return new Promise(async (resolve) => {
180
+ items.forEach(item => {
181
+ const itemId = item.item_id;
182
+ const field = item.fields.find(field => field.element_id === elementId);
183
+
184
+ if (field && field.field_value && field.field_value.length > 0) {
185
+ self.gudhub.getDocument({
186
+ _id: field.field_value
187
+ }).then(document => {
188
+ self.gudhub.createDocument({
189
+ app_id: appId,
190
+ item_id: itemId,
191
+ element_id: elementId,
192
+ data: document.data
193
+ }).then(new_document => {
194
+ field.field_value = new_document._id;
195
+ resolve();
196
+ })
197
+ })
198
+ }
199
+ });
200
+ });
201
+ }
202
+
203
+ _replaceValueItemRef(app, field_of_list, map) {
204
+ app.items_list.forEach(item => {
205
+ item.fields.forEach(field_of_item => {
206
+ if (field_of_item.field_id === field_of_list.field_id && field_of_item.field_value) {
207
+ let arr_values = field_of_item.field_value.split(',');
208
+
209
+ arr_values.forEach((one_value, key) => {
210
+ let value = one_value.split('.');
211
+
212
+ map.apps.forEach(app_ids => {
213
+ if (value[0] == app_ids.old_app_id) {
214
+ value[0] = app_ids.new_app_id;
215
+ }
216
+ });
217
+
218
+ map.items.forEach(item_ids => {
219
+ if (value[1] == item_ids.old_item_id) {
220
+ value[1] = item_ids.new_item_id;
221
+ }
222
+ });
223
+
224
+ arr_values[key] = value.join('.')
225
+
226
+ });
227
+
228
+ field_of_item.field_value = arr_values.join(',');
229
+
230
+ }
231
+ });
232
+ })
233
+ }
234
+
235
+ _addFieldValue(source_app_items, create_items, appsConnectingMap) {
236
+ create_items.forEach(new_item => {
237
+ appsConnectingMap.items.forEach(item_of_map => {
238
+ if (new_item.item_id === item_of_map.new_item_id) {
239
+ source_app_items.forEach(old_item => {
240
+ if (item_of_map.old_item_id === old_item.item_id) {
241
+ new_item.fields = old_item.fields;
242
+ }
243
+ })
244
+ }
245
+ })
246
+ })
247
+ }
248
+
249
+ _updateMap(new_items, old_items) {
250
+ old_items.forEach(old_item => {
251
+ new_items.forEach(new_item => {
252
+ if (old_item.index_number === new_item.index_number) {
253
+ this.appsConnectingMap.items.push({
254
+ old_item_id: old_item.item_id,
255
+ new_item_id: new_item.item_id
256
+ })
257
+ }
258
+ })
259
+ })
260
+ }
261
+
262
+ _searchOldAppId(app_id, apps) {
263
+ let findId = 0;
264
+
265
+ apps.forEach(value => {
266
+ if (value.new_app_id === app_id) {
267
+ findId = value.old_app_id;
268
+ }
269
+ });
270
+
271
+ return findId;
272
+ }
273
+
274
+ createApps(pack, callback) {
275
+ const self = this;
276
+
277
+ let progress = {
278
+ step_size: 100 / (pack.apps.length * 3),
279
+ apps: []
280
+ }
281
+
282
+ return new Promise(resolve => {
283
+ let source_apps = {};
284
+ let created_apps = [];
285
+ let updated_apps = [];
286
+
287
+ pack.apps.forEach(app_id => {
288
+ self.gudhub.getApp(app_id).then(result_app => {
289
+ callback ? callback.call(this, `GET APP: ${result_app.app_name} (App steps)`) : null;
290
+ let source_app = JSON.parse(JSON.stringify(result_app));
291
+ source_apps[source_app.app_id] = source_app;
292
+ progress.apps.push(source_app.icon);
293
+
294
+ let appTemplate = self.prepareAppTemplate(source_app);
295
+ appTemplate.app_name = appTemplate.app_name + ' New';
296
+ appTemplate.privacy = 1;
297
+ self.resetViewsIds(appTemplate);
298
+
299
+ self.gudhub.createNewApp(appTemplate).then(created_app => {
300
+ callback ? callback.call(this, `CREATE NEW APP: ${result_app.app_name} (App steps)`) : null;
301
+ created_apps.push(created_app);
302
+ self.mapApp(source_app, created_app, self.appsConnectingMap);
303
+
304
+ if (pack.apps.length == created_apps.length) {
305
+ self.connectApps(created_apps, self.appsConnectingMap, source_apps);
306
+
307
+ created_apps.forEach(created_app => {
308
+ self.gudhub.updateApp(created_app).then(updated_app => {
309
+ callback ? callback.call(this, `UPDATE APP: ${result_app.app_name} (App steps)`) : null;
310
+ updated_apps.push(updated_app);
311
+
312
+ if (pack.apps.length == updated_apps.length) {
313
+ resolve(updated_apps);
314
+ }
315
+ })
316
+ })
317
+ }
318
+ });
319
+ })
320
+ })
321
+ });
322
+ }
323
+
324
+ mapApp(base_app, new_app, appsConnectingMap) {
325
+ appsConnectingMap.apps.push({
326
+ old_app_id: base_app.app_id,
327
+ new_app_id: new_app.app_id,
328
+ old_view_init: base_app.view_init,
329
+ new_view_init: new_app.view_init
330
+ });
331
+
332
+ base_app.field_list.forEach(old_field => {
333
+ new_app.field_list.forEach(new_field => {
334
+ if (old_field.name_space == new_field.name_space) {
335
+ appsConnectingMap.fields.push({
336
+ name_space: old_field.name_space,
337
+ old_field_id: old_field.field_id,
338
+ new_field_id: new_field.field_id
339
+ })
340
+ }
341
+ })
342
+ });
343
+
344
+ base_app.views_list.forEach(old_view => {
345
+ new_app.views_list.forEach(new_view => {
346
+ if (old_view.name == new_view.name) {
347
+ appsConnectingMap.views.push({
348
+ name: old_view.name,
349
+ old_view_id: old_view.view_id,
350
+ new_view_id: new_view.view_id
351
+ })
352
+ }
353
+ })
354
+ })
355
+ }
356
+
357
+ crawling(object, action) {
358
+ let properties = object === null ? [] : Object.keys(object);
359
+ const self = this;
360
+
361
+ if (properties.length > 0) {
362
+ properties.forEach(prop => {
363
+ let propertyValue = object[prop];
364
+
365
+ if (propertyValue && typeof object != 'string') {
366
+ action(prop, propertyValue, object);
367
+ self.crawling(propertyValue, action);
368
+ }
369
+ })
370
+ }
371
+ }
372
+
373
+ resetViewsIds(app) {
374
+ app.view_init = 0;
375
+
376
+ this.crawling(app.views_list, function (prop, value, parent) {
377
+ if (prop == 'view_id' || prop == 'container_id') {
378
+ parent[prop] = 0;
379
+ }
380
+ })
381
+ }
382
+
383
+ connectApps(apps, appsConnectingMap, source_apps) {
384
+ const self = this;
385
+
386
+ apps.forEach(app => {
387
+ appsConnectingMap.apps.forEach(appMap => {
388
+ if (app.view_init === appMap.new_view_init) {
389
+ appsConnectingMap.views.forEach(view => {
390
+ if (appMap.old_view_init === view.old_view_init) {
391
+ app.view_init = view.new_view_id;
392
+ }
393
+ })
394
+ }
395
+ });
396
+
397
+ self.crawling(app.field_list, function (prop, value, parent) {
398
+ if (prop.indexOf("field_id") !== -1 || prop.indexOf("FieldId") !== -1 || prop.indexOf("destination_field") !== -1) {
399
+ let fieldsArr = String(value).split(','), newFieldsArr = [];
400
+
401
+ appsConnectingMap.fields.forEach(field => {
402
+ fieldsArr.forEach(fieldFromValue => {
403
+ if (fieldFromValue == field.old_field_id) {
404
+ newFieldsArr.push(field.new_field_id);
405
+ }
406
+ })
407
+ })
408
+
409
+ if (newFieldsArr.length) {
410
+ parent[prop] = newFieldsArr.join(',');
411
+ }
412
+ }
413
+
414
+ if (prop.indexOf("app_id") != -1 || prop.indexOf("AppId") != -1 || prop.indexOf("destination_app") != -1) {
415
+ appsConnectingMap.apps.forEach(app => {
416
+ if (value == app.old_app_id) {
417
+ parent[prop] = app.new_app_id;
418
+ }
419
+ })
420
+ }
421
+
422
+ if (prop.indexOf("view_id") !== -1) {
423
+ appsConnectingMap.views.forEach(view => {
424
+ if (value == view.old_view_id) {
425
+ parent[prop] = view.new_view_id;
426
+ }
427
+ })
428
+ }
429
+
430
+ if (prop.indexOf("src") !== -1 && isFinite(value)) {
431
+ const pron_name = 'container_id';
432
+ const old_app_id = appsConnectingMap.apps.find(appMap => appMap.new_app_id === app.app_id).old_app_id;
433
+ const path = self.findPath(source_apps[old_app_id].views_list, pron_name, value);
434
+
435
+ parent[prop] = `${self.getValueByPath(app.views_list, path, pron_name)}`;
436
+ }
437
+
438
+ })
439
+ })
440
+
441
+ return apps;
442
+ }
443
+
444
+ getValueByPath(source, path, prop) {
445
+ let temp = source;
446
+
447
+ path.split('.').forEach(item => {
448
+ temp = temp[item];
449
+ })
450
+
451
+ return temp[prop];
452
+ }
453
+
454
+ findPath(source, prop, value) {
455
+ const self = this;
456
+
457
+ let isFound = false;
458
+ let toClearPath = false;
459
+ let path = [];
460
+
461
+ self.crawling(source, function (propSource, valueSource, parentSource) {
462
+ if (toClearPath) {
463
+ path.reverse().forEach(item => {
464
+ if (toClearPath) {
465
+ item.delete = true;
466
+
467
+ if (item.parent === parentSource) {
468
+ toClearPath = false;
469
+ path = path.filter(item => !item.delete);
470
+ path.reverse();
471
+ }
472
+ }
473
+ })
474
+ }
475
+
476
+ if (!isFound) {
477
+ if (typeof parentSource[propSource] === 'object') {
478
+ path.push({
479
+ prop: propSource,
480
+ parent: parentSource
481
+ });
482
+ }
483
+
484
+ if (valueSource == value && prop === propSource) {
485
+ isFound = true;
486
+ } else if (Object.keys(parentSource).pop() === propSource && typeof parentSource[propSource] !== 'object') {
487
+ toClearPath = true;
488
+ }
489
+ }
490
+ });
491
+
492
+ return path.map(item => item.prop).join('.');
493
+ }
494
+
495
+ prepareAppTemplate(appToTemplate) {
496
+ const self = this;
497
+
498
+ let app = JSON.parse(JSON.stringify(appToTemplate));
499
+
500
+ self.crawling(app.views_list, function (prop, value, parent) {
501
+ if (prop == "element_id") {
502
+ parent.element_id = -Number(value);
503
+ parent.create_element = -Number(value);
504
+ }
505
+ })
506
+
507
+ app.field_list.forEach(field => {
508
+ field.create_field = -Number(field.field_id);
509
+ field.element_id = -Number(field.field_id);
510
+ field.field_id = -Number(field.field_id);
511
+ field.field_value = ""; /* Should be removed when we update createApp API*/
512
+ })
513
+
514
+ app.items_list = [];
515
+
516
+ delete app.app_id;
517
+ delete app.icon.id;
518
+ delete app.group_id;
519
+ delete app.trash;
520
+ delete app.last_update;
521
+ delete app.file_list;
522
+
523
+ return app;
524
+ };
525
+
526
+ }
@@ -0,0 +1,69 @@
1
+ export class FileHelper {
2
+ constructor(gudhub) {
3
+ this.gudhub = gudhub;
4
+ }
5
+
6
+ fileInstallerHelper(appId, items, elementId) {
7
+ const self = this;
8
+ return new Promise(resolve => {
9
+ const files = [[]];
10
+ let chainPromises = Promise.resolve();
11
+ let results = [];
12
+
13
+ items.forEach(item => {
14
+ const itemId = item.item_id;
15
+ const field = item.fields.find(field => field.element_id === elementId);
16
+
17
+ if(field && field.field_value) {
18
+ const fileIds = field.field_value.split('.');
19
+
20
+ fileIds.forEach(fileId => {
21
+ const newFile = {
22
+ source: fileId,
23
+ destination: {
24
+ app_id: appId,
25
+ item_id: itemId,
26
+ element_id: elementId
27
+ }
28
+ }
29
+
30
+ if(files[files.length - 1].length !== 10) { // 10 - max duplicate files
31
+ files[files.length - 1].push(newFile);
32
+ } else {
33
+ files.push([newFile]);
34
+ }
35
+ })
36
+ }
37
+ });
38
+
39
+ files.forEach(filePack => {
40
+ chainPromises = chainPromises.then(() => {
41
+ return self.gudhub.duplicateFile(filePack);
42
+ }).then(result => {
43
+ results = [
44
+ ...results,
45
+ ...result
46
+ ]
47
+ })
48
+ });
49
+
50
+ chainPromises.then(() => {
51
+ items.forEach(item => {
52
+ const itemId = item.item_id;
53
+ const field = item.fields.find(field => field.element_id === elementId);
54
+
55
+ if(field && field.field_value) {
56
+ field.field_value = '';
57
+ results.forEach(file => {
58
+ if(file.item_id === itemId) {
59
+ field.field_value = field.field_value.split(',').filter(fileId => fileId).concat(file.file_id).join(',');
60
+ }
61
+ })
62
+ }
63
+ })
64
+
65
+ resolve();
66
+ })
67
+ });
68
+ }
69
+ }
@@ -117,6 +117,8 @@ export default class FieldsOperator {
117
117
 
118
118
  let actualFieldIds = fieldList.map((field) => +field.field_id);
119
119
 
120
+ const promises = [];
121
+
120
122
  columnsToView = fieldList.reduce((viewColumsList, currentField) => {
121
123
  let field = viewColumsList.find((view, index) => {
122
124
  if (currentField.field_id == view.field_id) {
@@ -126,21 +128,28 @@ export default class FieldsOperator {
126
128
  });
127
129
 
128
130
  if (!field) {
129
- this.gudhub.ghconstructor.getInstance(currentField.data_type).then(instance => {
130
- let template = instance.getTemplate();
131
- let defaultIntepretation = template.model.data_model.interpretation.find((intrpr) => intrpr.src == 'table') || { settings: { show_field: 1 } };
132
- viewColumsList.push({
133
- field_id: currentField.field_id,
134
- data_type: currentField.data_type,
135
- show: defaultIntepretation.settings.show_field
136
- });
137
- })
131
+
132
+ viewColumsList.push({
133
+ field_id: currentField.field_id,
134
+ data_type: currentField.data_type,
135
+ });
136
+
137
+ promises.push(new Promise(async (resolve) => {
138
+ const instance = await this.gudhub.ghconstructor.getInstance(currentField.data_type);
139
+ const template = instance.getTemplate();
140
+ const defaultIntepretation = template.model.data_model.interpretation.find((intrpr) => intrpr.src == 'table') || { settings: { show_field: 1 } };
141
+ viewColumsList.find(view => view.field_id == currentField.field_id).show = defaultIntepretation.settings.show_field;
142
+ resolve(true);
143
+ }));
138
144
  }
139
145
 
140
146
  return viewColumsList;
141
- }, tableSettingsFieldListToView).filter((field) => actualFieldIds.indexOf(field.field_id) != -1);
147
+ }, tableSettingsFieldListToView);
142
148
 
143
- resolve(columnsToView);
149
+ Promise.all(promises).then(() => {
150
+ columnsToView = columnsToView.filter((field) => actualFieldIds.indexOf(field.field_id) != -1);
151
+ resolve(columnsToView)
152
+ })
144
153
  })
145
154
  }
146
155
  }
@@ -19,12 +19,16 @@ import ItemsSelection from "./ItemsSelection/ItemsSelection.js";
19
19
 
20
20
  import { compare_items_lists_Worker } from "./compare_items_lists_worker/compare_items_lists.worker.js";
21
21
  import { compiler } from "./json_constructor/json_constructor.js";
22
+ import AppsTemplateService from "./AppsTemplateService/AppsTemplateService.js";
23
+ import { FileHelper } from "./FIleHelper/FileHelper.js";
22
24
 
23
25
  export class Utils {
24
26
  constructor(gudhub) {
25
27
  this.gudhub = gudhub;
26
28
  this.MergeFields = new MergeFields(gudhub);
27
29
  this.ItemsSelection = new ItemsSelection(gudhub);
30
+ this.AppsTemplateService = new AppsTemplateService(gudhub);
31
+ this.FileHelper = new FileHelper(gudhub);
28
32
  }
29
33
 
30
34
  prefilter(filters_list, element_app_id, app_id, item_id, variables = []) {
@@ -174,6 +178,22 @@ export class Utils {
174
178
  jsonConstructor(scheme, item, variables){
175
179
  return compiler(scheme, item, this, variables)
176
180
  }
181
+
182
+ fileInstallerHelper(appId, items, elementId) {
183
+ return this.FileHelper.fileInstallerHelper(appId, items, elementId);
184
+ }
185
+
186
+ createAppsFromTemplate(pack, maxNumberOfInsstalledItems, progressCallback) {
187
+ return this.AppsTemplateService.createAppsFromTemplate(pack, maxNumberOfInsstalledItems, progressCallback);
188
+ }
189
+
190
+ createApps(pack) {
191
+ return this.AppsTemplateService.createApps(pack);
192
+ }
193
+
194
+ createItems(create_apps, maxNumberOfInsstalledItems) {
195
+ return this.AppsTemplateService.createItems(create_apps, maxNumberOfInsstalledItems);
196
+ }
177
197
 
178
198
  compareAppsItemsLists(items_list1, items_list2, callback) {
179
199
  const chunkWorkerBlob = new Blob([compare_items_lists_Worker()], {