@firestitch/filter 9.8.8 → 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.
@@ -45,6 +45,7 @@ export declare class FilterComponent implements OnInit, AfterViewInit, OnDestroy
45
45
  get filterParamsQuery(): Record<string, unknown>;
46
46
  get items(): BaseItem<import("../../interfaces/config.interface").IFilterConfigItem>[];
47
47
  get visibleItems(): BaseItem<import("../../interfaces/config.interface").IFilterConfigItem>[];
48
+ get itemsReady$(): Observable<boolean>;
48
49
  get hasFilterChips$(): Observable<boolean>;
49
50
  get hasVisibleItemOrSorting(): boolean;
50
51
  get hasKeyword(): boolean;
@@ -1,7 +1,9 @@
1
+ import { Observable } from 'rxjs';
1
2
  import { ItemType } from '../../enums/item-type.enum';
2
3
  import { BaseItem } from '../../models/items/base-item';
3
4
  export declare type FilterConfigDateType = ItemType.Date | ItemType.DateTime | ItemType.DateRange | ItemType.DateTimeRange;
4
5
  export declare type FilterDateRangeType = ItemType.DateRange | ItemType.DateTimeRange;
6
+ export declare type IFilterDefaultFn = () => Observable<unknown>;
5
7
  export interface IFilterConfigBaseItem<T = ItemType, U = string> {
6
8
  name: string;
7
9
  type: T;
@@ -11,7 +13,7 @@ export interface IFilterConfigBaseItem<T = ItemType, U = string> {
11
13
  disable?: boolean;
12
14
  values?: any;
13
15
  primary?: boolean;
14
- default?: unknown;
16
+ default?: IFilterDefaultFn | any;
15
17
  change?: (item: BaseItem<any>) => void;
16
18
  clear?: boolean;
17
19
  disablePersist?: boolean;
@@ -1,5 +1,5 @@
1
1
  import { BehaviorSubject, Observable, Subject } from 'rxjs';
2
- import { IFilterConfigBaseItem } from '../../interfaces/items/base.interface';
2
+ import { IFilterConfigBaseItem, IFilterDefaultFn } from '../../interfaces/items/base.interface';
3
3
  import { IFilterItemDefaultRange } from '../../interfaces/items/range.interface';
4
4
  export declare abstract class BaseItem<T extends IFilterConfigBaseItem> {
5
5
  protected _additionalConfig: unknown;
@@ -8,6 +8,7 @@ export declare abstract class BaseItem<T extends IFilterConfigBaseItem> {
8
8
  chipLabel: string | string[];
9
9
  hide: boolean;
10
10
  defaultValue: any | IFilterItemDefaultRange;
11
+ defaultValueFn: IFilterDefaultFn;
11
12
  persistedValue: unknown;
12
13
  clearAllowed: boolean;
13
14
  persistanceDisabled: boolean;
@@ -17,6 +18,7 @@ export declare abstract class BaseItem<T extends IFilterConfigBaseItem> {
17
18
  protected _model: any;
18
19
  protected _initialized: boolean;
19
20
  protected _pendingValues: boolean;
21
+ protected _pendingDefaultValue: boolean;
20
22
  protected _loading$: BehaviorSubject<boolean>;
21
23
  protected _value$: BehaviorSubject<any>;
22
24
  protected _valueChange$: Subject<void>;
@@ -41,6 +43,7 @@ export declare abstract class BaseItem<T extends IFilterConfigBaseItem> {
41
43
  get destroy$(): Observable<void>;
42
44
  get type(): T['type'];
43
45
  get hasPendingValues(): boolean;
46
+ get hasPendingDefaultValue(): boolean;
44
47
  get model(): any;
45
48
  set model(value: any);
46
49
  set values(values: any);
@@ -56,6 +59,7 @@ export declare abstract class BaseItem<T extends IFilterConfigBaseItem> {
56
59
  valueChanged(): void;
57
60
  get queryObject(): Record<string, unknown>;
58
61
  get persistanceObject(): Record<string, unknown>;
62
+ loadDefaultValue(): Observable<any>;
59
63
  initValues(persistedValue: unknown): void;
60
64
  loadAsyncValues(reload?: boolean): void;
61
65
  clear(defaultValue?: unknown): void;
@@ -15,6 +15,7 @@ export declare class FsFilterItemsStore implements OnDestroy {
15
15
  sortByItem: BaseItem<IFilterConfigItem>;
16
16
  sortDirectionItem: BaseItem<IFilterConfigItem>;
17
17
  keywordItem: TextItem;
18
+ private _ready$;
18
19
  private _items;
19
20
  private _visibleItems$;
20
21
  private _itemsByName;
@@ -22,6 +23,7 @@ export declare class FsFilterItemsStore implements OnDestroy {
22
23
  private _hasKeyword;
23
24
  private _config;
24
25
  private _itemsChange$;
26
+ private _destroy$;
25
27
  constructor();
26
28
  get items(): BaseItem<IFilterConfigItem>[];
27
29
  get visibleItems(): BaseItem<IFilterConfigItem>[];
@@ -29,12 +31,14 @@ export declare class FsFilterItemsStore implements OnDestroy {
29
31
  set visibleItems(items: BaseItem<IFilterConfigItem>[]);
30
32
  get hasKeyword(): boolean;
31
33
  get itemsChange$(): Observable<unknown>;
34
+ get ready$(): Observable<boolean>;
32
35
  ngOnDestroy(): void;
33
36
  setConfig(config: any): void;
34
37
  getItemByName(name: string): BaseItem<IFilterConfigBaseItem>;
35
38
  initItems(items: IFilterConfigItem[]): void;
36
39
  filtersClear(): void;
37
40
  loadAsyncValues(): void;
41
+ loadAsyncDefaults(): void;
38
42
  getSort(): FilterSort;
39
43
  getSortByValue(): any;
40
44
  getSortDirectionValue(): any;
@@ -51,6 +55,7 @@ export declare class FsFilterItemsStore implements OnDestroy {
51
55
  updateVisibleItems(): void;
52
56
  private _createItems;
53
57
  private _subscribeToItemsChanges;
58
+ private _lazyInit;
54
59
  private _createSortingItems;
55
60
  private _setKeywordItem;
56
61
  }
@@ -256,6 +256,7 @@
256
256
  this._additionalConfig = _additionalConfig;
257
257
  this._initialized = false;
258
258
  this._pendingValues = false;
259
+ this._pendingDefaultValue = false;
259
260
  this._loading$ = new rxjs.BehaviorSubject(false);
260
261
  this._value$ = new rxjs.BehaviorSubject(null);
261
262
  this._valueChange$ = new rxjs.Subject();
@@ -372,6 +373,13 @@
372
373
  enumerable: true,
373
374
  configurable: true
374
375
  });
376
+ Object.defineProperty(BaseItem.prototype, "hasPendingDefaultValue", {
377
+ get: function () {
378
+ return this._pendingDefaultValue;
379
+ },
380
+ enumerable: true,
381
+ configurable: true
382
+ });
375
383
  Object.defineProperty(BaseItem.prototype, "model", {
376
384
  get: function () {
377
385
  return this._model;
@@ -477,6 +485,15 @@
477
485
  enumerable: true,
478
486
  configurable: true
479
487
  });
488
+ BaseItem.prototype.loadDefaultValue = function () {
489
+ var _this = this;
490
+ return this.defaultValueFn()
491
+ .pipe(operators.tap(function (value) {
492
+ _this.defaultValue = value;
493
+ }), operators.finalize(function () {
494
+ _this._pendingDefaultValue = false;
495
+ }));
496
+ };
480
497
  BaseItem.prototype.initValues = function (persistedValue) {
481
498
  this._initialized = false;
482
499
  this.persistedValue = persistedValue;
@@ -540,7 +557,13 @@
540
557
  this.name = item.name;
541
558
  this.label = item.label;
542
559
  this.chipLabel = item.chipLabel;
543
- this.defaultValue = item.default;
560
+ if (typeof item.default === 'function') {
561
+ this._pendingDefaultValue = true;
562
+ this.defaultValueFn = item.default;
563
+ }
564
+ else {
565
+ this.defaultValue = item.default;
566
+ }
544
567
  this.change = item.change;
545
568
  this.hide = item.hide;
546
569
  this.clearAllowed = (_a = item.clear) !== null && _a !== void 0 ? _a : true;
@@ -1724,12 +1747,15 @@
1724
1747
  this.sortByItem = null;
1725
1748
  this.sortDirectionItem = null;
1726
1749
  this.keywordItem = null;
1750
+ this._ready$ = new rxjs.BehaviorSubject(false);
1727
1751
  this._items = [];
1728
1752
  this._visibleItems$ = new rxjs.BehaviorSubject([]);
1729
1753
  this._itemsByName = new Map();
1730
1754
  this._itemsValuesLoaded = false;
1731
1755
  this._hasKeyword = false;
1732
1756
  this._itemsChange$ = new rxjs.Subject();
1757
+ this._destroy$ = new rxjs.Subject();
1758
+ this._lazyInit();
1733
1759
  }
1734
1760
  Object.defineProperty(FsFilterItemsStore.prototype, "items", {
1735
1761
  get: function () {
@@ -1769,8 +1795,17 @@
1769
1795
  enumerable: true,
1770
1796
  configurable: true
1771
1797
  });
1798
+ Object.defineProperty(FsFilterItemsStore.prototype, "ready$", {
1799
+ get: function () {
1800
+ return this._ready$.asObservable();
1801
+ },
1802
+ enumerable: true,
1803
+ configurable: true
1804
+ });
1772
1805
  FsFilterItemsStore.prototype.ngOnDestroy = function () {
1773
1806
  this.destroyItems();
1807
+ this._destroy$.next();
1808
+ this._destroy$.complete();
1774
1809
  };
1775
1810
  FsFilterItemsStore.prototype.setConfig = function (config) {
1776
1811
  this._itemsByName.clear();
@@ -1784,8 +1819,6 @@
1784
1819
  this._itemsValuesLoaded = false;
1785
1820
  if (Array.isArray(items)) {
1786
1821
  this._createItems(items);
1787
- this.updateVisibleItems();
1788
- this._setKeywordItem();
1789
1822
  }
1790
1823
  };
1791
1824
  FsFilterItemsStore.prototype.filtersClear = function () {
@@ -1824,6 +1857,25 @@
1824
1857
  .filter(function (item) { return item.hasPendingValues; })
1825
1858
  .forEach(function (item) { return item.loadAsyncValues(); });
1826
1859
  };
1860
+ FsFilterItemsStore.prototype.loadAsyncDefaults = function () {
1861
+ var _this = this;
1862
+ var pendingItems = this.items
1863
+ .filter(function (item) {
1864
+ return item.hasPendingDefaultValue
1865
+ && (item.persistedValue === null || item.persistedValue === undefined);
1866
+ });
1867
+ if (pendingItems.length > 0) {
1868
+ rxjs.forkJoin(pendingItems
1869
+ .map(function (item) { return item.loadDefaultValue(); }))
1870
+ .pipe(operators.finalize(function () {
1871
+ _this._ready$.next(true);
1872
+ }), operators.takeUntil(this._destroy$))
1873
+ .subscribe();
1874
+ }
1875
+ else {
1876
+ this._ready$.next(true);
1877
+ }
1878
+ };
1827
1879
  FsFilterItemsStore.prototype.getSort = function () {
1828
1880
  var sortBy = this.getSortByValue();
1829
1881
  sortBy = sortBy === '__all' ? null : sortBy;
@@ -1880,6 +1932,7 @@
1880
1932
  item.initValues(p[item.name]);
1881
1933
  });
1882
1934
  this._createSortingItems(p);
1935
+ this.loadAsyncDefaults();
1883
1936
  this._subscribeToItemsChanges();
1884
1937
  };
1885
1938
  FsFilterItemsStore.prototype.updateItemsWithValues = function (values) {
@@ -1968,6 +2021,15 @@
1968
2021
  });
1969
2022
  }
1970
2023
  };
2024
+ FsFilterItemsStore.prototype._lazyInit = function () {
2025
+ var _this = this;
2026
+ this.ready$
2027
+ .pipe(operators.filter(function (state) { return state; }), operators.takeUntil(this._destroy$))
2028
+ .subscribe(function () {
2029
+ _this.updateVisibleItems();
2030
+ _this._setKeywordItem();
2031
+ });
2032
+ };
1971
2033
  FsFilterItemsStore.prototype._createSortingItems = function (p) {
1972
2034
  var _a;
1973
2035
  if (((_a = this._config.sortValues) === null || _a === void 0 ? void 0 : _a.length) > 0) {
@@ -3425,6 +3487,13 @@
3425
3487
  enumerable: true,
3426
3488
  configurable: true
3427
3489
  });
3490
+ Object.defineProperty(FilterComponent.prototype, "itemsReady$", {
3491
+ get: function () {
3492
+ return this._filterItems.ready$;
3493
+ },
3494
+ enumerable: true,
3495
+ configurable: true
3496
+ });
3428
3497
  Object.defineProperty(FilterComponent.prototype, "hasFilterChips$", {
3429
3498
  get: function () {
3430
3499
  return this._hasFilterChips$.asObservable();
@@ -3489,21 +3558,6 @@
3489
3558
  _this.focus();
3490
3559
  }
3491
3560
  });
3492
- if (this.config.init) {
3493
- if (this._externalParams.pending) {
3494
- this._externalParams
3495
- .pending$
3496
- .pipe(operators.filter(function (pending) {
3497
- return !pending;
3498
- }), operators.takeUntil(this._destroy$))
3499
- .subscribe(function () {
3500
- _this.init();
3501
- });
3502
- }
3503
- else {
3504
- this.init();
3505
- }
3506
- }
3507
3561
  this._listenInternalItemsChange();
3508
3562
  this._initOverlay();
3509
3563
  };
@@ -3904,10 +3958,18 @@
3904
3958
  // We may need some time to recieve external params and after that ready can be emitted
3905
3959
  FilterComponent.prototype._listenWhenFilterReady = function () {
3906
3960
  var _this = this;
3907
- this._externalParams
3908
- .pending$
3909
- .pipe(operators.filter(function (value) { return !value; }), operators.takeUntil(this._destroy$))
3961
+ rxjs.combineLatest([
3962
+ this._externalParams.pending$,
3963
+ this.itemsReady$,
3964
+ ])
3965
+ .pipe(operators.filter(function (_a) {
3966
+ var _b = __read(_a, 2), pendingParams = _b[0], itemsReady = _b[1];
3967
+ return !pendingParams && itemsReady;
3968
+ }), operators.takeUntil(this._destroy$))
3910
3969
  .subscribe(function () {
3970
+ if (_this.config.init) {
3971
+ _this.init();
3972
+ }
3911
3973
  _this.ready.emit();
3912
3974
  });
3913
3975
  };
@@ -3983,7 +4045,7 @@
3983
4045
  FilterComponent = __decorate([
3984
4046
  core.Component({
3985
4047
  selector: 'fs-filter',
3986
- 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",
4048
+ 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",
3987
4049
  encapsulation: core.ViewEncapsulation.None,
3988
4050
  providers: [
3989
4051
  FsFilterOverlayService,