@firestitch/filter 9.8.6 → 9.9.1

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.
@@ -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';
@@ -68,8 +68,9 @@ function findValue(values, value, children) {
68
68
  var BaseItem = /** @class */ (function () {
69
69
  function BaseItem(itemConfig, _additionalConfig) {
70
70
  this._additionalConfig = _additionalConfig;
71
- this._initialized = false;
71
+ // protected _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;
@@ -259,6 +267,13 @@ var BaseItem = /** @class */ (function () {
259
267
  enumerable: true,
260
268
  configurable: true
261
269
  });
270
+ Object.defineProperty(BaseItem.prototype, "_initialized", {
271
+ get: function () {
272
+ return !this._pendingDefaultValue && !this._pendingValues;
273
+ },
274
+ enumerable: true,
275
+ configurable: true
276
+ });
262
277
  BaseItem.prototype.valueChanged = function () {
263
278
  this._value$.next(this.value);
264
279
  if (this.change) {
@@ -291,8 +306,18 @@ var BaseItem = /** @class */ (function () {
291
306
  enumerable: true,
292
307
  configurable: true
293
308
  });
309
+ BaseItem.prototype.loadDefaultValue = function () {
310
+ var _this = this;
311
+ return this.defaultValueFn()
312
+ .pipe(tap(function (value) {
313
+ _this.defaultValue = value;
314
+ _this._initDefaultModel();
315
+ }), finalize(function () {
316
+ _this._pendingDefaultValue = false;
317
+ }));
318
+ };
294
319
  BaseItem.prototype.initValues = function (persistedValue) {
295
- this._initialized = false;
320
+ // this._initialized = false;
296
321
  this.persistedValue = persistedValue;
297
322
  this._initDefaultModel();
298
323
  var isAutocomplete = this.type === ItemType.AutoComplete || this.type === ItemType.AutoCompleteChips;
@@ -305,12 +330,12 @@ var BaseItem = /** @class */ (function () {
305
330
  this.values = valuesResult;
306
331
  // Move to some other place
307
332
  this._init();
308
- this._initialized = true;
333
+ // this._initialized = true;
309
334
  }
310
335
  }
311
336
  else {
312
337
  this._init();
313
- this._initialized = true;
338
+ // this._initialized = true;
314
339
  }
315
340
  };
316
341
  BaseItem.prototype.loadAsyncValues = function (reload) {
@@ -326,7 +351,7 @@ var BaseItem = /** @class */ (function () {
326
351
  _this.loading = false;
327
352
  _this._init();
328
353
  _this._validateModel();
329
- _this._initialized = true;
354
+ // this._initialized = true;
330
355
  });
331
356
  }
332
357
  };
@@ -354,7 +379,13 @@ var BaseItem = /** @class */ (function () {
354
379
  this.name = item.name;
355
380
  this.label = item.label;
356
381
  this.chipLabel = item.chipLabel;
357
- this.defaultValue = item.default;
382
+ if (typeof item.default === 'function') {
383
+ this._pendingDefaultValue = true;
384
+ this.defaultValueFn = item.default;
385
+ }
386
+ else {
387
+ this.defaultValue = item.default;
388
+ }
358
389
  this.change = item.change;
359
390
  this.hide = item.hide;
360
391
  this.clearAllowed = (_a = item.clear) !== null && _a !== void 0 ? _a : true;
@@ -1538,12 +1569,15 @@ var FsFilterItemsStore = /** @class */ (function () {
1538
1569
  this.sortByItem = null;
1539
1570
  this.sortDirectionItem = null;
1540
1571
  this.keywordItem = null;
1572
+ this._ready$ = new BehaviorSubject(false);
1541
1573
  this._items = [];
1542
1574
  this._visibleItems$ = new BehaviorSubject([]);
1543
1575
  this._itemsByName = new Map();
1544
1576
  this._itemsValuesLoaded = false;
1545
1577
  this._hasKeyword = false;
1546
1578
  this._itemsChange$ = new Subject();
1579
+ this._destroy$ = new Subject();
1580
+ this._lazyInit();
1547
1581
  }
1548
1582
  Object.defineProperty(FsFilterItemsStore.prototype, "items", {
1549
1583
  get: function () {
@@ -1583,8 +1617,17 @@ var FsFilterItemsStore = /** @class */ (function () {
1583
1617
  enumerable: true,
1584
1618
  configurable: true
1585
1619
  });
1620
+ Object.defineProperty(FsFilterItemsStore.prototype, "ready$", {
1621
+ get: function () {
1622
+ return this._ready$.asObservable();
1623
+ },
1624
+ enumerable: true,
1625
+ configurable: true
1626
+ });
1586
1627
  FsFilterItemsStore.prototype.ngOnDestroy = function () {
1587
1628
  this.destroyItems();
1629
+ this._destroy$.next();
1630
+ this._destroy$.complete();
1588
1631
  };
1589
1632
  FsFilterItemsStore.prototype.setConfig = function (config) {
1590
1633
  this._itemsByName.clear();
@@ -1598,8 +1641,6 @@ var FsFilterItemsStore = /** @class */ (function () {
1598
1641
  this._itemsValuesLoaded = false;
1599
1642
  if (Array.isArray(items)) {
1600
1643
  this._createItems(items);
1601
- this.updateVisibleItems();
1602
- this._setKeywordItem();
1603
1644
  }
1604
1645
  };
1605
1646
  FsFilterItemsStore.prototype.filtersClear = function () {
@@ -1638,6 +1679,25 @@ var FsFilterItemsStore = /** @class */ (function () {
1638
1679
  .filter(function (item) { return item.hasPendingValues; })
1639
1680
  .forEach(function (item) { return item.loadAsyncValues(); });
1640
1681
  };
1682
+ FsFilterItemsStore.prototype.loadAsyncDefaults = function () {
1683
+ var _this = this;
1684
+ var pendingItems = this.items
1685
+ .filter(function (item) {
1686
+ return item.hasPendingDefaultValue
1687
+ && (item.persistedValue === null || item.persistedValue === undefined);
1688
+ });
1689
+ if (pendingItems.length > 0) {
1690
+ forkJoin(pendingItems
1691
+ .map(function (item) { return item.loadDefaultValue(); }))
1692
+ .pipe(finalize(function () {
1693
+ _this._ready$.next(true);
1694
+ }), takeUntil(this._destroy$))
1695
+ .subscribe();
1696
+ }
1697
+ else {
1698
+ this._ready$.next(true);
1699
+ }
1700
+ };
1641
1701
  FsFilterItemsStore.prototype.getSort = function () {
1642
1702
  var sortBy = this.getSortByValue();
1643
1703
  sortBy = sortBy === '__all' ? null : sortBy;
@@ -1694,6 +1754,7 @@ var FsFilterItemsStore = /** @class */ (function () {
1694
1754
  item.initValues(p[item.name]);
1695
1755
  });
1696
1756
  this._createSortingItems(p);
1757
+ this.loadAsyncDefaults();
1697
1758
  this._subscribeToItemsChanges();
1698
1759
  };
1699
1760
  FsFilterItemsStore.prototype.updateItemsWithValues = function (values) {
@@ -1782,6 +1843,15 @@ var FsFilterItemsStore = /** @class */ (function () {
1782
1843
  });
1783
1844
  }
1784
1845
  };
1846
+ FsFilterItemsStore.prototype._lazyInit = function () {
1847
+ var _this = this;
1848
+ this.ready$
1849
+ .pipe(filter$1(function (state) { return state; }), takeUntil(this._destroy$))
1850
+ .subscribe(function () {
1851
+ _this.updateVisibleItems();
1852
+ _this._setKeywordItem();
1853
+ });
1854
+ };
1785
1855
  FsFilterItemsStore.prototype._createSortingItems = function (p) {
1786
1856
  var _a;
1787
1857
  if (((_a = this._config.sortValues) === null || _a === void 0 ? void 0 : _a.length) > 0) {
@@ -3239,6 +3309,13 @@ var FilterComponent = /** @class */ (function () {
3239
3309
  enumerable: true,
3240
3310
  configurable: true
3241
3311
  });
3312
+ Object.defineProperty(FilterComponent.prototype, "itemsReady$", {
3313
+ get: function () {
3314
+ return this._filterItems.ready$;
3315
+ },
3316
+ enumerable: true,
3317
+ configurable: true
3318
+ });
3242
3319
  Object.defineProperty(FilterComponent.prototype, "hasFilterChips$", {
3243
3320
  get: function () {
3244
3321
  return this._hasFilterChips$.asObservable();
@@ -3303,21 +3380,6 @@ var FilterComponent = /** @class */ (function () {
3303
3380
  _this.focus();
3304
3381
  }
3305
3382
  });
3306
- if (this.config.init) {
3307
- if (this._externalParams.pending) {
3308
- this._externalParams
3309
- .pending$
3310
- .pipe(filter$1(function (pending) {
3311
- return !pending;
3312
- }), takeUntil(this._destroy$))
3313
- .subscribe(function () {
3314
- _this.init();
3315
- });
3316
- }
3317
- else {
3318
- this.init();
3319
- }
3320
- }
3321
3383
  this._listenInternalItemsChange();
3322
3384
  this._initOverlay();
3323
3385
  };
@@ -3718,10 +3780,18 @@ var FilterComponent = /** @class */ (function () {
3718
3780
  // We may need some time to recieve external params and after that ready can be emitted
3719
3781
  FilterComponent.prototype._listenWhenFilterReady = function () {
3720
3782
  var _this = this;
3721
- this._externalParams
3722
- .pending$
3723
- .pipe(filter$1(function (value) { return !value; }), takeUntil(this._destroy$))
3783
+ combineLatest([
3784
+ this._externalParams.pending$,
3785
+ this.itemsReady$,
3786
+ ])
3787
+ .pipe(filter$1(function (_a) {
3788
+ var _b = __read(_a, 2), pendingParams = _b[0], itemsReady = _b[1];
3789
+ return !pendingParams && itemsReady;
3790
+ }), takeUntil(this._destroy$))
3724
3791
  .subscribe(function () {
3792
+ if (_this.config.init) {
3793
+ _this.init();
3794
+ }
3725
3795
  _this.ready.emit();
3726
3796
  });
3727
3797
  };
@@ -3797,7 +3867,7 @@ var FilterComponent = /** @class */ (function () {
3797
3867
  FilterComponent = __decorate([
3798
3868
  Component({
3799
3869
  selector: 'fs-filter',
3800
- 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",
3870
+ 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",
3801
3871
  encapsulation: ViewEncapsulation.None,
3802
3872
  providers: [
3803
3873
  FsFilterOverlayService,