@firestitch/filter 18.2.9 → 18.2.11

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 * as i0 from '@angular/core';
2
- import { Injectable, inject, Component, ChangeDetectionStrategy, Input, ChangeDetectorRef, HostBinding, EventEmitter, Output, InjectionToken, Injector, Directive, Optional, Self, Pipe, ViewChild, DestroyRef, HostListener, NgZone, ElementRef, ContentChild, NgModule } from '@angular/core';
2
+ import { Injectable, inject, Component, ChangeDetectionStrategy, Input, ChangeDetectorRef, HostBinding, EventEmitter, Output, InjectionToken, Injector, Directive, Optional, Self, DestroyRef, NgZone, ElementRef, ContentChild, ViewChild, Pipe, HostListener, NgModule } from '@angular/core';
3
3
  import { FsPrompt } from '@firestitch/prompt';
4
- import { BehaviorSubject, Subject, isObservable, forkJoin, of, timer, combineLatest, tap as tap$1, fromEvent, merge, switchMap as switchMap$1, map as map$1, interval } from 'rxjs';
5
- import { tap, finalize, take, takeUntil, debounceTime, filter as filter$1, distinctUntilChanged, switchMap, mapTo, startWith, map, delay, skip } from 'rxjs/operators';
4
+ import { BehaviorSubject, Subject, isObservable, forkJoin, of, timer, combineLatest, tap as tap$1, switchMap as switchMap$1, map as map$1, fromEvent, interval, merge } from 'rxjs';
5
+ import { map, tap, finalize, take, takeUntil, debounceTime, distinctUntilChanged, switchMap, filter as filter$1, mapTo, startWith, delay, skip } from 'rxjs/operators';
6
6
  import { isFunction, clone, toString, isObject, isString, pickBy } from 'lodash-es';
7
7
  import { isEmpty, filter, isArrayEqual, list, getNormalizedPath, remove } from '@firestitch/common';
8
8
  import { simpleFormat, format } from '@firestitch/date';
@@ -31,9 +31,9 @@ import { FsFileModule } from '@firestitch/file';
31
31
  import * as i2$2 from '@firestitch/chip';
32
32
  import { FsChipModule } from '@firestitch/chip';
33
33
  import { FsMessage } from '@firestitch/message';
34
- import { MatFormField, MatLabel, MatPrefix, MatSuffix, MatHint } from '@angular/material/form-field';
34
+ import { MatFormField, MatPrefix, MatLabel, MatSuffix, MatHint } from '@angular/material/form-field';
35
35
  import { MatInput } from '@angular/material/input';
36
- import * as i3$2 from '@firestitch/skeleton';
36
+ import * as i3$3 from '@firestitch/skeleton';
37
37
  import { FsSkeletonModule } from '@firestitch/skeleton';
38
38
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
39
39
  import { Overlay, OverlayConfig } from '@angular/cdk/overlay';
@@ -44,17 +44,17 @@ import * as i4 from '@firestitch/autocomplete';
44
44
  import { FsAutocompleteModule } from '@firestitch/autocomplete';
45
45
  import * as i1$3 from '@firestitch/autocomplete-chips';
46
46
  import { FsAutocompleteChipsModule } from '@firestitch/autocomplete-chips';
47
- import { MatCheckbox } from '@angular/material/checkbox';
48
- import * as i1$4 from '@firestitch/label';
49
- import { FsLabelModule } from '@firestitch/label';
50
47
  import { DomSanitizer } from '@angular/platform-browser';
51
- import * as i1$6 from '@angular/material/dialog';
48
+ import * as i1$5 from '@angular/material/dialog';
52
49
  import { MatDialogRef, MatDialogModule, MatDialog } from '@angular/material/dialog';
53
50
  import { MatSlideToggle } from '@angular/material/slide-toggle';
54
- import * as i3$3 from '@firestitch/clear';
51
+ import * as i3$2 from '@firestitch/clear';
55
52
  import { FsClearModule } from '@firestitch/clear';
56
53
  import { DrawerRef } from '@firestitch/drawer';
57
- import * as i1$5 from '@angular/cdk/layout';
54
+ import * as i1$4 from '@angular/cdk/layout';
55
+ import * as i1$6 from '@firestitch/label';
56
+ import { FsLabelModule } from '@firestitch/label';
57
+ import { MatCheckbox } from '@angular/material/checkbox';
58
58
 
59
59
  var ItemType;
60
60
  (function (ItemType) {
@@ -79,7 +79,6 @@ class BaseItem {
79
79
  name;
80
80
  label;
81
81
  chipLabel;
82
- hide;
83
82
  defaultValue;
84
83
  defaultValueFn;
85
84
  persistedValue;
@@ -94,6 +93,7 @@ class BaseItem {
94
93
  _pendingDefaultValue = false;
95
94
  _initializedValues = false;
96
95
  _valuesFn;
96
+ _hidden$ = new BehaviorSubject(false);
97
97
  _loading$ = new BehaviorSubject(false);
98
98
  _value$ = new BehaviorSubject(null);
99
99
  _valueChange$ = new Subject();
@@ -109,6 +109,16 @@ class BaseItem {
109
109
  get filter() {
110
110
  return this._filter;
111
111
  }
112
+ get hidden$() {
113
+ return this._hidden$.asObservable();
114
+ }
115
+ get visible$() {
116
+ return this._hidden$
117
+ .pipe(map((hidden) => !hidden));
118
+ }
119
+ get hidden() {
120
+ return this._hidden$.getValue();
121
+ }
112
122
  get isTypeAutocomplete() {
113
123
  return this.type === ItemType.AutoComplete;
114
124
  }
@@ -200,6 +210,12 @@ class BaseItem {
200
210
  get isQueryParamVisible() {
201
211
  return true;
202
212
  }
213
+ hide() {
214
+ this._hidden$.next(true);
215
+ }
216
+ show() {
217
+ this._hidden$.next(false);
218
+ }
203
219
  get queryObject() {
204
220
  const value = this.value;
205
221
  const name = this.name;
@@ -304,6 +320,11 @@ class BaseItem {
304
320
  this.name = item.name;
305
321
  this.label = item.label;
306
322
  this.chipLabel = item.chipLabel;
323
+ this.change = item.change;
324
+ this._hidden$.next(item.hide ?? false);
325
+ this.showClear = item.clear ?? true;
326
+ this.persistanceDisabled = item.disablePersist ?? false;
327
+ this.queryParamsDisabled = item.disableQueryParams ?? false;
307
328
  if (typeof item.default === 'function') {
308
329
  this.defaultValueFn = item.default;
309
330
  }
@@ -313,11 +334,6 @@ class BaseItem {
313
334
  this.init = item.init || (() => {
314
335
  //
315
336
  });
316
- this.change = item.change;
317
- this.hide = item.hide;
318
- this.showClear = item.clear ?? true;
319
- this.persistanceDisabled = item.disablePersist ?? false;
320
- this.queryParamsDisabled = item.disableQueryParams ?? false;
321
337
  if (isFunction(item.values)) {
322
338
  this._valuesFn = item.values;
323
339
  }
@@ -1495,24 +1511,12 @@ class ItemStore {
1495
1511
  _config;
1496
1512
  _itemsChange$ = new Subject();
1497
1513
  _destroy$ = new Subject();
1498
- constructor() {
1499
- this._lazyInit();
1500
- }
1501
1514
  get items() {
1502
1515
  return Array.from(this._items.values());
1503
1516
  }
1504
1517
  get itemNames() {
1505
1518
  return this.items.map((item) => item.name);
1506
1519
  }
1507
- get visibleItems() {
1508
- return this._visibleItems$.getValue();
1509
- }
1510
- set visibleItems(items) {
1511
- this._visibleItems$.next(items);
1512
- }
1513
- get visibleItems$() {
1514
- return this._visibleItems$.asObservable();
1515
- }
1516
1520
  get hasKeyword() {
1517
1521
  return this._hasKeyword;
1518
1522
  }
@@ -1728,10 +1732,6 @@ class ItemStore {
1728
1732
  this.loadAsyncValues();
1729
1733
  }
1730
1734
  }
1731
- updateItemsVisiblity() {
1732
- this.visibleItems = this.items
1733
- .filter((item) => !item.isTypeKeyword && !item.hide);
1734
- }
1735
1735
  _createItems(items) {
1736
1736
  this._items = new Map(items
1737
1737
  .filter((item) => !item.disable)
@@ -1773,13 +1773,6 @@ class ItemStore {
1773
1773
  });
1774
1774
  }
1775
1775
  }
1776
- _lazyInit() {
1777
- this.ready$
1778
- .pipe(filter$1((state) => state), takeUntil(this._destroy$))
1779
- .subscribe(() => {
1780
- this.updateItemsVisiblity();
1781
- });
1782
- }
1783
1776
  _initSortingItems(p) {
1784
1777
  if (this.sortByItem && this.sortDirectionItem) {
1785
1778
  this.sortByItem.initValues(p[this.sortByItem.name]);
@@ -1823,7 +1816,7 @@ class ItemStore {
1823
1816
  }
1824
1817
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ItemStore, decorators: [{
1825
1818
  type: Injectable
1826
- }], ctorParameters: () => [] });
1819
+ }] });
1827
1820
 
1828
1821
  class SavedFilterController {
1829
1822
  _config;
@@ -2607,6 +2600,9 @@ class FsFilterOverlayService {
2607
2600
  this._removeFilterClass();
2608
2601
  }
2609
2602
  }
2603
+ opened() {
2604
+ return !!this._overlayRef;
2605
+ }
2610
2606
  open() {
2611
2607
  if (this._overlayRef) {
2612
2608
  return;
@@ -3257,1608 +3253,1599 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3257
3253
  args: ['focusTargetType']
3258
3254
  }] } });
3259
3255
 
3260
- class TextComponent extends BaseItemComponent {
3256
+ class AutocompleteComponent extends BaseItemComponent {
3261
3257
  _kvDiffers;
3262
3258
  _cd;
3263
- textControl = new UntypedFormControl();
3264
3259
  constructor(_kvDiffers, _cd) {
3265
3260
  super(_kvDiffers, _cd);
3266
3261
  this._kvDiffers = _kvDiffers;
3267
3262
  this._cd = _cd;
3268
3263
  }
3269
- ngOnInit() {
3270
- this._listenControlValueChanges();
3271
- this._listenModelChanges();
3272
- }
3273
- _listenControlValueChanges() {
3274
- this.textControl.valueChanges
3275
- .pipe(distinctUntilChanged(), debounceTime(200), takeUntil(this.destroy$))
3276
- .subscribe((value) => {
3277
- this.item.model = value;
3278
- });
3279
- }
3280
- _listenModelChanges() {
3281
- this._item.value$
3282
- .pipe(takeUntil(this.destroy$))
3283
- .subscribe(() => {
3284
- this.textControl.setValue(this.item.model, { emitEvent: false });
3285
- });
3286
- }
3287
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3288
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: TextComponent, isStandalone: true, selector: "filter-item-text", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [formControl]=\"textControl\"\n [fsFilterFocusTrigger]=\"item\">\n @if (item.suffix) {\n <span\n matSuffix\n [innerHtml]=\"item.suffix\">\n </span>\n }\n</mat-form-field>", styles: [""], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3264
+ displayWith = (data) => {
3265
+ return data ? data.name : data;
3266
+ };
3267
+ fetch = (keyword) => {
3268
+ return this.item.valuesFn(keyword, this.item.filter);
3269
+ };
3270
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompleteComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3271
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AutocompleteComponent, isStandalone: true, selector: "filter-item-autocomplete", usesInheritance: true, ngImport: i0, template: "<fs-autocomplete\n [fsFilterFocusTrigger]=\"item\"\n [fetch]=\"fetch\"\n [displayWith]=\"displayWith\"\n [(ngModel)]=\"item.model\"\n [placeholder]=\"label\"\n [fetchOnFocus]=\"item.fetchOnFocus\"\n [showClear]=\"item.showClear\"\n name=\"item.name\">\n <ng-template fsAutocompleteTemplate let-data=\"data\">\n {{data.name}}\n </ng-template>\n</fs-autocomplete>\n", dependencies: [{ kind: "ngmodule", type: FsAutocompleteModule }, { kind: "component", type: i4.FsAutocompleteComponent, selector: "fs-autocomplete", inputs: ["fetch", "displayWith", "placeholder", "fetchOnFocus", "readonly", "required", "disabled", "formFieldClass", "appearance", "hint", "panelWidth", "panelClass", "showClear"], outputs: ["cleared", "opened", "closed"] }, { kind: "directive", type: i4.FsAutocompleteTemplateDirective, selector: "[fsAutocompleteTemplate]" }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3289
3272
  }
3290
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextComponent, decorators: [{
3273
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompleteComponent, decorators: [{
3291
3274
  type: Component,
3292
- args: [{ selector: 'filter-item-text', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3293
- MatFormField,
3294
- MatLabel,
3295
- MatPrefix,
3296
- MatInput,
3297
- FormsModule,
3298
- ReactiveFormsModule,
3275
+ args: [{ selector: 'filter-item-autocomplete', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3276
+ FsAutocompleteModule,
3299
3277
  FocusToItemDirective,
3300
- MatSuffix,
3301
- ], template: "<mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [formControl]=\"textControl\"\n [fsFilterFocusTrigger]=\"item\">\n @if (item.suffix) {\n <span\n matSuffix\n [innerHtml]=\"item.suffix\">\n </span>\n }\n</mat-form-field>" }]
3278
+ FormsModule,
3279
+ FsFormModule,
3280
+ ], template: "<fs-autocomplete\n [fsFilterFocusTrigger]=\"item\"\n [fetch]=\"fetch\"\n [displayWith]=\"displayWith\"\n [(ngModel)]=\"item.model\"\n [placeholder]=\"label\"\n [fetchOnFocus]=\"item.fetchOnFocus\"\n [showClear]=\"item.showClear\"\n name=\"item.name\">\n <ng-template fsAutocompleteTemplate let-data=\"data\">\n {{data.name}}\n </ng-template>\n</fs-autocomplete>\n" }]
3302
3281
  }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
3303
3282
 
3304
- class FsFilterIsolateValues {
3305
- transform(values, isolate) {
3306
- if (!isolate) {
3307
- return values;
3308
- }
3309
- return values.filter((value) => {
3310
- return value.value !== isolate.value;
3311
- });
3283
+ class ActionsController {
3284
+ _breakpointObserver;
3285
+ _visible$ = new BehaviorSubject(false);
3286
+ _actions$ = new BehaviorSubject([]);
3287
+ _menuActions$ = new BehaviorSubject([]);
3288
+ _destroy$ = new Subject();
3289
+ _config;
3290
+ _mobileMedia = '(max-width: 799px)';
3291
+ _allActions = [];
3292
+ _reorderAction;
3293
+ constructor(_breakpointObserver) {
3294
+ this._breakpointObserver = _breakpointObserver;
3295
+ this._listenMobileMedia();
3312
3296
  }
3313
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterIsolateValues, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
3314
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FsFilterIsolateValues, isStandalone: true, name: "fsFilterIsolateValues" });
3315
- }
3316
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterIsolateValues, decorators: [{
3317
- type: Pipe,
3318
- args: [{
3319
- name: 'fsFilterIsolateValues',
3320
- standalone: true,
3321
- }]
3322
- }] });
3323
-
3324
- class SelectMultipleComponent {
3325
- _cd;
3326
- item;
3327
- select;
3328
- constructor(_cd) {
3329
- this._cd = _cd;
3297
+ get menuActions() {
3298
+ return this._menuActions$.value;
3330
3299
  }
3331
- changed() {
3332
- if (this.item.isolate) {
3333
- this.item.isolate.enabled = false;
3334
- if (this.item.multiple && Array.isArray(this.item.model)) {
3335
- const index = this.item.model.indexOf(this.item.isolate.value);
3336
- if (index > -1) {
3337
- this.item.model.splice(index, 1);
3338
- }
3339
- }
3340
- }
3300
+ get actions() {
3301
+ return this._actions$.value;
3341
3302
  }
3342
- close() {
3343
- this.select.close();
3303
+ get actions$() {
3304
+ return this._actions$.asObservable();
3344
3305
  }
3345
- markForCheck() {
3346
- this._cd.markForCheck();
3306
+ get menuActions$() {
3307
+ return this._menuActions$.asObservable();
3347
3308
  }
3348
- isolateChange(filter) {
3349
- if (filter.isolate.enabled) {
3350
- filter.model = filter.multiple ? [filter.isolate.value] : filter.isolate.value;
3351
- }
3352
- else {
3353
- if (filter.multiple) {
3354
- filter.model = filter.defaultValue ? filter.defaultValue : [];
3355
- }
3356
- else {
3357
- filter.model = filter.defaultValue ? filter.defaultValue : null;
3358
- }
3359
- }
3309
+ get visible$() {
3310
+ return this._visible$.asObservable();
3360
3311
  }
3361
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectMultipleComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3362
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectMultipleComponent, isStandalone: true, selector: "filter-item-select-multiple", inputs: { item: "item" }, viewQueries: [{ propertyName: "select", first: true, predicate: ["select"], descendants: true, static: true }], ngImport: i0, template: "<mat-form-field [ngClass]=\"{ isolate: item.isolate }\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n (ngModelChange)=\"changed()\"\n [multiple]=\"item.multiple\">\n @for (item of item.values | fsFilterIsolateValues: item.isolate; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n @if (item.isolate) {\n <mat-checkbox\n (change)=\"isolateChange(item)\"\n [(ngModel)]=\"item.isolate.enabled\">\n <span class=\"checkbox-label\">\n {{ item.isolate.label }}\n </span>\n </mat-checkbox>\n }\n </mat-hint>\n</mat-form-field>", styles: [""], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "pipe", type: FsFilterIsolateValues, name: "fsFilterIsolateValues" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3363
- }
3364
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectMultipleComponent, decorators: [{
3365
- type: Component,
3366
- args: [{ selector: 'filter-item-select-multiple', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3367
- MatFormField,
3368
- NgClass,
3369
- MatLabel,
3370
- MatSelect,
3371
- FocusToItemDirective,
3372
- FormsModule,
3373
- FsFormModule,
3374
- MatOption,
3375
- MatHint,
3376
- MatCheckbox,
3377
- FsFilterIsolateValues,
3378
- ], template: "<mat-form-field [ngClass]=\"{ isolate: item.isolate }\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n (ngModelChange)=\"changed()\"\n [multiple]=\"item.multiple\">\n @for (item of item.values | fsFilterIsolateValues: item.isolate; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n @if (item.isolate) {\n <mat-checkbox\n (change)=\"isolateChange(item)\"\n [(ngModel)]=\"item.isolate.enabled\">\n <span class=\"checkbox-label\">\n {{ item.isolate.label }}\n </span>\n </mat-checkbox>\n }\n </mat-hint>\n</mat-form-field>" }]
3379
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
3380
- type: Input
3381
- }], select: [{
3382
- type: ViewChild,
3383
- args: ['select', { static: true }]
3384
- }] } });
3385
-
3386
- class SelectSimpleComponent {
3387
- _cd;
3388
- item;
3389
- select;
3390
- constructor(_cd) {
3391
- this._cd = _cd;
3312
+ get mobileMode() {
3313
+ return this._breakpointObserver.isMatched(this._mobileMedia);
3392
3314
  }
3393
- changed() {
3394
- if (this.item.isolate) {
3395
- this.item.isolate.enabled = false;
3396
- }
3315
+ ngOnDestroy() {
3316
+ this._destroy$.next(null);
3317
+ this._destroy$.complete();
3397
3318
  }
3398
- isolateChange(filter) {
3399
- filter.model = filter.isolate.enabled ? filter.isolate.value : null;
3319
+ setConfig(config) {
3320
+ this._config = config;
3321
+ this.initActions(config.actions);
3400
3322
  }
3401
- markForCheck() {
3402
- this._cd.markForCheck();
3323
+ initActions(rawActions) {
3324
+ if (!rawActions || !Array.isArray(rawActions)) {
3325
+ return;
3326
+ }
3327
+ this.show();
3328
+ this._allActions = rawActions
3329
+ .map((action) => new Action(this._config, action));
3330
+ if (this._reorderAction) {
3331
+ this._allActions.unshift(this._reorderAction);
3332
+ }
3333
+ this._classifyActions();
3403
3334
  }
3404
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectSimpleComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3405
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectSimpleComponent, isStandalone: true, selector: "filter-item-select-simple", inputs: { item: "item" }, viewQueries: [{ propertyName: "select", first: true, predicate: ["select"], descendants: true, static: true }], ngImport: i0, template: "<mat-form-field [ngClass]=\"{ isolate: !!item.isolate }\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n (ngModelChange)=\"changed()\">\n @for (item of item.values | fsFilterIsolateValues: item.isolate; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n</mat-form-field>\n@if (item.isolate) {\n <mat-checkbox\n (change)=\"isolateChange(item)\"\n [(ngModel)]=\"item.isolate.enabled\">\n <span class=\"checkbox-label\">\n {{ item.isolate.label }}\n </span>\n </mat-checkbox>\n}", styles: [""], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "pipe", type: FsFilterIsolateValues, name: "fsFilterIsolateValues" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3406
- }
3407
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectSimpleComponent, decorators: [{
3408
- type: Component,
3409
- args: [{ selector: 'filter-item-select-simple', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3410
- MatFormField,
3411
- NgClass,
3412
- MatLabel,
3413
- MatSelect,
3414
- FocusToItemDirective,
3415
- FormsModule,
3416
- FsFormModule,
3417
- MatOption,
3418
- MatCheckbox,
3419
- FsFilterIsolateValues,
3420
- ], template: "<mat-form-field [ngClass]=\"{ isolate: !!item.isolate }\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n (ngModelChange)=\"changed()\">\n @for (item of item.values | fsFilterIsolateValues: item.isolate; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n</mat-form-field>\n@if (item.isolate) {\n <mat-checkbox\n (change)=\"isolateChange(item)\"\n [(ngModel)]=\"item.isolate.enabled\">\n <span class=\"checkbox-label\">\n {{ item.isolate.label }}\n </span>\n </mat-checkbox>\n}" }]
3421
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
3422
- type: Input
3423
- }], select: [{
3424
- type: ViewChild,
3425
- args: ['select', { static: true }]
3426
- }] } });
3427
-
3428
- class SelectGroupsComponent {
3429
- cd;
3430
- select;
3431
- item;
3432
- constructor(cd) {
3433
- this.cd = cd;
3335
+ show() {
3336
+ this._visible$.next(true);
3434
3337
  }
3435
- compare(o1, o2) {
3436
- return o1 == o2;
3338
+ hide() {
3339
+ this._visible$.next(false);
3437
3340
  }
3438
- markForCheck() {
3439
- this.cd.markForCheck();
3341
+ addReorderAction(action) {
3342
+ this._allActions.unshift(action);
3343
+ action.isReorderAction = true;
3344
+ this._classifyAction(action);
3345
+ this._reorderAction = action;
3440
3346
  }
3441
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectGroupsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3442
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectGroupsComponent, isStandalone: true, selector: "filter-item-select-groups", inputs: { item: "item" }, viewQueries: [{ propertyName: "select", first: true, predicate: ["select"], descendants: true, static: true }], ngImport: i0, template: "<mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [compareWith]=\"compare\">\n @for (selectItem of item.values; track selectItem) {\n @if (selectItem[item.children]) {\n <mat-optgroup [label]=\"selectItem.name\">\n @for (subItem of selectItem[item.children]; track subItem) {\n <mat-option\n [value]=\"subItem.value\"\n [ngStyle]=\"selectItem.style\">\n {{ subItem.name }}\n </mat-option>\n }\n </mat-optgroup>\n } @else {\n <mat-option\n [value]=\"selectItem.value\"\n [ngStyle]=\"selectItem.style\">\n {{ selectItem.name }}\n </mat-option>\n }\n }\n </mat-select>\n</mat-form-field>\n", dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "component", type: MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3443
- }
3444
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectGroupsComponent, decorators: [{
3445
- type: Component,
3446
- args: [{ selector: 'filter-item-select-groups', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3447
- MatFormField,
3448
- MatLabel,
3449
- MatSelect,
3450
- FocusToItemDirective,
3451
- FormsModule,
3452
- FsFormModule,
3453
- MatOptgroup,
3454
- MatOption,
3455
- NgStyle,
3456
- ], template: "<mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [compareWith]=\"compare\">\n @for (selectItem of item.values; track selectItem) {\n @if (selectItem[item.children]) {\n <mat-optgroup [label]=\"selectItem.name\">\n @for (subItem of selectItem[item.children]; track subItem) {\n <mat-option\n [value]=\"subItem.value\"\n [ngStyle]=\"selectItem.style\">\n {{ subItem.name }}\n </mat-option>\n }\n </mat-optgroup>\n } @else {\n <mat-option\n [value]=\"selectItem.value\"\n [ngStyle]=\"selectItem.style\">\n {{ selectItem.name }}\n </mat-option>\n }\n }\n </mat-select>\n</mat-form-field>\n" }]
3457
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { select: [{
3458
- type: ViewChild,
3459
- args: ['select', { static: true }]
3460
- }], item: [{
3461
- type: Input
3462
- }] } });
3463
-
3464
- class SelectComponent extends BaseItemComponent {
3465
- _kvDiffers;
3466
- _cd;
3467
- selectedItem;
3468
- // For case when we have multiple selection with __all option
3469
- // If _all has been selected than we must disable all other items
3470
- allItemsOptionSelected = false;
3471
- get multipleSelectItem() {
3472
- return this.item;
3347
+ clearActions() {
3348
+ this._allActions = [];
3349
+ this._setActions([]);
3350
+ this._setKebabActions([]);
3473
3351
  }
3474
- get simpleSelectItem() {
3475
- return this.item;
3352
+ updateActionsVisibility() {
3353
+ this._allActions.forEach((action) => action.updateVisibility());
3354
+ this._classifyActions();
3476
3355
  }
3477
- values$;
3478
- constructor(_kvDiffers, _cd) {
3479
- super(_kvDiffers, _cd);
3480
- this._kvDiffers = _kvDiffers;
3481
- this._cd = _cd;
3356
+ updateDisabledState() {
3357
+ this.actions.forEach((action) => action.updateDisabledState());
3482
3358
  }
3483
- ngOnChanges(changes) {
3484
- if (changes.item) {
3485
- this.values$ = this.item.values$;
3486
- }
3359
+ _setKebabActions(actions) {
3360
+ this._menuActions$.next(actions);
3487
3361
  }
3488
- ngDoCheck() {
3489
- if (this._kvDiffer) {
3490
- const changes = this._kvDiffer.diff(this.item);
3491
- if (changes) {
3492
- this._cd.markForCheck();
3493
- if (this.selectedItem) {
3494
- this.selectedItem.markForCheck();
3495
- }
3362
+ _setActions(actions) {
3363
+ this._actions$.next(actions);
3364
+ }
3365
+ _classifyActions() {
3366
+ const kebabActions = [];
3367
+ const actions = [];
3368
+ const mobileMode = this.mobileMode;
3369
+ this._allActions
3370
+ .filter((action) => {
3371
+ return action.visible;
3372
+ })
3373
+ .forEach((action) => {
3374
+ if (action.menu !== false && (action.menu || mobileMode)) {
3375
+ kebabActions.push(action);
3496
3376
  }
3377
+ else {
3378
+ actions.push(action);
3379
+ }
3380
+ });
3381
+ this._setKebabActions(kebabActions);
3382
+ this._setActions(actions);
3383
+ }
3384
+ _classifyAction(action) {
3385
+ if (action.menu) {
3386
+ this._setKebabActions([...this.menuActions, action]);
3387
+ }
3388
+ else {
3389
+ this._setActions([...this.actions, action]);
3497
3390
  }
3498
3391
  }
3499
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3500
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectComponent, isStandalone: true, selector: "filter-item-select", viewQueries: [{ propertyName: "selectedItem", first: true, predicate: ["selectItem"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "@if ((item.loading$ | async)) {\n <mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <mat-select disabled></mat-select>\n </mat-form-field>\n} @else {\n @if ((values$ | async)?.length) {\n @if (item.multiple && !item.children) {\n <filter-item-select-multiple\n [item]=\"multipleSelectItem\"\n #selectItem>\n </filter-item-select-multiple>\n }\n @if (!item.multiple && !item.children) {\n <filter-item-select-simple\n [item]=\"simpleSelectItem\"\n #selectItem>\n </filter-item-select-simple>\n }\n @if (item.children) {\n <filter-item-select-groups\n [item]=\"item\"\n #selectItem>\n </filter-item-select-groups>\n }\n }\n}\n\n", styles: [":host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper{padding-left:0;padding-right:0;padding-top:8px}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field{position:relative}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-checkbox{position:absolute}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-label{margin-left:32px;font-size:smaller;line-height:normal}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: SelectMultipleComponent, selector: "filter-item-select-multiple", inputs: ["item"] }, { kind: "component", type: SelectSimpleComponent, selector: "filter-item-select-simple", inputs: ["item"] }, { kind: "component", type: SelectGroupsComponent, selector: "filter-item-select-groups", inputs: ["item"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3392
+ _listenMobileMedia() {
3393
+ this._breakpointObserver.observe(this._mobileMedia)
3394
+ .pipe(skip(1), takeUntil(this._destroy$))
3395
+ .subscribe(() => {
3396
+ this._classifyActions();
3397
+ });
3398
+ }
3399
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionsController, deps: [{ token: i1$4.BreakpointObserver }], target: i0.ɵɵFactoryTarget.Injectable });
3400
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionsController });
3501
3401
  }
3502
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectComponent, decorators: [{
3503
- type: Component,
3504
- args: [{ selector: 'filter-item-select', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3505
- MatFormField,
3506
- MatLabel,
3507
- MatSelect,
3508
- SelectMultipleComponent,
3509
- SelectSimpleComponent,
3510
- SelectGroupsComponent,
3511
- AsyncPipe,
3512
- ], template: "@if ((item.loading$ | async)) {\n <mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <mat-select disabled></mat-select>\n </mat-form-field>\n} @else {\n @if ((values$ | async)?.length) {\n @if (item.multiple && !item.children) {\n <filter-item-select-multiple\n [item]=\"multipleSelectItem\"\n #selectItem>\n </filter-item-select-multiple>\n }\n @if (!item.multiple && !item.children) {\n <filter-item-select-simple\n [item]=\"simpleSelectItem\"\n #selectItem>\n </filter-item-select-simple>\n }\n @if (item.children) {\n <filter-item-select-groups\n [item]=\"item\"\n #selectItem>\n </filter-item-select-groups>\n }\n }\n}\n\n", styles: [":host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper{padding-left:0;padding-right:0;padding-top:8px}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field{position:relative}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-checkbox{position:absolute}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-label{margin-left:32px;font-size:smaller;line-height:normal}\n"] }]
3513
- }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }], propDecorators: { selectedItem: [{
3514
- type: ViewChild,
3515
- args: ['selectItem']
3516
- }] } });
3402
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionsController, decorators: [{
3403
+ type: Injectable
3404
+ }], ctorParameters: () => [{ type: i1$4.BreakpointObserver }] });
3517
3405
 
3518
- class ChipsComponent extends BaseItemComponent {
3519
- _kvDiffers;
3520
- _cd;
3521
- constructor(_kvDiffers, _cd) {
3522
- super(_kvDiffers, _cd);
3523
- this._kvDiffers = _kvDiffers;
3524
- this._cd = _cd;
3406
+ const FilterIcon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M440-160q-17 0-28.5-11.5T400-200v-240L161-745q-14-17-4-36t31-19h584q21 0 31 19t-4 36L560-440v240q0 17-11.5 28.5T520-160h-80Zm40-276 240-304H240l240 304Zm0 0Z"/></svg>';
3407
+
3408
+ class FsFilterSavedFilterChipsComponent {
3409
+ savedFilter;
3410
+ items = [];
3411
+ _itemStore = inject(ItemStore);
3412
+ ngOnInit() {
3413
+ this.items = [...this._itemStore.items]
3414
+ .filter((item) => !!this.savedFilter.filters[item.name])
3415
+ .map((item) => {
3416
+ item.setModel(this.savedFilter.filters[item.name]);
3417
+ return item;
3418
+ });
3525
3419
  }
3526
- compareFn = (modelValue, chipValue) => {
3527
- return String(modelValue.value) === String(chipValue.value);
3528
- };
3529
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChipsComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3530
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ChipsComponent, isStandalone: true, selector: "filter-item-chips", usesInheritance: true, ngImport: i0, template: "@if (item.values?.length) {\n <fs-label-field>\n <fs-label>\n {{ item.label }}\n </fs-label>\n <fs-chips\n [(ngModel)]=\"item.model\"\n [compare]=\"compareFn\"\n [multiple]=\"item.multiple\">\n @for (value of item.values; track value) {\n <fs-chip\n [value]=\"value\"\n [selectable]=\"true\">\n {{ value.name }}\n </fs-chip>\n }\n </fs-chips>\n </fs-label-field>\n}\n@if (item.loading) {\n {{ item.label }} loading...\n}", styles: ["fs-chip{line-height:40px}\n"], dependencies: [{ kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i1$4.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i1$4.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsChipModule }, { kind: "component", type: i2$2.FsChipsComponent, selector: "fs-chips", inputs: ["compare", "multiple", "sortable", "selectable", "orientation", "width"] }, { kind: "component", type: i2$2.FsChipComponent, selector: "fs-chip", inputs: ["selectable", "removable", "value", "maxWidth", "width", "backgroundColor", "borderColor", "color", "shape", "outlined", "icon", "image", "selected", "padding", "contrastColor", "size"], outputs: ["selectedToggled", "removed"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3420
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3421
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsFilterSavedFilterChipsComponent, isStandalone: true, selector: "fs-saved-filter-chips", inputs: { savedFilter: "savedFilter" }, ngImport: i0, template: "<div class=\"filter-chips\">\n @for (item of items; track item.name) {\n <fs-filter-chip [item]=\"item\"></fs-filter-chip>\n }\n</div>", styles: [".filter-chips{display:flex;flex-wrap:wrap;gap:4px}\n"], dependencies: [{ kind: "component", type: FsFilterChipComponent, selector: "fs-filter-chip", inputs: ["item", "removable", "clickable"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3531
3422
  }
3532
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChipsComponent, decorators: [{
3423
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterChipsComponent, decorators: [{
3533
3424
  type: Component,
3534
- args: [{ selector: 'filter-item-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3535
- FsLabelModule,
3536
- FsChipModule,
3537
- FormsModule,
3538
- FsFormModule,
3539
- ], template: "@if (item.values?.length) {\n <fs-label-field>\n <fs-label>\n {{ item.label }}\n </fs-label>\n <fs-chips\n [(ngModel)]=\"item.model\"\n [compare]=\"compareFn\"\n [multiple]=\"item.multiple\">\n @for (value of item.values; track value) {\n <fs-chip\n [value]=\"value\"\n [selectable]=\"true\">\n {{ value.name }}\n </fs-chip>\n }\n </fs-chips>\n </fs-label-field>\n}\n@if (item.loading) {\n {{ item.label }} loading...\n}", styles: ["fs-chip{line-height:40px}\n"] }]
3540
- }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
3425
+ args: [{ selector: 'fs-saved-filter-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3426
+ FsFilterChipComponent,
3427
+ ], template: "<div class=\"filter-chips\">\n @for (item of items; track item.name) {\n <fs-filter-chip [item]=\"item\"></fs-filter-chip>\n }\n</div>", styles: [".filter-chips{display:flex;flex-wrap:wrap;gap:4px}\n"] }]
3428
+ }], propDecorators: { savedFilter: [{
3429
+ type: Input
3430
+ }] } });
3541
3431
 
3542
- class RangeComponent extends BaseItemComponent {
3543
- _kvDiffers;
3544
- _cd;
3545
- from;
3546
- to;
3547
- constructor(_kvDiffers, _cd) {
3548
- super(_kvDiffers, _cd);
3549
- this._kvDiffers = _kvDiffers;
3550
- this._cd = _cd;
3551
- }
3432
+ class FsFilterSavedFilterManageComponent {
3433
+ savedFilters;
3434
+ _savedFilterController = inject(SavedFilterController);
3435
+ _cdRef = inject(ChangeDetectorRef);
3436
+ _paramController = inject(ParamController);
3437
+ _itemStore = inject(ItemStore);
3438
+ _dialogRef = inject(MatDialogRef);
3439
+ _filterOverlayService = inject(FsFilterOverlayService);
3552
3440
  ngOnInit() {
3553
- this.listenChanges();
3441
+ this.savedFilters = this._savedFilterController.savedFilters;
3554
3442
  }
3555
- listenChanges() {
3556
- const fromListener = fromEvent(this.from.nativeElement, 'keyup')
3557
- .pipe(distinctUntilChanged());
3558
- const toListener = fromEvent(this.to.nativeElement, 'keyup')
3559
- .pipe(distinctUntilChanged());
3560
- merge(fromListener, toListener)
3561
- .pipe(takeUntil(this.destroy$))
3443
+ get items() {
3444
+ return this._itemStore.items;
3445
+ }
3446
+ get pluralLabelLower() {
3447
+ return this._savedFilterController.pluralLabelLower;
3448
+ }
3449
+ get sortable() {
3450
+ return this._savedFilterController.orderable;
3451
+ }
3452
+ selectFilter(savedFilter) {
3453
+ this._savedFilterController.setActiveFilter(savedFilter);
3454
+ this._filterOverlayService.open();
3455
+ this._dialogRef.close();
3456
+ }
3457
+ remove(savedFilter) {
3458
+ this._savedFilterController.delete(savedFilter)
3562
3459
  .subscribe(() => {
3563
- this.itemChange();
3460
+ this.savedFilters = this._savedFilterController.savedFilters;
3461
+ this._cdRef.markForCheck();
3564
3462
  });
3565
3463
  }
3566
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RangeComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3567
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: RangeComponent, isStandalone: true, selector: "filter-item-range", viewQueries: [{ propertyName: "from", first: true, predicate: ["from"], descendants: true, static: true }, { propertyName: "to", first: true, predicate: ["to"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"form-field\">\n <mat-form-field class=\"filter-range-min\">\n <mat-label>\n {{ item.label[0] }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n class=\"text-prefix\"\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'from'\"\n type=\"text\"\n inputmode=\"decimal\"\n [(ngModel)]=\"item.model.min\"\n #from>\n @if (item.suffix) {\n <span\n matSuffix\n class=\"text-suffix\"\n [innerHtml]=\"item.suffix\">\n </span>\n }\n </mat-form-field>\n <mat-form-field class=\"filter-range-max\">\n <mat-label>\n {{ item.label[1] }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n class=\"text-prefix\"\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'to'\"\n type=\"text\"\n inputmode=\"decimal\"\n [(ngModel)]=\"item.model.max\"\n #to>\n @if (item.suffix) {\n <span\n matSuffix\n class=\"text-suffix\"\n [innerHtml]=\"item.suffix\">\n </span>\n }\n </mat-form-field>\n</div>", styles: [".form-field{display:flex}.form-field mat-form-field{min-width:0}.form-field mat-form-field+mat-form-field{margin-left:10px}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3464
+ order(savedFilters) {
3465
+ this._savedFilterController.order(savedFilters)
3466
+ .subscribe();
3467
+ }
3468
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterManageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3469
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsFilterSavedFilterManageComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<h1 mat-dialog-title>\n Manage {{ pluralLabelLower }}\n</h1>\n<div mat-dialog-content>\n <table class=\"fs-list-table\">\n <thead>\n <tr>\n <th>\n Name\n </th>\n <th>\n Filters\n </th>\n <th class=\"actions-column\"></th>\n </tr>\n </thead>\n <tbody>\n @for (savedFilter of savedFilters; track savedFilter.id) {\n <tr>\n <td>\n <a (click)=\"selectFilter(savedFilter)\">\n {{ savedFilter.name }}\n </a>\n </td>\n <td>\n <fs-saved-filter-chips [savedFilter]=\"savedFilter\"></fs-saved-filter-chips>\n </td>\n <td>\n <fs-menu>\n <ng-template\n fs-menu-item\n (click)=\"remove(savedFilter)\">\n Delete\n </ng-template>\n </fs-menu>\n </td>\n </tr>\n }\n </tbody>\n </table>\n</div>\n<div mat-dialog-actions>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n</div>", styles: ["::ng-deep .fs-list-table{border-spacing:0;display:table;width:100%;border-collapse:collapse}::ng-deep .fs-list-table thead{display:table-header-group}::ng-deep .fs-list-table thead th{color:#999;padding:8px;font-weight:400;color:#8f8f8f;font-size:85%;text-align:left}::ng-deep .fs-list-table tbody{display:table-row-group;position:relative}::ng-deep .fs-list-table tbody tr,::ng-deep .fs-list-table thead tr,::ng-deep .fs-list-table tfoot tr{display:table-row}::ng-deep .fs-list-table tbody tr td,::ng-deep .fs-list-table thead tr td,::ng-deep .fs-list-table tfoot tr td{display:table-cell;padding:8px;vertical-align:middle;outline:none;text-align:left}::ng-deep .fs-list-table tfoot td{padding:8px}::ng-deep .fs-list-table.style-card tbody tr:not(.fs-list-row-group-footer):not(.fs-list-row-group){clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}::ng-deep .fs-list-table.style-card tbody tr td{border:none!important;background-color:#fafafa;padding:8px 16px}::ng-deep .fs-list-table.style-line tbody td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody td{box-sizing:border-box;border-top:1px solid #e7e7e7}::ng-deep .fs-list-table.style-line tbody tr:first-child td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody tr:first-child td{border-color:#c4c4c4}::ng-deep .fs-list-table.style-line tbody tr:last-child td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody tr:last-child td{border-bottom:1px solid #c4c4c4}::ng-deep .fs-list-table.style-line .fs-list-container.has-dragging thead th,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) .fs-list-container.has-dragging thead th{border-color:#e7e7e7}::ng-deep .fs-list-table.style-line .fs-list-container.has-dragging tbody tr:nth-child(2) td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) .fs-list-container.has-dragging tbody tr:nth-child(2) td{border-top:none}:host ::ng-deep .mat-mdc-dialog-content{width:800px;max-width:100%}.actions-column{width:1%}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$5.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$5.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$5.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$5.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: FsFilterSavedFilterChipsComponent, selector: "fs-saved-filter-chips", inputs: ["savedFilter"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i2$1.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i2$1.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3568
3470
  }
3569
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RangeComponent, decorators: [{
3471
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterManageComponent, decorators: [{
3570
3472
  type: Component,
3571
- args: [{ selector: 'filter-item-range', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3572
- MatFormField,
3573
- MatLabel,
3574
- MatPrefix,
3575
- MatInput,
3576
- FormsModule,
3577
- FocusToItemDirective,
3578
- FsFormModule,
3579
- MatSuffix,
3580
- ], template: "<div class=\"form-field\">\n <mat-form-field class=\"filter-range-min\">\n <mat-label>\n {{ item.label[0] }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n class=\"text-prefix\"\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'from'\"\n type=\"text\"\n inputmode=\"decimal\"\n [(ngModel)]=\"item.model.min\"\n #from>\n @if (item.suffix) {\n <span\n matSuffix\n class=\"text-suffix\"\n [innerHtml]=\"item.suffix\">\n </span>\n }\n </mat-form-field>\n <mat-form-field class=\"filter-range-max\">\n <mat-label>\n {{ item.label[1] }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n class=\"text-prefix\"\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'to'\"\n type=\"text\"\n inputmode=\"decimal\"\n [(ngModel)]=\"item.model.max\"\n #to>\n @if (item.suffix) {\n <span\n matSuffix\n class=\"text-suffix\"\n [innerHtml]=\"item.suffix\">\n </span>\n }\n </mat-form-field>\n</div>", styles: [".form-field{display:flex}.form-field mat-form-field{min-width:0}.form-field mat-form-field+mat-form-field{margin-left:10px}\n"] }]
3581
- }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }], propDecorators: { from: [{
3582
- type: ViewChild,
3583
- args: ['from', { static: true }]
3584
- }], to: [{
3585
- type: ViewChild,
3586
- args: ['to', { static: true }]
3587
- }] } });
3473
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3474
+ MatDialogModule,
3475
+ MatButton,
3476
+ FsFilterSavedFilterChipsComponent,
3477
+ FsMenuModule,
3478
+ ], template: "<h1 mat-dialog-title>\n Manage {{ pluralLabelLower }}\n</h1>\n<div mat-dialog-content>\n <table class=\"fs-list-table\">\n <thead>\n <tr>\n <th>\n Name\n </th>\n <th>\n Filters\n </th>\n <th class=\"actions-column\"></th>\n </tr>\n </thead>\n <tbody>\n @for (savedFilter of savedFilters; track savedFilter.id) {\n <tr>\n <td>\n <a (click)=\"selectFilter(savedFilter)\">\n {{ savedFilter.name }}\n </a>\n </td>\n <td>\n <fs-saved-filter-chips [savedFilter]=\"savedFilter\"></fs-saved-filter-chips>\n </td>\n <td>\n <fs-menu>\n <ng-template\n fs-menu-item\n (click)=\"remove(savedFilter)\">\n Delete\n </ng-template>\n </fs-menu>\n </td>\n </tr>\n }\n </tbody>\n </table>\n</div>\n<div mat-dialog-actions>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n</div>", styles: ["::ng-deep .fs-list-table{border-spacing:0;display:table;width:100%;border-collapse:collapse}::ng-deep .fs-list-table thead{display:table-header-group}::ng-deep .fs-list-table thead th{color:#999;padding:8px;font-weight:400;color:#8f8f8f;font-size:85%;text-align:left}::ng-deep .fs-list-table tbody{display:table-row-group;position:relative}::ng-deep .fs-list-table tbody tr,::ng-deep .fs-list-table thead tr,::ng-deep .fs-list-table tfoot tr{display:table-row}::ng-deep .fs-list-table tbody tr td,::ng-deep .fs-list-table thead tr td,::ng-deep .fs-list-table tfoot tr td{display:table-cell;padding:8px;vertical-align:middle;outline:none;text-align:left}::ng-deep .fs-list-table tfoot td{padding:8px}::ng-deep .fs-list-table.style-card tbody tr:not(.fs-list-row-group-footer):not(.fs-list-row-group){clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}::ng-deep .fs-list-table.style-card tbody tr td{border:none!important;background-color:#fafafa;padding:8px 16px}::ng-deep .fs-list-table.style-line tbody td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody td{box-sizing:border-box;border-top:1px solid #e7e7e7}::ng-deep .fs-list-table.style-line tbody tr:first-child td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody tr:first-child td{border-color:#c4c4c4}::ng-deep .fs-list-table.style-line tbody tr:last-child td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody tr:last-child td{border-bottom:1px solid #c4c4c4}::ng-deep .fs-list-table.style-line .fs-list-container.has-dragging thead th,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) .fs-list-container.has-dragging thead th{border-color:#e7e7e7}::ng-deep .fs-list-table.style-line .fs-list-container.has-dragging tbody tr:nth-child(2) td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) .fs-list-container.has-dragging tbody tr:nth-child(2) td{border-top:none}:host ::ng-deep .mat-mdc-dialog-content{width:800px;max-width:100%}.actions-column{width:1%}\n"] }]
3479
+ }] });
3588
3480
 
3589
- class AutocompleteComponent extends BaseItemComponent {
3590
- _kvDiffers;
3591
- _cd;
3592
- constructor(_kvDiffers, _cd) {
3593
- super(_kvDiffers, _cd);
3594
- this._kvDiffers = _kvDiffers;
3595
- this._cd = _cd;
3481
+ class FsSavedFilterAutocompleteChipsComponent {
3482
+ savedFiltersController;
3483
+ selectedFilter;
3484
+ _itemStore = inject(ItemStore);
3485
+ _paramController = inject(ParamController);
3486
+ _dialog = inject(MatDialog);
3487
+ _destroyRef = inject(DestroyRef);
3488
+ _injector = inject(Injector);
3489
+ _cdRef = inject(ChangeDetectorRef);
3490
+ _prompt = inject(FsPrompt);
3491
+ _message = inject(FsMessage);
3492
+ get filters$() {
3493
+ return this.savedFiltersController.savedFilters$;
3596
3494
  }
3597
- displayWith = (data) => {
3598
- return data ? data.name : data;
3599
- };
3600
- fetch = (keyword) => {
3601
- return this.item.valuesFn(keyword, this.item.filter);
3602
- };
3603
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompleteComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3604
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AutocompleteComponent, isStandalone: true, selector: "filter-item-autocomplete", usesInheritance: true, ngImport: i0, template: "<fs-autocomplete\n [fsFilterFocusTrigger]=\"item\"\n [fetch]=\"fetch\"\n [displayWith]=\"displayWith\"\n [(ngModel)]=\"item.model\"\n [placeholder]=\"label\"\n [fetchOnFocus]=\"item.fetchOnFocus\"\n [showClear]=\"item.showClear\"\n name=\"item.name\">\n <ng-template fsAutocompleteTemplate let-data=\"data\">\n {{data.name}}\n </ng-template>\n</fs-autocomplete>\n", dependencies: [{ kind: "ngmodule", type: FsAutocompleteModule }, { kind: "component", type: i4.FsAutocompleteComponent, selector: "fs-autocomplete", inputs: ["fetch", "displayWith", "placeholder", "fetchOnFocus", "readonly", "required", "disabled", "formFieldClass", "appearance", "hint", "panelWidth", "panelClass", "showClear"], outputs: ["cleared", "opened", "closed"] }, { kind: "directive", type: i4.FsAutocompleteTemplateDirective, selector: "[fsAutocompleteTemplate]" }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3605
- }
3606
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompleteComponent, decorators: [{
3607
- type: Component,
3608
- args: [{ selector: 'filter-item-autocomplete', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3609
- FsAutocompleteModule,
3610
- FocusToItemDirective,
3611
- FormsModule,
3612
- FsFormModule,
3613
- ], template: "<fs-autocomplete\n [fsFilterFocusTrigger]=\"item\"\n [fetch]=\"fetch\"\n [displayWith]=\"displayWith\"\n [(ngModel)]=\"item.model\"\n [placeholder]=\"label\"\n [fetchOnFocus]=\"item.fetchOnFocus\"\n [showClear]=\"item.showClear\"\n name=\"item.name\">\n <ng-template fsAutocompleteTemplate let-data=\"data\">\n {{data.name}}\n </ng-template>\n</fs-autocomplete>\n" }]
3614
- }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
3615
-
3616
- class AutocompletechipsComponent extends BaseItemComponent {
3617
- _kvDiffers;
3618
- _cd;
3619
- constructor(_kvDiffers, _cd) {
3620
- super(_kvDiffers, _cd);
3621
- this._kvDiffers = _kvDiffers;
3622
- this._cd = _cd;
3495
+ get activeFilter$() {
3496
+ return this.savedFiltersController.activeFilter$;
3623
3497
  }
3624
- addAutocompleteChipItem(event) {
3625
- if (event.data && this.item.model.indexOf(event.data.value) === -1) {
3626
- this.item.model.push(event.data);
3627
- this.itemChange();
3628
- }
3498
+ get pluralLabelLower() {
3499
+ return this.savedFiltersController.pluralLabelLower;
3629
3500
  }
3630
- removeAutocompleteChipItem(event) {
3631
- remove(this.item.model, { value: event.data.value });
3632
- this.itemChange();
3501
+ get pluralLabel() {
3502
+ return this.savedFiltersController.pluralLabel;
3633
3503
  }
3634
- clearAutocompleteChipItem() {
3635
- this.item.clear();
3636
- this.itemChange();
3504
+ get labelIcon() {
3505
+ return this.savedFiltersController.labelIcon;
3637
3506
  }
3638
- fetch = (keyword) => {
3639
- return this.item.valuesFn(keyword, this.item.filter);
3507
+ compareWith = (o1, o2) => {
3508
+ return o1?.id === o2?.id;
3640
3509
  };
3641
- compareItems(item1, item2) {
3642
- return item1?.value === item2?.value;
3510
+ selectFilter(savedFilter) {
3511
+ this.savedFiltersController.setActiveFilter(savedFilter);
3643
3512
  }
3644
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompletechipsComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3645
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AutocompletechipsComponent, isStandalone: true, selector: "filter-item-autocompletechips", usesInheritance: true, ngImport: i0, template: "<fs-autocomplete-chips\n [fsFilterFocusTrigger]=\"item\"\n [fetch]=\"fetch\"\n [ngModel]=\"item.model\"\n (selected)=\"addAutocompleteChipItem($event)\"\n (removed)=\"removeAutocompleteChipItem($event)\"\n (clear)=\"clearAutocompleteChipItem()\"\n [allowText]=\"false\"\n [label]=\"label\"\n [size]=\"'small'\"\n [chipImage]=\"item.chipImage\"\n [chipColor]=\"item.chipColor\"\n [chipIconColor]=\"item.chipIcon\"\n [chipBackground]=\"item.chipBackground\"\n [chipIcon]=\"item.chipIcon\"\n [chipClass]=\"item.chipClass\"\n [allowClear]=\"item.showClear\"\n [removable]=\"item.showClear\"\n [compareWith]=\"compareItems\"\n [panelWidth]=\"300\"\n name=\"model\">\n <ng-template\n fsAutocompleteObject\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n @for (action of item.panelActions; track action.label) {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"action.click()\">\n {{ action.label }}\n </ng-template>\n }\n</fs-autocomplete-chips>", dependencies: [{ kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i1$3.FsAutocompleteChipsComponent, selector: "fs-autocomplete-chips", inputs: ["fetch", "appearance", "floatLabel", "readonly", "size", "label", "placeholder", "chipMargin", "chipImage", "chipBackground", "chipColor", "chipIcon", "chipIconColor", "chipClass", "chipPadding", "shape", "hint", "allowText", "allowObject", "delay", "minPanelWidth", "validateText", "removable", "allowClear", "color", "background", "orderable", "padless", "initOnClick", "fetchOnFocus", "multiple", "multipleAdd", "confirm", "disabled", "groupBy", "panelWidth", "panelClass", "compareWith"], outputs: ["selected", "removed", "reordered", "clear"] }, { kind: "directive", type: i1$3.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "directive", type: i1$3.FsAutocompleteChipsStaticDirective, selector: "[fsAutocompleteChipsStatic]", inputs: ["show", "disable"], outputs: ["click", "selected"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3646
- }
3647
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompletechipsComponent, decorators: [{
3648
- type: Component,
3649
- args: [{ selector: 'filter-item-autocompletechips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3650
- FsAutocompleteChipsModule,
3651
- FocusToItemDirective,
3652
- FormsModule,
3653
- FsFormModule,
3654
- ], template: "<fs-autocomplete-chips\n [fsFilterFocusTrigger]=\"item\"\n [fetch]=\"fetch\"\n [ngModel]=\"item.model\"\n (selected)=\"addAutocompleteChipItem($event)\"\n (removed)=\"removeAutocompleteChipItem($event)\"\n (clear)=\"clearAutocompleteChipItem()\"\n [allowText]=\"false\"\n [label]=\"label\"\n [size]=\"'small'\"\n [chipImage]=\"item.chipImage\"\n [chipColor]=\"item.chipColor\"\n [chipIconColor]=\"item.chipIcon\"\n [chipBackground]=\"item.chipBackground\"\n [chipIcon]=\"item.chipIcon\"\n [chipClass]=\"item.chipClass\"\n [allowClear]=\"item.showClear\"\n [removable]=\"item.showClear\"\n [compareWith]=\"compareItems\"\n [panelWidth]=\"300\"\n name=\"model\">\n <ng-template\n fsAutocompleteObject\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n @for (action of item.panelActions; track action.label) {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"action.click()\">\n {{ action.label }}\n </ng-template>\n }\n</fs-autocomplete-chips>" }]
3655
- }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
3656
-
3657
- class DateComponent extends BaseItemComponent {
3658
- _kvDiffers;
3659
- _cd;
3660
- viewType = PickerViewType.Date;
3661
- itemDateMode = ItemDateMode;
3662
- showYear = true;
3663
- showMonth = true;
3664
- showDay = true;
3665
- constructor(_kvDiffers, _cd) {
3666
- super(_kvDiffers, _cd);
3667
- this._kvDiffers = _kvDiffers;
3668
- this._cd = _cd;
3513
+ selectedFilterChange(savedFilter) {
3514
+ this.savedFiltersController.setActiveFilter(savedFilter);
3515
+ if (!savedFilter) {
3516
+ this._itemStore.filtersClear();
3517
+ }
3669
3518
  }
3670
3519
  ngOnInit() {
3671
- this.viewType = this.item.type === ItemType.DateTime ? PickerViewType.DateTime : PickerViewType.Date;
3672
- if (this.item.mode === ItemDateMode.ScrollMonthYear) {
3673
- this.showDay = false;
3674
- }
3520
+ this.savedFiltersController.activeFilter$
3521
+ .pipe(takeUntilDestroyed(this._destroyRef))
3522
+ .subscribe((savedFilter) => {
3523
+ this.selectedFilter = savedFilter;
3524
+ this._cdRef.markForCheck();
3525
+ });
3675
3526
  }
3676
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3677
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DateComponent, isStandalone: true, selector: "filter-item-date", usesInheritance: true, ngImport: i0, template: "@if (item.mode === itemDateMode.ScrollMonthDayYear || item.mode === itemDateMode.ScrollMonthYear) {\n <mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n <input\n matInput\n fsDateScrollPicker\n [placeholder]=\"item.label\"\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [maxYear]=\"item.maxYear\"\n [showMonth]=\"showMonth\"\n [showDay]=\"showDay\"\n [showYear]=\"showYear\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n </mat-form-field>\n} @else if (item.mode === itemDateMode.Calendar) {\n <mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [maxYear]=\"item.maxYear\"\n [view]=\"viewType\"\n [placeholder]=\"item.label\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n </mat-form-field>\n}", dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i3$1.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes"], outputs: ["change"] }, { kind: "component", type: i3$1.FsDateScrollPickerComponent, selector: "[fsDateScrollPicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "showMonth", "showYear", "showDay"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3678
- }
3679
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateComponent, decorators: [{
3680
- type: Component,
3681
- args: [{ selector: 'filter-item-date', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3682
- MatFormField,
3683
- MatLabel,
3684
- MatInput,
3685
- FormsModule,
3686
- FsDatePickerModule,
3687
- FocusToItemDirective,
3688
- FsFormModule,
3689
- ], template: "@if (item.mode === itemDateMode.ScrollMonthDayYear || item.mode === itemDateMode.ScrollMonthYear) {\n <mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n <input\n matInput\n fsDateScrollPicker\n [placeholder]=\"item.label\"\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [maxYear]=\"item.maxYear\"\n [showMonth]=\"showMonth\"\n [showDay]=\"showDay\"\n [showYear]=\"showYear\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n </mat-form-field>\n} @else if (item.mode === itemDateMode.Calendar) {\n <mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [maxYear]=\"item.maxYear\"\n [view]=\"viewType\"\n [placeholder]=\"item.label\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n </mat-form-field>\n}" }]
3690
- }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
3691
-
3692
- class DateRangeComponent extends BaseItemComponent {
3693
- _kvDiffers;
3694
- _cd;
3695
- viewType = PickerViewType.Date;
3696
- constructor(_kvDiffers, _cd) {
3697
- super(_kvDiffers, _cd);
3698
- this._kvDiffers = _kvDiffers;
3699
- this._cd = _cd;
3527
+ save() {
3528
+ this.savedFiltersController
3529
+ .save(this.selectedFilter)
3530
+ .pipe(tap$1(() => {
3531
+ this._message.success(`Saved ${this.savedFiltersController.singularLabel}`);
3532
+ }))
3533
+ .subscribe();
3700
3534
  }
3701
- ngOnInit() {
3702
- if (this.item.type === ItemType.DateTimeRange) {
3703
- this.viewType = PickerViewType.DateTime;
3704
- }
3705
- else {
3706
- this.viewType = PickerViewType.Date;
3707
- }
3535
+ create() {
3536
+ this.savedFiltersController.create()
3537
+ .pipe(tap$1(() => {
3538
+ this._message
3539
+ .success(`Created ${this.savedFiltersController.singularLabel}`);
3540
+ }))
3541
+ .subscribe();
3708
3542
  }
3709
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateRangeComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3710
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DateRangeComponent, isStandalone: true, selector: "filter-item-date-range", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{item.label[0]}}</mat-label>\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'from'\"\n [fsDateRangeFrom]=\"item.name\"\n [(ngModel)]=\"item.model.from\"\n (ngModelChange)=\"itemChange()\"\n [clear]=\"item.showClear\"\n [view]=\"viewType\"\n name=\"date_from\">\n</mat-form-field>\n\n<mat-form-field>\n <mat-label>{{item.label[1]}}</mat-label>\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'to'\"\n [fsDateRangeTo]=\"item.name\"\n [(ngModel)]=\"item.model.to\"\n (ngModelChange)=\"itemChange()\"\n [clear]=\"item.showClear\"\n [view]=\"viewType\"\n name=\"date_to\">\n</mat-form-field>\n", dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i3$1.DateRangePickerFromComponent, selector: "[fsDateRangeFrom],[fsDateRangeFromPicker]", inputs: ["fsDateRangeFrom", "fsDateRangeFromPicker"] }, { kind: "component", type: i3$1.DateRangePickerToComponent, selector: "[fsDateRangeTo],[fsDateRangeToPicker]", inputs: ["fsDateRangeTo", "fsDateRangeToPicker"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3711
- }
3712
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateRangeComponent, decorators: [{
3713
- type: Component,
3714
- args: [{ selector: 'filter-item-date-range', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3715
- MatFormField,
3716
- MatLabel,
3717
- MatInput,
3718
- FormsModule,
3719
- FocusToItemDirective,
3720
- FsDatePickerModule,
3721
- FsFormModule,
3722
- ], template: "<mat-form-field>\n <mat-label>{{item.label[0]}}</mat-label>\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'from'\"\n [fsDateRangeFrom]=\"item.name\"\n [(ngModel)]=\"item.model.from\"\n (ngModelChange)=\"itemChange()\"\n [clear]=\"item.showClear\"\n [view]=\"viewType\"\n name=\"date_from\">\n</mat-form-field>\n\n<mat-form-field>\n <mat-label>{{item.label[1]}}</mat-label>\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'to'\"\n [fsDateRangeTo]=\"item.name\"\n [(ngModel)]=\"item.model.to\"\n (ngModelChange)=\"itemChange()\"\n [clear]=\"item.showClear\"\n [view]=\"viewType\"\n name=\"date_to\">\n</mat-form-field>\n" }]
3723
- }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
3724
-
3725
- class WeekComponent extends BaseItemComponent {
3726
- _kvDiffers;
3727
- _cd;
3728
- constructor(_kvDiffers, _cd) {
3729
- super(_kvDiffers, _cd);
3730
- this._kvDiffers = _kvDiffers;
3731
- this._cd = _cd;
3543
+ saveAs() {
3544
+ this._prompt.input({
3545
+ title: 'Save as new alert',
3546
+ label: 'Name',
3547
+ required: true,
3548
+ commitLabel: 'Save',
3549
+ dialogConfig: {
3550
+ restoreFocus: false,
3551
+ },
3552
+ })
3553
+ .pipe(switchMap$1((name) => {
3554
+ const data = {
3555
+ id: null,
3556
+ name,
3557
+ };
3558
+ return this.savedFiltersController.save(data);
3559
+ }), tap$1(() => {
3560
+ this._message.success(`Saved ${this.savedFiltersController.singularLabel}`);
3561
+ }))
3562
+ .subscribe();
3732
3563
  }
3733
- ngOnInit() { }
3734
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WeekComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3735
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: WeekComponent, isStandalone: true, selector: "filter-item-week", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <input \n matInput\n fsDateWeekPicker\n [placeholder]=\"item.label\"\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [seedDate]=\"item.seedDate\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n</mat-form-field>\n", dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i3$1.FsDateWeekPickerComponent, selector: "[fsDateWeekPicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "seedDate", "period", "view"], outputs: ["change"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3564
+ fetch = (query) => {
3565
+ return this.savedFiltersController.savedFilters$
3566
+ .pipe(map$1((filters) => filters
3567
+ .filter((filter) => filter
3568
+ .name.toLowerCase().includes(query.toLowerCase()))));
3569
+ };
3570
+ manageFilters() {
3571
+ this._dialog
3572
+ .open(FsFilterSavedFilterManageComponent, {
3573
+ injector: this._injector,
3574
+ restoreFocus: false,
3575
+ });
3576
+ }
3577
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsSavedFilterAutocompleteChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3578
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsSavedFilterAutocompleteChipsComponent, isStandalone: true, selector: "fs-saved-filter-autocomplete-chips", inputs: { savedFiltersController: "savedFiltersController" }, ngImport: i0, template: "<fs-autocomplete-chips\n [fetch]=\"fetch\"\n [size]=\"'small'\"\n [multiple]=\"false\"\n [placeholder]=\"pluralLabel\"\n [(ngModel)]=\"selectedFilter\"\n [compareWith]=\"compareWith\"\n [panelClass]=\"'fs-autocomplete-chips-panel-saved-filter'\"\n (ngModelChange)=\"selectedFilterChange($event)\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n <ng-template\n fsAutocompleteChipsPrefix\n [icon]=\"labelIcon\">\n </ng-template>\n @if (selectedFilter) {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"save()\">\n Save alert filters\n </ng-template>\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"saveAs()\">\n Save as new alert\n </ng-template>\n } @else {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"create()\">\n Create alert\n </ng-template>\n }\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"manageFilters()\">\n Manage {{ pluralLabelLower }}\n </ng-template>\n</fs-autocomplete-chips>", styles: ["fs-autocomplete-chips{width:200px;display:flex;margin-right:5px}fs-autocomplete-chips ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline{margin:0}fs-autocomplete-chips ::ng-deep .prefix-icon{color:#626262}fs-autocomplete-chips ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .fs-autocomplete-chips-panel-saved-filter{max-height:400px!important}\n"], dependencies: [{ kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i1$3.FsAutocompleteChipsComponent, selector: "fs-autocomplete-chips", inputs: ["fetch", "appearance", "floatLabel", "readonly", "size", "label", "placeholder", "chipMargin", "chipImage", "chipBackground", "chipColor", "chipIcon", "chipIconColor", "chipClass", "chipPadding", "shape", "hint", "allowText", "allowObject", "delay", "minPanelWidth", "validateText", "removable", "allowClear", "color", "background", "orderable", "padless", "initOnClick", "fetchOnFocus", "multiple", "multipleAdd", "confirm", "disabled", "groupBy", "panelWidth", "panelClass", "compareWith"], outputs: ["selected", "removed", "reordered", "clear"] }, { kind: "directive", type: i1$3.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "directive", type: i1$3.FsAutocompleteChipsStaticDirective, selector: "[fsAutocompleteChipsStatic]", inputs: ["show", "disable"], outputs: ["click", "selected"] }, { kind: "directive", type: i1$3.FsAutocompleteChipsPrefixDirective, selector: "[fsAutocompleteChipsPrefix]", inputs: ["icon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3736
3579
  }
3737
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WeekComponent, decorators: [{
3580
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsSavedFilterAutocompleteChipsComponent, decorators: [{
3738
3581
  type: Component,
3739
- args: [{ selector: 'filter-item-week', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3740
- MatFormField,
3741
- MatLabel,
3742
- MatInput,
3582
+ args: [{ selector: 'fs-saved-filter-autocomplete-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3583
+ FsAutocompleteChipsModule,
3743
3584
  FormsModule,
3744
- FsDatePickerModule,
3745
- FocusToItemDirective,
3746
- FsFormModule,
3747
- ], template: "<mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <input \n matInput\n fsDateWeekPicker\n [placeholder]=\"item.label\"\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [seedDate]=\"item.seedDate\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n</mat-form-field>\n" }]
3748
- }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
3585
+ ], template: "<fs-autocomplete-chips\n [fetch]=\"fetch\"\n [size]=\"'small'\"\n [multiple]=\"false\"\n [placeholder]=\"pluralLabel\"\n [(ngModel)]=\"selectedFilter\"\n [compareWith]=\"compareWith\"\n [panelClass]=\"'fs-autocomplete-chips-panel-saved-filter'\"\n (ngModelChange)=\"selectedFilterChange($event)\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n <ng-template\n fsAutocompleteChipsPrefix\n [icon]=\"labelIcon\">\n </ng-template>\n @if (selectedFilter) {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"save()\">\n Save alert filters\n </ng-template>\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"saveAs()\">\n Save as new alert\n </ng-template>\n } @else {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"create()\">\n Create alert\n </ng-template>\n }\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"manageFilters()\">\n Manage {{ pluralLabelLower }}\n </ng-template>\n</fs-autocomplete-chips>", styles: ["fs-autocomplete-chips{width:200px;display:flex;margin-right:5px}fs-autocomplete-chips ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline{margin:0}fs-autocomplete-chips ::ng-deep .prefix-icon{color:#626262}fs-autocomplete-chips ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .fs-autocomplete-chips-panel-saved-filter{max-height:400px!important}\n"] }]
3586
+ }], propDecorators: { savedFiltersController: [{
3587
+ type: Input
3588
+ }] } });
3749
3589
 
3750
- class CheckboxComponent extends BaseItemComponent {
3751
- _kvDiffers;
3752
- _cd;
3753
- constructor(_kvDiffers, _cd) {
3754
- super(_kvDiffers, _cd);
3755
- this._kvDiffers = _kvDiffers;
3756
- this._cd = _cd;
3590
+ class FilterStatusBarDirective {
3591
+ templateRef;
3592
+ constructor(templateRef) {
3593
+ this.templateRef = templateRef;
3757
3594
  }
3758
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CheckboxComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3759
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CheckboxComponent, isStandalone: true, selector: "filter-item-checkbox", usesInheritance: true, ngImport: i0, template: "<fs-label-field>\n <mat-checkbox\n [(ngModel)]=\"item.model\"\n [name]=\"item.name\">\n {{ item.label }}\n </mat-checkbox>\n</fs-label-field>", styles: ["fs-label-field{margin:0 0 -12px -8px}\n"], dependencies: [{ kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i1$4.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3595
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterStatusBarDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
3596
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FilterStatusBarDirective, isStandalone: true, selector: "[fsFilterStatusBar]", ngImport: i0 });
3760
3597
  }
3761
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CheckboxComponent, decorators: [{
3762
- type: Component,
3763
- args: [{ selector: 'filter-item-checkbox', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3764
- FsLabelModule,
3765
- MatCheckbox,
3766
- FormsModule,
3767
- FsFormModule,
3768
- ], template: "<fs-label-field>\n <mat-checkbox\n [(ngModel)]=\"item.model\"\n [name]=\"item.name\">\n {{ item.label }}\n </mat-checkbox>\n</fs-label-field>", styles: ["fs-label-field{margin:0 0 -12px -8px}\n"] }]
3769
- }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
3598
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterStatusBarDirective, decorators: [{
3599
+ type: Directive,
3600
+ args: [{
3601
+ selector: '[fsFilterStatusBar]',
3602
+ standalone: true,
3603
+ }]
3604
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
3770
3605
 
3771
- class FilterItemComponent {
3772
- _cdRef;
3773
- item;
3774
- itemType = ItemType;
3775
- get textItem() {
3776
- return this.item;
3606
+ const FS_FILTER_CONFIG = new InjectionToken('fs.filter-config');
3607
+
3608
+ class FilterComponent {
3609
+ set setConfig(config) {
3610
+ this._initFilterWithConfig(config);
3777
3611
  }
3778
- get chipsItem() {
3779
- return this.item;
3780
- }
3781
- get baseSelectItem() {
3782
- return this.item;
3783
- }
3784
- get rangeItem() {
3785
- return this.item;
3786
- }
3787
- get autocompleteItem() {
3788
- return this.item;
3789
- }
3790
- get autocompleteChipsItem() {
3791
- return this.item;
3792
- }
3793
- get dateItem() {
3794
- return this.item;
3795
- }
3796
- get dateRangeItem() {
3797
- return this.item;
3798
- }
3799
- get dateTimeItem() {
3800
- return this.item;
3801
- }
3802
- get dateTimeRangeItem() {
3803
- return this.item;
3804
- }
3805
- get weekItem() {
3806
- return this.item;
3807
- }
3808
- get checkboxItem() {
3809
- return this.item;
3612
+ set setFilter(config) {
3613
+ this._initFilterWithConfig(config);
3810
3614
  }
3615
+ showSortBy = true;
3616
+ closed = new EventEmitter();
3617
+ opened = new EventEmitter();
3618
+ ready = new EventEmitter();
3619
+ statusBar;
3620
+ keywordMatInput;
3621
+ reloadEl;
3622
+ showFilterMenu = false;
3623
+ windowDesktop = false;
3624
+ fsFilterClass = true;
3625
+ searchPlaceholder = 'Search';
3626
+ keyword = '';
3627
+ autoReload = true;
3628
+ _config = null;
3629
+ _sort;
3630
+ _filtersBtnVisible$ = new BehaviorSubject(true);
3631
+ _keywordVisible$ = new BehaviorSubject(false);
3632
+ _hasFilterChips$ = new BehaviorSubject(false);
3633
+ _keyword$ = new Subject();
3811
3634
  _destroy$ = new Subject();
3812
- constructor(_cdRef) {
3813
- this._cdRef = _cdRef;
3814
- }
3815
- ngOnInit() {
3816
- this.item.value$
3635
+ _dialogRef = inject(MatDialogRef, { optional: true });
3636
+ _drawerRef = inject(DrawerRef, { optional: true });
3637
+ _defaultConfig = inject(FS_FILTER_CONFIG, { optional: true });
3638
+ _filterOverlay = inject(FsFilterOverlayService);
3639
+ _zone = inject(NgZone);
3640
+ _paramController = inject(ParamController);
3641
+ _persistanceController = inject(PersistanceController);
3642
+ _itemStore = inject(ItemStore);
3643
+ _actions = inject(ActionsController);
3644
+ _savedFilterController = inject(SavedFilterController);
3645
+ constructor() {
3646
+ this._itemStore.filter = this;
3647
+ this._listenWhenFilterReady();
3648
+ this._updateWindowWidth();
3649
+ const iconRegistry = inject(MatIconRegistry);
3650
+ const sanitizer = inject(DomSanitizer);
3651
+ iconRegistry.addSvgIconLiteral('filterOutline', sanitizer.bypassSecurityTrustHtml(FilterIcon));
3652
+ this._filterOverlay.attach$
3817
3653
  .pipe(takeUntil(this._destroy$))
3818
3654
  .subscribe(() => {
3819
- this._cdRef.markForCheck();
3655
+ this.showFilterMenu = true;
3656
+ });
3657
+ this._filterOverlay.detach$
3658
+ .pipe(takeUntil(this._destroy$))
3659
+ .subscribe(() => {
3660
+ this.showFilterMenu = false;
3820
3661
  });
3662
+ this._listenWindowResize();
3821
3663
  }
3822
- ngOnDestroy() {
3823
- this._destroy$.next(null);
3824
- this._destroy$.complete();
3664
+ get config() {
3665
+ return this._config;
3825
3666
  }
3826
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterItemComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3827
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilterItemComponent, isStandalone: true, selector: "filter-item", inputs: { item: "item" }, ngImport: i0, template: "<div class=\"filter filter-{{ item.type }}\">\n\n @switch (item.type) {\n @case (itemType.Text) {\n <filter-item-text\n class=\"interface\"\n [item]=\"textItem\">\n </filter-item-text>\n }\n @case (itemType.Select) {\n <filter-item-select\n class=\"interface\"\n [item]=\"baseSelectItem\">\n </filter-item-select>\n }\n @case (itemType.Chips) {\n <filter-item-chips\n class=\"interface\"\n [item]=\"chipsItem\">\n </filter-item-chips>\n }\n @case (itemType.Range) {\n <filter-item-range\n class=\"interface interface-range\"\n [item]=\"rangeItem\">\n </filter-item-range>\n }\n @case (itemType.AutoComplete) {\n <filter-item-autocomplete\n class=\"interface\"\n [item]=\"autocompleteItem\">\n </filter-item-autocomplete>\n }\n @case (itemType.AutoCompleteChips) {\n <filter-item-autocompletechips\n class=\"interface\"\n [item]=\"autocompleteChipsItem\">\n </filter-item-autocompletechips>\n }\n @case (itemType.Date) {\n <filter-item-date\n class=\"interface interface-date\"\n [item]=\"dateItem\">\n </filter-item-date>\n }\n @case (itemType.DateTime) {\n <filter-item-date\n class=\"interface interface-date\"\n [item]=\"dateTimeItem\">\n </filter-item-date>\n }\n @case (itemType.DateRange) {\n <filter-item-date-range\n class=\"interface interface-date\"\n [item]=\"dateRangeItem\">\n </filter-item-date-range>\n }\n @case (itemType.DateTimeRange) {\n <filter-item-date-range\n class=\"interface interface-date\"\n [item]=\"dateTimeRangeItem\">\n </filter-item-date-range>\n }\n @case (itemType.Week) {\n <filter-item-week\n class=\"interface\"\n [item]=\"weekItem\">\n </filter-item-week>\n }\n @case (itemType.Checkbox) {\n <filter-item-checkbox\n class=\"interface interface-checkbox\"\n [item]=\"checkboxItem\">\n </filter-item-checkbox>\n }\n }\n\n</div>\n", styles: [":host ::ng-deep mat-form-field .mat-form-field-prefix .text-prefix,:host ::ng-deep mat-form-field .mat-form-field-prefix .text-suffix,:host ::ng-deep mat-form-field .mat-form-field-suffix .text-prefix,:host ::ng-deep mat-form-field .mat-form-field-suffix .text-suffix{top:-.25em;position:relative}:host ::ng-deep mat-form-field:not(.mat-form-field-should-float) .mat-form-field-prefix .text-prefix,:host ::ng-deep mat-form-field:not(.mat-form-field-should-float) .mat-form-field-suffix .text-suffix{display:none}\n"], dependencies: [{ kind: "component", type: TextComponent, selector: "filter-item-text" }, { kind: "component", type: SelectComponent, selector: "filter-item-select" }, { kind: "component", type: ChipsComponent, selector: "filter-item-chips" }, { kind: "component", type: RangeComponent, selector: "filter-item-range" }, { kind: "component", type: AutocompleteComponent, selector: "filter-item-autocomplete" }, { kind: "component", type: AutocompletechipsComponent, selector: "filter-item-autocompletechips" }, { kind: "component", type: DateComponent, selector: "filter-item-date" }, { kind: "component", type: DateRangeComponent, selector: "filter-item-date-range" }, { kind: "component", type: WeekComponent, selector: "filter-item-week" }, { kind: "component", type: CheckboxComponent, selector: "filter-item-checkbox" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3828
- }
3829
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterItemComponent, decorators: [{
3830
- type: Component,
3831
- args: [{ selector: 'filter-item', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3832
- TextComponent,
3833
- SelectComponent,
3834
- ChipsComponent,
3835
- RangeComponent,
3836
- AutocompleteComponent,
3837
- AutocompletechipsComponent,
3838
- DateComponent,
3839
- DateRangeComponent,
3840
- WeekComponent,
3841
- CheckboxComponent,
3842
- ], template: "<div class=\"filter filter-{{ item.type }}\">\n\n @switch (item.type) {\n @case (itemType.Text) {\n <filter-item-text\n class=\"interface\"\n [item]=\"textItem\">\n </filter-item-text>\n }\n @case (itemType.Select) {\n <filter-item-select\n class=\"interface\"\n [item]=\"baseSelectItem\">\n </filter-item-select>\n }\n @case (itemType.Chips) {\n <filter-item-chips\n class=\"interface\"\n [item]=\"chipsItem\">\n </filter-item-chips>\n }\n @case (itemType.Range) {\n <filter-item-range\n class=\"interface interface-range\"\n [item]=\"rangeItem\">\n </filter-item-range>\n }\n @case (itemType.AutoComplete) {\n <filter-item-autocomplete\n class=\"interface\"\n [item]=\"autocompleteItem\">\n </filter-item-autocomplete>\n }\n @case (itemType.AutoCompleteChips) {\n <filter-item-autocompletechips\n class=\"interface\"\n [item]=\"autocompleteChipsItem\">\n </filter-item-autocompletechips>\n }\n @case (itemType.Date) {\n <filter-item-date\n class=\"interface interface-date\"\n [item]=\"dateItem\">\n </filter-item-date>\n }\n @case (itemType.DateTime) {\n <filter-item-date\n class=\"interface interface-date\"\n [item]=\"dateTimeItem\">\n </filter-item-date>\n }\n @case (itemType.DateRange) {\n <filter-item-date-range\n class=\"interface interface-date\"\n [item]=\"dateRangeItem\">\n </filter-item-date-range>\n }\n @case (itemType.DateTimeRange) {\n <filter-item-date-range\n class=\"interface interface-date\"\n [item]=\"dateTimeRangeItem\">\n </filter-item-date-range>\n }\n @case (itemType.Week) {\n <filter-item-week\n class=\"interface\"\n [item]=\"weekItem\">\n </filter-item-week>\n }\n @case (itemType.Checkbox) {\n <filter-item-checkbox\n class=\"interface interface-checkbox\"\n [item]=\"checkboxItem\">\n </filter-item-checkbox>\n }\n }\n\n</div>\n", styles: [":host ::ng-deep mat-form-field .mat-form-field-prefix .text-prefix,:host ::ng-deep mat-form-field .mat-form-field-prefix .text-suffix,:host ::ng-deep mat-form-field .mat-form-field-suffix .text-prefix,:host ::ng-deep mat-form-field .mat-form-field-suffix .text-suffix{top:-.25em;position:relative}:host ::ng-deep mat-form-field:not(.mat-form-field-should-float) .mat-form-field-prefix .text-prefix,:host ::ng-deep mat-form-field:not(.mat-form-field-should-float) .mat-form-field-suffix .text-suffix{display:none}\n"] }]
3843
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
3844
- type: Input
3845
- }] } });
3846
-
3847
- class FilterDrawerComponent {
3848
- inline = false;
3849
- windowDesktop = false;
3850
- savedFilterName = '';
3851
- _clear;
3852
- _done;
3853
- _destroyRef = inject(DestroyRef);
3854
- _savedFilterController = inject(SavedFilterController);
3855
- _message = inject(FsMessage);
3856
- _itemStore = inject(ItemStore);
3857
- _overlayRef = inject(FILTER_DRAWER_OVERLAY);
3858
- _data = inject(FILTER_DRAWER_DATA);
3859
- _paramController = inject(ParamController);
3860
- constructor() {
3861
- this._itemStore.prepareItems();
3862
- this._clear = this._data.clear;
3863
- this._done = this._data.done;
3864
- this.updateWindowWidth();
3667
+ get filterParams() {
3668
+ return this._itemStore.values();
3865
3669
  }
3866
- updateWindowWidth() {
3867
- this.windowDesktop = window.innerWidth > 1200;
3670
+ get inDialog() {
3671
+ return !!this._dialogRef || !!this._drawerRef;
3868
3672
  }
3869
- get items$() {
3870
- return this._itemStore.visibleItems$;
3673
+ get filterParamsQuery() {
3674
+ return this._itemStore.valuesAsQuery();
3871
3675
  }
3872
- get paramCointroller() {
3873
- return this._paramController;
3676
+ get items() {
3677
+ return this._itemStore.items;
3874
3678
  }
3875
- get savedFiltersController() {
3876
- return this._savedFilterController;
3679
+ get visibleItems() {
3680
+ return this._itemStore.items
3681
+ .filter((item) => !item.hidden);
3877
3682
  }
3878
- ngOnInit() {
3879
- this._savedFilterController.activeFilter$
3880
- .pipe(takeUntilDestroyed(this._destroyRef))
3881
- .subscribe((activeFilter) => {
3882
- this.savedFilterName = activeFilter?.name || '';
3883
- });
3683
+ get keywordItem() {
3684
+ return this._itemStore.keywordItem;
3884
3685
  }
3885
- clear() {
3886
- this._clear();
3686
+ get itemsReady$() {
3687
+ return this._itemStore.ready$;
3887
3688
  }
3888
- done() {
3889
- this._done();
3890
- this._overlayRef.detach();
3689
+ get hasFilterChips$() {
3690
+ return this._hasFilterChips$.asObservable();
3891
3691
  }
3892
- backdropClick() {
3893
- this.done();
3692
+ get hasVisibleItemOrSorting() {
3693
+ return this.visibleItems.length > 0 || !!this._itemStore.sortByItem;
3894
3694
  }
3895
- saveSavedFilter = () => {
3896
- return this._savedFilterController
3897
- .save({ name: this.savedFilterName })
3898
- .pipe(tap$1((savedFilter) => {
3899
- this._savedFilterController.setActiveFilter(savedFilter);
3900
- this._message
3901
- .success(`Saved ${this._savedFilterController.singularLabel}`, {
3902
- positionClass: 'toast-bottom-left',
3903
- });
3695
+ get filtersBtnVisible$() {
3696
+ return this._filtersBtnVisible$.asObservable();
3697
+ }
3698
+ get inlineToolbar$() {
3699
+ return combineLatest({
3700
+ keywordVisible: this._keywordVisible$.asObservable(),
3701
+ activeFilter: of(this.savedFiltersController.enabled),
3702
+ })
3703
+ .pipe(map(({ keywordVisible, activeFilter }) => {
3704
+ return !keywordVisible && !activeFilter;
3904
3705
  }));
3905
- };
3906
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3907
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilterDrawerComponent, isStandalone: true, selector: "ng-component", inputs: { inline: "inline" }, host: { listeners: { "window:resize": "updateWindowWidth()" } }, ngImport: i0, template: "<form\n fsForm\n [submit]=\"saveSavedFilter\"\n [dirtySubmitButton]=\"false\">\n <div class=\"filters\">\n <div class=\"filters-wrap\">\n @if (savedFiltersController.activeFilter$ | async) {\n <div class=\"filter-heading\">\n <mat-icon>\n {{ savedFiltersController.labelIcon }}\n </mat-icon>\n <span class=\"text\">\n {{ savedFiltersController.singularLabel }}\n </span>\n </div>\n <div class=\"filter-name\">\n <mat-form-field>\n <mat-label>\n {{ savedFiltersController.singularLabel }} name\n </mat-label>\n <input\n matInput\n required\n [(ngModel)]=\"savedFilterName\"\n name=\"savedFilterName\">\n </mat-form-field>\n <hr>\n <br>\n </div>\n } @else {\n <div class=\"filter-heading\">\n <mat-icon svgIcon=\"filterOutline\"></mat-icon>\n <span class=\"text\">\n Filters\n </span>\n </div>\n }\n <div class=\"overflow-shadow filter-items\">\n <div class=\"overflow-shadow-content\">\n <ng-container *fsSkeleton=\"(paramCointroller.pending$ | async) !== true\">\n @for (filterItem of items$ | async; track filterItem) {\n <filter-item\n class=\"filter-group\"\n [item]=\"filterItem\">\n </filter-item>\n }\n </ng-container>\n </div>\n </div>\n @if ((paramCointroller.pending$ | async) !== true) {\n <fs-filter-drawer-actions\n [savedFiltersController]=\"savedFiltersController\"\n class=\"filter-actions\"\n (clear)=\"clear()\"\n (done)=\"done()\">\n </fs-filter-drawer-actions>\n }\n </div>\n </div>\n @if (!windowDesktop) {\n <div\n class=\"backdrop\"\n (click)=\"backdropClick()\">\n </div>\n }\n</form>", styles: ["@charset \"UTF-8\";@media (max-width: 599px){h1[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"]{margin-top:0}}@media (max-width: 1023px){h1[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"]{margin-top:0}}@media (max-width: 1439px){h1[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"]{margin-top:0}}div[class*=fs-delimit]:not([class*=\".middot\"])>:not(:last-child):after{content:\",\\a0\"}div[class*=fs-delimit][class*=\".middot\"]>:not(:last-child):after{content:\"\\a0\\b7\\a0\"}div[class*=fs-delimit]>*{display:inline-flex}:host ::ng-deep mat-form-field{width:100%}.filter-heading{display:flex;flex-direction:row;align-items:center;box-sizing:border-box;padding:0 25px 20px}.filter-heading mat-icon{margin-right:8px;font-size:24px;line-height:24px}.filter-heading .text{font-weight:400;font-size:19px}.filter-name{padding:0 25px}.filter-name hr{border-color:#a4a4a4;border-top:0;border-left:0;border-right:0}.filter-actions{display:block;box-sizing:border-box;padding:13px}.filter-actions button{margin-right:6px}.filter-actions button:last-child{margin-right:0}.filters{position:fixed;display:block;top:0;right:0;z-index:1002;bottom:0}.filters .filters-wrap{background:#fff;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f;width:100vw;max-width:350px;display:flex;flex-direction:column;padding-top:calc(env(safe-area-inset-top) + 20px);box-sizing:border-box;height:100%}.filters .filters-wrap .filter-items{padding-top:5px;overflow-y:auto;height:auto}.filters .filters-wrap .filter-items .overflow-shadow-content{padding:0 25px;box-sizing:border-box}.filters .filter-group{margin:10px 0 0}.filters .filter-group:first-child{margin:0}.filters .filter label{white-space:nowrap;color:#0000008a}.filters .filter .interface.interface-range input,.filters .filter .interface.interface-range .mat-input-wrapper,.filters .filter .interface.interface-range{text-align:center}.filters .filter .interface.interface-datetime fs-datetime.has-time .md-input{width:100%}.filters .filter .interface fs-datetime-range input{text-align:center}.filters .filter .filter-label{width:1%;white-space:nowrap;vertical-align:middle;padding-right:15px}.filters md-autocomplete-container md-input-container{margin:0}.filters .isolate{margin-top:-12px}.filters .isolate .interface{line-height:20px;padding-bottom:1.25em}.filters .isolate md-checkbox{margin:0 0 0 2px}.backdrop{position:fixed;inset:0;z-index:900;outline:none}@media (max-width: 599px){.filters .filters-wrap{max-width:none}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { kind: "directive", type: i2.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i3$2.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: FilterItemComponent, selector: "filter-item", inputs: ["item"] }, { kind: "component", type: FsFilterDrawerActionsComponent, selector: "fs-filter-drawer-actions", inputs: ["savedFiltersController"], outputs: ["clear", "done"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3908
- }
3909
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterDrawerComponent, decorators: [{
3910
- type: Component,
3911
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3912
- FormsModule,
3913
- FsFormModule,
3914
- MatIcon,
3915
- MatFormField,
3916
- MatLabel,
3917
- MatInput,
3918
- FsSkeletonModule,
3919
- FilterItemComponent,
3920
- FsFilterDrawerActionsComponent,
3921
- AsyncPipe,
3922
- ], template: "<form\n fsForm\n [submit]=\"saveSavedFilter\"\n [dirtySubmitButton]=\"false\">\n <div class=\"filters\">\n <div class=\"filters-wrap\">\n @if (savedFiltersController.activeFilter$ | async) {\n <div class=\"filter-heading\">\n <mat-icon>\n {{ savedFiltersController.labelIcon }}\n </mat-icon>\n <span class=\"text\">\n {{ savedFiltersController.singularLabel }}\n </span>\n </div>\n <div class=\"filter-name\">\n <mat-form-field>\n <mat-label>\n {{ savedFiltersController.singularLabel }} name\n </mat-label>\n <input\n matInput\n required\n [(ngModel)]=\"savedFilterName\"\n name=\"savedFilterName\">\n </mat-form-field>\n <hr>\n <br>\n </div>\n } @else {\n <div class=\"filter-heading\">\n <mat-icon svgIcon=\"filterOutline\"></mat-icon>\n <span class=\"text\">\n Filters\n </span>\n </div>\n }\n <div class=\"overflow-shadow filter-items\">\n <div class=\"overflow-shadow-content\">\n <ng-container *fsSkeleton=\"(paramCointroller.pending$ | async) !== true\">\n @for (filterItem of items$ | async; track filterItem) {\n <filter-item\n class=\"filter-group\"\n [item]=\"filterItem\">\n </filter-item>\n }\n </ng-container>\n </div>\n </div>\n @if ((paramCointroller.pending$ | async) !== true) {\n <fs-filter-drawer-actions\n [savedFiltersController]=\"savedFiltersController\"\n class=\"filter-actions\"\n (clear)=\"clear()\"\n (done)=\"done()\">\n </fs-filter-drawer-actions>\n }\n </div>\n </div>\n @if (!windowDesktop) {\n <div\n class=\"backdrop\"\n (click)=\"backdropClick()\">\n </div>\n }\n</form>", styles: ["@charset \"UTF-8\";@media (max-width: 599px){h1[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"]{margin-top:0}}@media (max-width: 1023px){h1[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"]{margin-top:0}}@media (max-width: 1439px){h1[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"]{margin-top:0}}div[class*=fs-delimit]:not([class*=\".middot\"])>:not(:last-child):after{content:\",\\a0\"}div[class*=fs-delimit][class*=\".middot\"]>:not(:last-child):after{content:\"\\a0\\b7\\a0\"}div[class*=fs-delimit]>*{display:inline-flex}:host ::ng-deep mat-form-field{width:100%}.filter-heading{display:flex;flex-direction:row;align-items:center;box-sizing:border-box;padding:0 25px 20px}.filter-heading mat-icon{margin-right:8px;font-size:24px;line-height:24px}.filter-heading .text{font-weight:400;font-size:19px}.filter-name{padding:0 25px}.filter-name hr{border-color:#a4a4a4;border-top:0;border-left:0;border-right:0}.filter-actions{display:block;box-sizing:border-box;padding:13px}.filter-actions button{margin-right:6px}.filter-actions button:last-child{margin-right:0}.filters{position:fixed;display:block;top:0;right:0;z-index:1002;bottom:0}.filters .filters-wrap{background:#fff;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f;width:100vw;max-width:350px;display:flex;flex-direction:column;padding-top:calc(env(safe-area-inset-top) + 20px);box-sizing:border-box;height:100%}.filters .filters-wrap .filter-items{padding-top:5px;overflow-y:auto;height:auto}.filters .filters-wrap .filter-items .overflow-shadow-content{padding:0 25px;box-sizing:border-box}.filters .filter-group{margin:10px 0 0}.filters .filter-group:first-child{margin:0}.filters .filter label{white-space:nowrap;color:#0000008a}.filters .filter .interface.interface-range input,.filters .filter .interface.interface-range .mat-input-wrapper,.filters .filter .interface.interface-range{text-align:center}.filters .filter .interface.interface-datetime fs-datetime.has-time .md-input{width:100%}.filters .filter .interface fs-datetime-range input{text-align:center}.filters .filter .filter-label{width:1%;white-space:nowrap;vertical-align:middle;padding-right:15px}.filters md-autocomplete-container md-input-container{margin:0}.filters .isolate{margin-top:-12px}.filters .isolate .interface{line-height:20px;padding-bottom:1.25em}.filters .isolate md-checkbox{margin:0 0 0 2px}.backdrop{position:fixed;inset:0;z-index:900;outline:none}@media (max-width: 599px){.filters .filters-wrap{max-width:none}}\n"] }]
3923
- }], ctorParameters: () => [], propDecorators: { inline: [{
3924
- type: Input
3925
- }], updateWindowWidth: [{
3926
- type: HostListener,
3927
- args: ['window:resize']
3928
- }] } });
3929
-
3930
- class ActionsController {
3931
- _breakpointObserver;
3932
- _visible$ = new BehaviorSubject(false);
3933
- _actions$ = new BehaviorSubject([]);
3934
- _menuActions$ = new BehaviorSubject([]);
3935
- _destroy$ = new Subject();
3936
- _config;
3937
- _mobileMedia = '(max-width: 799px)';
3938
- _allActions = [];
3939
- _reorderAction;
3940
- constructor(_breakpointObserver) {
3941
- this._breakpointObserver = _breakpointObserver;
3942
- this._listenMobileMedia();
3943
3706
  }
3944
- get menuActions() {
3945
- return this._menuActions$.value;
3707
+ get notInlineToolbar$() {
3708
+ return this.inlineToolbar$
3709
+ .pipe(map((inline) => !inline));
3946
3710
  }
3947
- get actions() {
3948
- return this._actions$.value;
3711
+ get keywordVisible$() {
3712
+ return this._keywordVisible$.asObservable();
3713
+ }
3714
+ get actionsVisible$() {
3715
+ return this._actions.visible$;
3949
3716
  }
3950
3717
  get actions$() {
3951
- return this._actions$.asObservable();
3718
+ return this._actions.actions$;
3952
3719
  }
3953
3720
  get menuActions$() {
3954
- return this._menuActions$.asObservable();
3721
+ return this._actions.menuActions$;
3955
3722
  }
3956
- get visible$() {
3957
- return this._visible$.asObservable();
3723
+ set activeSavedFilter(savedFilter) {
3724
+ this._savedFilterController.setActiveFilter(savedFilter);
3958
3725
  }
3959
- get mobileMode() {
3960
- return this._breakpointObserver.isMatched(this._mobileMedia);
3726
+ get activeSavedFilter() {
3727
+ return this._savedFilterController.activeFilter;
3961
3728
  }
3962
- ngOnDestroy() {
3963
- this._destroy$.next(null);
3964
- this._destroy$.complete();
3729
+ get savedFilters() {
3730
+ return this._savedFilterController.savedFilters;
3965
3731
  }
3966
- setConfig(config) {
3967
- this._config = config;
3968
- this.initActions(config.actions);
3732
+ get savedFiltersController() {
3733
+ return this._savedFilterController;
3969
3734
  }
3970
- initActions(rawActions) {
3971
- if (!rawActions || !Array.isArray(rawActions)) {
3972
- return;
3973
- }
3974
- this.show();
3975
- this._allActions = rawActions
3976
- .map((action) => new Action(this._config, action));
3977
- if (this._reorderAction) {
3978
- this._allActions.unshift(this._reorderAction);
3979
- }
3980
- this._classifyActions();
3981
- }
3982
- show() {
3983
- this._visible$.next(true);
3984
- }
3985
- hide() {
3986
- this._visible$.next(false);
3987
- }
3988
- addReorderAction(action) {
3989
- this._allActions.unshift(action);
3990
- action.isReorderAction = true;
3991
- this._classifyAction(action);
3992
- this._reorderAction = action;
3993
- }
3994
- clearActions() {
3995
- this._allActions = [];
3996
- this._setActions([]);
3997
- this._setKebabActions([]);
3998
- }
3999
- updateActionsVisibility() {
4000
- this._allActions.forEach((action) => action.updateVisibility());
4001
- this._classifyActions();
3735
+ ngOnInit() {
3736
+ this._initAutoFocus();
3737
+ this._initAutoReload();
3738
+ this._listenInputChanges();
3739
+ this._listenInternalItemsChange();
3740
+ this._initKeywordVisibility();
3741
+ this._initOverlay();
4002
3742
  }
4003
- updateDisabledState() {
4004
- this.actions.forEach((action) => action.updateDisabledState());
3743
+ ngOnDestroy() {
3744
+ this._destroyFilterDrawer();
3745
+ this._destroy$.next(null);
3746
+ this._destroy$.complete();
4005
3747
  }
4006
- _setKebabActions(actions) {
4007
- this._menuActions$.next(actions);
3748
+ focus() {
3749
+ this.keywordMatInput?.focus();
4008
3750
  }
4009
- _setActions(actions) {
4010
- this._actions$.next(actions);
3751
+ updateSort(sort) {
3752
+ this._itemStore.updateSort(sort);
4011
3753
  }
4012
- _classifyActions() {
4013
- const kebabActions = [];
4014
- const actions = [];
4015
- const mobileMode = this.mobileMode;
4016
- this._allActions
4017
- .filter((action) => {
4018
- return action.visible;
4019
- })
4020
- .forEach((action) => {
4021
- if (action.menu !== false && (action.menu || mobileMode)) {
4022
- kebabActions.push(action);
4023
- }
4024
- else {
4025
- actions.push(action);
3754
+ /**
3755
+ *
3756
+ * Do update value of some field
3757
+ *
3758
+ * @param values - values for update
3759
+ *
3760
+ * To update text value just pass new text value
3761
+ *
3762
+ * public updateSelectValue(val) {
3763
+ * this.filterEl.updateValues({ keyword: val });
3764
+ * }
3765
+ *
3766
+ * To update select or observable select you could pass suitable value
3767
+ *
3768
+ * public updateSelectValue(val: number) {
3769
+ * this.filterEl.updateValues({ simple_select: val }, { observable_select: val });
3770
+ * }
3771
+ *
3772
+ * To update checkbox value just pass true/false as value
3773
+ *
3774
+ * public updateCheckox(val: boolean) {
3775
+ * this.filterEl.updateValues({ checkbox: val });
3776
+ * }
3777
+ *
3778
+ * To update range value just pass object with min&max object or just with one of targets
3779
+ *
3780
+ * Ex.: { min: 10, max 15 }, { min: 5 }, { max 5 }
3781
+ *
3782
+ * public updateRange(val) {
3783
+ * this.filterEl.updateValues({ range: val });
3784
+ * }
3785
+ *
3786
+ * To update autocomplete just pass object with name/value fields
3787
+ *
3788
+ * Ex.: { name: 'John Doe', value: 1 }
3789
+ *
3790
+ * public updateAutocomplete(val) {
3791
+ * this.filterEl.updateValues({ autocomplete_user_id: val });
3792
+ * }
3793
+ *
3794
+ * To update autocompletechips just pass:
3795
+ *
3796
+ * 1) object with name/value fields - will be appended to existing set of values
3797
+ *
3798
+ * { name: 'John Doe', value: 1 }
3799
+ *
3800
+ * 2) array of objects - will be appended to existing set of values
3801
+ *
3802
+ * [{ name: 'John Doe', value: 1 }, { name: 'Darya Filipova', value: 2 }]
3803
+ *
3804
+ * 3) null - clear existing set of values
3805
+ *
3806
+ * public updateAutocomplete(val) {
3807
+ * this.filterEl.updateValues({ autocompletechips_user_id: val });
3808
+ * }
3809
+ *
3810
+ */
3811
+ updateValues(values) {
3812
+ Object.keys(values).forEach((key) => {
3813
+ const filterItem = this.items
3814
+ .find((item) => item.name === key);
3815
+ if (!filterItem) {
3816
+ return;
4026
3817
  }
3818
+ filterItem.model = values[key];
4027
3819
  });
4028
- this._setKebabActions(kebabActions);
4029
- this._setActions(actions);
4030
3820
  }
4031
- _classifyAction(action) {
4032
- if (action.menu) {
4033
- this._setKebabActions([...this.menuActions, action]);
3821
+ hideDrawer() {
3822
+ this.closed.emit();
3823
+ this._destroyFilterDrawer();
3824
+ }
3825
+ showDrawer() {
3826
+ if (!this.hasVisibleItemOrSorting) {
3827
+ return;
3828
+ }
3829
+ this._listenEscButton();
3830
+ this.opened.emit();
3831
+ this._filterOverlay.open();
3832
+ }
3833
+ filterButtonClick(event = null) {
3834
+ event.stopPropagation();
3835
+ if (this._filterOverlay.opened()) {
3836
+ this.hideDrawer();
4034
3837
  }
4035
3838
  else {
4036
- this._setActions([...this.actions, action]);
3839
+ this.showDrawer();
4037
3840
  }
4038
3841
  }
4039
- _listenMobileMedia() {
4040
- this._breakpointObserver.observe(this._mobileMedia)
4041
- .pipe(skip(1), takeUntil(this._destroy$))
4042
- .subscribe(() => {
4043
- this._classifyActions();
4044
- });
3842
+ get itemValues() {
3843
+ return this.items
3844
+ .map((item) => item.value);
4045
3845
  }
4046
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionsController, deps: [{ token: i1$5.BreakpointObserver }], target: i0.ɵɵFactoryTarget.Injectable });
4047
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionsController });
4048
- }
4049
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionsController, decorators: [{
4050
- type: Injectable
4051
- }], ctorParameters: () => [{ type: i1$5.BreakpointObserver }] });
4052
-
4053
- const FilterIcon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M440-160q-17 0-28.5-11.5T400-200v-240L161-745q-14-17-4-36t31-19h584q21 0 31 19t-4 36L560-440v240q0 17-11.5 28.5T520-160h-80Zm40-276 240-304H240l240 304Zm0 0Z"/></svg>';
4054
-
4055
- class FsFilterSavedFilterChipsComponent {
4056
- savedFilter;
4057
- items = [];
4058
- _itemStore = inject(ItemStore);
4059
- ngOnInit() {
4060
- this.items = [...this._itemStore.items]
4061
- .filter((item) => !!this.savedFilter.filters[item.name])
4062
- .map((item) => {
4063
- item.setModel(this.savedFilter.filters[item.name]);
4064
- return item;
4065
- });
3846
+ get nonEmptyItemValues() {
3847
+ return this.items
3848
+ .filter((item) => item.value !== undefined)
3849
+ .map((item) => item.value);
4066
3850
  }
4067
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4068
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsFilterSavedFilterChipsComponent, isStandalone: true, selector: "fs-saved-filter-chips", inputs: { savedFilter: "savedFilter" }, ngImport: i0, template: "<div class=\"filter-chips\">\n @for (item of items; track item.name) {\n <fs-filter-chip [item]=\"item\"></fs-filter-chip>\n }\n</div>", styles: [".filter-chips{display:flex;flex-wrap:wrap;gap:4px}\n"], dependencies: [{ kind: "component", type: FsFilterChipComponent, selector: "fs-filter-chip", inputs: ["item", "removable", "clickable"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4069
- }
4070
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterChipsComponent, decorators: [{
4071
- type: Component,
4072
- args: [{ selector: 'fs-saved-filter-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4073
- FsFilterChipComponent,
4074
- ], template: "<div class=\"filter-chips\">\n @for (item of items; track item.name) {\n <fs-filter-chip [item]=\"item\"></fs-filter-chip>\n }\n</div>", styles: [".filter-chips{display:flex;flex-wrap:wrap;gap:4px}\n"] }]
4075
- }], propDecorators: { savedFilter: [{
4076
- type: Input
4077
- }] } });
4078
-
4079
- class FsFilterSavedFilterManageComponent {
4080
- savedFilters;
4081
- _savedFilterController = inject(SavedFilterController);
4082
- _cdRef = inject(ChangeDetectorRef);
4083
- _paramController = inject(ParamController);
4084
- _itemStore = inject(ItemStore);
4085
- _dialogRef = inject(MatDialogRef);
4086
- _filterOverlayService = inject(FsFilterOverlayService);
4087
- ngOnInit() {
4088
- this.savedFilters = this._savedFilterController.savedFilters;
3851
+ get hasItemValues() {
3852
+ return this.items
3853
+ .some((item) => item.value !== undefined);
4089
3854
  }
4090
- get items() {
4091
- return this._itemStore.items;
3855
+ getItemValue(name) {
3856
+ const item = this.items
3857
+ .find((_item) => _item.name === name);
3858
+ return item?.value;
4092
3859
  }
4093
- get pluralLabelLower() {
4094
- return this._savedFilterController.pluralLabelLower;
3860
+ showItem(name) {
3861
+ this.getItem(name)?.show();
4095
3862
  }
4096
- get sortable() {
4097
- return this._savedFilterController.orderable;
3863
+ hideItem(name) {
3864
+ this.getItem(name)?.hide();
4098
3865
  }
4099
- selectFilter(savedFilter) {
4100
- this._savedFilterController.setActiveFilter(savedFilter);
4101
- this._filterOverlayService.open();
4102
- this._dialogRef.close();
3866
+ clearItem(name) {
3867
+ const item = this.getItem(name);
3868
+ if (!item) {
3869
+ return;
3870
+ }
3871
+ item.clear();
4103
3872
  }
4104
- remove(savedFilter) {
4105
- this._savedFilterController.delete(savedFilter)
4106
- .subscribe(() => {
4107
- this.savedFilters = this._savedFilterController.savedFilters;
4108
- this._cdRef.markForCheck();
4109
- });
3873
+ updateItemConfig(name, params) {
3874
+ const item = this.getItem(name);
3875
+ if (!item) {
3876
+ return;
3877
+ }
3878
+ item.label = params.label ?? item.label;
3879
+ item.chipLabel = params.chipLabel ?? item.chipLabel;
4110
3880
  }
4111
- order(savedFilters) {
4112
- this._savedFilterController.order(savedFilters)
4113
- .subscribe();
3881
+ getItemValueChange$(name) {
3882
+ const item = this.items.find((i) => i.name === name);
3883
+ if (item) {
3884
+ return item.value$
3885
+ .pipe(map(() => {
3886
+ return item.model;
3887
+ }));
3888
+ }
3889
+ return null;
4114
3890
  }
4115
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterManageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4116
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsFilterSavedFilterManageComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<h1 mat-dialog-title>\n Manage {{ pluralLabelLower }}\n</h1>\n<div mat-dialog-content>\n <table class=\"fs-list-table\">\n <thead>\n <tr>\n <th>\n Name\n </th>\n <th>\n Filters\n </th>\n <th class=\"actions-column\"></th>\n </tr>\n </thead>\n <tbody>\n @for (savedFilter of savedFilters; track savedFilter.id) {\n <tr>\n <td>\n <a (click)=\"selectFilter(savedFilter)\">\n {{ savedFilter.name }}\n </a>\n </td>\n <td>\n <fs-saved-filter-chips [savedFilter]=\"savedFilter\"></fs-saved-filter-chips>\n </td>\n <td>\n <fs-menu>\n <ng-template\n fs-menu-item\n (click)=\"remove(savedFilter)\">\n Delete\n </ng-template>\n </fs-menu>\n </td>\n </tr>\n }\n </tbody>\n </table>\n</div>\n<div mat-dialog-actions>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n</div>", styles: ["::ng-deep .fs-list-table{border-spacing:0;display:table;width:100%;border-collapse:collapse}::ng-deep .fs-list-table thead{display:table-header-group}::ng-deep .fs-list-table thead th{color:#999;padding:8px;font-weight:400;color:#8f8f8f;font-size:85%;text-align:left}::ng-deep .fs-list-table tbody{display:table-row-group;position:relative}::ng-deep .fs-list-table tbody tr,::ng-deep .fs-list-table thead tr,::ng-deep .fs-list-table tfoot tr{display:table-row}::ng-deep .fs-list-table tbody tr td,::ng-deep .fs-list-table thead tr td,::ng-deep .fs-list-table tfoot tr td{display:table-cell;padding:8px;vertical-align:middle;outline:none;text-align:left}::ng-deep .fs-list-table tfoot td{padding:8px}::ng-deep .fs-list-table.style-card tbody tr:not(.fs-list-row-group-footer):not(.fs-list-row-group){clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}::ng-deep .fs-list-table.style-card tbody tr td{border:none!important;background-color:#fafafa;padding:8px 16px}::ng-deep .fs-list-table.style-line tbody td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody td{box-sizing:border-box;border-top:1px solid #e7e7e7}::ng-deep .fs-list-table.style-line tbody tr:first-child td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody tr:first-child td{border-color:#c4c4c4}::ng-deep .fs-list-table.style-line tbody tr:last-child td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody tr:last-child td{border-bottom:1px solid #c4c4c4}::ng-deep .fs-list-table.style-line .fs-list-container.has-dragging thead th,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) .fs-list-container.has-dragging thead th{border-color:#e7e7e7}::ng-deep .fs-list-table.style-line .fs-list-container.has-dragging tbody tr:nth-child(2) td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) .fs-list-container.has-dragging tbody tr:nth-child(2) td{border-top:none}:host ::ng-deep .mat-mdc-dialog-content{width:800px;max-width:100%}.actions-column{width:1%}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$6.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$6.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$6.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$6.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: FsFilterSavedFilterChipsComponent, selector: "fs-saved-filter-chips", inputs: ["savedFilter"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i2$1.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i2$1.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4117
- }
4118
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterManageComponent, decorators: [{
4119
- type: Component,
4120
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4121
- MatDialogModule,
4122
- MatButton,
4123
- FsFilterSavedFilterChipsComponent,
4124
- FsMenuModule,
4125
- ], template: "<h1 mat-dialog-title>\n Manage {{ pluralLabelLower }}\n</h1>\n<div mat-dialog-content>\n <table class=\"fs-list-table\">\n <thead>\n <tr>\n <th>\n Name\n </th>\n <th>\n Filters\n </th>\n <th class=\"actions-column\"></th>\n </tr>\n </thead>\n <tbody>\n @for (savedFilter of savedFilters; track savedFilter.id) {\n <tr>\n <td>\n <a (click)=\"selectFilter(savedFilter)\">\n {{ savedFilter.name }}\n </a>\n </td>\n <td>\n <fs-saved-filter-chips [savedFilter]=\"savedFilter\"></fs-saved-filter-chips>\n </td>\n <td>\n <fs-menu>\n <ng-template\n fs-menu-item\n (click)=\"remove(savedFilter)\">\n Delete\n </ng-template>\n </fs-menu>\n </td>\n </tr>\n }\n </tbody>\n </table>\n</div>\n<div mat-dialog-actions>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n</div>", styles: ["::ng-deep .fs-list-table{border-spacing:0;display:table;width:100%;border-collapse:collapse}::ng-deep .fs-list-table thead{display:table-header-group}::ng-deep .fs-list-table thead th{color:#999;padding:8px;font-weight:400;color:#8f8f8f;font-size:85%;text-align:left}::ng-deep .fs-list-table tbody{display:table-row-group;position:relative}::ng-deep .fs-list-table tbody tr,::ng-deep .fs-list-table thead tr,::ng-deep .fs-list-table tfoot tr{display:table-row}::ng-deep .fs-list-table tbody tr td,::ng-deep .fs-list-table thead tr td,::ng-deep .fs-list-table tfoot tr td{display:table-cell;padding:8px;vertical-align:middle;outline:none;text-align:left}::ng-deep .fs-list-table tfoot td{padding:8px}::ng-deep .fs-list-table.style-card tbody tr:not(.fs-list-row-group-footer):not(.fs-list-row-group){clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}::ng-deep .fs-list-table.style-card tbody tr td{border:none!important;background-color:#fafafa;padding:8px 16px}::ng-deep .fs-list-table.style-line tbody td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody td{box-sizing:border-box;border-top:1px solid #e7e7e7}::ng-deep .fs-list-table.style-line tbody tr:first-child td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody tr:first-child td{border-color:#c4c4c4}::ng-deep .fs-list-table.style-line tbody tr:last-child td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) tbody tr:last-child td{border-bottom:1px solid #c4c4c4}::ng-deep .fs-list-table.style-line .fs-list-container.has-dragging thead th,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) .fs-list-container.has-dragging thead th{border-color:#e7e7e7}::ng-deep .fs-list-table.style-line .fs-list-container.has-dragging tbody tr:nth-child(2) td,::ng-deep .fs-list-table:not(.style-card):not(.style-basic) .fs-list-container.has-dragging tbody tr:nth-child(2) td{border-top:none}:host ::ng-deep .mat-mdc-dialog-content{width:800px;max-width:100%}.actions-column{width:1%}\n"] }]
4126
- }] });
4127
-
4128
- class FsSavedFilterAutocompleteChipsComponent {
4129
- savedFiltersController;
4130
- selectedFilter;
4131
- _itemStore = inject(ItemStore);
4132
- _paramController = inject(ParamController);
4133
- _dialog = inject(MatDialog);
4134
- _destroyRef = inject(DestroyRef);
4135
- _injector = inject(Injector);
4136
- _cdRef = inject(ChangeDetectorRef);
4137
- _prompt = inject(FsPrompt);
4138
- _message = inject(FsMessage);
4139
- get filters$() {
4140
- return this.savedFiltersController.savedFilters$;
4141
- }
4142
- get activeFilter$() {
4143
- return this.savedFiltersController.activeFilter$;
3891
+ init() {
3892
+ const data = this._itemStore.valuesAsQuery();
3893
+ this._sort = this._itemStore.getSort();
3894
+ if (this.config.init) {
3895
+ this.config.init(data, this._sort, this);
3896
+ }
3897
+ this._updateChipsVisibility();
3898
+ this.items
3899
+ .forEach((item) => {
3900
+ item.init(item, this);
3901
+ });
4144
3902
  }
4145
- get pluralLabelLower() {
4146
- return this.savedFiltersController.pluralLabelLower;
3903
+ clear(event = null) {
3904
+ if (event) {
3905
+ event.stopPropagation();
3906
+ }
3907
+ this._itemStore.filtersClear();
3908
+ if (this.config.clear) {
3909
+ this.config.clear();
3910
+ }
3911
+ this.keyword = '';
4147
3912
  }
4148
- get pluralLabel() {
4149
- return this.savedFiltersController.pluralLabel;
3913
+ reload(event = null) {
3914
+ if (event) {
3915
+ event.preventDefault();
3916
+ event.stopPropagation();
3917
+ }
3918
+ const data = this._itemStore.valuesAsQuery();
3919
+ const el = this.reloadEl?.nativeElement;
3920
+ if (el) {
3921
+ el.style.transition = 'all 0.75s 0.0s';
3922
+ el.style.transform = 'rotate(360deg)';
3923
+ setTimeout(() => {
3924
+ el.style.transition = null;
3925
+ el.style.transform = null;
3926
+ }, 1000);
3927
+ }
3928
+ if (this.config.reload) {
3929
+ this.config.reload(data, this._itemStore.getSort());
3930
+ }
4150
3931
  }
4151
- get labelIcon() {
4152
- return this.savedFiltersController.labelIcon;
3932
+ getItem(name) {
3933
+ return this.items
3934
+ .find((item) => item.name === name);
4153
3935
  }
4154
- compareWith = (o1, o2) => {
4155
- return o1?.id === o2?.id;
4156
- };
4157
- selectFilter(savedFilter) {
4158
- this.savedFiltersController.setActiveFilter(savedFilter);
3936
+ fetchQueryParams() {
3937
+ this._paramController.fetchQueryParams();
4159
3938
  }
4160
- selectedFilterChange(savedFilter) {
4161
- this.savedFiltersController.setActiveFilter(savedFilter);
4162
- if (!savedFilter) {
4163
- this._itemStore.filtersClear();
3939
+ /**
3940
+ * Call change callback and apply new filter values
3941
+ */
3942
+ change() {
3943
+ const valuesAsQuery = this._itemStore.valuesAsQuery();
3944
+ const sort = this._itemStore.getSort();
3945
+ const sortingChanged = ((!sort || !this._sort) && sort !== this._sort)
3946
+ || (sort && this._sort && !objectsAreEquals(this._sort, sort));
3947
+ if (sortingChanged) {
3948
+ this._sort = sort;
3949
+ if (this.config.sortChange) {
3950
+ this.config.sortChange(valuesAsQuery, sort);
3951
+ }
4164
3952
  }
3953
+ if (this.config.change) {
3954
+ this.config.change(valuesAsQuery, sort);
3955
+ }
3956
+ this._updateChipsVisibility();
3957
+ // visibility for actions can depend on filters state
3958
+ this._actions.updateActionsVisibility();
4165
3959
  }
4166
- ngOnInit() {
4167
- this.savedFiltersController.activeFilter$
4168
- .pipe(takeUntilDestroyed(this._destroyRef))
4169
- .subscribe((savedFilter) => {
4170
- this.selectedFilter = savedFilter;
4171
- this._cdRef.markForCheck();
4172
- });
3960
+ /**
3961
+ * Update filter actions config
3962
+ *
3963
+ * @param actions
3964
+ */
3965
+ updateActions(actions) {
3966
+ this._actions.initActions(actions);
4173
3967
  }
4174
- save() {
4175
- this.savedFiltersController
4176
- .save(this.selectedFilter)
4177
- .pipe(tap$1(() => {
4178
- this._message.success(`Saved ${this.savedFiltersController.singularLabel}`);
4179
- }))
4180
- .subscribe();
3968
+ /**
3969
+ * Show "Filters" button
3970
+ */
3971
+ showFiltersBtn() {
3972
+ this._filtersBtnVisible$.next(true);
4181
3973
  }
4182
- create() {
4183
- this.savedFiltersController.create()
4184
- .pipe(tap$1(() => {
4185
- this._message
4186
- .success(`Created ${this.savedFiltersController.singularLabel}`);
4187
- }))
4188
- .subscribe();
3974
+ /**
3975
+ * Hide "Filters" button
3976
+ */
3977
+ hideFiltersBtn() {
3978
+ this._filtersBtnVisible$.next(false);
4189
3979
  }
4190
- saveAs() {
4191
- this._prompt.input({
4192
- title: 'Save as new alert',
4193
- label: 'Name',
4194
- required: true,
4195
- commitLabel: 'Save',
4196
- dialogConfig: {
4197
- restoreFocus: false,
4198
- },
4199
- })
4200
- .pipe(switchMap$1((name) => {
4201
- const data = {
4202
- id: null,
4203
- name,
4204
- };
4205
- return this.savedFiltersController.save(data);
4206
- }), tap$1(() => {
4207
- this._message.success(`Saved ${this.savedFiltersController.singularLabel}`);
4208
- }))
4209
- .subscribe();
3980
+ /**
3981
+ * Show "Keyword" field if it present
3982
+ */
3983
+ showKeywordField() {
3984
+ this._keywordVisible$.next(true);
4210
3985
  }
4211
- fetch = (query) => {
4212
- return this.savedFiltersController.savedFilters$
4213
- .pipe(map$1((filters) => filters
4214
- .filter((filter) => filter
4215
- .name.toLowerCase().includes(query.toLowerCase()))));
4216
- };
4217
- manageFilters() {
4218
- this._dialog
4219
- .open(FsFilterSavedFilterManageComponent, {
4220
- injector: this._injector,
4221
- restoreFocus: false,
4222
- });
3986
+ /**
3987
+ * Hide "Keyword" field if it present
3988
+ */
3989
+ hideKeywordField() {
3990
+ this._keywordVisible$.next(false);
4223
3991
  }
4224
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsSavedFilterAutocompleteChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4225
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsSavedFilterAutocompleteChipsComponent, isStandalone: true, selector: "fs-saved-filter-autocomplete-chips", inputs: { savedFiltersController: "savedFiltersController" }, ngImport: i0, template: "<fs-autocomplete-chips\n [fetch]=\"fetch\"\n [size]=\"'small'\"\n [multiple]=\"false\"\n [placeholder]=\"pluralLabel\"\n [(ngModel)]=\"selectedFilter\"\n [compareWith]=\"compareWith\"\n [panelClass]=\"'fs-autocomplete-chips-panel-saved-filter'\"\n (ngModelChange)=\"selectedFilterChange($event)\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n <ng-template\n fsAutocompleteChipsPrefix\n [icon]=\"labelIcon\">\n </ng-template>\n @if (selectedFilter) {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"save()\">\n Save alert filters\n </ng-template>\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"saveAs()\">\n Save as new alert\n </ng-template>\n } @else {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"create()\">\n Create alert\n </ng-template>\n }\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"manageFilters()\">\n Manage {{ pluralLabelLower }}\n </ng-template>\n</fs-autocomplete-chips>", styles: ["fs-autocomplete-chips{width:200px;display:flex;margin-right:5px}fs-autocomplete-chips ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline{margin:0}fs-autocomplete-chips ::ng-deep .prefix-icon{color:#626262}fs-autocomplete-chips ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .fs-autocomplete-chips-panel-saved-filter{max-height:400px!important}\n"], dependencies: [{ kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i1$3.FsAutocompleteChipsComponent, selector: "fs-autocomplete-chips", inputs: ["fetch", "appearance", "floatLabel", "readonly", "size", "label", "placeholder", "chipMargin", "chipImage", "chipBackground", "chipColor", "chipIcon", "chipIconColor", "chipClass", "chipPadding", "shape", "hint", "allowText", "allowObject", "delay", "minPanelWidth", "validateText", "removable", "allowClear", "color", "background", "orderable", "padless", "initOnClick", "fetchOnFocus", "multiple", "multipleAdd", "confirm", "disabled", "groupBy", "panelWidth", "panelClass", "compareWith"], outputs: ["selected", "removed", "reordered", "clear"] }, { kind: "directive", type: i1$3.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "directive", type: i1$3.FsAutocompleteChipsStaticDirective, selector: "[fsAutocompleteChipsStatic]", inputs: ["show", "disable"], outputs: ["click", "selected"] }, { kind: "directive", type: i1$3.FsAutocompleteChipsPrefixDirective, selector: "[fsAutocompleteChipsPrefix]", inputs: ["icon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4226
- }
4227
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsSavedFilterAutocompleteChipsComponent, decorators: [{
4228
- type: Component,
4229
- args: [{ selector: 'fs-saved-filter-autocomplete-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4230
- FsAutocompleteChipsModule,
4231
- FormsModule,
4232
- ], template: "<fs-autocomplete-chips\n [fetch]=\"fetch\"\n [size]=\"'small'\"\n [multiple]=\"false\"\n [placeholder]=\"pluralLabel\"\n [(ngModel)]=\"selectedFilter\"\n [compareWith]=\"compareWith\"\n [panelClass]=\"'fs-autocomplete-chips-panel-saved-filter'\"\n (ngModelChange)=\"selectedFilterChange($event)\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n <ng-template\n fsAutocompleteChipsPrefix\n [icon]=\"labelIcon\">\n </ng-template>\n @if (selectedFilter) {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"save()\">\n Save alert filters\n </ng-template>\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"saveAs()\">\n Save as new alert\n </ng-template>\n } @else {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"create()\">\n Create alert\n </ng-template>\n }\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"manageFilters()\">\n Manage {{ pluralLabelLower }}\n </ng-template>\n</fs-autocomplete-chips>", styles: ["fs-autocomplete-chips{width:200px;display:flex;margin-right:5px}fs-autocomplete-chips ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline{margin:0}fs-autocomplete-chips ::ng-deep .prefix-icon{color:#626262}fs-autocomplete-chips ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .fs-autocomplete-chips-panel-saved-filter{max-height:400px!important}\n"] }]
4233
- }], propDecorators: { savedFiltersController: [{
4234
- type: Input
4235
- }] } });
4236
-
4237
- class FilterStatusBarDirective {
4238
- templateRef;
4239
- constructor(templateRef) {
4240
- this.templateRef = templateRef;
3992
+ /**
3993
+ * Go through actions and check show() callback and update visible actions
3994
+ */
3995
+ updateActionsVisibility() {
3996
+ this._actions.updateActionsVisibility();
4241
3997
  }
4242
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterStatusBarDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
4243
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FilterStatusBarDirective, isStandalone: true, selector: "[fsFilterStatusBar]", ngImport: i0 });
4244
- }
4245
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterStatusBarDirective, decorators: [{
4246
- type: Directive,
4247
- args: [{
4248
- selector: '[fsFilterStatusBar]',
4249
- standalone: true,
4250
- }]
4251
- }], ctorParameters: () => [{ type: i0.TemplateRef }] });
4252
-
4253
- const FS_FILTER_CONFIG = new InjectionToken('fs.filter-config');
4254
-
4255
- class FilterComponent {
4256
- set setConfig(config) {
4257
- this._initFilterWithConfig(config);
3998
+ /**
3999
+ * Go through actions and check disabled() callback and update disabled state
4000
+ */
4001
+ updateDisabledState() {
4002
+ this._actions.updateDisabledState();
4258
4003
  }
4259
- set setFilter(config) {
4260
- this._initFilterWithConfig(config);
4004
+ setItems(items) {
4005
+ this._itemStore.destroyItems();
4006
+ this.config.items = items;
4007
+ this._itemStore.setConfig(this._config);
4008
+ this._paramController.initItems();
4009
+ this._updateKeyword();
4261
4010
  }
4262
- showSortBy = true;
4263
- closed = new EventEmitter();
4264
- opened = new EventEmitter();
4265
- ready = new EventEmitter();
4266
- statusBar;
4267
- keywordMatInput;
4268
- reloadEl;
4269
- showFilterMenu = false;
4270
- windowDesktop = false;
4271
- fsFilterClass = true;
4272
- searchPlaceholder = 'Search';
4273
- keyword = '';
4274
- autoReload = true;
4275
- _config = null;
4276
- _sort;
4277
- _filtersBtnVisible$ = new BehaviorSubject(true);
4278
- _keywordVisible$ = new BehaviorSubject(false);
4279
- _hasFilterChips$ = new BehaviorSubject(false);
4280
- _keyword$ = new Subject();
4281
- _destroy$ = new Subject();
4282
- _dialogRef = inject(MatDialogRef, { optional: true });
4283
- _drawerRef = inject(DrawerRef, { optional: true });
4284
- _defaultConfig = inject(FS_FILTER_CONFIG, { optional: true });
4285
- _filterOverlay = inject(FsFilterOverlayService);
4286
- _zone = inject(NgZone);
4287
- _paramController = inject(ParamController);
4288
- _persistanceController = inject(PersistanceController);
4289
- _itemStore = inject(ItemStore);
4290
- _actions = inject(ActionsController);
4291
- _savedFilterController = inject(SavedFilterController);
4292
- constructor() {
4293
- this._itemStore.filter = this;
4294
- this._listenWhenFilterReady();
4295
- this._updateWindowWidth();
4296
- const iconRegistry = inject(MatIconRegistry);
4297
- const sanitizer = inject(DomSanitizer);
4298
- iconRegistry.addSvgIconLiteral('filterOutline', sanitizer.bypassSecurityTrustHtml(FilterIcon));
4299
- this._filterOverlay.attach$
4300
- .pipe(takeUntil(this._destroy$))
4301
- .subscribe(() => {
4302
- this.showFilterMenu = true;
4303
- });
4304
- this._filterOverlay.detach$
4305
- .pipe(takeUntil(this._destroy$))
4306
- .subscribe(() => {
4307
- this.showFilterMenu = false;
4308
- });
4309
- this._listenWindowResize();
4310
- }
4311
- get config() {
4312
- return this._config;
4313
- }
4314
- get filterParams() {
4315
- return this._itemStore.values();
4011
+ keywordChange(keyword) {
4012
+ this._keyword$.next(keyword);
4316
4013
  }
4317
- get inDialog() {
4318
- return !!this._dialogRef || !!this._drawerRef;
4014
+ updateSortings(items) {
4015
+ this._itemStore.updateSortingItemsValues(items);
4319
4016
  }
4320
- get filterParamsQuery() {
4321
- return this._itemStore.valuesAsQuery();
4017
+ _initFilterWithConfig(config) {
4018
+ if (this.config) {
4019
+ this._itemStore.destroyItems();
4020
+ }
4021
+ config = {
4022
+ ...(this._defaultConfig || {}),
4023
+ ...config,
4024
+ };
4025
+ this._config = new FsFilterConfig(config);
4026
+ this._actions.setConfig(this._config);
4027
+ this._persistanceController.setConfig(this._config, this.inDialog);
4028
+ this._itemStore.setConfig(this._config);
4029
+ this._paramController.setConfig(this._config);
4030
+ this._updateKeyword();
4031
+ if (this.config.reloadWhenConfigChanged) {
4032
+ this.change();
4033
+ }
4322
4034
  }
4323
- get items() {
4324
- return this._itemStore.items;
4035
+ _destroyFilterDrawer() {
4036
+ this._filterOverlay.close();
4325
4037
  }
4326
- get visibleItems() {
4327
- return this._itemStore.visibleItems;
4038
+ _updateWindowWidth() {
4039
+ this.windowDesktop = window.innerWidth > 1200;
4328
4040
  }
4329
- get keywordItem() {
4330
- return this._itemStore.keywordItem;
4041
+ _listenEscButton() {
4042
+ this._zone.runOutsideAngular(() => {
4043
+ fromEvent(window, 'keyup')
4044
+ .pipe(filter$1((event) => event.code === 'Escape'), takeUntil(this.closed), takeUntil(this._destroy$))
4045
+ .subscribe(() => {
4046
+ this._zone.run(() => {
4047
+ this.hideDrawer();
4048
+ });
4049
+ });
4050
+ });
4331
4051
  }
4332
- get itemsReady$() {
4333
- return this._itemStore.ready$;
4052
+ _listenWindowResize() {
4053
+ this._zone.runOutsideAngular(() => {
4054
+ fromEvent(window, 'resize')
4055
+ .pipe(debounceTime(100), takeUntil(this._destroy$))
4056
+ .subscribe(() => {
4057
+ this._zone.run(() => {
4058
+ this._updateWindowWidth();
4059
+ });
4060
+ });
4061
+ });
4334
4062
  }
4335
- get hasFilterChips$() {
4336
- return this._hasFilterChips$.asObservable();
4063
+ _initAutoReload() {
4064
+ if (this.config.autoReload) {
4065
+ interval(this.config.autoReload.seconds * 1000)
4066
+ .pipe(filter$1(() => this.autoReload), takeUntil(this._destroy$))
4067
+ .subscribe(() => {
4068
+ this.reload(null);
4069
+ });
4070
+ }
4337
4071
  }
4338
- get hasVisibleItemOrSorting() {
4339
- return this.visibleItems.length > 0 || !!this._itemStore.sortByItem;
4072
+ _listenInputChanges() {
4073
+ this._keyword$
4074
+ .pipe(debounceTime(200), distinctUntilChanged(), takeUntil(this._destroy$))
4075
+ .subscribe((value) => {
4076
+ const keywordItem = this._itemStore.keywordItem;
4077
+ keywordItem.model = value;
4078
+ this.change();
4079
+ });
4340
4080
  }
4341
- get filtersBtnVisible$() {
4342
- return this._filtersBtnVisible$.asObservable();
4081
+ _initKeywordVisibility() {
4082
+ this._keywordVisible$.next(!!this.keywordItem && !this.keywordItem?.hidden);
4343
4083
  }
4344
- get inlineToolbar$() {
4345
- return combineLatest({
4346
- keywordVisible: this._keywordVisible$.asObservable(),
4347
- activeFilter: of(this.savedFiltersController.enabled),
4348
- })
4349
- .pipe(map(({ keywordVisible, activeFilter }) => {
4350
- return !keywordVisible && !activeFilter;
4351
- }));
4084
+ _initAutoFocus() {
4085
+ // Avoid ngChanges error
4086
+ setTimeout(() => {
4087
+ if (this.config.autofocus) {
4088
+ this.focus();
4089
+ }
4090
+ });
4352
4091
  }
4353
- get notInlineToolbar$() {
4354
- return this.inlineToolbar$
4355
- .pipe(map((inline) => !inline));
4092
+ _listenInternalItemsChange() {
4093
+ this._itemStore
4094
+ .itemsChange$
4095
+ .pipe(takeUntil(this._destroy$))
4096
+ .subscribe(() => {
4097
+ this.keyword = this._itemStore.keywordItem?.model;
4098
+ this.change();
4099
+ });
4356
4100
  }
4357
- get keywordVisible$() {
4358
- return this._keywordVisible$.asObservable();
4101
+ _initOverlay() {
4102
+ this._filterOverlay.setClearFn(this.clear.bind(this));
4103
+ this._filterOverlay.setDoneFn(this.hideDrawer.bind(this));
4359
4104
  }
4360
- get actionsVisible$() {
4361
- return this._actions.visible$;
4105
+ // We may need some time to recieve external params and after that ready can be emitted
4106
+ _listenWhenFilterReady() {
4107
+ combineLatest([
4108
+ this._paramController.pending$,
4109
+ this.itemsReady$,
4110
+ ])
4111
+ .pipe(filter$1(([pendingParams, itemsReady]) => !pendingParams && itemsReady), takeUntil(this._destroy$))
4112
+ .subscribe(() => {
4113
+ this.init();
4114
+ this._updateKeyword();
4115
+ this.ready.emit();
4116
+ });
4362
4117
  }
4363
- get actions$() {
4364
- return this._actions.actions$;
4118
+ _updateKeyword() {
4119
+ this.keyword = this._itemStore.keywordItem?.model;
4365
4120
  }
4366
- get menuActions$() {
4367
- return this._actions.menuActions$;
4121
+ _updateChipsVisibility() {
4122
+ const hasFilterChips = this._itemStore.items
4123
+ .some((item) => {
4124
+ return item.isChipVisible;
4125
+ });
4126
+ this._hasFilterChips$.next(hasFilterChips);
4368
4127
  }
4369
- set activeSavedFilter(savedFilter) {
4370
- this._savedFilterController.setActiveFilter(savedFilter);
4128
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4129
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilterComponent, isStandalone: true, selector: "fs-filter", inputs: { setConfig: ["config", "setConfig"], setFilter: ["filter", "setFilter"], showSortBy: "showSortBy" }, outputs: { closed: "closed", opened: "opened", ready: "ready" }, host: { properties: { "class.filters-open": "this.showFilterMenu", "class.window-desktop": "this.windowDesktop", "class.fs-filter": "this.fsFilterClass" } }, providers: [
4130
+ FsFilterOverlayService,
4131
+ ParamController,
4132
+ PersistanceController,
4133
+ QueryParamController,
4134
+ FocusControllerService,
4135
+ ItemStore,
4136
+ SavedFilterController,
4137
+ ActionsController,
4138
+ ], queries: [{ propertyName: "statusBar", first: true, predicate: FilterStatusBarDirective, descendants: true }], viewQueries: [{ propertyName: "keywordMatInput", first: true, predicate: ["keywordMatInput"], descendants: true, read: MatInput }, { propertyName: "reloadEl", first: true, predicate: ["reloadEl"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"filter-container\">\n @if (notInlineToolbar$ | async) {\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n }\n <div class=\"filter-inner-container\">\n @if (notInlineToolbar$ | async) {\n <div class=\"filter-inner-inputs\">\n @if (keywordVisible$ | async) {\n <mat-form-field\n class=\"search-form-field form-field-padless\"\n [ngClass]=\"{\n 'has-keyword': !!keyword\n }\">\n <span\n matPrefix\n class=\"icon\">\n <mat-icon matPrefix>\n search\n </mat-icon>\n </span>\n <input\n #keywordMatInput\n matInput\n [(ngModel)]=\"keyword\"\n (ngModelChange)=\"keywordChange($event)\"\n name=\"filter-input\"\n [fsClear]=\"true\"\n [placeholder]=\"searchPlaceholder\">\n </mat-form-field>\n }\n @if (savedFiltersController.enabled) {\n <fs-saved-filter-autocomplete-chips [savedFiltersController]=\"savedFiltersController\"></fs-saved-filter-autocomplete-chips>\n }\n </div>\n } @else {\n <div>\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n <ng-container *ngTemplateOutlet=\"filterStatusBarChips\"></ng-container>\n </div>\n }\n <ng-container [ngTemplateOutlet]=\"filterToolbar\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"filterActions\"></ng-container>\n </div>\n @if (notInlineToolbar$ | async) {\n <ng-container *ngTemplateOutlet=\"filterStatusBarChips\"></ng-container>\n }\n</div>\n<ng-template #filterStatusBarChips>\n @if (statusBar) {\n <div\n class=\"filter-status-container\"\n [ngClass]=\"{ 'has-status': !!filterStatus.textContent }\">\n <div\n class=\"filter-status\"\n #filterStatus>\n <ng-container *ngTemplateOutlet=\"statusBar.templateRef\"></ng-container>\n </div>\n </div>\n }\n @if (config.chips && hasFilterChips$ | async) {\n <fs-filter-chips\n class=\"filter-chips\"\n [filters]=\"items\">\n </fs-filter-chips>\n }\n</ng-template>\n<ng-template #filterActions>\n @if (actionsVisible$ | async) {\n <div class=\"filter-actions\">\n <fs-filter-actions\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n }\n</ng-template>\n<ng-template #filterToolbar>\n @if (config.reload || config.autoReload || ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting)) {\n <div class=\"filter-toolbar\">\n @if ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting) {\n <a\n mat-icon-button\n class=\"button-filters\"\n (click)=\"filterButtonClick($event)\"\n [color]=\"config.button.color\">\n @if (config.button.icon) {\n <mat-icon svgIcon=\"filterOutline\"></mat-icon>\n }\n {{ config.button.label }}\n </a>\n }\n @if (config.reload) {\n <a\n mat-icon-button\n (click)=\"reload($event)\"\n class=\"button-reload\">\n <mat-icon #reloadEl>\n refresh\n </mat-icon>\n </a>\n }\n @if (config.autoReload) {\n <div class=\"filter-reload\">\n @if (config.autoReload) {\n <mat-slide-toggle\n name=\"autoReload\"\n class=\"auto-reload\"\n [(ngModel)]=\"autoReload\">\n <span>\n Auto refresh\n </span>\n </mat-slide-toggle>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n<ng-template #heading>\n @if (config.heading) {\n <div class=\"heading\">\n <h2>\n {{ config.heading }}\n </h2>\n <div class=\"subheading\">\n {{ config.subheading }}\n </div>\n </div>\n }\n</ng-template>", styles: [":host{margin-bottom:20px;display:block}.filter-status-container{flex-grow:1;display:flex;justify-content:center;flex-direction:column;align-self:flex-end}.filter-status-container .filter-status{overflow:hidden;text-overflow:ellipsis;line-height:18px}.filter-container{width:100%}.filter-inner-container{flex-direction:row;box-sizing:border-box;display:flex;position:relative;align-items:center}.filter-inner-container .filter-inner-inputs{flex-direction:row;box-sizing:border-box;display:flex;align-items:center;min-width:0;gap:5px}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field{max-width:100%;width:250px;margin-top:0}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field .icon{margin-left:10px;color:#626262}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-actions{display:flex;align-items:center;flex:1;justify-content:flex-end}.filter-toolbar{white-space:nowrap;display:flex;align-items:center}.filter-toolbar .button-filters,.filter-toolbar .button-reload{display:flex;width:40px;padding:8px;height:40px;overflow:hidden}.filter-toolbar .button-filters ::ng-deep svg,.filter-toolbar .button-reload ::ng-deep svg{display:flex}.filter-toolbar .filter-reload{margin-left:10px;display:flex;align-items:center}.filter-toolbar .filter-reload .auto-reload{margin-right:5px}.filter-toolbar .filter-reload .auto-reload span{font-size:80%}.heading{margin-right:10px}.heading h2{margin:0}.heading h2+.subheading{margin:0}.results{min-height:90px;position:relative;overflow-x:auto;overflow-y:hidden}fs-filter-chips{margin:4px 0;display:flex;flex-wrap:wrap;gap:5px}@media screen and (min-width: 1200px){html.fs-filter-open body{margin-right:350px}}html.fs-filter-open{scrollbar-width:none}:host ::ng-deep .auto-reload.mat-checked .mat-slide-toggle-thumb-container{transform:translate3d(12px,0,0)}:host ::ng-deep .auto-reload:not(.mat-checked) .mat-slide-toggle-content{color:#ccc}:host ::ng-deep .auto-reload .mat-slide-toggle-thumb,:host ::ng-deep .auto-reload .mat-slide-toggle-thumb-container{height:15px;width:15px}:host ::ng-deep .auto-reload .mat-slide-toggle-content{font-size:90%}:host ::ng-deep .auto-reload .mat-slide-toggle-bar{width:26px;height:10px;border-radius:10px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FsSavedFilterAutocompleteChipsComponent, selector: "fs-saved-filter-autocomplete-chips", inputs: ["savedFiltersController"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "ngmodule", type: FsClearModule }, { kind: "component", type: i3$2.FsClearComponent, selector: "[fsClear]", inputs: ["ngModel", "visible", "fsClear"], outputs: ["ngModelChange", "cleared"] }, { kind: "component", type: FsFilterChipsComponent, selector: "fs-filter-chips", inputs: ["filters"] }, { kind: "component", type: FsFilterActionsComponent, selector: "fs-filter-actions", inputs: ["kebabActions", "actions"] }, { kind: "component", type: MatIconAnchor, selector: "a[mat-icon-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4139
+ }
4140
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, decorators: [{
4141
+ type: Component,
4142
+ args: [{ selector: 'fs-filter', providers: [
4143
+ FsFilterOverlayService,
4144
+ ParamController,
4145
+ PersistanceController,
4146
+ QueryParamController,
4147
+ FocusControllerService,
4148
+ ItemStore,
4149
+ SavedFilterController,
4150
+ ActionsController,
4151
+ ], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4152
+ NgTemplateOutlet,
4153
+ FsSavedFilterAutocompleteChipsComponent,
4154
+ MatFormField,
4155
+ NgClass,
4156
+ MatPrefix,
4157
+ MatIcon,
4158
+ MatInput,
4159
+ FormsModule,
4160
+ FsFormModule,
4161
+ FsClearModule,
4162
+ FsFilterChipsComponent,
4163
+ FsFilterActionsComponent,
4164
+ MatIconAnchor,
4165
+ MatSlideToggle,
4166
+ AsyncPipe,
4167
+ ], template: "<div class=\"filter-container\">\n @if (notInlineToolbar$ | async) {\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n }\n <div class=\"filter-inner-container\">\n @if (notInlineToolbar$ | async) {\n <div class=\"filter-inner-inputs\">\n @if (keywordVisible$ | async) {\n <mat-form-field\n class=\"search-form-field form-field-padless\"\n [ngClass]=\"{\n 'has-keyword': !!keyword\n }\">\n <span\n matPrefix\n class=\"icon\">\n <mat-icon matPrefix>\n search\n </mat-icon>\n </span>\n <input\n #keywordMatInput\n matInput\n [(ngModel)]=\"keyword\"\n (ngModelChange)=\"keywordChange($event)\"\n name=\"filter-input\"\n [fsClear]=\"true\"\n [placeholder]=\"searchPlaceholder\">\n </mat-form-field>\n }\n @if (savedFiltersController.enabled) {\n <fs-saved-filter-autocomplete-chips [savedFiltersController]=\"savedFiltersController\"></fs-saved-filter-autocomplete-chips>\n }\n </div>\n } @else {\n <div>\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n <ng-container *ngTemplateOutlet=\"filterStatusBarChips\"></ng-container>\n </div>\n }\n <ng-container [ngTemplateOutlet]=\"filterToolbar\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"filterActions\"></ng-container>\n </div>\n @if (notInlineToolbar$ | async) {\n <ng-container *ngTemplateOutlet=\"filterStatusBarChips\"></ng-container>\n }\n</div>\n<ng-template #filterStatusBarChips>\n @if (statusBar) {\n <div\n class=\"filter-status-container\"\n [ngClass]=\"{ 'has-status': !!filterStatus.textContent }\">\n <div\n class=\"filter-status\"\n #filterStatus>\n <ng-container *ngTemplateOutlet=\"statusBar.templateRef\"></ng-container>\n </div>\n </div>\n }\n @if (config.chips && hasFilterChips$ | async) {\n <fs-filter-chips\n class=\"filter-chips\"\n [filters]=\"items\">\n </fs-filter-chips>\n }\n</ng-template>\n<ng-template #filterActions>\n @if (actionsVisible$ | async) {\n <div class=\"filter-actions\">\n <fs-filter-actions\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n }\n</ng-template>\n<ng-template #filterToolbar>\n @if (config.reload || config.autoReload || ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting)) {\n <div class=\"filter-toolbar\">\n @if ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting) {\n <a\n mat-icon-button\n class=\"button-filters\"\n (click)=\"filterButtonClick($event)\"\n [color]=\"config.button.color\">\n @if (config.button.icon) {\n <mat-icon svgIcon=\"filterOutline\"></mat-icon>\n }\n {{ config.button.label }}\n </a>\n }\n @if (config.reload) {\n <a\n mat-icon-button\n (click)=\"reload($event)\"\n class=\"button-reload\">\n <mat-icon #reloadEl>\n refresh\n </mat-icon>\n </a>\n }\n @if (config.autoReload) {\n <div class=\"filter-reload\">\n @if (config.autoReload) {\n <mat-slide-toggle\n name=\"autoReload\"\n class=\"auto-reload\"\n [(ngModel)]=\"autoReload\">\n <span>\n Auto refresh\n </span>\n </mat-slide-toggle>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n<ng-template #heading>\n @if (config.heading) {\n <div class=\"heading\">\n <h2>\n {{ config.heading }}\n </h2>\n <div class=\"subheading\">\n {{ config.subheading }}\n </div>\n </div>\n }\n</ng-template>", styles: [":host{margin-bottom:20px;display:block}.filter-status-container{flex-grow:1;display:flex;justify-content:center;flex-direction:column;align-self:flex-end}.filter-status-container .filter-status{overflow:hidden;text-overflow:ellipsis;line-height:18px}.filter-container{width:100%}.filter-inner-container{flex-direction:row;box-sizing:border-box;display:flex;position:relative;align-items:center}.filter-inner-container .filter-inner-inputs{flex-direction:row;box-sizing:border-box;display:flex;align-items:center;min-width:0;gap:5px}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field{max-width:100%;width:250px;margin-top:0}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field .icon{margin-left:10px;color:#626262}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-actions{display:flex;align-items:center;flex:1;justify-content:flex-end}.filter-toolbar{white-space:nowrap;display:flex;align-items:center}.filter-toolbar .button-filters,.filter-toolbar .button-reload{display:flex;width:40px;padding:8px;height:40px;overflow:hidden}.filter-toolbar .button-filters ::ng-deep svg,.filter-toolbar .button-reload ::ng-deep svg{display:flex}.filter-toolbar .filter-reload{margin-left:10px;display:flex;align-items:center}.filter-toolbar .filter-reload .auto-reload{margin-right:5px}.filter-toolbar .filter-reload .auto-reload span{font-size:80%}.heading{margin-right:10px}.heading h2{margin:0}.heading h2+.subheading{margin:0}.results{min-height:90px;position:relative;overflow-x:auto;overflow-y:hidden}fs-filter-chips{margin:4px 0;display:flex;flex-wrap:wrap;gap:5px}@media screen and (min-width: 1200px){html.fs-filter-open body{margin-right:350px}}html.fs-filter-open{scrollbar-width:none}:host ::ng-deep .auto-reload.mat-checked .mat-slide-toggle-thumb-container{transform:translate3d(12px,0,0)}:host ::ng-deep .auto-reload:not(.mat-checked) .mat-slide-toggle-content{color:#ccc}:host ::ng-deep .auto-reload .mat-slide-toggle-thumb,:host ::ng-deep .auto-reload .mat-slide-toggle-thumb-container{height:15px;width:15px}:host ::ng-deep .auto-reload .mat-slide-toggle-content{font-size:90%}:host ::ng-deep .auto-reload .mat-slide-toggle-bar{width:26px;height:10px;border-radius:10px}\n"] }]
4168
+ }], ctorParameters: () => [], propDecorators: { setConfig: [{
4169
+ type: Input,
4170
+ args: ['config']
4171
+ }], setFilter: [{
4172
+ type: Input,
4173
+ args: ['filter']
4174
+ }], showSortBy: [{
4175
+ type: Input
4176
+ }], closed: [{
4177
+ type: Output
4178
+ }], opened: [{
4179
+ type: Output
4180
+ }], ready: [{
4181
+ type: Output
4182
+ }], statusBar: [{
4183
+ type: ContentChild,
4184
+ args: [FilterStatusBarDirective]
4185
+ }], keywordMatInput: [{
4186
+ type: ViewChild,
4187
+ args: ['keywordMatInput', { read: MatInput }]
4188
+ }], reloadEl: [{
4189
+ type: ViewChild,
4190
+ args: ['reloadEl', { read: ElementRef }]
4191
+ }], showFilterMenu: [{
4192
+ type: HostBinding,
4193
+ args: ['class.filters-open']
4194
+ }], windowDesktop: [{
4195
+ type: HostBinding,
4196
+ args: ['class.window-desktop']
4197
+ }], fsFilterClass: [{
4198
+ type: HostBinding,
4199
+ args: ['class.fs-filter']
4200
+ }] } });
4201
+
4202
+ class AutocompletechipsComponent extends BaseItemComponent {
4203
+ _kvDiffers;
4204
+ _cd;
4205
+ _injector = inject(Injector);
4206
+ constructor(_kvDiffers, _cd) {
4207
+ super(_kvDiffers, _cd);
4208
+ this._kvDiffers = _kvDiffers;
4209
+ this._cd = _cd;
4371
4210
  }
4372
- get activeSavedFilter() {
4373
- return this._savedFilterController.activeFilter;
4211
+ addAutocompleteChipItem(event) {
4212
+ if (event.data && this.item.model.indexOf(event.data.value) === -1) {
4213
+ this.item.model.push(event.data);
4214
+ this.itemChange();
4215
+ }
4374
4216
  }
4375
- get savedFilters() {
4376
- return this._savedFilterController.savedFilters;
4217
+ removeAutocompleteChipItem(event) {
4218
+ remove(this.item.model, { value: event.data.value });
4219
+ this.itemChange();
4377
4220
  }
4378
- get savedFiltersController() {
4379
- return this._savedFilterController;
4221
+ clearAutocompleteChipItem() {
4222
+ this.item.clear();
4223
+ this.itemChange();
4380
4224
  }
4381
- ngOnInit() {
4382
- this._initAutoFocus();
4383
- this._initAutoReload();
4384
- this._listenInputChanges();
4385
- this._listenInternalItemsChange();
4386
- this._initKeywordVisibility();
4387
- this._initOverlay();
4225
+ fetch = (keyword) => {
4226
+ return this.item.valuesFn(keyword, this.item.filter);
4227
+ };
4228
+ compareItems(item1, item2) {
4229
+ return item1?.value === item2?.value;
4388
4230
  }
4389
- ngOnDestroy() {
4390
- this._destroyFilterDrawer();
4391
- this._destroy$.next(null);
4392
- this._destroy$.complete();
4231
+ actionClick(action) {
4232
+ const filterComponent = this._injector.get(FilterComponent);
4233
+ action.click(filterComponent);
4393
4234
  }
4394
- focus() {
4395
- this.keywordMatInput?.focus();
4235
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompletechipsComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4236
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AutocompletechipsComponent, isStandalone: true, selector: "filter-item-autocompletechips", usesInheritance: true, ngImport: i0, template: "<fs-autocomplete-chips\n [fsFilterFocusTrigger]=\"item\"\n [fetch]=\"fetch\"\n [ngModel]=\"item.model\"\n (selected)=\"addAutocompleteChipItem($event)\"\n (removed)=\"removeAutocompleteChipItem($event)\"\n (clear)=\"clearAutocompleteChipItem()\"\n [allowText]=\"false\"\n [label]=\"label\"\n [size]=\"'small'\"\n [chipImage]=\"item.chipImage\"\n [chipColor]=\"item.chipColor\"\n [chipIconColor]=\"item.chipIcon\"\n [chipBackground]=\"item.chipBackground\"\n [chipIcon]=\"item.chipIcon\"\n [chipClass]=\"item.chipClass\"\n [allowClear]=\"item.showClear\"\n [removable]=\"item.showClear\"\n [compareWith]=\"compareItems\"\n [panelWidth]=\"300\"\n name=\"model\">\n <ng-template\n fsAutocompleteObject\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n @for (action of item.panelActions; track action.label) {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"actionClick(action)\">\n {{ action.label }}\n </ng-template>\n }\n</fs-autocomplete-chips>", dependencies: [{ kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i1$3.FsAutocompleteChipsComponent, selector: "fs-autocomplete-chips", inputs: ["fetch", "appearance", "floatLabel", "readonly", "size", "label", "placeholder", "chipMargin", "chipImage", "chipBackground", "chipColor", "chipIcon", "chipIconColor", "chipClass", "chipPadding", "shape", "hint", "allowText", "allowObject", "delay", "minPanelWidth", "validateText", "removable", "allowClear", "color", "background", "orderable", "padless", "initOnClick", "fetchOnFocus", "multiple", "multipleAdd", "confirm", "disabled", "groupBy", "panelWidth", "panelClass", "compareWith"], outputs: ["selected", "removed", "reordered", "clear"] }, { kind: "directive", type: i1$3.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "directive", type: i1$3.FsAutocompleteChipsStaticDirective, selector: "[fsAutocompleteChipsStatic]", inputs: ["show", "disable"], outputs: ["click", "selected"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4237
+ }
4238
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompletechipsComponent, decorators: [{
4239
+ type: Component,
4240
+ args: [{ selector: 'filter-item-autocompletechips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4241
+ FsAutocompleteChipsModule,
4242
+ FocusToItemDirective,
4243
+ FormsModule,
4244
+ FsFormModule,
4245
+ ], template: "<fs-autocomplete-chips\n [fsFilterFocusTrigger]=\"item\"\n [fetch]=\"fetch\"\n [ngModel]=\"item.model\"\n (selected)=\"addAutocompleteChipItem($event)\"\n (removed)=\"removeAutocompleteChipItem($event)\"\n (clear)=\"clearAutocompleteChipItem()\"\n [allowText]=\"false\"\n [label]=\"label\"\n [size]=\"'small'\"\n [chipImage]=\"item.chipImage\"\n [chipColor]=\"item.chipColor\"\n [chipIconColor]=\"item.chipIcon\"\n [chipBackground]=\"item.chipBackground\"\n [chipIcon]=\"item.chipIcon\"\n [chipClass]=\"item.chipClass\"\n [allowClear]=\"item.showClear\"\n [removable]=\"item.showClear\"\n [compareWith]=\"compareItems\"\n [panelWidth]=\"300\"\n name=\"model\">\n <ng-template\n fsAutocompleteObject\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n @for (action of item.panelActions; track action.label) {\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"actionClick(action)\">\n {{ action.label }}\n </ng-template>\n }\n</fs-autocomplete-chips>" }]
4246
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4247
+
4248
+ class CheckboxComponent extends BaseItemComponent {
4249
+ _kvDiffers;
4250
+ _cd;
4251
+ constructor(_kvDiffers, _cd) {
4252
+ super(_kvDiffers, _cd);
4253
+ this._kvDiffers = _kvDiffers;
4254
+ this._cd = _cd;
4396
4255
  }
4397
- updateSort(sort) {
4398
- this._itemStore.updateSort(sort);
4256
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CheckboxComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4257
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CheckboxComponent, isStandalone: true, selector: "filter-item-checkbox", usesInheritance: true, ngImport: i0, template: "<fs-label-field>\n <mat-checkbox\n [(ngModel)]=\"item.model\"\n [name]=\"item.name\">\n {{ item.label }}\n </mat-checkbox>\n</fs-label-field>", styles: ["fs-label-field{margin:0 0 -12px -8px}\n"], dependencies: [{ kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i1$6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4258
+ }
4259
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CheckboxComponent, decorators: [{
4260
+ type: Component,
4261
+ args: [{ selector: 'filter-item-checkbox', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4262
+ FsLabelModule,
4263
+ MatCheckbox,
4264
+ FormsModule,
4265
+ FsFormModule,
4266
+ ], template: "<fs-label-field>\n <mat-checkbox\n [(ngModel)]=\"item.model\"\n [name]=\"item.name\">\n {{ item.label }}\n </mat-checkbox>\n</fs-label-field>", styles: ["fs-label-field{margin:0 0 -12px -8px}\n"] }]
4267
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4268
+
4269
+ class ChipsComponent extends BaseItemComponent {
4270
+ _kvDiffers;
4271
+ _cd;
4272
+ constructor(_kvDiffers, _cd) {
4273
+ super(_kvDiffers, _cd);
4274
+ this._kvDiffers = _kvDiffers;
4275
+ this._cd = _cd;
4399
4276
  }
4400
- /**
4401
- *
4402
- * Do update value of some field
4403
- *
4404
- * @param values - values for update
4405
- *
4406
- * To update text value just pass new text value
4407
- *
4408
- * public updateSelectValue(val) {
4409
- * this.filterEl.updateValues({ keyword: val });
4410
- * }
4411
- *
4412
- * To update select or observable select you could pass suitable value
4413
- *
4414
- * public updateSelectValue(val: number) {
4415
- * this.filterEl.updateValues({ simple_select: val }, { observable_select: val });
4416
- * }
4417
- *
4418
- * To update checkbox value just pass true/false as value
4419
- *
4420
- * public updateCheckox(val: boolean) {
4421
- * this.filterEl.updateValues({ checkbox: val });
4422
- * }
4423
- *
4424
- * To update range value just pass object with min&max object or just with one of targets
4425
- *
4426
- * Ex.: { min: 10, max 15 }, { min: 5 }, { max 5 }
4427
- *
4428
- * public updateRange(val) {
4429
- * this.filterEl.updateValues({ range: val });
4430
- * }
4431
- *
4432
- * To update autocomplete just pass object with name/value fields
4433
- *
4434
- * Ex.: { name: 'John Doe', value: 1 }
4435
- *
4436
- * public updateAutocomplete(val) {
4437
- * this.filterEl.updateValues({ autocomplete_user_id: val });
4438
- * }
4439
- *
4440
- * To update autocompletechips just pass:
4441
- *
4442
- * 1) object with name/value fields - will be appended to existing set of values
4443
- *
4444
- * { name: 'John Doe', value: 1 }
4445
- *
4446
- * 2) array of objects - will be appended to existing set of values
4447
- *
4448
- * [{ name: 'John Doe', value: 1 }, { name: 'Darya Filipova', value: 2 }]
4449
- *
4450
- * 3) null - clear existing set of values
4451
- *
4452
- * public updateAutocomplete(val) {
4453
- * this.filterEl.updateValues({ autocompletechips_user_id: val });
4454
- * }
4455
- *
4456
- */
4457
- updateValues(values) {
4458
- Object.keys(values).forEach((key) => {
4459
- const filterItem = this.items
4460
- .find((item) => item.name === key);
4461
- if (!filterItem) {
4462
- return;
4463
- }
4464
- filterItem.model = values[key];
4465
- });
4277
+ compareFn = (modelValue, chipValue) => {
4278
+ return String(modelValue.value) === String(chipValue.value);
4279
+ };
4280
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChipsComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4281
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ChipsComponent, isStandalone: true, selector: "filter-item-chips", usesInheritance: true, ngImport: i0, template: "@if (item.values?.length) {\n <fs-label-field>\n <fs-label>\n {{ item.label }}\n </fs-label>\n <fs-chips\n [(ngModel)]=\"item.model\"\n [compare]=\"compareFn\"\n [multiple]=\"item.multiple\">\n @for (value of item.values; track value) {\n <fs-chip\n [value]=\"value\"\n [selectable]=\"true\">\n {{ value.name }}\n </fs-chip>\n }\n </fs-chips>\n </fs-label-field>\n}\n@if (item.loading) {\n {{ item.label }} loading...\n}", styles: ["fs-chip{line-height:40px}\n"], dependencies: [{ kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i1$6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i1$6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsChipModule }, { kind: "component", type: i2$2.FsChipsComponent, selector: "fs-chips", inputs: ["compare", "multiple", "sortable", "selectable", "orientation", "width"] }, { kind: "component", type: i2$2.FsChipComponent, selector: "fs-chip", inputs: ["selectable", "removable", "value", "maxWidth", "width", "backgroundColor", "borderColor", "color", "shape", "outlined", "icon", "image", "selected", "padding", "contrastColor", "size"], outputs: ["selectedToggled", "removed"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4282
+ }
4283
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChipsComponent, decorators: [{
4284
+ type: Component,
4285
+ args: [{ selector: 'filter-item-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4286
+ FsLabelModule,
4287
+ FsChipModule,
4288
+ FormsModule,
4289
+ FsFormModule,
4290
+ ], template: "@if (item.values?.length) {\n <fs-label-field>\n <fs-label>\n {{ item.label }}\n </fs-label>\n <fs-chips\n [(ngModel)]=\"item.model\"\n [compare]=\"compareFn\"\n [multiple]=\"item.multiple\">\n @for (value of item.values; track value) {\n <fs-chip\n [value]=\"value\"\n [selectable]=\"true\">\n {{ value.name }}\n </fs-chip>\n }\n </fs-chips>\n </fs-label-field>\n}\n@if (item.loading) {\n {{ item.label }} loading...\n}", styles: ["fs-chip{line-height:40px}\n"] }]
4291
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4292
+
4293
+ class DateRangeComponent extends BaseItemComponent {
4294
+ _kvDiffers;
4295
+ _cd;
4296
+ viewType = PickerViewType.Date;
4297
+ constructor(_kvDiffers, _cd) {
4298
+ super(_kvDiffers, _cd);
4299
+ this._kvDiffers = _kvDiffers;
4300
+ this._cd = _cd;
4466
4301
  }
4467
- hide() {
4468
- this.changeVisibility(false);
4302
+ ngOnInit() {
4303
+ if (this.item.type === ItemType.DateTimeRange) {
4304
+ this.viewType = PickerViewType.DateTime;
4305
+ }
4306
+ else {
4307
+ this.viewType = PickerViewType.Date;
4308
+ }
4469
4309
  }
4470
- show() {
4471
- this.changeVisibility(true);
4310
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateRangeComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4311
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DateRangeComponent, isStandalone: true, selector: "filter-item-date-range", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{item.label[0]}}</mat-label>\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'from'\"\n [fsDateRangeFrom]=\"item.name\"\n [(ngModel)]=\"item.model.from\"\n (ngModelChange)=\"itemChange()\"\n [clear]=\"item.showClear\"\n [view]=\"viewType\"\n name=\"date_from\">\n</mat-form-field>\n\n<mat-form-field>\n <mat-label>{{item.label[1]}}</mat-label>\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'to'\"\n [fsDateRangeTo]=\"item.name\"\n [(ngModel)]=\"item.model.to\"\n (ngModelChange)=\"itemChange()\"\n [clear]=\"item.showClear\"\n [view]=\"viewType\"\n name=\"date_to\">\n</mat-form-field>\n", dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i3$1.DateRangePickerFromComponent, selector: "[fsDateRangeFrom],[fsDateRangeFromPicker]", inputs: ["fsDateRangeFrom", "fsDateRangeFromPicker"] }, { kind: "component", type: i3$1.DateRangePickerToComponent, selector: "[fsDateRangeTo],[fsDateRangeToPicker]", inputs: ["fsDateRangeTo", "fsDateRangeToPicker"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4312
+ }
4313
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateRangeComponent, decorators: [{
4314
+ type: Component,
4315
+ args: [{ selector: 'filter-item-date-range', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4316
+ MatFormField,
4317
+ MatLabel,
4318
+ MatInput,
4319
+ FormsModule,
4320
+ FocusToItemDirective,
4321
+ FsDatePickerModule,
4322
+ FsFormModule,
4323
+ ], template: "<mat-form-field>\n <mat-label>{{item.label[0]}}</mat-label>\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'from'\"\n [fsDateRangeFrom]=\"item.name\"\n [(ngModel)]=\"item.model.from\"\n (ngModelChange)=\"itemChange()\"\n [clear]=\"item.showClear\"\n [view]=\"viewType\"\n name=\"date_from\">\n</mat-form-field>\n\n<mat-form-field>\n <mat-label>{{item.label[1]}}</mat-label>\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'to'\"\n [fsDateRangeTo]=\"item.name\"\n [(ngModel)]=\"item.model.to\"\n (ngModelChange)=\"itemChange()\"\n [clear]=\"item.showClear\"\n [view]=\"viewType\"\n name=\"date_to\">\n</mat-form-field>\n" }]
4324
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4325
+
4326
+ class DateComponent extends BaseItemComponent {
4327
+ _kvDiffers;
4328
+ _cd;
4329
+ viewType = PickerViewType.Date;
4330
+ itemDateMode = ItemDateMode;
4331
+ showYear = true;
4332
+ showMonth = true;
4333
+ showDay = true;
4334
+ constructor(_kvDiffers, _cd) {
4335
+ super(_kvDiffers, _cd);
4336
+ this._kvDiffers = _kvDiffers;
4337
+ this._cd = _cd;
4472
4338
  }
4473
- changeVisibilityClick(value, event = null) {
4474
- if (event) {
4475
- event.stopPropagation();
4339
+ ngOnInit() {
4340
+ this.viewType = this.item.type === ItemType.DateTime ? PickerViewType.DateTime : PickerViewType.Date;
4341
+ if (this.item.mode === ItemDateMode.ScrollMonthYear) {
4342
+ this.showDay = false;
4476
4343
  }
4477
- this.changeVisibility(value);
4478
4344
  }
4479
- get itemValues() {
4480
- return this.items
4481
- .map((item) => item.value);
4345
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4346
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DateComponent, isStandalone: true, selector: "filter-item-date", usesInheritance: true, ngImport: i0, template: "@if (item.mode === itemDateMode.ScrollMonthDayYear || item.mode === itemDateMode.ScrollMonthYear) {\n <mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n <input\n matInput\n fsDateScrollPicker\n [placeholder]=\"item.label\"\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [maxYear]=\"item.maxYear\"\n [showMonth]=\"showMonth\"\n [showDay]=\"showDay\"\n [showYear]=\"showYear\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n </mat-form-field>\n} @else if (item.mode === itemDateMode.Calendar) {\n <mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [maxYear]=\"item.maxYear\"\n [view]=\"viewType\"\n [placeholder]=\"item.label\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n </mat-form-field>\n}", dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i3$1.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes"], outputs: ["change"] }, { kind: "component", type: i3$1.FsDateScrollPickerComponent, selector: "[fsDateScrollPicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "showMonth", "showYear", "showDay"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4347
+ }
4348
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateComponent, decorators: [{
4349
+ type: Component,
4350
+ args: [{ selector: 'filter-item-date', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4351
+ MatFormField,
4352
+ MatLabel,
4353
+ MatInput,
4354
+ FormsModule,
4355
+ FsDatePickerModule,
4356
+ FocusToItemDirective,
4357
+ FsFormModule,
4358
+ ], template: "@if (item.mode === itemDateMode.ScrollMonthDayYear || item.mode === itemDateMode.ScrollMonthYear) {\n <mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n <input\n matInput\n fsDateScrollPicker\n [placeholder]=\"item.label\"\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [maxYear]=\"item.maxYear\"\n [showMonth]=\"showMonth\"\n [showDay]=\"showDay\"\n [showYear]=\"showYear\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n </mat-form-field>\n} @else if (item.mode === itemDateMode.Calendar) {\n <mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [maxYear]=\"item.maxYear\"\n [view]=\"viewType\"\n [placeholder]=\"item.label\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n </mat-form-field>\n}" }]
4359
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4360
+
4361
+ class RangeComponent extends BaseItemComponent {
4362
+ _kvDiffers;
4363
+ _cd;
4364
+ from;
4365
+ to;
4366
+ constructor(_kvDiffers, _cd) {
4367
+ super(_kvDiffers, _cd);
4368
+ this._kvDiffers = _kvDiffers;
4369
+ this._cd = _cd;
4482
4370
  }
4483
- get nonEmptyItemValues() {
4484
- return this.items
4485
- .filter((item) => item.value !== undefined)
4486
- .map((item) => item.value);
4371
+ ngOnInit() {
4372
+ this.listenChanges();
4487
4373
  }
4488
- get hasItemValues() {
4489
- return this.items
4490
- .some((item) => item.value !== undefined);
4374
+ listenChanges() {
4375
+ const fromListener = fromEvent(this.from.nativeElement, 'keyup')
4376
+ .pipe(distinctUntilChanged());
4377
+ const toListener = fromEvent(this.to.nativeElement, 'keyup')
4378
+ .pipe(distinctUntilChanged());
4379
+ merge(fromListener, toListener)
4380
+ .pipe(takeUntil(this.destroy$))
4381
+ .subscribe(() => {
4382
+ this.itemChange();
4383
+ });
4491
4384
  }
4492
- getItemValue(name) {
4493
- const item = this.items
4494
- .find((_item) => _item.name === name);
4495
- return item?.value;
4385
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RangeComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4386
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: RangeComponent, isStandalone: true, selector: "filter-item-range", viewQueries: [{ propertyName: "from", first: true, predicate: ["from"], descendants: true, static: true }, { propertyName: "to", first: true, predicate: ["to"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"form-field\">\n <mat-form-field class=\"filter-range-min\">\n <mat-label>\n {{ item.label[0] }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n class=\"text-prefix\"\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'from'\"\n type=\"text\"\n inputmode=\"decimal\"\n [(ngModel)]=\"item.model.min\"\n #from>\n @if (item.suffix) {\n <span\n matSuffix\n class=\"text-suffix\"\n [innerHtml]=\"item.suffix\">\n </span>\n }\n </mat-form-field>\n <mat-form-field class=\"filter-range-max\">\n <mat-label>\n {{ item.label[1] }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n class=\"text-prefix\"\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'to'\"\n type=\"text\"\n inputmode=\"decimal\"\n [(ngModel)]=\"item.model.max\"\n #to>\n @if (item.suffix) {\n <span\n matSuffix\n class=\"text-suffix\"\n [innerHtml]=\"item.suffix\">\n </span>\n }\n </mat-form-field>\n</div>", styles: [".form-field{display:flex}.form-field mat-form-field{min-width:0}.form-field mat-form-field+mat-form-field{margin-left:10px}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4387
+ }
4388
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RangeComponent, decorators: [{
4389
+ type: Component,
4390
+ args: [{ selector: 'filter-item-range', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4391
+ MatFormField,
4392
+ MatLabel,
4393
+ MatPrefix,
4394
+ MatInput,
4395
+ FormsModule,
4396
+ FocusToItemDirective,
4397
+ FsFormModule,
4398
+ MatSuffix,
4399
+ ], template: "<div class=\"form-field\">\n <mat-form-field class=\"filter-range-min\">\n <mat-label>\n {{ item.label[0] }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n class=\"text-prefix\"\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'from'\"\n type=\"text\"\n inputmode=\"decimal\"\n [(ngModel)]=\"item.model.min\"\n #from>\n @if (item.suffix) {\n <span\n matSuffix\n class=\"text-suffix\"\n [innerHtml]=\"item.suffix\">\n </span>\n }\n </mat-form-field>\n <mat-form-field class=\"filter-range-max\">\n <mat-label>\n {{ item.label[1] }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n class=\"text-prefix\"\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [fsFilterFocusTrigger]=\"item\"\n [focusTargetType]=\"'to'\"\n type=\"text\"\n inputmode=\"decimal\"\n [(ngModel)]=\"item.model.max\"\n #to>\n @if (item.suffix) {\n <span\n matSuffix\n class=\"text-suffix\"\n [innerHtml]=\"item.suffix\">\n </span>\n }\n </mat-form-field>\n</div>", styles: [".form-field{display:flex}.form-field mat-form-field{min-width:0}.form-field mat-form-field+mat-form-field{margin-left:10px}\n"] }]
4400
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }], propDecorators: { from: [{
4401
+ type: ViewChild,
4402
+ args: ['from', { static: true }]
4403
+ }], to: [{
4404
+ type: ViewChild,
4405
+ args: ['to', { static: true }]
4406
+ }] } });
4407
+
4408
+ class SelectGroupsComponent {
4409
+ cd;
4410
+ select;
4411
+ item;
4412
+ constructor(cd) {
4413
+ this.cd = cd;
4496
4414
  }
4497
- showItem(name) {
4498
- const item = this.getItem(name);
4499
- if (item) {
4500
- item.hide = false;
4501
- this._itemStore.updateItemsVisiblity();
4502
- }
4415
+ compare(o1, o2) {
4416
+ return o1 == o2;
4503
4417
  }
4504
- hideItem(name) {
4505
- const item = this.getItem(name);
4506
- if (!item) {
4507
- return;
4508
- }
4509
- item.hide = true;
4510
- this._itemStore.updateItemsVisiblity();
4418
+ markForCheck() {
4419
+ this.cd.markForCheck();
4511
4420
  }
4512
- clearItem(name) {
4513
- const item = this.getItem(name);
4514
- if (!item) {
4515
- return;
4421
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectGroupsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4422
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectGroupsComponent, isStandalone: true, selector: "filter-item-select-groups", inputs: { item: "item" }, viewQueries: [{ propertyName: "select", first: true, predicate: ["select"], descendants: true, static: true }], ngImport: i0, template: "<mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [compareWith]=\"compare\">\n @for (selectItem of item.values; track selectItem) {\n @if (selectItem[item.children]) {\n <mat-optgroup [label]=\"selectItem.name\">\n @for (subItem of selectItem[item.children]; track subItem) {\n <mat-option\n [value]=\"subItem.value\"\n [ngStyle]=\"selectItem.style\">\n {{ subItem.name }}\n </mat-option>\n }\n </mat-optgroup>\n } @else {\n <mat-option\n [value]=\"selectItem.value\"\n [ngStyle]=\"selectItem.style\">\n {{ selectItem.name }}\n </mat-option>\n }\n }\n </mat-select>\n</mat-form-field>\n", dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "component", type: MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4423
+ }
4424
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectGroupsComponent, decorators: [{
4425
+ type: Component,
4426
+ args: [{ selector: 'filter-item-select-groups', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4427
+ MatFormField,
4428
+ MatLabel,
4429
+ MatSelect,
4430
+ FocusToItemDirective,
4431
+ FormsModule,
4432
+ FsFormModule,
4433
+ MatOptgroup,
4434
+ MatOption,
4435
+ NgStyle,
4436
+ ], template: "<mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [compareWith]=\"compare\">\n @for (selectItem of item.values; track selectItem) {\n @if (selectItem[item.children]) {\n <mat-optgroup [label]=\"selectItem.name\">\n @for (subItem of selectItem[item.children]; track subItem) {\n <mat-option\n [value]=\"subItem.value\"\n [ngStyle]=\"selectItem.style\">\n {{ subItem.name }}\n </mat-option>\n }\n </mat-optgroup>\n } @else {\n <mat-option\n [value]=\"selectItem.value\"\n [ngStyle]=\"selectItem.style\">\n {{ selectItem.name }}\n </mat-option>\n }\n }\n </mat-select>\n</mat-form-field>\n" }]
4437
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { select: [{
4438
+ type: ViewChild,
4439
+ args: ['select', { static: true }]
4440
+ }], item: [{
4441
+ type: Input
4442
+ }] } });
4443
+
4444
+ class FsFilterIsolateValues {
4445
+ transform(values, isolate) {
4446
+ if (!isolate) {
4447
+ return values;
4516
4448
  }
4517
- item.clear();
4449
+ return values.filter((value) => {
4450
+ return value.value !== isolate.value;
4451
+ });
4518
4452
  }
4519
- updateItemConfig(name, params) {
4520
- const item = this.getItem(name);
4521
- if (!item) {
4522
- return;
4523
- }
4524
- item.label = params.label ?? item.label;
4525
- item.chipLabel = params.chipLabel ?? item.chipLabel;
4526
- this._itemStore.updateItemsVisiblity();
4453
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterIsolateValues, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
4454
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FsFilterIsolateValues, isStandalone: true, name: "fsFilterIsolateValues" });
4455
+ }
4456
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterIsolateValues, decorators: [{
4457
+ type: Pipe,
4458
+ args: [{
4459
+ name: 'fsFilterIsolateValues',
4460
+ standalone: true,
4461
+ }]
4462
+ }] });
4463
+
4464
+ class SelectMultipleComponent {
4465
+ _cd;
4466
+ item;
4467
+ select;
4468
+ constructor(_cd) {
4469
+ this._cd = _cd;
4527
4470
  }
4528
- getItemValueChange$(name) {
4529
- const item = this.items.find((i) => i.name === name);
4530
- if (item) {
4531
- return item.value$
4532
- .pipe(map(() => {
4533
- return item.model;
4534
- }));
4471
+ changed() {
4472
+ if (this.item.isolate) {
4473
+ this.item.isolate.enabled = false;
4474
+ if (this.item.multiple && Array.isArray(this.item.model)) {
4475
+ const index = this.item.model.indexOf(this.item.isolate.value);
4476
+ if (index > -1) {
4477
+ this.item.model.splice(index, 1);
4478
+ }
4479
+ }
4535
4480
  }
4536
- return null;
4537
4481
  }
4538
- changeVisibility(state) {
4539
- if (state === this.showFilterMenu) {
4540
- return;
4541
- }
4542
- if (!state) {
4543
- this.closed.emit();
4544
- return this._destroyFilterDrawer();
4545
- }
4546
- if (!this.hasVisibleItemOrSorting) {
4547
- return;
4548
- }
4549
- this._listenEscButton();
4550
- this.opened.emit();
4551
- this._filterOverlay.open();
4482
+ close() {
4483
+ this.select.close();
4552
4484
  }
4553
- init() {
4554
- const data = this._itemStore.valuesAsQuery();
4555
- this._sort = this._itemStore.getSort();
4556
- if (this.config.init) {
4557
- this.config.init(data, this._sort, this);
4558
- }
4559
- this._updateChipsVisibility();
4560
- this.items
4561
- .forEach((item) => {
4562
- item.init(item, this);
4563
- });
4485
+ markForCheck() {
4486
+ this._cd.markForCheck();
4564
4487
  }
4565
- clear(event = null) {
4566
- if (event) {
4567
- event.stopPropagation();
4488
+ isolateChange(filter) {
4489
+ if (filter.isolate.enabled) {
4490
+ filter.model = filter.multiple ? [filter.isolate.value] : filter.isolate.value;
4568
4491
  }
4569
- this._itemStore.filtersClear();
4570
- if (this.config.clear) {
4571
- this.config.clear();
4492
+ else {
4493
+ if (filter.multiple) {
4494
+ filter.model = filter.defaultValue ? filter.defaultValue : [];
4495
+ }
4496
+ else {
4497
+ filter.model = filter.defaultValue ? filter.defaultValue : null;
4498
+ }
4572
4499
  }
4573
- this.keyword = '';
4574
4500
  }
4575
- reload(event = null) {
4576
- if (event) {
4577
- event.preventDefault();
4578
- event.stopPropagation();
4579
- }
4580
- const data = this._itemStore.valuesAsQuery();
4581
- const el = this.reloadEl?.nativeElement;
4582
- if (el) {
4583
- el.style.transition = 'all 0.75s 0.0s';
4584
- el.style.transform = 'rotate(360deg)';
4585
- setTimeout(() => {
4586
- el.style.transition = null;
4587
- el.style.transform = null;
4588
- }, 1000);
4589
- }
4590
- if (this.config.reload) {
4591
- this.config.reload(data, this._itemStore.getSort());
4501
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectMultipleComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4502
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectMultipleComponent, isStandalone: true, selector: "filter-item-select-multiple", inputs: { item: "item" }, viewQueries: [{ propertyName: "select", first: true, predicate: ["select"], descendants: true, static: true }], ngImport: i0, template: "<mat-form-field [ngClass]=\"{ isolate: item.isolate }\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n (ngModelChange)=\"changed()\"\n [multiple]=\"item.multiple\">\n @for (item of item.values | fsFilterIsolateValues: item.isolate; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n @if (item.isolate) {\n <mat-checkbox\n (change)=\"isolateChange(item)\"\n [(ngModel)]=\"item.isolate.enabled\">\n <span class=\"checkbox-label\">\n {{ item.isolate.label }}\n </span>\n </mat-checkbox>\n }\n </mat-hint>\n</mat-form-field>", styles: [""], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "pipe", type: FsFilterIsolateValues, name: "fsFilterIsolateValues" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4503
+ }
4504
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectMultipleComponent, decorators: [{
4505
+ type: Component,
4506
+ args: [{ selector: 'filter-item-select-multiple', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4507
+ MatFormField,
4508
+ NgClass,
4509
+ MatLabel,
4510
+ MatSelect,
4511
+ FocusToItemDirective,
4512
+ FormsModule,
4513
+ FsFormModule,
4514
+ MatOption,
4515
+ MatHint,
4516
+ MatCheckbox,
4517
+ FsFilterIsolateValues,
4518
+ ], template: "<mat-form-field [ngClass]=\"{ isolate: item.isolate }\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n (ngModelChange)=\"changed()\"\n [multiple]=\"item.multiple\">\n @for (item of item.values | fsFilterIsolateValues: item.isolate; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n @if (item.isolate) {\n <mat-checkbox\n (change)=\"isolateChange(item)\"\n [(ngModel)]=\"item.isolate.enabled\">\n <span class=\"checkbox-label\">\n {{ item.isolate.label }}\n </span>\n </mat-checkbox>\n }\n </mat-hint>\n</mat-form-field>" }]
4519
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
4520
+ type: Input
4521
+ }], select: [{
4522
+ type: ViewChild,
4523
+ args: ['select', { static: true }]
4524
+ }] } });
4525
+
4526
+ class SelectSimpleComponent {
4527
+ _cd;
4528
+ item;
4529
+ select;
4530
+ constructor(_cd) {
4531
+ this._cd = _cd;
4532
+ }
4533
+ changed() {
4534
+ if (this.item.isolate) {
4535
+ this.item.isolate.enabled = false;
4592
4536
  }
4593
4537
  }
4594
- getItem(name) {
4595
- return this.items
4596
- .find((item) => item.name === name);
4538
+ isolateChange(filter) {
4539
+ filter.model = filter.isolate.enabled ? filter.isolate.value : null;
4597
4540
  }
4598
- fetchQueryParams() {
4599
- this._paramController.fetchQueryParams();
4541
+ markForCheck() {
4542
+ this._cd.markForCheck();
4600
4543
  }
4601
- /**
4602
- * Call change callback and apply new filter values
4603
- */
4604
- change() {
4605
- const valuesAsQuery = this._itemStore.valuesAsQuery();
4606
- const sort = this._itemStore.getSort();
4607
- const sortingChanged = ((!sort || !this._sort) && sort !== this._sort)
4608
- || (sort && this._sort && !objectsAreEquals(this._sort, sort));
4609
- if (sortingChanged) {
4610
- this._sort = sort;
4611
- if (this.config.sortChange) {
4612
- this.config.sortChange(valuesAsQuery, sort);
4613
- }
4614
- }
4615
- if (this.config.change) {
4616
- this.config.change(valuesAsQuery, sort);
4617
- }
4618
- this._updateChipsVisibility();
4619
- // visibility for actions can depend on filters state
4620
- this._actions.updateActionsVisibility();
4544
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectSimpleComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4545
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectSimpleComponent, isStandalone: true, selector: "filter-item-select-simple", inputs: { item: "item" }, viewQueries: [{ propertyName: "select", first: true, predicate: ["select"], descendants: true, static: true }], ngImport: i0, template: "<mat-form-field [ngClass]=\"{ isolate: !!item.isolate }\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n (ngModelChange)=\"changed()\">\n @for (item of item.values | fsFilterIsolateValues: item.isolate; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n</mat-form-field>\n@if (item.isolate) {\n <mat-checkbox\n (change)=\"isolateChange(item)\"\n [(ngModel)]=\"item.isolate.enabled\">\n <span class=\"checkbox-label\">\n {{ item.isolate.label }}\n </span>\n </mat-checkbox>\n}", styles: [""], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "pipe", type: FsFilterIsolateValues, name: "fsFilterIsolateValues" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4546
+ }
4547
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectSimpleComponent, decorators: [{
4548
+ type: Component,
4549
+ args: [{ selector: 'filter-item-select-simple', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4550
+ MatFormField,
4551
+ NgClass,
4552
+ MatLabel,
4553
+ MatSelect,
4554
+ FocusToItemDirective,
4555
+ FormsModule,
4556
+ FsFormModule,
4557
+ MatOption,
4558
+ MatCheckbox,
4559
+ FsFilterIsolateValues,
4560
+ ], template: "<mat-form-field [ngClass]=\"{ isolate: !!item.isolate }\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n #select\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n (ngModelChange)=\"changed()\">\n @for (item of item.values | fsFilterIsolateValues: item.isolate; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n</mat-form-field>\n@if (item.isolate) {\n <mat-checkbox\n (change)=\"isolateChange(item)\"\n [(ngModel)]=\"item.isolate.enabled\">\n <span class=\"checkbox-label\">\n {{ item.isolate.label }}\n </span>\n </mat-checkbox>\n}" }]
4561
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
4562
+ type: Input
4563
+ }], select: [{
4564
+ type: ViewChild,
4565
+ args: ['select', { static: true }]
4566
+ }] } });
4567
+
4568
+ class SelectComponent extends BaseItemComponent {
4569
+ _kvDiffers;
4570
+ _cd;
4571
+ selectedItem;
4572
+ // For case when we have multiple selection with __all option
4573
+ // If _all has been selected than we must disable all other items
4574
+ allItemsOptionSelected = false;
4575
+ get multipleSelectItem() {
4576
+ return this.item;
4621
4577
  }
4622
- /**
4623
- * Update filter actions config
4624
- *
4625
- * @param actions
4626
- */
4627
- updateActions(actions) {
4628
- this._actions.initActions(actions);
4578
+ get simpleSelectItem() {
4579
+ return this.item;
4629
4580
  }
4630
- /**
4631
- * Show "Filters" button
4632
- */
4633
- showFiltersBtn() {
4634
- this._filtersBtnVisible$.next(true);
4581
+ values$;
4582
+ constructor(_kvDiffers, _cd) {
4583
+ super(_kvDiffers, _cd);
4584
+ this._kvDiffers = _kvDiffers;
4585
+ this._cd = _cd;
4635
4586
  }
4636
- /**
4637
- * Hide "Filters" button
4638
- */
4639
- hideFiltersBtn() {
4640
- this._filtersBtnVisible$.next(false);
4587
+ ngOnChanges(changes) {
4588
+ if (changes.item) {
4589
+ this.values$ = this.item.values$;
4590
+ }
4641
4591
  }
4642
- /**
4643
- * Show "Keyword" field if it present
4644
- */
4645
- showKeywordField() {
4646
- this._keywordVisible$.next(true);
4592
+ ngDoCheck() {
4593
+ if (this._kvDiffer) {
4594
+ const changes = this._kvDiffer.diff(this.item);
4595
+ if (changes) {
4596
+ this._cd.markForCheck();
4597
+ if (this.selectedItem) {
4598
+ this.selectedItem.markForCheck();
4599
+ }
4600
+ }
4601
+ }
4647
4602
  }
4648
- /**
4649
- * Hide "Keyword" field if it present
4650
- */
4651
- hideKeywordField() {
4652
- this._keywordVisible$.next(false);
4603
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4604
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectComponent, isStandalone: true, selector: "filter-item-select", viewQueries: [{ propertyName: "selectedItem", first: true, predicate: ["selectItem"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "@if ((item.loading$ | async)) {\n <mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <mat-select disabled></mat-select>\n </mat-form-field>\n} @else {\n @if ((values$ | async)?.length) {\n @if (item.multiple && !item.children) {\n <filter-item-select-multiple\n [item]=\"multipleSelectItem\"\n #selectItem>\n </filter-item-select-multiple>\n }\n @if (!item.multiple && !item.children) {\n <filter-item-select-simple\n [item]=\"simpleSelectItem\"\n #selectItem>\n </filter-item-select-simple>\n }\n @if (item.children) {\n <filter-item-select-groups\n [item]=\"item\"\n #selectItem>\n </filter-item-select-groups>\n }\n }\n}\n\n", styles: [":host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper{padding-left:0;padding-right:0;padding-top:8px}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field{position:relative}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-checkbox{position:absolute}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-label{margin-left:32px;font-size:smaller;line-height:normal}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: SelectMultipleComponent, selector: "filter-item-select-multiple", inputs: ["item"] }, { kind: "component", type: SelectSimpleComponent, selector: "filter-item-select-simple", inputs: ["item"] }, { kind: "component", type: SelectGroupsComponent, selector: "filter-item-select-groups", inputs: ["item"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4605
+ }
4606
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectComponent, decorators: [{
4607
+ type: Component,
4608
+ args: [{ selector: 'filter-item-select', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4609
+ MatFormField,
4610
+ MatLabel,
4611
+ MatSelect,
4612
+ SelectMultipleComponent,
4613
+ SelectSimpleComponent,
4614
+ SelectGroupsComponent,
4615
+ AsyncPipe,
4616
+ ], template: "@if ((item.loading$ | async)) {\n <mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <mat-select disabled></mat-select>\n </mat-form-field>\n} @else {\n @if ((values$ | async)?.length) {\n @if (item.multiple && !item.children) {\n <filter-item-select-multiple\n [item]=\"multipleSelectItem\"\n #selectItem>\n </filter-item-select-multiple>\n }\n @if (!item.multiple && !item.children) {\n <filter-item-select-simple\n [item]=\"simpleSelectItem\"\n #selectItem>\n </filter-item-select-simple>\n }\n @if (item.children) {\n <filter-item-select-groups\n [item]=\"item\"\n #selectItem>\n </filter-item-select-groups>\n }\n }\n}\n\n", styles: [":host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper{padding-left:0;padding-right:0;padding-top:8px}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field{position:relative}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-checkbox{position:absolute}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-label{margin-left:32px;font-size:smaller;line-height:normal}\n"] }]
4617
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }], propDecorators: { selectedItem: [{
4618
+ type: ViewChild,
4619
+ args: ['selectItem']
4620
+ }] } });
4621
+
4622
+ class TextComponent extends BaseItemComponent {
4623
+ _kvDiffers;
4624
+ _cd;
4625
+ textControl = new UntypedFormControl();
4626
+ constructor(_kvDiffers, _cd) {
4627
+ super(_kvDiffers, _cd);
4628
+ this._kvDiffers = _kvDiffers;
4629
+ this._cd = _cd;
4653
4630
  }
4654
- /**
4655
- * Go through actions and check show() callback and update visible actions
4656
- */
4657
- updateActionsVisibility() {
4658
- this._actions.updateActionsVisibility();
4631
+ ngOnInit() {
4632
+ this._listenControlValueChanges();
4633
+ this._listenModelChanges();
4659
4634
  }
4660
- /**
4661
- * Go through actions and check disabled() callback and update disabled state
4662
- */
4663
- updateDisabledState() {
4664
- this._actions.updateDisabledState();
4635
+ _listenControlValueChanges() {
4636
+ this.textControl.valueChanges
4637
+ .pipe(distinctUntilChanged(), debounceTime(200), takeUntil(this.destroy$))
4638
+ .subscribe((value) => {
4639
+ this.item.model = value;
4640
+ });
4665
4641
  }
4666
- setItems(items) {
4667
- this._itemStore.destroyItems();
4668
- this.config.items = items;
4669
- this._itemStore.setConfig(this._config);
4670
- this._paramController.initItems();
4671
- this._updateKeyword();
4642
+ _listenModelChanges() {
4643
+ this._item.value$
4644
+ .pipe(takeUntil(this.destroy$))
4645
+ .subscribe(() => {
4646
+ this.textControl.setValue(this.item.model, { emitEvent: false });
4647
+ });
4672
4648
  }
4673
- keywordChange(keyword) {
4674
- this._keyword$.next(keyword);
4649
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4650
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: TextComponent, isStandalone: true, selector: "filter-item-text", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [formControl]=\"textControl\"\n [fsFilterFocusTrigger]=\"item\">\n @if (item.suffix) {\n <span\n matSuffix\n [innerHtml]=\"item.suffix\">\n </span>\n }\n</mat-form-field>", styles: [""], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4651
+ }
4652
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextComponent, decorators: [{
4653
+ type: Component,
4654
+ args: [{ selector: 'filter-item-text', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4655
+ MatFormField,
4656
+ MatLabel,
4657
+ MatPrefix,
4658
+ MatInput,
4659
+ FormsModule,
4660
+ ReactiveFormsModule,
4661
+ FocusToItemDirective,
4662
+ MatSuffix,
4663
+ ], template: "<mat-form-field>\n <mat-label>\n {{ item.label }}\n </mat-label>\n @if (item.prefix) {\n <span\n matTextPrefix\n [innerHtml]=\"item.prefix\">\n </span>\n }\n <input\n matInput\n [formControl]=\"textControl\"\n [fsFilterFocusTrigger]=\"item\">\n @if (item.suffix) {\n <span\n matSuffix\n [innerHtml]=\"item.suffix\">\n </span>\n }\n</mat-form-field>" }]
4664
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4665
+
4666
+ class WeekComponent extends BaseItemComponent {
4667
+ _kvDiffers;
4668
+ _cd;
4669
+ constructor(_kvDiffers, _cd) {
4670
+ super(_kvDiffers, _cd);
4671
+ this._kvDiffers = _kvDiffers;
4672
+ this._cd = _cd;
4675
4673
  }
4676
- updateSortings(items) {
4677
- this._itemStore.updateSortingItemsValues(items);
4674
+ ngOnInit() { }
4675
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WeekComponent, deps: [{ token: i0.KeyValueDiffers }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4676
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: WeekComponent, isStandalone: true, selector: "filter-item-week", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <input \n matInput\n fsDateWeekPicker\n [placeholder]=\"item.label\"\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [seedDate]=\"item.seedDate\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n</mat-form-field>\n", dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i3$1.FsDateWeekPickerComponent, selector: "[fsDateWeekPicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "seedDate", "period", "view"], outputs: ["change"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger", "focusTargetType"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4677
+ }
4678
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WeekComponent, decorators: [{
4679
+ type: Component,
4680
+ args: [{ selector: 'filter-item-week', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4681
+ MatFormField,
4682
+ MatLabel,
4683
+ MatInput,
4684
+ FormsModule,
4685
+ FsDatePickerModule,
4686
+ FocusToItemDirective,
4687
+ FsFormModule,
4688
+ ], template: "<mat-form-field>\n <mat-label>{{item.label}}</mat-label>\n <input \n matInput\n fsDateWeekPicker\n [placeholder]=\"item.label\"\n [fsFilterFocusTrigger]=\"item\"\n [(ngModel)]=\"item.model\"\n [seedDate]=\"item.seedDate\"\n [clear]=\"item.showClear\"\n [name]=\"item.name\">\n</mat-form-field>\n" }]
4689
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4690
+
4691
+ class FilterItemComponent {
4692
+ _cdRef;
4693
+ item;
4694
+ itemType = ItemType;
4695
+ get textItem() {
4696
+ return this.item;
4678
4697
  }
4679
- _initFilterWithConfig(config) {
4680
- if (this.config) {
4681
- this._itemStore.destroyItems();
4682
- }
4683
- config = {
4684
- ...(this._defaultConfig || {}),
4685
- ...config,
4686
- };
4687
- this._config = new FsFilterConfig(config);
4688
- this._actions.setConfig(this._config);
4689
- this._persistanceController.setConfig(this._config, this.inDialog);
4690
- this._itemStore.setConfig(this._config);
4691
- this._paramController.setConfig(this._config);
4692
- this._updateKeyword();
4693
- if (this.config.reloadWhenConfigChanged) {
4694
- this.change();
4695
- }
4698
+ get chipsItem() {
4699
+ return this.item;
4700
+ }
4701
+ get baseSelectItem() {
4702
+ return this.item;
4696
4703
  }
4697
- _destroyFilterDrawer() {
4698
- this._filterOverlay.close();
4704
+ get rangeItem() {
4705
+ return this.item;
4699
4706
  }
4700
- _updateWindowWidth() {
4701
- this.windowDesktop = window.innerWidth > 1200;
4707
+ get autocompleteItem() {
4708
+ return this.item;
4702
4709
  }
4703
- _listenEscButton() {
4704
- this._zone.runOutsideAngular(() => {
4705
- fromEvent(window, 'keyup')
4706
- .pipe(filter$1((event) => event.code === 'Escape'), takeUntil(this.closed), takeUntil(this._destroy$))
4707
- .subscribe(() => {
4708
- this._zone.run(() => {
4709
- this.changeVisibility(false);
4710
- });
4711
- });
4712
- });
4710
+ get autocompleteChipsItem() {
4711
+ return this.item;
4713
4712
  }
4714
- _listenWindowResize() {
4715
- this._zone.runOutsideAngular(() => {
4716
- fromEvent(window, 'resize')
4717
- .pipe(debounceTime(100), takeUntil(this._destroy$))
4718
- .subscribe(() => {
4719
- this._zone.run(() => {
4720
- this._updateWindowWidth();
4721
- });
4722
- });
4723
- });
4713
+ get dateItem() {
4714
+ return this.item;
4724
4715
  }
4725
- _initAutoReload() {
4726
- if (this.config.autoReload) {
4727
- interval(this.config.autoReload.seconds * 1000)
4728
- .pipe(filter$1(() => this.autoReload), takeUntil(this._destroy$))
4729
- .subscribe(() => {
4730
- this.reload(null);
4731
- });
4732
- }
4716
+ get dateRangeItem() {
4717
+ return this.item;
4733
4718
  }
4734
- _listenInputChanges() {
4735
- this._keyword$
4736
- .pipe(debounceTime(200), distinctUntilChanged(), takeUntil(this._destroy$))
4737
- .subscribe((value) => {
4738
- const keywordItem = this._itemStore.keywordItem;
4739
- keywordItem.model = value;
4740
- this.change();
4741
- });
4719
+ get dateTimeItem() {
4720
+ return this.item;
4742
4721
  }
4743
- _initKeywordVisibility() {
4744
- this._keywordVisible$.next(!!this.keywordItem && !this.keywordItem?.hide);
4722
+ get dateTimeRangeItem() {
4723
+ return this.item;
4745
4724
  }
4746
- _initAutoFocus() {
4747
- // Avoid ngChanges error
4748
- setTimeout(() => {
4749
- if (this.config.autofocus) {
4750
- this.focus();
4751
- }
4752
- });
4725
+ get weekItem() {
4726
+ return this.item;
4753
4727
  }
4754
- _listenInternalItemsChange() {
4755
- this._itemStore
4756
- .itemsChange$
4728
+ get checkboxItem() {
4729
+ return this.item;
4730
+ }
4731
+ _destroy$ = new Subject();
4732
+ constructor(_cdRef) {
4733
+ this._cdRef = _cdRef;
4734
+ }
4735
+ ngOnInit() {
4736
+ this.item.value$
4757
4737
  .pipe(takeUntil(this._destroy$))
4758
4738
  .subscribe(() => {
4759
- this.keyword = this._itemStore.keywordItem?.model;
4760
- this.change();
4739
+ this._cdRef.markForCheck();
4761
4740
  });
4762
4741
  }
4763
- _initOverlay() {
4764
- this._filterOverlay.setClearFn(this.clear.bind(this));
4765
- this._filterOverlay.setDoneFn(this.hide.bind(this));
4742
+ ngOnDestroy() {
4743
+ this._destroy$.next(null);
4744
+ this._destroy$.complete();
4766
4745
  }
4767
- // We may need some time to recieve external params and after that ready can be emitted
4768
- _listenWhenFilterReady() {
4769
- combineLatest([
4770
- this._paramController.pending$,
4771
- this.itemsReady$,
4772
- ])
4773
- .pipe(filter$1(([pendingParams, itemsReady]) => !pendingParams && itemsReady), takeUntil(this._destroy$))
4774
- .subscribe(() => {
4775
- this.init();
4776
- this._updateKeyword();
4777
- this.ready.emit();
4778
- });
4746
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterItemComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4747
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilterItemComponent, isStandalone: true, selector: "filter-item", inputs: { item: "item" }, ngImport: i0, template: "@if (item.visible$ | async) {\n <div class=\"filter filter-{{ item.type }}\">\n @switch (item.type) {\n @case (itemType.Text) {\n <filter-item-text\n class=\"interface\"\n [item]=\"textItem\">\n </filter-item-text>\n }\n @case (itemType.Select) {\n <filter-item-select\n class=\"interface\"\n [item]=\"baseSelectItem\">\n </filter-item-select>\n }\n @case (itemType.Chips) {\n <filter-item-chips\n class=\"interface\"\n [item]=\"chipsItem\">\n </filter-item-chips>\n }\n @case (itemType.Range) {\n <filter-item-range\n class=\"interface interface-range\"\n [item]=\"rangeItem\">\n </filter-item-range>\n }\n @case (itemType.AutoComplete) {\n <filter-item-autocomplete\n class=\"interface\"\n [item]=\"autocompleteItem\">\n </filter-item-autocomplete>\n }\n @case (itemType.AutoCompleteChips) {\n <filter-item-autocompletechips\n class=\"interface\"\n [item]=\"autocompleteChipsItem\">\n </filter-item-autocompletechips>\n }\n @case (itemType.Date) {\n <filter-item-date\n class=\"interface interface-date\"\n [item]=\"dateItem\">\n </filter-item-date>\n }\n @case (itemType.DateTime) {\n <filter-item-date\n class=\"interface interface-date\"\n [item]=\"dateTimeItem\">\n </filter-item-date>\n }\n @case (itemType.DateRange) {\n <filter-item-date-range\n class=\"interface interface-date\"\n [item]=\"dateRangeItem\">\n </filter-item-date-range>\n }\n @case (itemType.DateTimeRange) {\n <filter-item-date-range\n class=\"interface interface-date\"\n [item]=\"dateTimeRangeItem\">\n </filter-item-date-range>\n }\n @case (itemType.Week) {\n <filter-item-week\n class=\"interface\"\n [item]=\"weekItem\">\n </filter-item-week>\n }\n @case (itemType.Checkbox) {\n <filter-item-checkbox\n class=\"interface interface-checkbox\"\n [item]=\"checkboxItem\">\n </filter-item-checkbox>\n }\n }\n </div>\n}", styles: [":host ::ng-deep mat-form-field .mat-form-field-prefix .text-prefix,:host ::ng-deep mat-form-field .mat-form-field-prefix .text-suffix,:host ::ng-deep mat-form-field .mat-form-field-suffix .text-prefix,:host ::ng-deep mat-form-field .mat-form-field-suffix .text-suffix{top:-.25em;position:relative}:host ::ng-deep mat-form-field:not(.mat-form-field-should-float) .mat-form-field-prefix .text-prefix,:host ::ng-deep mat-form-field:not(.mat-form-field-should-float) .mat-form-field-suffix .text-suffix{display:none}\n"], dependencies: [{ kind: "component", type: TextComponent, selector: "filter-item-text" }, { kind: "component", type: SelectComponent, selector: "filter-item-select" }, { kind: "component", type: ChipsComponent, selector: "filter-item-chips" }, { kind: "component", type: RangeComponent, selector: "filter-item-range" }, { kind: "component", type: AutocompleteComponent, selector: "filter-item-autocomplete" }, { kind: "component", type: AutocompletechipsComponent, selector: "filter-item-autocompletechips" }, { kind: "component", type: DateComponent, selector: "filter-item-date" }, { kind: "component", type: DateRangeComponent, selector: "filter-item-date-range" }, { kind: "component", type: WeekComponent, selector: "filter-item-week" }, { kind: "component", type: CheckboxComponent, selector: "filter-item-checkbox" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4748
+ }
4749
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterItemComponent, decorators: [{
4750
+ type: Component,
4751
+ args: [{ selector: 'filter-item', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4752
+ TextComponent,
4753
+ SelectComponent,
4754
+ ChipsComponent,
4755
+ RangeComponent,
4756
+ AutocompleteComponent,
4757
+ AutocompletechipsComponent,
4758
+ DateComponent,
4759
+ DateRangeComponent,
4760
+ WeekComponent,
4761
+ CheckboxComponent,
4762
+ AsyncPipe,
4763
+ ], template: "@if (item.visible$ | async) {\n <div class=\"filter filter-{{ item.type }}\">\n @switch (item.type) {\n @case (itemType.Text) {\n <filter-item-text\n class=\"interface\"\n [item]=\"textItem\">\n </filter-item-text>\n }\n @case (itemType.Select) {\n <filter-item-select\n class=\"interface\"\n [item]=\"baseSelectItem\">\n </filter-item-select>\n }\n @case (itemType.Chips) {\n <filter-item-chips\n class=\"interface\"\n [item]=\"chipsItem\">\n </filter-item-chips>\n }\n @case (itemType.Range) {\n <filter-item-range\n class=\"interface interface-range\"\n [item]=\"rangeItem\">\n </filter-item-range>\n }\n @case (itemType.AutoComplete) {\n <filter-item-autocomplete\n class=\"interface\"\n [item]=\"autocompleteItem\">\n </filter-item-autocomplete>\n }\n @case (itemType.AutoCompleteChips) {\n <filter-item-autocompletechips\n class=\"interface\"\n [item]=\"autocompleteChipsItem\">\n </filter-item-autocompletechips>\n }\n @case (itemType.Date) {\n <filter-item-date\n class=\"interface interface-date\"\n [item]=\"dateItem\">\n </filter-item-date>\n }\n @case (itemType.DateTime) {\n <filter-item-date\n class=\"interface interface-date\"\n [item]=\"dateTimeItem\">\n </filter-item-date>\n }\n @case (itemType.DateRange) {\n <filter-item-date-range\n class=\"interface interface-date\"\n [item]=\"dateRangeItem\">\n </filter-item-date-range>\n }\n @case (itemType.DateTimeRange) {\n <filter-item-date-range\n class=\"interface interface-date\"\n [item]=\"dateTimeRangeItem\">\n </filter-item-date-range>\n }\n @case (itemType.Week) {\n <filter-item-week\n class=\"interface\"\n [item]=\"weekItem\">\n </filter-item-week>\n }\n @case (itemType.Checkbox) {\n <filter-item-checkbox\n class=\"interface interface-checkbox\"\n [item]=\"checkboxItem\">\n </filter-item-checkbox>\n }\n }\n </div>\n}", styles: [":host ::ng-deep mat-form-field .mat-form-field-prefix .text-prefix,:host ::ng-deep mat-form-field .mat-form-field-prefix .text-suffix,:host ::ng-deep mat-form-field .mat-form-field-suffix .text-prefix,:host ::ng-deep mat-form-field .mat-form-field-suffix .text-suffix{top:-.25em;position:relative}:host ::ng-deep mat-form-field:not(.mat-form-field-should-float) .mat-form-field-prefix .text-prefix,:host ::ng-deep mat-form-field:not(.mat-form-field-should-float) .mat-form-field-suffix .text-suffix{display:none}\n"] }]
4764
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
4765
+ type: Input
4766
+ }] } });
4767
+
4768
+ class FilterDrawerComponent {
4769
+ inline = false;
4770
+ windowDesktop = false;
4771
+ savedFilterName = '';
4772
+ _clear;
4773
+ _done;
4774
+ _destroyRef = inject(DestroyRef);
4775
+ _savedFilterController = inject(SavedFilterController);
4776
+ _message = inject(FsMessage);
4777
+ _itemStore = inject(ItemStore);
4778
+ _overlayRef = inject(FILTER_DRAWER_OVERLAY);
4779
+ _data = inject(FILTER_DRAWER_DATA);
4780
+ _paramController = inject(ParamController);
4781
+ constructor() {
4782
+ this._itemStore.prepareItems();
4783
+ this._clear = this._data.clear;
4784
+ this._done = this._data.done;
4785
+ this.updateWindowWidth();
4779
4786
  }
4780
- _updateKeyword() {
4781
- this.keyword = this._itemStore.keywordItem?.model;
4787
+ updateWindowWidth() {
4788
+ this.windowDesktop = window.innerWidth > 1200;
4782
4789
  }
4783
- _updateChipsVisibility() {
4784
- const hasFilterChips = this._itemStore.items
4785
- .some((item) => {
4786
- return item.isChipVisible;
4790
+ get items$() {
4791
+ return of(this._itemStore.items);
4792
+ }
4793
+ get paramCointroller() {
4794
+ return this._paramController;
4795
+ }
4796
+ get savedFiltersController() {
4797
+ return this._savedFilterController;
4798
+ }
4799
+ ngOnInit() {
4800
+ this._savedFilterController.activeFilter$
4801
+ .pipe(takeUntilDestroyed(this._destroyRef))
4802
+ .subscribe((activeFilter) => {
4803
+ this.savedFilterName = activeFilter?.name || '';
4787
4804
  });
4788
- this._hasFilterChips$.next(hasFilterChips);
4789
4805
  }
4790
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4791
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilterComponent, isStandalone: true, selector: "fs-filter", inputs: { setConfig: ["config", "setConfig"], setFilter: ["filter", "setFilter"], showSortBy: "showSortBy" }, outputs: { closed: "closed", opened: "opened", ready: "ready" }, host: { properties: { "class.filters-open": "this.showFilterMenu", "class.window-desktop": "this.windowDesktop", "class.fs-filter": "this.fsFilterClass" } }, providers: [
4792
- FsFilterOverlayService,
4793
- ParamController,
4794
- PersistanceController,
4795
- QueryParamController,
4796
- FocusControllerService,
4797
- ItemStore,
4798
- SavedFilterController,
4799
- ActionsController,
4800
- ], queries: [{ propertyName: "statusBar", first: true, predicate: FilterStatusBarDirective, descendants: true }], viewQueries: [{ propertyName: "keywordMatInput", first: true, predicate: ["keywordMatInput"], descendants: true, read: MatInput }, { propertyName: "reloadEl", first: true, predicate: ["reloadEl"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"filter-container\">\n @if (notInlineToolbar$ | async) {\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n }\n <div class=\"filter-inner-container\">\n @if (notInlineToolbar$ | async) {\n <div class=\"filter-inner-inputs\">\n @if (keywordVisible$ | async) {\n <mat-form-field\n class=\"search-form-field form-field-padless\"\n [ngClass]=\"{\n 'has-keyword': !!keyword\n }\">\n <span\n matPrefix\n class=\"icon\">\n <mat-icon matPrefix>\n search\n </mat-icon>\n </span>\n <input\n #keywordMatInput\n matInput\n [(ngModel)]=\"keyword\"\n (ngModelChange)=\"keywordChange($event)\"\n name=\"filter-input\"\n [fsClear]=\"true\"\n [placeholder]=\"searchPlaceholder\">\n </mat-form-field>\n }\n @if (savedFiltersController.enabled) {\n <fs-saved-filter-autocomplete-chips [savedFiltersController]=\"savedFiltersController\"></fs-saved-filter-autocomplete-chips>\n }\n </div>\n } @else {\n <div>\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n <ng-container *ngTemplateOutlet=\"filterStatusBarChips\"></ng-container>\n </div>\n }\n <ng-container [ngTemplateOutlet]=\"filterToolbar\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"filterActions\"></ng-container>\n </div>\n @if (notInlineToolbar$ | async) {\n <ng-container *ngTemplateOutlet=\"filterStatusBarChips\"></ng-container>\n }\n</div>\n<ng-template #filterStatusBarChips>\n @if (statusBar) {\n <div\n class=\"filter-status-container\"\n [ngClass]=\"{ 'has-status': !!filterStatus.textContent }\">\n <div\n class=\"filter-status\"\n #filterStatus>\n <ng-container *ngTemplateOutlet=\"statusBar.templateRef\"></ng-container>\n </div>\n </div>\n }\n @if (config.chips && hasFilterChips$ | async) {\n <fs-filter-chips\n class=\"filter-chips\"\n [filters]=\"items\">\n </fs-filter-chips>\n }\n</ng-template>\n<ng-template #filterActions>\n @if (actionsVisible$ | async) {\n <div class=\"filter-actions\">\n <fs-filter-actions\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n }\n</ng-template>\n<ng-template #filterToolbar>\n @if (config.reload || config.autoReload || ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting)) {\n <div class=\"filter-toolbar\">\n @if ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting) {\n <a\n mat-icon-button\n class=\"button-filters\"\n (click)=\"changeVisibilityClick(!showFilterMenu, $event)\"\n [color]=\"config.button.color\">\n @if (config.button.icon) {\n <mat-icon svgIcon=\"filterOutline\"></mat-icon>\n }\n {{ config.button.label }}\n </a>\n }\n @if (config.reload) {\n <a\n mat-icon-button\n (click)=\"reload($event)\"\n class=\"button-reload\">\n <mat-icon #reloadEl>\n refresh\n </mat-icon>\n </a>\n }\n @if (config.autoReload) {\n <div class=\"filter-reload\">\n @if (config.autoReload) {\n <mat-slide-toggle\n name=\"autoReload\"\n class=\"auto-reload\"\n [(ngModel)]=\"autoReload\">\n <span>\n Auto refresh\n </span>\n </mat-slide-toggle>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n<ng-template #heading>\n @if (config.heading) {\n <div class=\"heading\">\n <h2>\n {{ config.heading }}\n </h2>\n <div class=\"subheading\">\n {{ config.subheading }}\n </div>\n </div>\n }\n</ng-template>", styles: [":host{margin-bottom:20px;display:block}.filter-status-container{flex-grow:1;display:flex;justify-content:center;flex-direction:column;align-self:flex-end}.filter-status-container .filter-status{overflow:hidden;text-overflow:ellipsis;line-height:18px}.filter-container{width:100%}.filter-inner-container{flex-direction:row;box-sizing:border-box;display:flex;position:relative;align-items:center}.filter-inner-container .filter-inner-inputs{flex-direction:row;box-sizing:border-box;display:flex;align-items:center;min-width:0;gap:5px}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field{max-width:100%;width:250px;margin-top:0}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field .icon{margin-left:10px;color:#626262}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-actions{display:flex;align-items:center;flex:1;justify-content:flex-end}.filter-toolbar{white-space:nowrap;display:flex;align-items:center}.filter-toolbar .button-filters,.filter-toolbar .button-reload{display:flex;width:40px;padding:8px;height:40px;overflow:hidden}.filter-toolbar .button-filters ::ng-deep svg,.filter-toolbar .button-reload ::ng-deep svg{display:flex}.filter-toolbar .filter-reload{margin-left:10px;display:flex;align-items:center}.filter-toolbar .filter-reload .auto-reload{margin-right:5px}.filter-toolbar .filter-reload .auto-reload span{font-size:80%}.heading{margin-right:10px}.heading h2{margin:0}.heading h2+.subheading{margin:0}.results{min-height:90px;position:relative;overflow-x:auto;overflow-y:hidden}fs-filter-chips{margin:4px 0;display:flex;flex-wrap:wrap;gap:5px}@media screen and (min-width: 1200px){html.fs-filter-open body{margin-right:350px}}html.fs-filter-open{scrollbar-width:none}:host ::ng-deep .auto-reload.mat-checked .mat-slide-toggle-thumb-container{transform:translate3d(12px,0,0)}:host ::ng-deep .auto-reload:not(.mat-checked) .mat-slide-toggle-content{color:#ccc}:host ::ng-deep .auto-reload .mat-slide-toggle-thumb,:host ::ng-deep .auto-reload .mat-slide-toggle-thumb-container{height:15px;width:15px}:host ::ng-deep .auto-reload .mat-slide-toggle-content{font-size:90%}:host ::ng-deep .auto-reload .mat-slide-toggle-bar{width:26px;height:10px;border-radius:10px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FsSavedFilterAutocompleteChipsComponent, selector: "fs-saved-filter-autocomplete-chips", inputs: ["savedFiltersController"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "ngmodule", type: FsClearModule }, { kind: "component", type: i3$3.FsClearComponent, selector: "[fsClear]", inputs: ["ngModel", "visible", "fsClear"], outputs: ["ngModelChange", "cleared"] }, { kind: "component", type: FsFilterChipsComponent, selector: "fs-filter-chips", inputs: ["filters"] }, { kind: "component", type: FsFilterActionsComponent, selector: "fs-filter-actions", inputs: ["kebabActions", "actions"] }, { kind: "component", type: MatIconAnchor, selector: "a[mat-icon-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4806
+ clear() {
4807
+ this._clear();
4808
+ }
4809
+ done() {
4810
+ this._done();
4811
+ this._overlayRef.detach();
4812
+ }
4813
+ backdropClick() {
4814
+ this.done();
4815
+ }
4816
+ saveSavedFilter = () => {
4817
+ return this._savedFilterController
4818
+ .save({ name: this.savedFilterName })
4819
+ .pipe(tap$1((savedFilter) => {
4820
+ this._savedFilterController.setActiveFilter(savedFilter);
4821
+ this._message
4822
+ .success(`Saved ${this._savedFilterController.singularLabel}`, {
4823
+ positionClass: 'toast-bottom-left',
4824
+ });
4825
+ }));
4826
+ };
4827
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4828
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilterDrawerComponent, isStandalone: true, selector: "ng-component", inputs: { inline: "inline" }, host: { listeners: { "window:resize": "updateWindowWidth()" } }, ngImport: i0, template: "<form\n fsForm\n [submit]=\"saveSavedFilter\"\n [dirtySubmitButton]=\"false\">\n <div class=\"filters\">\n <div class=\"filters-wrap\">\n @if (savedFiltersController.activeFilter$ | async) {\n <div class=\"filter-heading\">\n <mat-icon>\n {{ savedFiltersController.labelIcon }}\n </mat-icon>\n <span class=\"text\">\n {{ savedFiltersController.singularLabel }}\n </span>\n </div>\n <div class=\"filter-name\">\n <mat-form-field>\n <mat-label>\n {{ savedFiltersController.singularLabel }} name\n </mat-label>\n <input\n matInput\n required\n [(ngModel)]=\"savedFilterName\"\n name=\"savedFilterName\">\n </mat-form-field>\n <hr>\n <br>\n </div>\n } @else {\n <div class=\"filter-heading\">\n <mat-icon svgIcon=\"filterOutline\"></mat-icon>\n <span class=\"text\">\n Filters\n </span>\n </div>\n }\n <div class=\"overflow-shadow filter-items\">\n <div class=\"overflow-shadow-content\">\n <ng-container *fsSkeleton=\"(paramCointroller.pending$ | async) !== true\">\n @for (filterItem of items$ | async; track filterItem) {\n <filter-item\n class=\"filter-group\"\n [item]=\"filterItem\">\n </filter-item>\n }\n </ng-container>\n </div>\n </div>\n @if ((paramCointroller.pending$ | async) !== true) {\n <fs-filter-drawer-actions\n [savedFiltersController]=\"savedFiltersController\"\n class=\"filter-actions\"\n (clear)=\"clear()\"\n (done)=\"done()\">\n </fs-filter-drawer-actions>\n }\n </div>\n </div>\n @if (!windowDesktop) {\n <div\n class=\"backdrop\"\n (click)=\"backdropClick()\">\n </div>\n }\n</form>", styles: ["@charset \"UTF-8\";@media (max-width: 599px){h1[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"]{margin-top:0}}@media (max-width: 1023px){h1[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"]{margin-top:0}}@media (max-width: 1439px){h1[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"]{margin-top:0}}div[class*=fs-delimit]:not([class*=\".middot\"])>:not(:last-child):after{content:\",\\a0\"}div[class*=fs-delimit][class*=\".middot\"]>:not(:last-child):after{content:\"\\a0\\b7\\a0\"}div[class*=fs-delimit]>*{display:inline-flex}:host ::ng-deep mat-form-field{width:100%}.filter-heading{display:flex;flex-direction:row;align-items:center;box-sizing:border-box;padding:0 25px 20px}.filter-heading mat-icon{margin-right:8px;font-size:24px;line-height:24px}.filter-heading .text{font-weight:400;font-size:19px}.filter-name{padding:0 25px}.filter-name hr{border-color:#a4a4a4;border-top:0;border-left:0;border-right:0}.filter-actions{display:block;box-sizing:border-box;padding:13px}.filter-actions button{margin-right:6px}.filter-actions button:last-child{margin-right:0}.filters{position:fixed;display:block;top:0;right:0;z-index:1002;bottom:0}.filters .filters-wrap{background:#fff;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f;width:100vw;max-width:350px;display:flex;flex-direction:column;padding-top:calc(env(safe-area-inset-top) + 20px);box-sizing:border-box;height:100%}.filters .filters-wrap .filter-items{padding-top:5px;overflow-y:auto;height:auto}.filters .filters-wrap .filter-items .overflow-shadow-content{padding:0 25px;box-sizing:border-box}.filters .filter-group{margin:10px 0 0}.filters .filter-group:first-child{margin:0}.filters .filter label{white-space:nowrap;color:#0000008a}.filters .filter .interface.interface-range input,.filters .filter .interface.interface-range .mat-input-wrapper,.filters .filter .interface.interface-range{text-align:center}.filters .filter .interface.interface-datetime fs-datetime.has-time .md-input{width:100%}.filters .filter .interface fs-datetime-range input{text-align:center}.filters .filter .filter-label{width:1%;white-space:nowrap;vertical-align:middle;padding-right:15px}.filters md-autocomplete-container md-input-container{margin:0}.filters .isolate{margin-top:-12px}.filters .isolate .interface{line-height:20px;padding-bottom:1.25em}.filters .isolate md-checkbox{margin:0 0 0 2px}.backdrop{position:fixed;inset:0;z-index:900;outline:none}@media (max-width: 599px){.filters .filters-wrap{max-width:none}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { kind: "directive", type: i2.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i3$3.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: FilterItemComponent, selector: "filter-item", inputs: ["item"] }, { kind: "component", type: FsFilterDrawerActionsComponent, selector: "fs-filter-drawer-actions", inputs: ["savedFiltersController"], outputs: ["clear", "done"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4801
4829
  }
4802
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, decorators: [{
4830
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterDrawerComponent, decorators: [{
4803
4831
  type: Component,
4804
- args: [{ selector: 'fs-filter', providers: [
4805
- FsFilterOverlayService,
4806
- ParamController,
4807
- PersistanceController,
4808
- QueryParamController,
4809
- FocusControllerService,
4810
- ItemStore,
4811
- SavedFilterController,
4812
- ActionsController,
4813
- ], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4814
- NgTemplateOutlet,
4815
- FsSavedFilterAutocompleteChipsComponent,
4816
- MatFormField,
4817
- NgClass,
4818
- MatPrefix,
4819
- MatIcon,
4820
- MatInput,
4832
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4821
4833
  FormsModule,
4822
4834
  FsFormModule,
4823
- FsClearModule,
4824
- FsFilterChipsComponent,
4825
- FsFilterActionsComponent,
4826
- MatIconAnchor,
4827
- MatSlideToggle,
4835
+ MatIcon,
4836
+ MatFormField,
4837
+ MatLabel,
4838
+ MatInput,
4839
+ FsSkeletonModule,
4840
+ FilterItemComponent,
4841
+ FsFilterDrawerActionsComponent,
4828
4842
  AsyncPipe,
4829
- ], template: "<div class=\"filter-container\">\n @if (notInlineToolbar$ | async) {\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n }\n <div class=\"filter-inner-container\">\n @if (notInlineToolbar$ | async) {\n <div class=\"filter-inner-inputs\">\n @if (keywordVisible$ | async) {\n <mat-form-field\n class=\"search-form-field form-field-padless\"\n [ngClass]=\"{\n 'has-keyword': !!keyword\n }\">\n <span\n matPrefix\n class=\"icon\">\n <mat-icon matPrefix>\n search\n </mat-icon>\n </span>\n <input\n #keywordMatInput\n matInput\n [(ngModel)]=\"keyword\"\n (ngModelChange)=\"keywordChange($event)\"\n name=\"filter-input\"\n [fsClear]=\"true\"\n [placeholder]=\"searchPlaceholder\">\n </mat-form-field>\n }\n @if (savedFiltersController.enabled) {\n <fs-saved-filter-autocomplete-chips [savedFiltersController]=\"savedFiltersController\"></fs-saved-filter-autocomplete-chips>\n }\n </div>\n } @else {\n <div>\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n <ng-container *ngTemplateOutlet=\"filterStatusBarChips\"></ng-container>\n </div>\n }\n <ng-container [ngTemplateOutlet]=\"filterToolbar\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"filterActions\"></ng-container>\n </div>\n @if (notInlineToolbar$ | async) {\n <ng-container *ngTemplateOutlet=\"filterStatusBarChips\"></ng-container>\n }\n</div>\n<ng-template #filterStatusBarChips>\n @if (statusBar) {\n <div\n class=\"filter-status-container\"\n [ngClass]=\"{ 'has-status': !!filterStatus.textContent }\">\n <div\n class=\"filter-status\"\n #filterStatus>\n <ng-container *ngTemplateOutlet=\"statusBar.templateRef\"></ng-container>\n </div>\n </div>\n }\n @if (config.chips && hasFilterChips$ | async) {\n <fs-filter-chips\n class=\"filter-chips\"\n [filters]=\"items\">\n </fs-filter-chips>\n }\n</ng-template>\n<ng-template #filterActions>\n @if (actionsVisible$ | async) {\n <div class=\"filter-actions\">\n <fs-filter-actions\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n }\n</ng-template>\n<ng-template #filterToolbar>\n @if (config.reload || config.autoReload || ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting)) {\n <div class=\"filter-toolbar\">\n @if ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting) {\n <a\n mat-icon-button\n class=\"button-filters\"\n (click)=\"changeVisibilityClick(!showFilterMenu, $event)\"\n [color]=\"config.button.color\">\n @if (config.button.icon) {\n <mat-icon svgIcon=\"filterOutline\"></mat-icon>\n }\n {{ config.button.label }}\n </a>\n }\n @if (config.reload) {\n <a\n mat-icon-button\n (click)=\"reload($event)\"\n class=\"button-reload\">\n <mat-icon #reloadEl>\n refresh\n </mat-icon>\n </a>\n }\n @if (config.autoReload) {\n <div class=\"filter-reload\">\n @if (config.autoReload) {\n <mat-slide-toggle\n name=\"autoReload\"\n class=\"auto-reload\"\n [(ngModel)]=\"autoReload\">\n <span>\n Auto refresh\n </span>\n </mat-slide-toggle>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n<ng-template #heading>\n @if (config.heading) {\n <div class=\"heading\">\n <h2>\n {{ config.heading }}\n </h2>\n <div class=\"subheading\">\n {{ config.subheading }}\n </div>\n </div>\n }\n</ng-template>", styles: [":host{margin-bottom:20px;display:block}.filter-status-container{flex-grow:1;display:flex;justify-content:center;flex-direction:column;align-self:flex-end}.filter-status-container .filter-status{overflow:hidden;text-overflow:ellipsis;line-height:18px}.filter-container{width:100%}.filter-inner-container{flex-direction:row;box-sizing:border-box;display:flex;position:relative;align-items:center}.filter-inner-container .filter-inner-inputs{flex-direction:row;box-sizing:border-box;display:flex;align-items:center;min-width:0;gap:5px}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field{max-width:100%;width:250px;margin-top:0}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field .icon{margin-left:10px;color:#626262}.filter-inner-container .filter-inner-inputs mat-form-field.search-form-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-actions{display:flex;align-items:center;flex:1;justify-content:flex-end}.filter-toolbar{white-space:nowrap;display:flex;align-items:center}.filter-toolbar .button-filters,.filter-toolbar .button-reload{display:flex;width:40px;padding:8px;height:40px;overflow:hidden}.filter-toolbar .button-filters ::ng-deep svg,.filter-toolbar .button-reload ::ng-deep svg{display:flex}.filter-toolbar .filter-reload{margin-left:10px;display:flex;align-items:center}.filter-toolbar .filter-reload .auto-reload{margin-right:5px}.filter-toolbar .filter-reload .auto-reload span{font-size:80%}.heading{margin-right:10px}.heading h2{margin:0}.heading h2+.subheading{margin:0}.results{min-height:90px;position:relative;overflow-x:auto;overflow-y:hidden}fs-filter-chips{margin:4px 0;display:flex;flex-wrap:wrap;gap:5px}@media screen and (min-width: 1200px){html.fs-filter-open body{margin-right:350px}}html.fs-filter-open{scrollbar-width:none}:host ::ng-deep .auto-reload.mat-checked .mat-slide-toggle-thumb-container{transform:translate3d(12px,0,0)}:host ::ng-deep .auto-reload:not(.mat-checked) .mat-slide-toggle-content{color:#ccc}:host ::ng-deep .auto-reload .mat-slide-toggle-thumb,:host ::ng-deep .auto-reload .mat-slide-toggle-thumb-container{height:15px;width:15px}:host ::ng-deep .auto-reload .mat-slide-toggle-content{font-size:90%}:host ::ng-deep .auto-reload .mat-slide-toggle-bar{width:26px;height:10px;border-radius:10px}\n"] }]
4830
- }], ctorParameters: () => [], propDecorators: { setConfig: [{
4831
- type: Input,
4832
- args: ['config']
4833
- }], setFilter: [{
4834
- type: Input,
4835
- args: ['filter']
4836
- }], showSortBy: [{
4843
+ ], template: "<form\n fsForm\n [submit]=\"saveSavedFilter\"\n [dirtySubmitButton]=\"false\">\n <div class=\"filters\">\n <div class=\"filters-wrap\">\n @if (savedFiltersController.activeFilter$ | async) {\n <div class=\"filter-heading\">\n <mat-icon>\n {{ savedFiltersController.labelIcon }}\n </mat-icon>\n <span class=\"text\">\n {{ savedFiltersController.singularLabel }}\n </span>\n </div>\n <div class=\"filter-name\">\n <mat-form-field>\n <mat-label>\n {{ savedFiltersController.singularLabel }} name\n </mat-label>\n <input\n matInput\n required\n [(ngModel)]=\"savedFilterName\"\n name=\"savedFilterName\">\n </mat-form-field>\n <hr>\n <br>\n </div>\n } @else {\n <div class=\"filter-heading\">\n <mat-icon svgIcon=\"filterOutline\"></mat-icon>\n <span class=\"text\">\n Filters\n </span>\n </div>\n }\n <div class=\"overflow-shadow filter-items\">\n <div class=\"overflow-shadow-content\">\n <ng-container *fsSkeleton=\"(paramCointroller.pending$ | async) !== true\">\n @for (filterItem of items$ | async; track filterItem) {\n <filter-item\n class=\"filter-group\"\n [item]=\"filterItem\">\n </filter-item>\n }\n </ng-container>\n </div>\n </div>\n @if ((paramCointroller.pending$ | async) !== true) {\n <fs-filter-drawer-actions\n [savedFiltersController]=\"savedFiltersController\"\n class=\"filter-actions\"\n (clear)=\"clear()\"\n (done)=\"done()\">\n </fs-filter-drawer-actions>\n }\n </div>\n </div>\n @if (!windowDesktop) {\n <div\n class=\"backdrop\"\n (click)=\"backdropClick()\">\n </div>\n }\n</form>", styles: ["@charset \"UTF-8\";@media (max-width: 599px){h1[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-xs*=fs-heading][fs\\.lt-xs*=\".top-none\"]{margin-top:0}}@media (max-width: 1023px){h1[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-sm*=fs-heading][fs\\.lt-sm*=\".top-none\"]{margin-top:0}}@media (max-width: 1439px){h1[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"],h2[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"],h3[class*=\".top\"][fs\\.lt-md*=fs-heading][fs\\.lt-md*=\".top-none\"]{margin-top:0}}div[class*=fs-delimit]:not([class*=\".middot\"])>:not(:last-child):after{content:\",\\a0\"}div[class*=fs-delimit][class*=\".middot\"]>:not(:last-child):after{content:\"\\a0\\b7\\a0\"}div[class*=fs-delimit]>*{display:inline-flex}:host ::ng-deep mat-form-field{width:100%}.filter-heading{display:flex;flex-direction:row;align-items:center;box-sizing:border-box;padding:0 25px 20px}.filter-heading mat-icon{margin-right:8px;font-size:24px;line-height:24px}.filter-heading .text{font-weight:400;font-size:19px}.filter-name{padding:0 25px}.filter-name hr{border-color:#a4a4a4;border-top:0;border-left:0;border-right:0}.filter-actions{display:block;box-sizing:border-box;padding:13px}.filter-actions button{margin-right:6px}.filter-actions button:last-child{margin-right:0}.filters{position:fixed;display:block;top:0;right:0;z-index:1002;bottom:0}.filters .filters-wrap{background:#fff;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f;width:100vw;max-width:350px;display:flex;flex-direction:column;padding-top:calc(env(safe-area-inset-top) + 20px);box-sizing:border-box;height:100%}.filters .filters-wrap .filter-items{padding-top:5px;overflow-y:auto;height:auto}.filters .filters-wrap .filter-items .overflow-shadow-content{padding:0 25px;box-sizing:border-box}.filters .filter-group{margin:10px 0 0}.filters .filter-group:first-child{margin:0}.filters .filter label{white-space:nowrap;color:#0000008a}.filters .filter .interface.interface-range input,.filters .filter .interface.interface-range .mat-input-wrapper,.filters .filter .interface.interface-range{text-align:center}.filters .filter .interface.interface-datetime fs-datetime.has-time .md-input{width:100%}.filters .filter .interface fs-datetime-range input{text-align:center}.filters .filter .filter-label{width:1%;white-space:nowrap;vertical-align:middle;padding-right:15px}.filters md-autocomplete-container md-input-container{margin:0}.filters .isolate{margin-top:-12px}.filters .isolate .interface{line-height:20px;padding-bottom:1.25em}.filters .isolate md-checkbox{margin:0 0 0 2px}.backdrop{position:fixed;inset:0;z-index:900;outline:none}@media (max-width: 599px){.filters .filters-wrap{max-width:none}}\n"] }]
4844
+ }], ctorParameters: () => [], propDecorators: { inline: [{
4837
4845
  type: Input
4838
- }], closed: [{
4839
- type: Output
4840
- }], opened: [{
4841
- type: Output
4842
- }], ready: [{
4843
- type: Output
4844
- }], statusBar: [{
4845
- type: ContentChild,
4846
- args: [FilterStatusBarDirective]
4847
- }], keywordMatInput: [{
4848
- type: ViewChild,
4849
- args: ['keywordMatInput', { read: MatInput }]
4850
- }], reloadEl: [{
4851
- type: ViewChild,
4852
- args: ['reloadEl', { read: ElementRef }]
4853
- }], showFilterMenu: [{
4854
- type: HostBinding,
4855
- args: ['class.filters-open']
4856
- }], windowDesktop: [{
4857
- type: HostBinding,
4858
- args: ['class.window-desktop']
4859
- }], fsFilterClass: [{
4860
- type: HostBinding,
4861
- args: ['class.fs-filter']
4846
+ }], updateWindowWidth: [{
4847
+ type: HostListener,
4848
+ args: ['window:resize']
4862
4849
  }] } });
4863
4850
 
4864
4851
  class SelectBackdropComponent {