@firestitch/filter 9.8.8 → 9.9.4

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,19 @@ var BaseItem = /** @class */ (function () {
291
306
  enumerable: true,
292
307
  configurable: true
293
308
  });
309
+ BaseItem.prototype.loadDefaultValue = function () {
310
+ var _this = this;
311
+ this._pendingDefaultValue = true;
312
+ return this.defaultValueFn()
313
+ .pipe(tap(function (value) {
314
+ _this.defaultValue = value;
315
+ _this._initDefaultModel();
316
+ }), finalize(function () {
317
+ _this._pendingDefaultValue = false;
318
+ }));
319
+ };
294
320
  BaseItem.prototype.initValues = function (persistedValue) {
295
- this._initialized = false;
321
+ // this._initialized = false;
296
322
  this.persistedValue = persistedValue;
297
323
  this._initDefaultModel();
298
324
  var isAutocomplete = this.type === ItemType.AutoComplete || this.type === ItemType.AutoCompleteChips;
@@ -305,12 +331,12 @@ var BaseItem = /** @class */ (function () {
305
331
  this.values = valuesResult;
306
332
  // Move to some other place
307
333
  this._init();
308
- this._initialized = true;
334
+ // this._initialized = true;
309
335
  }
310
336
  }
311
337
  else {
312
338
  this._init();
313
- this._initialized = true;
339
+ // this._initialized = true;
314
340
  }
315
341
  };
316
342
  BaseItem.prototype.loadAsyncValues = function (reload) {
@@ -326,7 +352,7 @@ var BaseItem = /** @class */ (function () {
326
352
  _this.loading = false;
327
353
  _this._init();
328
354
  _this._validateModel();
329
- _this._initialized = true;
355
+ // this._initialized = true;
330
356
  });
331
357
  }
332
358
  };
@@ -354,7 +380,12 @@ var BaseItem = /** @class */ (function () {
354
380
  this.name = item.name;
355
381
  this.label = item.label;
356
382
  this.chipLabel = item.chipLabel;
357
- this.defaultValue = item.default;
383
+ if (typeof item.default === 'function') {
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.defaultValueFn
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) {
@@ -2436,6 +2506,12 @@ var ExternalParamsController = /** @class */ (function () {
2436
2506
  };
2437
2507
  ExternalParamsController.prototype._listenItemsChange = function () {
2438
2508
  var _this = this;
2509
+ this._itemsStore.ready$
2510
+ .pipe(filter$1(function (v) { return v; }), take(1), takeUntil(this._destroy$))
2511
+ .subscribe(function () {
2512
+ _this._saveQueryParams();
2513
+ _this._savePersistedParams();
2514
+ });
2439
2515
  this._itemsStore
2440
2516
  .itemsChange$
2441
2517
  .pipe(takeUntil(this._destroy$))
@@ -3239,6 +3315,13 @@ var FilterComponent = /** @class */ (function () {
3239
3315
  enumerable: true,
3240
3316
  configurable: true
3241
3317
  });
3318
+ Object.defineProperty(FilterComponent.prototype, "itemsReady$", {
3319
+ get: function () {
3320
+ return this._filterItems.ready$;
3321
+ },
3322
+ enumerable: true,
3323
+ configurable: true
3324
+ });
3242
3325
  Object.defineProperty(FilterComponent.prototype, "hasFilterChips$", {
3243
3326
  get: function () {
3244
3327
  return this._hasFilterChips$.asObservable();
@@ -3303,21 +3386,6 @@ var FilterComponent = /** @class */ (function () {
3303
3386
  _this.focus();
3304
3387
  }
3305
3388
  });
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
3389
  this._listenInternalItemsChange();
3322
3390
  this._initOverlay();
3323
3391
  };
@@ -3718,10 +3786,18 @@ var FilterComponent = /** @class */ (function () {
3718
3786
  // We may need some time to recieve external params and after that ready can be emitted
3719
3787
  FilterComponent.prototype._listenWhenFilterReady = function () {
3720
3788
  var _this = this;
3721
- this._externalParams
3722
- .pending$
3723
- .pipe(filter$1(function (value) { return !value; }), takeUntil(this._destroy$))
3789
+ combineLatest([
3790
+ this._externalParams.pending$,
3791
+ this.itemsReady$,
3792
+ ])
3793
+ .pipe(filter$1(function (_a) {
3794
+ var _b = __read(_a, 2), pendingParams = _b[0], itemsReady = _b[1];
3795
+ return !pendingParams && itemsReady;
3796
+ }), takeUntil(this._destroy$))
3724
3797
  .subscribe(function () {
3798
+ if (_this.config.init) {
3799
+ _this.init();
3800
+ }
3725
3801
  _this.ready.emit();
3726
3802
  });
3727
3803
  };
@@ -3797,7 +3873,7 @@ var FilterComponent = /** @class */ (function () {
3797
3873
  FilterComponent = __decorate([
3798
3874
  Component({
3799
3875
  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 #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",
3876
+ 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
3877
  encapsulation: ViewEncapsulation.None,
3802
3878
  providers: [
3803
3879
  FsFilterOverlayService,