@sumaris-net/ngx-components 0.18.11 → 0.18.16

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.
@@ -7706,6 +7706,7 @@ class EntityUtils {
7706
7706
  return !obj || obj[checkedAttribute] === null || obj[checkedAttribute] === undefined;
7707
7707
  }
7708
7708
  static equals(o1, o2, checkAttribute) {
7709
+ checkAttribute = checkAttribute || 'id';
7709
7710
  return (o1 === o2) || (isNil(o1) && isNil(o2)) || (o1 && o2 && o1[checkAttribute] === o2[checkAttribute]);
7710
7711
  }
7711
7712
  static getPropertyByPath(obj, path) {
@@ -14224,6 +14225,7 @@ class InMemoryEntitiesService extends EntitiesService {
14224
14225
  this.filterType = filterType;
14225
14226
  this.debug = false;
14226
14227
  this.dirty = false;
14228
+ this._saving = false;
14227
14229
  this._onChange = new BehaviorSubject(true);
14228
14230
  options = Object.assign({ onSort: this.sort, equals: this.equals }, options);
14229
14231
  this._sortFn = options.onSort;
@@ -14241,7 +14243,6 @@ class InMemoryEntitiesService extends EntitiesService {
14241
14243
  // Detect rankOrder on the entity class
14242
14244
  id: (Object.getOwnPropertyNames(new dataType()).findIndex(key => key === 'rankOrder') !== -1) ? 'rankOrder' : undefined }, options.sortByReplacement);
14243
14245
  }
14244
- // TODO add test see sub-batches.modal.ts onLoadData & _hiddenData
14245
14246
  set value(data) {
14246
14247
  this.setValue(data);
14247
14248
  }
@@ -14272,78 +14273,90 @@ class InMemoryEntitiesService extends EntitiesService {
14272
14273
  console.warn('[memory-data-service] Waiting value to be set...');
14273
14274
  }
14274
14275
  return this._onChange
14275
- .pipe(filter(isNotNil), mergeMap((_) => __awaiter(this, void 0, void 0, function* () {
14276
- this._hiddenData = [];
14277
- if (isEmptyArray(this.data)) {
14278
- return { data: [], total: 0 };
14279
- }
14280
- // Apply sort
14281
- let data = this._sortFn(this.data || [], sortBy, sortDirection);
14282
- if (this._onLoad) {
14283
- const promiseOrData = this._onLoad(data);
14284
- data = ((promiseOrData instanceof Promise)) ? yield promiseOrData : promiseOrData;
14285
- }
14286
- // Apply filter (will update hiddenData)
14287
- data = this.filter(data, filterData, this._hiddenData);
14288
- // Compute the total length
14289
- const total = data.length;
14290
- // If page size=0 (e.g. only need total)
14291
- if (size === 0) {
14292
- this._hiddenData.push(...data);
14293
- return { data: [], total };
14294
- }
14295
- // Slice in a page (using offset and size)
14296
- if (offset > 0) {
14297
- // Offset after the end: no result
14298
- if (offset >= data.length) {
14299
- this._hiddenData.push(...data);
14300
- data = [];
14276
+ .pipe(filter(isNotNil), mergeMap(_ => waitFor(() => !this._saving)), mergeMap((_) => __awaiter(this, void 0, void 0, function* () {
14277
+ const excludedDataByFilter = [];
14278
+ let excludedDataByPagination;
14279
+ try {
14280
+ if (isEmptyArray(this.data)) {
14281
+ return { data: [], total: 0 };
14301
14282
  }
14302
- else {
14303
- const hiddenData = (size > 0 && ((offset + size) < data.length)) ?
14304
- // Slice using limit to size
14305
- data.slice(0, offset - 1).concat(data.slice(offset + size)) :
14306
- // Slice without limit
14307
- data.slice(0, offset - 1);
14308
- this._hiddenData.push(...hiddenData);
14309
- data = (size > 0 && ((offset + size) < data.length)) ?
14310
- // Slice using limit to size
14311
- data.slice(offset, offset + size) :
14312
- // Slice without limit
14313
- data.slice(offset);
14283
+ // Apply sort
14284
+ let data = this._sortFn(this.data || [], sortBy, sortDirection);
14285
+ if (this._onLoad) {
14286
+ const promiseOrData = this._onLoad(data);
14287
+ data = ((promiseOrData instanceof Promise)) ? yield promiseOrData : promiseOrData;
14314
14288
  }
14289
+ // Apply filter (will update hiddenData)
14290
+ data = this.filter(data, filterData, excludedDataByFilter);
14291
+ // Compute the total length
14292
+ const total = data.length;
14293
+ // If page size=0 (e.g. only need total)
14294
+ if (size === 0) {
14295
+ excludedDataByPagination = data;
14296
+ return { data: [], total };
14297
+ }
14298
+ // Slice in a page (using offset and size)
14299
+ if (offset > 0) {
14300
+ // Offset after the end: no result
14301
+ if (offset >= data.length) {
14302
+ excludedDataByPagination = data;
14303
+ data = [];
14304
+ }
14305
+ else {
14306
+ excludedDataByPagination = (size > 0 && ((offset + size) < data.length)) ?
14307
+ // Slice using limit to size
14308
+ data.slice(0, offset - 1).concat(data.slice(offset + size)) :
14309
+ // Slice without limit
14310
+ data.slice(0, offset - 1);
14311
+ data = (size > 0 && ((offset + size) < data.length)) ?
14312
+ // Slice using limit to size
14313
+ data.slice(offset, offset + size) :
14314
+ // Slice without limit
14315
+ data.slice(offset);
14316
+ }
14317
+ }
14318
+ // Apply a limit
14319
+ else if (size > 0) {
14320
+ excludedDataByPagination = data.slice(size);
14321
+ data = data.slice(0, size);
14322
+ }
14323
+ // No limit:
14324
+ else if (size === -1) {
14325
+ // Keep all data
14326
+ }
14327
+ // /!\ If already observed, then always create a copy of the original array
14328
+ // Because datasource will only update if the array changed
14329
+ if (data === this.data) {
14330
+ data = data.slice();
14331
+ }
14332
+ return { data, total };
14315
14333
  }
14316
- // Apply a limit
14317
- else if (size > 0) {
14318
- this._hiddenData.push(...data.slice(size));
14319
- data = data.slice(0, size);
14320
- }
14321
- // No limit:
14322
- else if (size === -1) {
14323
- // Keep all data
14324
- }
14325
- // /!\ If already observed, then always create a copy of the original array
14326
- // Because datasource will only update if the array changed
14327
- if (data === this.data) {
14328
- data = data.slice(0);
14334
+ finally {
14335
+ // Remember hidden data
14336
+ this._hiddenData = !excludedDataByPagination ? excludedDataByFilter : excludedDataByFilter.concat(...excludedDataByPagination);
14329
14337
  }
14330
- return { data, total };
14331
14338
  })));
14332
14339
  }
14333
14340
  saveAll(data, options) {
14334
14341
  return __awaiter(this, void 0, void 0, function* () {
14335
14342
  if (!this.data)
14336
14343
  throw new Error('[memory-service] Could not save, because value not set');
14337
- // Restore hidden data
14338
- if (isNotEmptyArray(this._hiddenData))
14339
- data = data.concat(this._hiddenData);
14340
- if (this._onSaveFn) {
14341
- const res = this._onSaveFn(data);
14342
- data = ((res instanceof Promise)) ? yield res : res;
14344
+ this.markAsSaving();
14345
+ try {
14346
+ // Restore hidden data
14347
+ if (isNotEmptyArray(this._hiddenData))
14348
+ data = data.concat(...this._hiddenData);
14349
+ if (this._onSaveFn) {
14350
+ const res = this._onSaveFn(data);
14351
+ data = ((res instanceof Promise)) ? yield res : res;
14352
+ }
14353
+ this.data = data;
14354
+ this.dirty = true;
14355
+ return this.data;
14356
+ }
14357
+ finally {
14358
+ this.markAsSaved();
14343
14359
  }
14344
- this.data = data;
14345
- this.dirty = true;
14346
- return this.data;
14347
14360
  });
14348
14361
  }
14349
14362
  deleteAll(dataToRemove, options) {
@@ -14352,8 +14365,8 @@ class InMemoryEntitiesService extends EntitiesService {
14352
14365
  throw new Error('[memory-service] Could not delete, because value not set');
14353
14366
  // Remove deleted item, from data
14354
14367
  const updatedData = this.data.filter(entity => {
14355
- const shouldRemoved = dataToRemove.findIndex(entityToRemove => this._equalsFn(entityToRemove, entity)) !== -1;
14356
- return !shouldRemoved;
14368
+ const removed = dataToRemove.findIndex(entityToRemove => this.equals(entityToRemove, entity)) !== -1;
14369
+ return !removed;
14357
14370
  });
14358
14371
  const deleteCount = this.data.length - updatedData.length;
14359
14372
  if (deleteCount > 0) {
@@ -14375,6 +14388,11 @@ class InMemoryEntitiesService extends EntitiesService {
14375
14388
  addSortByReplacement(source, target) {
14376
14389
  this._sortByReplacement[source] = target;
14377
14390
  }
14391
+ equals(d1, d2) {
14392
+ if (this._equalsFn)
14393
+ return this._equalsFn(d1, d2);
14394
+ return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');
14395
+ }
14378
14396
  /* -- protected methods -- */
14379
14397
  filter(data, _filter, hiddenData) {
14380
14398
  // if filter is DataFilter instance, use its test function
@@ -14399,8 +14417,11 @@ class InMemoryEntitiesService extends EntitiesService {
14399
14417
  return { data, total };
14400
14418
  }));
14401
14419
  }
14402
- equals(d1, d2) {
14403
- return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');
14420
+ markAsSaving() {
14421
+ this._saving = true;
14422
+ }
14423
+ markAsSaved() {
14424
+ this._saving = false;
14404
14425
  }
14405
14426
  }
14406
14427
  InMemoryEntitiesService.decorators = [
@@ -19982,7 +20003,7 @@ class AppTable {
19982
20003
  }
19983
20004
  }
19984
20005
  markAsUntouched(opts) {
19985
- if (this.dirtySubject.value !== false || (this.editedRow && this.editedRow.id !== this.previouslySavedEditedRowId)) {
20006
+ if (this.dirtySubject.value !== false || (this.editedRow && this.editedRow.id !== this.previouslyEditedRowId)) {
19986
20007
  // Cancel the current editing row only if editing and if it was not previously saved
19987
20008
  this.dirtySubject.next(false);
19988
20009
  if (this.editedRow && this.editedRow.editing) {
@@ -19993,7 +20014,7 @@ class AppTable {
19993
20014
  this.markForCheck();
19994
20015
  }
19995
20016
  }
19996
- this.previouslySavedEditedRowId = undefined;
20017
+ this.previouslyEditedRowId = undefined;
19997
20018
  }
19998
20019
  /**
19999
20020
  * @deprecated prefer to use markAllAsTouched()
@@ -20416,7 +20437,8 @@ class AppTable {
20416
20437
  }
20417
20438
  this.resetError();
20418
20439
  // Keep edited row id (should be done BEFORE confirmEditCreate() )
20419
- this.previouslySavedEditedRowId = opts.keepEditing && ((_a = this.editedRow) === null || _a === void 0 ? void 0 : _a.editing) ? this.editedRow.id : undefined;
20440
+ this.previouslyEditedRowId = opts.keepEditing && ((_a = this.editedRow) === null || _a === void 0 ? void 0 : _a.editing) ? this.editedRow.id : undefined;
20441
+ const previouslyEditedData = isNotNil(this.previouslyEditedRowId) && this.editedRow.currentData || ((_b = this.singleSelectedRow) === null || _b === void 0 ? void 0 : _b.currentData);
20420
20442
  if (!this.confirmEditCreate()) {
20421
20443
  throw { code: ErrorCodes$2.TABLE_INVALID_ROW_ERROR, message: 'ERROR.TABLE_INVALID_ROW_ERROR' };
20422
20444
  }
@@ -20437,15 +20459,9 @@ class AppTable {
20437
20459
  }
20438
20460
  finally {
20439
20461
  this.markAsSaved();
20440
- // Restoring previous row
20441
- if (isNotNil(this.previouslySavedEditedRowId)) {
20442
- if (this.previouslySavedEditedRowId !== -1) {
20443
- // Select by row id
20444
- this.selectRowById(this.previouslySavedEditedRowId);
20445
- }
20446
- else {
20447
- this.selectRowByData((_b = this.singleSelectedRow) === null || _b === void 0 ? void 0 : _b.currentData);
20448
- }
20462
+ // Restore previous row
20463
+ if (isNotNil(this.previouslyEditedRowId)) {
20464
+ yield this.selectRowByIdOrData(this.previouslyEditedRowId, previouslyEditedData);
20449
20465
  }
20450
20466
  }
20451
20467
  });
@@ -20590,37 +20606,24 @@ class AppTable {
20590
20606
  }
20591
20607
  });
20592
20608
  }
20593
- editRow(event, row, opts) {
20594
- if (!this._enabled)
20595
- return false;
20596
- if (this.editedRow === row)
20597
- return true; // Already the edited row
20598
- if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
20599
- return false;
20600
- if (!this.confirmEditCreate()) {
20601
- return false;
20602
- }
20603
- if (!row.editing && !this.loading) {
20604
- this._focusColumn = opts && opts.focusColumn || this._focusColumn;
20605
- this._dataSource.startEdit(row);
20606
- }
20607
- this.editedRow = row;
20608
- this.onStartEditingRow.emit(row);
20609
- return true;
20610
- }
20611
20609
  selectRowById(id) {
20612
20610
  if (id === undefined)
20613
- return;
20614
- this.dataSource.waitIdle()
20611
+ return Promise.resolve(false);
20612
+ return this.dataSource.waitIdle()
20615
20613
  .then(() => this.dataSource.getRow(id))
20616
- .then(row => this.clickRow(null, row));
20614
+ .then(row => row && this.clickRow(null, row));
20617
20615
  }
20616
+ /**
20617
+ * Try to select row by data. Will use dataEquals() (that call EntityUtils.equals()) to find same row's data
20618
+ * @param data
20619
+ */
20618
20620
  selectRowByData(data) {
20619
20621
  if (data === undefined)
20620
- return;
20621
- this.dataSource.waitIdle()
20622
+ return Promise.resolve(false);
20623
+ return this.dataSource.waitIdle()
20622
20624
  .then(() => this.dataSource.getRows())
20623
- .then(rows => { var _a; return this.selectRowById((_a = rows.find(row => this.dataEquals(row.currentData, data))) === null || _a === void 0 ? void 0 : _a.id); });
20625
+ .then(rows => rows.find(row => this.equals(row.currentData, data)))
20626
+ .then(row => row && this.clickRow(null, row));
20624
20627
  }
20625
20628
  clickRow(event, row) {
20626
20629
  var _a;
@@ -20637,8 +20640,6 @@ class AppTable {
20637
20640
  return true; // Already in edition
20638
20641
  if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
20639
20642
  return false; // Cancelled by event
20640
- if (this.loading)
20641
- return false; // Already busy
20642
20643
  // Open the detail page (if not inline editing)
20643
20644
  if (!this.inlineEdition) {
20644
20645
  if (this.dirty && this.debug) {
@@ -20651,10 +20652,10 @@ class AppTable {
20651
20652
  // No ID defined: unable to open details
20652
20653
  if (isNil(row.currentData.id)) {
20653
20654
  console.warn('[table] Opening row details, but missing currentData.id!');
20654
- //return false;
20655
+ return false;
20655
20656
  }
20656
20657
  this.markAsLoading();
20657
- this.openRow(row.currentData.id, row)
20658
+ this.openRowDetail(row.currentData.id, row)
20658
20659
  .then(() => this.markAsLoaded());
20659
20660
  return true;
20660
20661
  }
@@ -20741,6 +20742,57 @@ class AppTable {
20741
20742
  }
20742
20743
  }
20743
20744
  /* -- protected method -- */
20745
+ editRow(event, row, opts) {
20746
+ if (!this._enabled)
20747
+ return false;
20748
+ if (this.editedRow === row)
20749
+ return true; // Already the edited row
20750
+ if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
20751
+ return false;
20752
+ if (!this.confirmEditCreate()) {
20753
+ return false;
20754
+ }
20755
+ if (!row.editing && !this.loading) {
20756
+ this._focusColumn = opts && opts.focusColumn || this._focusColumn;
20757
+ this._dataSource.startEdit(row);
20758
+ }
20759
+ this.editedRow = row;
20760
+ this.onStartEditingRow.emit(row);
20761
+ return true;
20762
+ }
20763
+ /**
20764
+ * Try to select row, by row.id, or by data. WIll use EntityUtils.equals()
20765
+ * @param id
20766
+ * @param data
20767
+ * @protected
20768
+ */
20769
+ selectRowByIdOrData(id, data) {
20770
+ return __awaiter(this, void 0, void 0, function* () {
20771
+ let done = false;
20772
+ try {
20773
+ // Select by row id (if NOT a new row)
20774
+ if (isNotNil(id) || id !== -1) {
20775
+ done = yield this.selectRowById(id);
20776
+ if (done)
20777
+ return true;
20778
+ console.warn('[app-table] Save: Cannot reselect row by row.id: ', id);
20779
+ }
20780
+ // Try by data
20781
+ if (data) {
20782
+ done = yield this.selectRowByData(data);
20783
+ if (done)
20784
+ return true;
20785
+ console.warn('[app-table] Save: Cannot reselect row by data: ', data);
20786
+ }
20787
+ return false;
20788
+ }
20789
+ catch (err) {
20790
+ // Log, but continue
20791
+ console.error(err && err.message || err);
20792
+ return false;
20793
+ }
20794
+ });
20795
+ }
20744
20796
  /**
20745
20797
  * return the selected row if unique in selection
20746
20798
  */
@@ -20854,7 +20906,7 @@ class AppTable {
20854
20906
  return false; // User cancel the action
20855
20907
  });
20856
20908
  }
20857
- openRow(id, row) {
20909
+ openRowDetail(id, row) {
20858
20910
  return __awaiter(this, void 0, void 0, function* () {
20859
20911
  if (!this.allowRowDetail)
20860
20912
  return false;
@@ -21094,12 +21146,12 @@ class AppTable {
21094
21146
  * Compare data equality (default by id)
21095
21147
  * Can be overridden to add additional properties to compare
21096
21148
  *
21097
- * @param t1
21098
- * @param t2
21149
+ * @param d1
21150
+ * @param d2
21099
21151
  * @protected
21100
21152
  */
21101
- dataEquals(t1, t2) {
21102
- return EntityUtils.equals(t1, t2, 'id');
21153
+ equals(d1, d2) {
21154
+ return EntityUtils.equals(d1, d2, 'id');
21103
21155
  }
21104
21156
  /* -- private method -- */
21105
21157
  setLoading(value, opts) {
@@ -22468,6 +22520,9 @@ class AppInMemoryTable extends AppTable {
22468
22520
  this.onRefresh.emit();
22469
22521
  }
22470
22522
  }
22523
+ equals(t1, t2) {
22524
+ return this.memoryDataService.equals(t1, t2);
22525
+ }
22471
22526
  }
22472
22527
  AppInMemoryTable.decorators = [
22473
22528
  { type: Directive }