@sumaris-net/ngx-components 1.20.28 → 1.20.29

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 (27) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +105 -104
  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/pipes/arrays.pipe.js +1 -1
  14. package/esm2015/src/app/shared/pipes/form.pipes.js +2 -4
  15. package/esm2015/src/app/shared/pipes/highlight.pipe.js +4 -4
  16. package/esm2015/src/app/shared/pipes/string.pipes.js +7 -18
  17. package/esm2015/src/app/shared/services/memory-entity-service.class.js +12 -1
  18. package/esm2015/src/app/shared/services.js +61 -0
  19. package/fesm2015/sumaris-net.ngx-components.js +80 -80
  20. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  21. package/package.json +1 -1
  22. package/public_api.d.ts +2 -0
  23. package/src/app/shared/functions.d.ts +0 -9
  24. package/src/app/shared/pipes/form.pipes.d.ts +1 -2
  25. package/src/app/shared/services/memory-entity-service.class.d.ts +7 -0
  26. package/src/app/shared/services.d.ts +9 -0
  27. package/sumaris-net.ngx-components.metadata.json +1 -1
@@ -500,67 +500,6 @@
500
500
  function removeDiacritics(text) {
501
501
  return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
502
502
  }
503
- function suggestFromArray(items, value, opts) {
504
- var _this = this;
505
- if (isNotNil(value) && typeof value === 'object')
506
- return { data: [value] };
507
- value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
508
- var keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
509
- if (!items) {
510
- return { data: [], total: 0 };
511
- }
512
- // Filter items
513
- var filteredItems = items;
514
- if (isNotNilOrBlank(value)) {
515
- // If wildcard, search using regexp
516
- if (value.indexOf('*') !== -1) {
517
- value = value.replace(/[*]+/g, '.*');
518
- filteredItems = filteredItems.filter(function (v) { return keys.findIndex(function (key) { return matchUpperCase(getPropertyByPathAsString(v, key), value); }) !== -1; });
519
- }
520
- // Else (no wildcard), search using startsWith
521
- else {
522
- filteredItems = filteredItems.filter(function (v) { return keys.findIndex(function (key) { return startsWithUpperCase(getPropertyByPathAsString(v, key), value); }) !== -1; });
523
- }
524
- }
525
- // Exclude ids
526
- if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
527
- filteredItems = filteredItems.filter(function (v) { return !opts.excludedIds.includes(+v['id']); });
528
- }
529
- // Sort
530
- if (!opts || opts.skipSort !== true) {
531
- // Make to copy input items, before sorting (if not yet already done)
532
- if (filteredItems === items)
533
- filteredItems = filteredItems.slice();
534
- // Sort by keys
535
- filteredItems.sort(propertiesPathComparator(keys));
536
- }
537
- var total = filteredItems.length || 0;
538
- // Pagination (truncate if need)
539
- var pageData = filteredItems;
540
- if (opts) {
541
- if ((opts.offset || 0) > 0) {
542
- pageData = pageData.slice(opts.offset);
543
- }
544
- if (isNotNil(opts.size) && pageData.length > opts.size) {
545
- pageData = pageData.slice(0, opts.size);
546
- }
547
- }
548
- var result = {
549
- data: pageData,
550
- total: total
551
- };
552
- // Add fetch more capability, if total was fetched
553
- var nextOffset = (opts && opts.offset || 0) + pageData.length;
554
- if (nextOffset < total) {
555
- result.fetchMore = function (_) { return __awaiter(_this, void 0, void 0, function () {
556
- return __generator(this, function (_b) {
557
- return [2 /*return*/, suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
558
- }))];
559
- });
560
- }); };
561
- }
562
- return result;
563
- }
564
503
  function suggestFromStringArray(values, value, options) {
565
504
  value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
566
505
  if (isNilOrBlank(value))
@@ -1377,6 +1316,68 @@
1377
1316
  return _cache.mobile;
1378
1317
  };
1379
1318
 
1319
+ function suggestFromArray(items, value, opts) {
1320
+ var _this = this;
1321
+ if (isNotNil(value) && typeof value === 'object')
1322
+ return { data: [value] };
1323
+ value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
1324
+ var keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
1325
+ if (!items) {
1326
+ return { data: [], total: 0 };
1327
+ }
1328
+ // Filter items
1329
+ var filteredItems = items;
1330
+ if (isNotNilOrBlank(value)) {
1331
+ // If wildcard, search using regexp
1332
+ if (value.indexOf('*') !== -1) {
1333
+ value = value.replace(/[*]+/g, '.*');
1334
+ filteredItems = filteredItems.filter(function (v) { return keys.findIndex(function (key) { return matchUpperCase(getPropertyByPathAsString(v, key), value); }) !== -1; });
1335
+ }
1336
+ // Else (no wildcard), search using startsWith
1337
+ else {
1338
+ filteredItems = filteredItems.filter(function (v) { return keys.findIndex(function (key) { return startsWithUpperCase(getPropertyByPathAsString(v, key), value); }) !== -1; });
1339
+ }
1340
+ }
1341
+ // Exclude ids
1342
+ if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
1343
+ filteredItems = filteredItems.filter(function (v) { return !opts.excludedIds.includes(+v['id']); });
1344
+ }
1345
+ // Sort
1346
+ if (!opts || opts.skipSort !== true) {
1347
+ // Make to copy input items, before sorting (if not yet already done)
1348
+ if (filteredItems === items)
1349
+ filteredItems = filteredItems.slice();
1350
+ // Sort by keys
1351
+ filteredItems.sort(propertiesPathComparator(keys));
1352
+ }
1353
+ var total = filteredItems.length || 0;
1354
+ // Pagination (truncate if need)
1355
+ var pageData = filteredItems;
1356
+ if (opts) {
1357
+ if ((opts.offset || 0) > 0) {
1358
+ pageData = pageData.slice(opts.offset);
1359
+ }
1360
+ if (isNotNil(opts.size) && pageData.length > opts.size) {
1361
+ pageData = pageData.slice(0, opts.size);
1362
+ }
1363
+ }
1364
+ var result = {
1365
+ data: pageData,
1366
+ total: total
1367
+ };
1368
+ // Add fetch more capability, if total was fetched
1369
+ var nextOffset = (opts && opts.offset || 0) + pageData.length;
1370
+ if (nextOffset < total) {
1371
+ result.fetchMore = function (_) { return __awaiter(_this, void 0, void 0, function () {
1372
+ return __generator(this, function (_a) {
1373
+ return [2 /*return*/, suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
1374
+ }))];
1375
+ });
1376
+ }); };
1377
+ }
1378
+ return result;
1379
+ }
1380
+
1380
1381
  var MatAutocompleteConfigHolder = /** @class */ (function () {
1381
1382
  function MatAutocompleteConfigHolder(options) {
1382
1383
  this.options = options;
@@ -2700,9 +2701,9 @@
2700
2701
  var cleanedSearchText = removeDiacritics(searchRegexp).toUpperCase();
2701
2702
  var index = removeDiacritics(value.toUpperCase()).indexOf(cleanedSearchText);
2702
2703
  if (index !== -1) {
2703
- return value.substr(0, index - 1) +
2704
- '<b>' + value.substr(index, cleanedSearchText.length) + '</b>' +
2705
- value.substr(index + cleanedSearchText.length);
2704
+ return value.substring(0, index - 1) +
2705
+ '<b>' + value.substring(index, cleanedSearchText.length) + '</b>' +
2706
+ value.substring(index + cleanedSearchText.length);
2706
2707
  }
2707
2708
  return value;
2708
2709
  }
@@ -3150,12 +3151,10 @@
3150
3151
  };
3151
3152
  return IsNotNilOrBlankPipe;
3152
3153
  }());
3153
- IsNotNilOrBlankPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function IsNotNilOrBlankPipe_Factory() { return new IsNotNilOrBlankPipe(); }, token: IsNotNilOrBlankPipe, providedIn: "root" });
3154
3154
  IsNotNilOrBlankPipe.decorators = [
3155
3155
  { type: i0.Pipe, args: [{
3156
3156
  name: 'isNotNilOrBlank'
3157
- },] },
3158
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3157
+ },] }
3159
3158
  ];
3160
3159
  var IsNilOrBlankPipe = /** @class */ (function () {
3161
3160
  function IsNilOrBlankPipe() {
@@ -3165,12 +3164,10 @@
3165
3164
  };
3166
3165
  return IsNilOrBlankPipe;
3167
3166
  }());
3168
- IsNilOrBlankPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function IsNilOrBlankPipe_Factory() { return new IsNilOrBlankPipe(); }, token: IsNilOrBlankPipe, providedIn: "root" });
3169
3167
  IsNilOrBlankPipe.decorators = [
3170
3168
  { type: i0.Pipe, args: [{
3171
3169
  name: 'isNilOrBlank'
3172
- },] },
3173
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3170
+ },] }
3174
3171
  ];
3175
3172
  var ToStringPipe = /** @class */ (function () {
3176
3173
  function ToStringPipe() {
@@ -3180,12 +3177,10 @@
3180
3177
  };
3181
3178
  return ToStringPipe;
3182
3179
  }());
3183
- ToStringPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function ToStringPipe_Factory() { return new ToStringPipe(); }, token: ToStringPipe, providedIn: "root" });
3184
3180
  ToStringPipe.decorators = [
3185
3181
  { type: i0.Pipe, args: [{
3186
3182
  name: 'toString'
3187
- },] },
3188
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3183
+ },] }
3189
3184
  ];
3190
3185
  var StrLengthPipe = /** @class */ (function () {
3191
3186
  function StrLengthPipe() {
@@ -3195,12 +3190,10 @@
3195
3190
  };
3196
3191
  return StrLengthPipe;
3197
3192
  }());
3198
- StrLengthPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function StrLengthPipe_Factory() { return new StrLengthPipe(); }, token: StrLengthPipe, providedIn: "root" });
3199
3193
  StrLengthPipe.decorators = [
3200
3194
  { type: i0.Pipe, args: [{
3201
3195
  name: 'strLength'
3202
- },] },
3203
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3196
+ },] }
3204
3197
  ];
3205
3198
  var StrIncludesPipe = /** @class */ (function () {
3206
3199
  function StrIncludesPipe() {
@@ -3210,12 +3203,10 @@
3210
3203
  };
3211
3204
  return StrIncludesPipe;
3212
3205
  }());
3213
- StrIncludesPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function StrIncludesPipe_Factory() { return new StrIncludesPipe(); }, token: StrIncludesPipe, providedIn: "root" });
3214
3206
  StrIncludesPipe.decorators = [
3215
3207
  { type: i0.Pipe, args: [{
3216
3208
  name: 'strIncludes'
3217
- },] },
3218
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3209
+ },] }
3219
3210
  ];
3220
3211
 
3221
3212
  var TranslateContextService = /** @class */ (function () {
@@ -4796,8 +4787,7 @@
4796
4787
  },] }
4797
4788
  ];
4798
4789
  var FormGetValuePipe = /** @class */ (function () {
4799
- function FormGetValuePipe(adapter, _ref) {
4800
- this.adapter = adapter;
4790
+ function FormGetValuePipe(_ref) {
4801
4791
  this._ref = _ref;
4802
4792
  this.value = undefined;
4803
4793
  this._lastControl = null;
@@ -4865,7 +4855,6 @@
4865
4855
  },] }
4866
4856
  ];
4867
4857
  FormGetValuePipe.ctorParameters = function () { return [
4868
- { type: FormErrorTranslator },
4869
4858
  { type: i0.ChangeDetectorRef }
4870
4859
  ]; };
4871
4860
 
@@ -20730,14 +20719,14 @@
20730
20719
  }
20731
20720
  return this._onChange
20732
20721
  .pipe(operators.filter(isNotNil), operators.mergeMap(function (_) { return waitFor(function () { return !_this._saving; }); }), operators.mergeMap(function (_) { return __awaiter(_this, void 0, void 0, function () {
20733
- var excludedDataByFilter, excludedDataByPagination, data, promiseOrData, _a, total;
20734
- return __generator(this, function (_b) {
20735
- switch (_b.label) {
20722
+ var excludedDataByFilter, excludedDataByPagination, data, promiseOrData, _d, total;
20723
+ return __generator(this, function (_e) {
20724
+ switch (_e.label) {
20736
20725
  case 0:
20737
20726
  excludedDataByFilter = [];
20738
- _b.label = 1;
20727
+ _e.label = 1;
20739
20728
  case 1:
20740
- _b.trys.push([1, , 6, 7]);
20729
+ _e.trys.push([1, , 6, 7]);
20741
20730
  if (isEmptyArray(this.data)) {
20742
20731
  return [2 /*return*/, { data: [], total: 0 }];
20743
20732
  }
@@ -20747,14 +20736,14 @@
20747
20736
  if (!((promiseOrData instanceof Promise))) return [3 /*break*/, 3];
20748
20737
  return [4 /*yield*/, promiseOrData];
20749
20738
  case 2:
20750
- _a = _b.sent();
20739
+ _d = _e.sent();
20751
20740
  return [3 /*break*/, 4];
20752
20741
  case 3:
20753
- _a = promiseOrData;
20754
- _b.label = 4;
20742
+ _d = promiseOrData;
20743
+ _e.label = 4;
20755
20744
  case 4:
20756
- data = _a;
20757
- _b.label = 5;
20745
+ data = _d;
20746
+ _e.label = 5;
20758
20747
  case 5:
20759
20748
  // Apply filter (will update hiddenData)
20760
20749
  data = this.filter(data, filterData, excludedDataByFilter);
@@ -20810,16 +20799,16 @@
20810
20799
  };
20811
20800
  InMemoryEntitiesService.prototype.saveAll = function (data, options) {
20812
20801
  return __awaiter(this, void 0, void 0, function () {
20813
- var res, _a;
20814
- return __generator(this, function (_b) {
20815
- switch (_b.label) {
20802
+ var res, _d;
20803
+ return __generator(this, function (_e) {
20804
+ switch (_e.label) {
20816
20805
  case 0:
20817
20806
  if (!this.data)
20818
20807
  throw new Error('[memory-service] Could not save, because value not set');
20819
20808
  this.markAsSaving();
20820
- _b.label = 1;
20809
+ _e.label = 1;
20821
20810
  case 1:
20822
- _b.trys.push([1, , 6, 7]);
20811
+ _e.trys.push([1, , 6, 7]);
20823
20812
  // Restore hidden data
20824
20813
  if (isNotEmptyArray(this._hiddenData))
20825
20814
  data = data.concat.apply(data, __spread(this._hiddenData));
@@ -20828,14 +20817,14 @@
20828
20817
  if (!((res instanceof Promise))) return [3 /*break*/, 3];
20829
20818
  return [4 /*yield*/, res];
20830
20819
  case 2:
20831
- _a = _b.sent();
20820
+ _d = _e.sent();
20832
20821
  return [3 /*break*/, 4];
20833
20822
  case 3:
20834
- _a = res;
20835
- _b.label = 4;
20823
+ _d = res;
20824
+ _e.label = 4;
20836
20825
  case 4:
20837
- data = _a;
20838
- _b.label = 5;
20826
+ data = _d;
20827
+ _e.label = 5;
20839
20828
  case 5:
20840
20829
  this.data = data;
20841
20830
  this.dirty = true;
@@ -20852,7 +20841,7 @@
20852
20841
  return __awaiter(this, void 0, void 0, function () {
20853
20842
  var updatedData, deleteCount;
20854
20843
  var _this = this;
20855
- return __generator(this, function (_a) {
20844
+ return __generator(this, function (_d) {
20856
20845
  if (!this.data)
20857
20846
  throw new Error('[memory-service] Could not delete, because value not set');
20858
20847
  updatedData = this.data.filter(function (entity) {
@@ -20886,6 +20875,18 @@
20886
20875
  return this._equalsFn(d1, d2);
20887
20876
  return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');
20888
20877
  };
20878
+ /**
20879
+ * Count data inside the service.
20880
+ * @param opts
20881
+ */
20882
+ InMemoryEntitiesService.prototype.count = function (opts) {
20883
+ if (opts === void 0) { opts = { withHidden: false }; }
20884
+ var _a, _b, _c;
20885
+ if (opts.withHidden) {
20886
+ return (((_a = this.data) === null || _a === void 0 ? void 0 : _a.length) || 0) + (((_b = this._hiddenData) === null || _b === void 0 ? void 0 : _b.length) || 0);
20887
+ }
20888
+ return (((_c = this.data) === null || _c === void 0 ? void 0 : _c.length) || 0);
20889
+ };
20889
20890
  /* -- protected methods -- */
20890
20891
  InMemoryEntitiesService.prototype.filter = function (data, _filter, hiddenData) {
20891
20892
  // if filter is DataFilter instance, use its test function
@@ -22689,7 +22690,7 @@
22689
22690
  FormButtonsBarComponent.decorators = [
22690
22691
  { type: i0.Component, args: [{
22691
22692
  selector: 'app-form-buttons-bar',
22692
- 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",
22693
+ 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",
22693
22694
  providers: [
22694
22695
  { provide: FormButtonsBarToken, useExisting: FormButtonsBarComponent }
22695
22696
  ],