@sumaris-net/ngx-components 1.20.28 → 1.20.31

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.
Files changed (28) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +116 -109
  2. package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
  3. package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
  4. package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
  5. package/doc/changelog.md +3 -0
  6. package/esm2015/public_api.js +3 -1
  7. package/esm2015/src/app/core/form/form-buttons-bar.component.js +2 -2
  8. package/esm2015/src/app/shared/functions.js +1 -60
  9. package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +3 -2
  10. package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +3 -2
  11. package/esm2015/src/app/shared/material/chips/material.chips.js +3 -2
  12. package/esm2015/src/app/shared/material/chips/testing/chips.test.js +3 -2
  13. package/esm2015/src/app/shared/material/datetime/material.datetime.js +4 -5
  14. package/esm2015/src/app/shared/pipes/arrays.pipe.js +1 -1
  15. package/esm2015/src/app/shared/pipes/form.pipes.js +2 -4
  16. package/esm2015/src/app/shared/pipes/highlight.pipe.js +4 -4
  17. package/esm2015/src/app/shared/pipes/string.pipes.js +7 -18
  18. package/esm2015/src/app/shared/services/memory-entity-service.class.js +13 -1
  19. package/esm2015/src/app/shared/services.js +61 -0
  20. package/fesm2015/sumaris-net.ngx-components.js +84 -84
  21. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  22. package/package.json +1 -1
  23. package/public_api.d.ts +2 -0
  24. package/src/app/shared/functions.d.ts +0 -9
  25. package/src/app/shared/pipes/form.pipes.d.ts +1 -2
  26. package/src/app/shared/services/memory-entity-service.class.d.ts +6 -0
  27. package/src/app/shared/services.d.ts +9 -0
  28. package/sumaris-net.ngx-components.metadata.json +1 -1
@@ -241,64 +241,6 @@ function changeCaseToUnderscore(value) {
241
241
  function removeDiacritics(text) {
242
242
  return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
243
243
  }
244
- function suggestFromArray(items, value, opts) {
245
- if (isNotNil(value) && typeof value === 'object')
246
- return { data: [value] };
247
- value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
248
- const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
249
- if (!items) {
250
- return { data: [], total: 0 };
251
- }
252
- // Filter items
253
- let filteredItems = items;
254
- if (isNotNilOrBlank(value)) {
255
- // If wildcard, search using regexp
256
- if (value.indexOf('*') !== -1) {
257
- value = value.replace(/[*]+/g, '.*');
258
- filteredItems = filteredItems.filter(v => keys.findIndex(key => matchUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
259
- }
260
- // Else (no wildcard), search using startsWith
261
- else {
262
- filteredItems = filteredItems.filter(v => keys.findIndex(key => startsWithUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
263
- }
264
- }
265
- // Exclude ids
266
- if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
267
- filteredItems = filteredItems.filter(v => !opts.excludedIds.includes(+v['id']));
268
- }
269
- // Sort
270
- if (!opts || opts.skipSort !== true) {
271
- // Make to copy input items, before sorting (if not yet already done)
272
- if (filteredItems === items)
273
- filteredItems = filteredItems.slice();
274
- // Sort by keys
275
- filteredItems.sort(propertiesPathComparator(keys));
276
- }
277
- const total = filteredItems.length || 0;
278
- // Pagination (truncate if need)
279
- let pageData = filteredItems;
280
- if (opts) {
281
- if ((opts.offset || 0) > 0) {
282
- pageData = pageData.slice(opts.offset);
283
- }
284
- if (isNotNil(opts.size) && pageData.length > opts.size) {
285
- pageData = pageData.slice(0, opts.size);
286
- }
287
- }
288
- const result = {
289
- data: pageData,
290
- total
291
- };
292
- // Add fetch more capability, if total was fetched
293
- const nextOffset = (opts && opts.offset || 0) + pageData.length;
294
- if (nextOffset < total) {
295
- result.fetchMore = (_) => __awaiter(this, void 0, void 0, function* () {
296
- return suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
297
- }));
298
- });
299
- }
300
- return result;
301
- }
302
244
  function suggestFromStringArray(values, value, options) {
303
245
  value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
304
246
  if (isNilOrBlank(value))
@@ -1100,6 +1042,65 @@ const isMobile = (win) => {
1100
1042
  return _cache.mobile;
1101
1043
  };
1102
1044
 
1045
+ function suggestFromArray(items, value, opts) {
1046
+ if (isNotNil(value) && typeof value === 'object')
1047
+ return { data: [value] };
1048
+ value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
1049
+ const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
1050
+ if (!items) {
1051
+ return { data: [], total: 0 };
1052
+ }
1053
+ // Filter items
1054
+ let filteredItems = items;
1055
+ if (isNotNilOrBlank(value)) {
1056
+ // If wildcard, search using regexp
1057
+ if (value.indexOf('*') !== -1) {
1058
+ value = value.replace(/[*]+/g, '.*');
1059
+ filteredItems = filteredItems.filter(v => keys.findIndex(key => matchUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
1060
+ }
1061
+ // Else (no wildcard), search using startsWith
1062
+ else {
1063
+ filteredItems = filteredItems.filter(v => keys.findIndex(key => startsWithUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
1064
+ }
1065
+ }
1066
+ // Exclude ids
1067
+ if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
1068
+ filteredItems = filteredItems.filter(v => !opts.excludedIds.includes(+v['id']));
1069
+ }
1070
+ // Sort
1071
+ if (!opts || opts.skipSort !== true) {
1072
+ // Make to copy input items, before sorting (if not yet already done)
1073
+ if (filteredItems === items)
1074
+ filteredItems = filteredItems.slice();
1075
+ // Sort by keys
1076
+ filteredItems.sort(propertiesPathComparator(keys));
1077
+ }
1078
+ const total = filteredItems.length || 0;
1079
+ // Pagination (truncate if need)
1080
+ let pageData = filteredItems;
1081
+ if (opts) {
1082
+ if ((opts.offset || 0) > 0) {
1083
+ pageData = pageData.slice(opts.offset);
1084
+ }
1085
+ if (isNotNil(opts.size) && pageData.length > opts.size) {
1086
+ pageData = pageData.slice(0, opts.size);
1087
+ }
1088
+ }
1089
+ const result = {
1090
+ data: pageData,
1091
+ total
1092
+ };
1093
+ // Add fetch more capability, if total was fetched
1094
+ const nextOffset = (opts && opts.offset || 0) + pageData.length;
1095
+ if (nextOffset < total) {
1096
+ result.fetchMore = (_) => __awaiter(this, void 0, void 0, function* () {
1097
+ return suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
1098
+ }));
1099
+ });
1100
+ }
1101
+ return result;
1102
+ }
1103
+
1103
1104
  class MatAutocompleteConfigHolder {
1104
1105
  constructor(options) {
1105
1106
  this.options = options;
@@ -2328,9 +2329,9 @@ class HighlightPipe {
2328
2329
  const cleanedSearchText = removeDiacritics(searchRegexp).toUpperCase();
2329
2330
  const index = removeDiacritics(value.toUpperCase()).indexOf(cleanedSearchText);
2330
2331
  if (index !== -1) {
2331
- return value.substr(0, index - 1) +
2332
- '<b>' + value.substr(index, cleanedSearchText.length) + '</b>' +
2333
- value.substr(index + cleanedSearchText.length);
2332
+ return value.substring(0, index - 1) +
2333
+ '<b>' + value.substring(index, cleanedSearchText.length) + '</b>' +
2334
+ value.substring(index + cleanedSearchText.length);
2334
2335
  }
2335
2336
  return value;
2336
2337
  }
@@ -2728,60 +2729,50 @@ class IsNotNilOrBlankPipe {
2728
2729
  return isNotNilOrBlank(value);
2729
2730
  }
2730
2731
  }
2731
- IsNotNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNotNilOrBlankPipe_Factory() { return new IsNotNilOrBlankPipe(); }, token: IsNotNilOrBlankPipe, providedIn: "root" });
2732
2732
  IsNotNilOrBlankPipe.decorators = [
2733
2733
  { type: Pipe, args: [{
2734
2734
  name: 'isNotNilOrBlank'
2735
- },] },
2736
- { type: Injectable, args: [{ providedIn: 'root' },] }
2735
+ },] }
2737
2736
  ];
2738
2737
  class IsNilOrBlankPipe {
2739
2738
  transform(value) {
2740
2739
  return isNilOrBlank(value);
2741
2740
  }
2742
2741
  }
2743
- IsNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNilOrBlankPipe_Factory() { return new IsNilOrBlankPipe(); }, token: IsNilOrBlankPipe, providedIn: "root" });
2744
2742
  IsNilOrBlankPipe.decorators = [
2745
2743
  { type: Pipe, args: [{
2746
2744
  name: 'isNilOrBlank'
2747
- },] },
2748
- { type: Injectable, args: [{ providedIn: 'root' },] }
2745
+ },] }
2749
2746
  ];
2750
2747
  class ToStringPipe {
2751
2748
  transform(value) {
2752
2749
  return (value !== null && value !== undefined) ? value.toString() : '';
2753
2750
  }
2754
2751
  }
2755
- ToStringPipe.ɵprov = ɵɵdefineInjectable({ factory: function ToStringPipe_Factory() { return new ToStringPipe(); }, token: ToStringPipe, providedIn: "root" });
2756
2752
  ToStringPipe.decorators = [
2757
2753
  { type: Pipe, args: [{
2758
2754
  name: 'toString'
2759
- },] },
2760
- { type: Injectable, args: [{ providedIn: 'root' },] }
2755
+ },] }
2761
2756
  ];
2762
2757
  class StrLengthPipe {
2763
2758
  transform(value) {
2764
2759
  return value && value.length || 0;
2765
2760
  }
2766
2761
  }
2767
- StrLengthPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrLengthPipe_Factory() { return new StrLengthPipe(); }, token: StrLengthPipe, providedIn: "root" });
2768
2762
  StrLengthPipe.decorators = [
2769
2763
  { type: Pipe, args: [{
2770
2764
  name: 'strLength'
2771
- },] },
2772
- { type: Injectable, args: [{ providedIn: 'root' },] }
2765
+ },] }
2773
2766
  ];
2774
2767
  class StrIncludesPipe {
2775
2768
  transform(value, searchString, position) {
2776
2769
  return (value === null || value === void 0 ? void 0 : value.includes(searchString, position)) || false;
2777
2770
  }
2778
2771
  }
2779
- StrIncludesPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrIncludesPipe_Factory() { return new StrIncludesPipe(); }, token: StrIncludesPipe, providedIn: "root" });
2780
2772
  StrIncludesPipe.decorators = [
2781
2773
  { type: Pipe, args: [{
2782
2774
  name: 'strIncludes'
2783
- },] },
2784
- { type: Injectable, args: [{ providedIn: 'root' },] }
2775
+ },] }
2785
2776
  ];
2786
2777
 
2787
2778
  class TranslateContextService {
@@ -4232,8 +4223,7 @@ FormGetGroupPipe.decorators = [
4232
4223
  },] }
4233
4224
  ];
4234
4225
  class FormGetValuePipe {
4235
- constructor(adapter, _ref) {
4236
- this.adapter = adapter;
4226
+ constructor(_ref) {
4237
4227
  this._ref = _ref;
4238
4228
  this.value = undefined;
4239
4229
  this._lastControl = null;
@@ -4298,7 +4288,6 @@ FormGetValuePipe.decorators = [
4298
4288
  },] }
4299
4289
  ];
4300
4290
  FormGetValuePipe.ctorParameters = () => [
4301
- { type: FormErrorTranslator },
4302
4291
  { type: ChangeDetectorRef }
4303
4292
  ];
4304
4293
 
@@ -5526,10 +5515,9 @@ class MatDateTime {
5526
5515
  return this._readonly;
5527
5516
  }
5528
5517
  set tabindex(value) {
5529
- if (this._tabindex !== value) {
5530
- this._tabindex = value;
5531
- setTimeout(() => this.updateTabIndex());
5532
- }
5518
+ this._tabindex = value;
5519
+ if (!this._writing)
5520
+ this.updateTabIndex();
5533
5521
  }
5534
5522
  get tabindex() {
5535
5523
  return this._tabindex;
@@ -18213,6 +18201,18 @@ class InMemoryEntitiesService extends EntitiesService {
18213
18201
  return this._equalsFn(d1, d2);
18214
18202
  return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');
18215
18203
  }
18204
+ /**
18205
+ * Count data stored by the service (without hidden data).
18206
+ * @param opts
18207
+ */
18208
+ get count() {
18209
+ var _a;
18210
+ return (((_a = this.data) === null || _a === void 0 ? void 0 : _a.length) || 0);
18211
+ }
18212
+ get hiddenCount() {
18213
+ var _a;
18214
+ return ((_a = this._hiddenData) === null || _a === void 0 ? void 0 : _a.length) || 0;
18215
+ }
18216
18216
  /* -- protected methods -- */
18217
18217
  filter(data, _filter, hiddenData) {
18218
18218
  // if filter is DataFilter instance, use its test function
@@ -19758,7 +19758,7 @@ class FormButtonsBarComponent {
19758
19758
  FormButtonsBarComponent.decorators = [
19759
19759
  { type: Component, args: [{
19760
19760
  selector: 'app-form-buttons-bar',
19761
- template: "\n<ion-toolbar [class]=\"classList\">\n <ion-row class=\"ion-no-padding\" nowrap>\n <!-- show menu button -->\n <ion-col size=\"auto\" class=\"hidden-xs hidden-sm\">\n <ion-menu-toggle>\n <button\n mat-icon-button\n color=\"accent\"\n [title]=\"'COMMON.BTN_SHOW_MENU' | translate\"\n (click)=\"menu.toggleSplitPaneWhen()\">\n <mat-icon><span>&#xbb;</span></mat-icon>\n </button>\n </ion-menu-toggle>\n </ion-col>\n\n <ion-col>\n <ng-content></ng-content>\n </ion-col>\n\n <ion-col size=\"auto\">\n\n <!-- close (go back) -->\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"onBack.emit($event)\"\n (keyup.enter)=\"onBack.emit($event)\"\n *ngIf=\"onBack.observers | isNotEmptyArray\">\n <ion-label translate>COMMON.BTN_CLOSE</ion-label>\n </ion-button>\n\n <!-- reload -->\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"onCancel.emit($event)\"\n (keyup.enter)=\"onCancel.emit($event)\"\n [disabled]=\"disabledCancel\">\n <ion-icon slot=\"start\" name=\"refresh\"></ion-icon>\n <ion-label translate>COMMON.BTN_RESET</ion-label>\n </ion-button>\n\n <!-- next -->\n <ion-button fill=\"solid\" (click)=\"onNext.emit($event)\" (keyup.enter)=\"onNext.emit($event)\" *ngIf=\"onNext.observers | isNotEmptyArray\">\n <ion-label translate>COMMON.BTN_NEXT</ion-label>\n <ion-icon slot=\"end\" name=\"arrow-forward\"></ion-icon>\n </ion-button>\n\n <!-- save -->\n <ion-button [fill]=\"disabled ? 'clear' : 'solid'\"\n (click)=\"onSave.emit($event)\"\n (keyup.enter)=\"onSave.emit($event)\" color=\"danger\"\n [disabled]=\"disabled\">\n <ion-label [innerHTML]=\"'COMMON.BTN_SAVE_WITH_SHORTCUT'|translate\" [title]=\"'COMMON.BTN_SAVE_WITH_SHORTCUT_HELP'|translate\"></ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n</ion-toolbar>\n",
19761
+ template: "\n<ion-toolbar [class]=\"classList\">\n <ion-row class=\"ion-no-padding\" nowrap>\n <!-- show menu button -->\n <ion-col size=\"auto\" class=\"hidden-xs hidden-sm\">\n <ion-menu-toggle>\n <button\n mat-icon-button\n color=\"accent\"\n [title]=\"'COMMON.BTN_SHOW_MENU' | translate\"\n (click)=\"menu.toggleSplitPaneWhen()\">\n <mat-icon><span>&#xbb;</span></mat-icon>\n </button>\n </ion-menu-toggle>\n </ion-col>\n\n <ion-col>\n <ng-content></ng-content>\n </ion-col>\n\n <ion-col size=\"auto\">\n\n <ng-content select=\"[slot=end]\"></ng-content>\n\n <!-- close (go back) -->\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"onBack.emit($event)\"\n (keyup.enter)=\"onBack.emit($event)\"\n *ngIf=\"onBack.observers | isNotEmptyArray\">\n <ion-label translate>COMMON.BTN_CLOSE</ion-label>\n </ion-button>\n\n <!-- reload -->\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"onCancel.emit($event)\"\n (keyup.enter)=\"onCancel.emit($event)\"\n [disabled]=\"disabledCancel\">\n <ion-icon slot=\"start\" name=\"refresh\"></ion-icon>\n <ion-label translate>COMMON.BTN_RESET</ion-label>\n </ion-button>\n\n <!-- next -->\n <ion-button fill=\"solid\" (click)=\"onNext.emit($event)\" (keyup.enter)=\"onNext.emit($event)\" *ngIf=\"onNext.observers | isNotEmptyArray\">\n <ion-label translate>COMMON.BTN_NEXT</ion-label>\n <ion-icon slot=\"end\" name=\"arrow-forward\"></ion-icon>\n </ion-button>\n\n <!-- save -->\n <ion-button [fill]=\"disabled ? 'clear' : 'solid'\"\n (click)=\"onSave.emit($event)\"\n (keyup.enter)=\"onSave.emit($event)\" color=\"danger\"\n [disabled]=\"disabled\">\n <ion-label [innerHTML]=\"'COMMON.BTN_SAVE_WITH_SHORTCUT'|translate\" [title]=\"'COMMON.BTN_SAVE_WITH_SHORTCUT_HELP'|translate\"></ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n</ion-toolbar>\n",
19762
19762
  providers: [
19763
19763
  { provide: FormButtonsBarToken, useExisting: FormButtonsBarComponent }
19764
19764
  ],