@firestitch/filter 9.8.5 → 9.9.0

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 (32) hide show
  1. package/app/components/filter/filter.component.d.ts +1 -0
  2. package/app/components/filters-item/text/text.component.d.ts +2 -0
  3. package/app/interfaces/items/base.interface.d.ts +3 -1
  4. package/app/models/items/base-item.d.ts +5 -1
  5. package/app/services/items-store.service.d.ts +5 -0
  6. package/bundles/firestitch-filter.umd.js +103 -32
  7. package/bundles/firestitch-filter.umd.js.map +1 -1
  8. package/bundles/firestitch-filter.umd.min.js +2 -2
  9. package/bundles/firestitch-filter.umd.min.js.map +1 -1
  10. package/esm2015/app/components/filter/filter.component.js +14 -21
  11. package/esm2015/app/components/filters-item/text/text.component.js +15 -5
  12. package/esm2015/app/interfaces/items/base.interface.js +1 -1
  13. package/esm2015/app/models/items/base-item.js +21 -3
  14. package/esm2015/app/models/items/date-range/base-date-range-item.js +3 -4
  15. package/esm2015/app/models/items/range-item.js +3 -4
  16. package/esm2015/app/services/items-store.service.js +38 -5
  17. package/esm2015/public_api.js +1 -1
  18. package/esm5/app/components/filter/filter.component.js +22 -22
  19. package/esm5/app/components/filters-item/text/text.component.js +16 -5
  20. package/esm5/app/interfaces/items/base.interface.js +1 -1
  21. package/esm5/app/models/items/base-item.js +26 -3
  22. package/esm5/app/models/items/date-range/base-date-range-item.js +3 -4
  23. package/esm5/app/models/items/range-item.js +3 -4
  24. package/esm5/app/services/items-store.service.js +44 -5
  25. package/esm5/public_api.js +1 -1
  26. package/fesm2015/firestitch-filter.js +86 -34
  27. package/fesm2015/firestitch-filter.js.map +1 -1
  28. package/fesm5/firestitch-filter.js +105 -34
  29. package/fesm5/firestitch-filter.js.map +1 -1
  30. package/firestitch-filter.metadata.json +1 -1
  31. package/package.json +1 -1
  32. package/public_api.d.ts +5 -4
@@ -1,8 +1,8 @@
1
1
  import { __extends, __assign, __decorate, __metadata, __spread, __param, __values, __read } from 'tslib';
2
2
  import { Injectable, Optional, Inject, Component, ChangeDetectionStrategy, InjectionToken, ChangeDetectorRef, HostListener, Input, Injector, Directive, EventEmitter, NgZone, Output, ContentChild, TemplateRef, ViewChild, ElementRef, HostBinding, ViewEncapsulation, KeyValueDiffers, Pipe, Self, NgModule } from '@angular/core';
3
3
  import { ActivatedRoute, Router, RouterModule } from '@angular/router';
4
- import { BehaviorSubject, Subject, isObservable, of, fromEvent, merge, timer, combineLatest } from 'rxjs';
5
- import { take, takeUntil, debounceTime, tap, distinctUntilChanged, filter as filter$1, switchMap, skip, map, mapTo, startWith, delay } from 'rxjs/operators';
4
+ import { BehaviorSubject, Subject, isObservable, forkJoin, of, fromEvent, combineLatest, merge, timer } from 'rxjs';
5
+ import { tap, finalize, take, takeUntil, debounceTime, filter as filter$1, distinctUntilChanged, switchMap, skip, map, mapTo, startWith, delay } from 'rxjs/operators';
6
6
  import { isFunction, clone, isObject, isString, toString, pickBy } from 'lodash-es';
7
7
  import { Alias, Model } from 'tsmodels';
8
8
  import { filter, isEmpty, getNormalizedPath, list, remove, FsCommonModule } from '@firestitch/common';
@@ -70,6 +70,7 @@ var BaseItem = /** @class */ (function () {
70
70
  this._additionalConfig = _additionalConfig;
71
71
  this._initialized = false;
72
72
  this._pendingValues = false;
73
+ this._pendingDefaultValue = false;
73
74
  this._loading$ = new BehaviorSubject(false);
74
75
  this._value$ = new BehaviorSubject(null);
75
76
  this._valueChange$ = new Subject();
@@ -186,6 +187,13 @@ var BaseItem = /** @class */ (function () {
186
187
  enumerable: true,
187
188
  configurable: true
188
189
  });
190
+ Object.defineProperty(BaseItem.prototype, "hasPendingDefaultValue", {
191
+ get: function () {
192
+ return this._pendingDefaultValue;
193
+ },
194
+ enumerable: true,
195
+ configurable: true
196
+ });
189
197
  Object.defineProperty(BaseItem.prototype, "model", {
190
198
  get: function () {
191
199
  return this._model;
@@ -291,6 +299,15 @@ var BaseItem = /** @class */ (function () {
291
299
  enumerable: true,
292
300
  configurable: true
293
301
  });
302
+ BaseItem.prototype.loadDefaultValue = function () {
303
+ var _this = this;
304
+ return this.defaultValueFn()
305
+ .pipe(tap(function (value) {
306
+ _this.defaultValue = value;
307
+ }), finalize(function () {
308
+ _this._pendingDefaultValue = false;
309
+ }));
310
+ };
294
311
  BaseItem.prototype.initValues = function (persistedValue) {
295
312
  this._initialized = false;
296
313
  this.persistedValue = persistedValue;
@@ -354,7 +371,13 @@ var BaseItem = /** @class */ (function () {
354
371
  this.name = item.name;
355
372
  this.label = item.label;
356
373
  this.chipLabel = item.chipLabel;
357
- this.defaultValue = item.default;
374
+ if (typeof item.default === 'function') {
375
+ this._pendingDefaultValue = true;
376
+ this.defaultValueFn = item.default;
377
+ }
378
+ else {
379
+ this.defaultValue = item.default;
380
+ }
358
381
  this.change = item.change;
359
382
  this.hide = item.hide;
360
383
  this.clearAllowed = (_a = item.clear) !== null && _a !== void 0 ? _a : true;
@@ -865,15 +888,14 @@ var RangeItem = /** @class */ (function (_super) {
865
888
  });
866
889
  Object.defineProperty(RangeItem.prototype, "queryObject", {
867
890
  get: function () {
868
- var _a, _b;
869
891
  var value = this.value;
870
892
  var name = this.name;
871
893
  var params = {};
872
894
  var paramMinName = getRangeName(this.case, name, 'min');
873
895
  var paramMaxName = getRangeName(this.case, name, 'max');
874
896
  if (isObject(value)) {
875
- params[paramMinName] = (_a = value.min) !== null && _a !== void 0 ? _a : null;
876
- params[paramMaxName] = (_b = value.max) !== null && _b !== void 0 ? _b : null;
897
+ params[paramMinName] = value.min || null;
898
+ params[paramMaxName] = value.max || null;
877
899
  }
878
900
  else {
879
901
  params[paramMinName] = null;
@@ -1011,14 +1033,13 @@ var BaseDateRangeItem = /** @class */ (function (_super) {
1011
1033
  Object.defineProperty(BaseDateRangeItem.prototype, "queryObject", {
1012
1034
  get: function () {
1013
1035
  var _a;
1014
- var _b, _c;
1015
1036
  var value = this.value || {};
1016
1037
  var name = this.name;
1017
1038
  var paramFromName = getRangeName(this.case, name, 'from');
1018
1039
  var paramToName = getRangeName(this.case, name, 'to');
1019
1040
  return _a = {},
1020
- _a[paramFromName] = (_b = value.from) !== null && _b !== void 0 ? _b : null,
1021
- _a[paramToName] = (_c = value.to) !== null && _c !== void 0 ? _c : null,
1041
+ _a[paramFromName] = value.from || null,
1042
+ _a[paramToName] = value.to || null,
1022
1043
  _a;
1023
1044
  },
1024
1045
  enumerable: true,
@@ -1540,12 +1561,15 @@ var FsFilterItemsStore = /** @class */ (function () {
1540
1561
  this.sortByItem = null;
1541
1562
  this.sortDirectionItem = null;
1542
1563
  this.keywordItem = null;
1564
+ this._ready$ = new BehaviorSubject(false);
1543
1565
  this._items = [];
1544
1566
  this._visibleItems$ = new BehaviorSubject([]);
1545
1567
  this._itemsByName = new Map();
1546
1568
  this._itemsValuesLoaded = false;
1547
1569
  this._hasKeyword = false;
1548
1570
  this._itemsChange$ = new Subject();
1571
+ this._destroy$ = new Subject();
1572
+ this._lazyInit();
1549
1573
  }
1550
1574
  Object.defineProperty(FsFilterItemsStore.prototype, "items", {
1551
1575
  get: function () {
@@ -1585,8 +1609,17 @@ var FsFilterItemsStore = /** @class */ (function () {
1585
1609
  enumerable: true,
1586
1610
  configurable: true
1587
1611
  });
1612
+ Object.defineProperty(FsFilterItemsStore.prototype, "ready$", {
1613
+ get: function () {
1614
+ return this._ready$.asObservable();
1615
+ },
1616
+ enumerable: true,
1617
+ configurable: true
1618
+ });
1588
1619
  FsFilterItemsStore.prototype.ngOnDestroy = function () {
1589
1620
  this.destroyItems();
1621
+ this._destroy$.next();
1622
+ this._destroy$.complete();
1590
1623
  };
1591
1624
  FsFilterItemsStore.prototype.setConfig = function (config) {
1592
1625
  this._itemsByName.clear();
@@ -1600,8 +1633,6 @@ var FsFilterItemsStore = /** @class */ (function () {
1600
1633
  this._itemsValuesLoaded = false;
1601
1634
  if (Array.isArray(items)) {
1602
1635
  this._createItems(items);
1603
- this.updateVisibleItems();
1604
- this._setKeywordItem();
1605
1636
  }
1606
1637
  };
1607
1638
  FsFilterItemsStore.prototype.filtersClear = function () {
@@ -1640,6 +1671,25 @@ var FsFilterItemsStore = /** @class */ (function () {
1640
1671
  .filter(function (item) { return item.hasPendingValues; })
1641
1672
  .forEach(function (item) { return item.loadAsyncValues(); });
1642
1673
  };
1674
+ FsFilterItemsStore.prototype.loadAsyncDefaults = function () {
1675
+ var _this = this;
1676
+ var pendingItems = this.items
1677
+ .filter(function (item) {
1678
+ return item.hasPendingDefaultValue
1679
+ && (item.persistedValue === null || item.persistedValue === undefined);
1680
+ });
1681
+ if (pendingItems.length > 0) {
1682
+ forkJoin(pendingItems
1683
+ .map(function (item) { return item.loadDefaultValue(); }))
1684
+ .pipe(finalize(function () {
1685
+ _this._ready$.next(true);
1686
+ }), takeUntil(this._destroy$))
1687
+ .subscribe();
1688
+ }
1689
+ else {
1690
+ this._ready$.next(true);
1691
+ }
1692
+ };
1643
1693
  FsFilterItemsStore.prototype.getSort = function () {
1644
1694
  var sortBy = this.getSortByValue();
1645
1695
  sortBy = sortBy === '__all' ? null : sortBy;
@@ -1696,6 +1746,7 @@ var FsFilterItemsStore = /** @class */ (function () {
1696
1746
  item.initValues(p[item.name]);
1697
1747
  });
1698
1748
  this._createSortingItems(p);
1749
+ this.loadAsyncDefaults();
1699
1750
  this._subscribeToItemsChanges();
1700
1751
  };
1701
1752
  FsFilterItemsStore.prototype.updateItemsWithValues = function (values) {
@@ -1784,6 +1835,15 @@ var FsFilterItemsStore = /** @class */ (function () {
1784
1835
  });
1785
1836
  }
1786
1837
  };
1838
+ FsFilterItemsStore.prototype._lazyInit = function () {
1839
+ var _this = this;
1840
+ this.ready$
1841
+ .pipe(filter$1(function (state) { return state; }), takeUntil(this._destroy$))
1842
+ .subscribe(function () {
1843
+ _this.updateVisibleItems();
1844
+ _this._setKeywordItem();
1845
+ });
1846
+ };
1787
1847
  FsFilterItemsStore.prototype._createSortingItems = function (p) {
1788
1848
  var _a;
1789
1849
  if (((_a = this._config.sortValues) === null || _a === void 0 ? void 0 : _a.length) > 0) {
@@ -3241,6 +3301,13 @@ var FilterComponent = /** @class */ (function () {
3241
3301
  enumerable: true,
3242
3302
  configurable: true
3243
3303
  });
3304
+ Object.defineProperty(FilterComponent.prototype, "itemsReady$", {
3305
+ get: function () {
3306
+ return this._filterItems.ready$;
3307
+ },
3308
+ enumerable: true,
3309
+ configurable: true
3310
+ });
3244
3311
  Object.defineProperty(FilterComponent.prototype, "hasFilterChips$", {
3245
3312
  get: function () {
3246
3313
  return this._hasFilterChips$.asObservable();
@@ -3305,21 +3372,6 @@ var FilterComponent = /** @class */ (function () {
3305
3372
  _this.focus();
3306
3373
  }
3307
3374
  });
3308
- if (this.config.init) {
3309
- if (this._externalParams.pending) {
3310
- this._externalParams
3311
- .pending$
3312
- .pipe(filter$1(function (pending) {
3313
- return !pending;
3314
- }), takeUntil(this._destroy$))
3315
- .subscribe(function () {
3316
- _this.init();
3317
- });
3318
- }
3319
- else {
3320
- this.init();
3321
- }
3322
- }
3323
3375
  this._listenInternalItemsChange();
3324
3376
  this._initOverlay();
3325
3377
  };
@@ -3720,10 +3772,18 @@ var FilterComponent = /** @class */ (function () {
3720
3772
  // We may need some time to recieve external params and after that ready can be emitted
3721
3773
  FilterComponent.prototype._listenWhenFilterReady = function () {
3722
3774
  var _this = this;
3723
- this._externalParams
3724
- .pending$
3725
- .pipe(filter$1(function (value) { return !value; }), takeUntil(this._destroy$))
3775
+ combineLatest([
3776
+ this._externalParams.pending$,
3777
+ this.itemsReady$,
3778
+ ])
3779
+ .pipe(filter$1(function (_a) {
3780
+ var _b = __read(_a, 2), pendingParams = _b[0], itemsReady = _b[1];
3781
+ return !pendingParams && itemsReady;
3782
+ }), takeUntil(this._destroy$))
3726
3783
  .subscribe(function () {
3784
+ if (_this.config.init) {
3785
+ _this.init();
3786
+ }
3727
3787
  _this.ready.emit();
3728
3788
  });
3729
3789
  };
@@ -3799,7 +3859,7 @@ var FilterComponent = /** @class */ (function () {
3799
3859
  FilterComponent = __decorate([
3800
3860
  Component({
3801
3861
  selector: 'fs-filter',
3802
- template: "<ng-container *ngIf=\"hasKeyword; else noKeywordFilter\">\n <div class=\"filter-search-container\">\n <div class=\"filter-input-field\">\n <form autocomplete=\"off\" role=\"presentation\" *ngIf=\"keywordVisible$ | async\">\n <mat-form-field floatLabel=\"never\">\n <span matPrefix>\n <mat-icon matPrefix>search</mat-icon>\n </span>\n\n <input\n matInput\n [formControl]=\"searchText\"\n [placeholder]=\"searchPlaceholder\"\n name=\"filter-input\"\n (click)=\"filterInputEvent($event)\"\n class=\"filter-input\">\n\n <a matSuffix\n *ngIf=\"searchText.value && showFilterInput && config.clear\"\n (click)=\"clearSearchText($event)\"\n href=\"javascript:void(0)\"\n class=\"clear\">\n <mat-icon>clear</mat-icon>\n </a>\n\n <a matSuffix\n (click)=\"reload($event)\"\n class=\"reload\"\n *ngIf=\"config.reload\">\n <mat-icon>refresh</mat-icon>\n </a>\n </mat-form-field>\n </form>\n </div>\n <ng-container *ngTemplateOutlet=\"filterActions\"></ng-container>\n </div>\n <div class=\"status-actions\" *ngIf=\"keywordVisible$ | async\">\n <ng-container *ngTemplateOutlet=\"statusBarContainer\"></ng-container>\n <ng-container *ngTemplateOutlet=\"filterChips\"></ng-container>\n </div>\n</ng-container>\n\n<ng-template #noKeywordFilter>\n <div class=\"filter-searchless-container\">\n <div class=\"status-actions\">\n <ng-container *ngTemplateOutlet=\"statusBarContainer\"></ng-container>\n <ng-container *ngTemplateOutlet=\"filterChips\"></ng-container>\n </div>\n <ng-container *ngTemplateOutlet=\"filterActions\"></ng-container>\n </div>\n</ng-template>\n\n\n<ng-template #filterActions>\n <div class=\"filter-actions\">\n <ng-container *ngIf=\"hasVisibleItemOrSorting && filtersBtnVisible$ | async \">\n <button\n mat-button\n class=\"filters-button\"\n [ngClass]=\"{\n 'mat-raised-button': config.button.style == 'raised',\n 'mat-button': config.button.style == 'basic',\n 'mat-icon-button': config.button.style == 'icon'\n }\"\n (click)=\"changeVisibilityClick(!showFilterMenu, $event)\"\n type=\"button\"\n [color]=\"config.button.color\">\n <mat-icon *ngIf=\"config.button.icon\">{{config.button.icon}}</mat-icon>\n {{ config.button.label }}\n </button>\n </ng-container>\n\n <fs-filter-actions\n *ngIf=\"actionsVisible$ | async\"\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n</ng-template>\n\n<ng-template #filterChips>\n <fs-filter-chips\n *ngIf=\"config.chips && hasFilterChips$ | async\"\n class=\"filter-chips\"\n [filters]=\"items\">\n </fs-filter-chips>\n</ng-template>\n\n<ng-template #statusBarContainer>\n <div class=\"status-bar\" *ngIf=\"statusBar\">\n <small><ng-container *ngTemplateOutlet=\"statusBar\"></ng-container></small>\n </div>\n</ng-template>\n",
3862
+ template: "<ng-container *ngIf=\"hasKeyword; else noKeywordFilter\">\n <div class=\"filter-search-container\">\n <div class=\"filter-input-field\">\n <form autocomplete=\"off\" role=\"presentation\" *ngIf=\"keywordVisible$ | async\">\n <mat-form-field floatLabel=\"never\">\n <span matPrefix>\n <mat-icon matPrefix>search</mat-icon>\n </span>\n\n <input\n #searchTextInput\n matInput\n [formControl]=\"searchText\"\n [placeholder]=\"searchPlaceholder\"\n name=\"filter-input\"\n (click)=\"filterInputEvent($event)\"\n class=\"filter-input\">\n\n <a matSuffix\n *ngIf=\"searchText.value && showFilterInput && config.clear\"\n (click)=\"clearSearchText($event)\"\n href=\"javascript:void(0)\"\n class=\"clear\">\n <mat-icon>clear</mat-icon>\n </a>\n\n <a matSuffix\n (click)=\"reload($event)\"\n class=\"reload\"\n *ngIf=\"config.reload\">\n <mat-icon>refresh</mat-icon>\n </a>\n </mat-form-field>\n </form>\n </div>\n <ng-container *ngTemplateOutlet=\"filterActions\"></ng-container>\n </div>\n <div class=\"status-actions\" *ngIf=\"keywordVisible$ | async\">\n <ng-container *ngTemplateOutlet=\"statusBarContainer\"></ng-container>\n <ng-container *ngTemplateOutlet=\"filterChips\"></ng-container>\n </div>\n</ng-container>\n\n<ng-template #noKeywordFilter>\n <div class=\"filter-searchless-container\">\n <div class=\"status-actions\">\n <ng-container *ngTemplateOutlet=\"statusBarContainer\"></ng-container>\n <ng-container *ngTemplateOutlet=\"filterChips\"></ng-container>\n </div>\n <ng-container *ngTemplateOutlet=\"filterActions\"></ng-container>\n </div>\n</ng-template>\n\n\n<ng-template #filterActions>\n <div class=\"filter-actions\">\n <ng-container *ngIf=\"hasVisibleItemOrSorting && filtersBtnVisible$ | async\">\n <button\n mat-button\n class=\"filters-button\"\n [ngClass]=\"{\n 'mat-raised-button': config.button.style == 'raised',\n 'mat-button': config.button.style == 'basic',\n 'mat-icon-button': config.button.style == 'icon'\n }\"\n (click)=\"changeVisibilityClick(!showFilterMenu, $event)\"\n type=\"button\"\n [color]=\"config.button.color\">\n <mat-icon *ngIf=\"config.button.icon\">{{config.button.icon}}</mat-icon>\n {{ config.button.label }}\n </button>\n </ng-container>\n\n <fs-filter-actions\n *ngIf=\"actionsVisible$ | async\"\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n</ng-template>\n\n<ng-template #filterChips>\n <fs-filter-chips\n *ngIf=\"config.chips && hasFilterChips$ | async\"\n class=\"filter-chips\"\n [filters]=\"items\">\n </fs-filter-chips>\n</ng-template>\n\n<ng-template #statusBarContainer>\n <div class=\"status-bar\" *ngIf=\"statusBar\">\n <small><ng-container *ngTemplateOutlet=\"statusBar\"></ng-container></small>\n </div>\n</ng-template>\n",
3803
3863
  encapsulation: ViewEncapsulation.None,
3804
3864
  providers: [
3805
3865
  FsFilterOverlayService,
@@ -4137,17 +4197,28 @@ var TextComponent = /** @class */ (function (_super) {
4137
4197
  return _this;
4138
4198
  }
4139
4199
  TextComponent.prototype.ngOnInit = function () {
4200
+ this._listenControlValueChanges();
4201
+ this._listenModelChanges();
4202
+ };
4203
+ TextComponent.prototype.ngOnDestroy = function () {
4204
+ this.destroy$.next();
4205
+ this.destroy$.complete();
4206
+ };
4207
+ TextComponent.prototype._listenControlValueChanges = function () {
4140
4208
  var _this = this;
4141
- this.textControl.setValue(this.item.model);
4142
4209
  this.textControl.valueChanges
4143
4210
  .pipe(distinctUntilChanged(), debounceTime(200), takeUntil(this.destroy$))
4144
4211
  .subscribe(function (value) {
4145
4212
  _this.item.model = value;
4146
4213
  });
4147
4214
  };
4148
- TextComponent.prototype.ngOnDestroy = function () {
4149
- this.destroy$.next();
4150
- this.destroy$.complete();
4215
+ TextComponent.prototype._listenModelChanges = function () {
4216
+ var _this = this;
4217
+ this._item.value$
4218
+ .pipe(takeUntil(this.destroy$))
4219
+ .subscribe(function () {
4220
+ _this.textControl.setValue(_this.item.model, { emitEvent: false });
4221
+ });
4151
4222
  };
4152
4223
  TextComponent.ctorParameters = function () { return [
4153
4224
  { type: KeyValueDiffers },