@firestitch/filter 18.2.9 → 18.2.10

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,7 +1,7 @@
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';
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
5
  import { tap, finalize, take, takeUntil, debounceTime, filter as filter$1, distinctUntilChanged, switchMap, mapTo, startWith, map, 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';
@@ -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) {
@@ -3257,1608 +3257,1613 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3257
3257
  args: ['focusTargetType']
3258
3258
  }] } });
3259
3259
 
3260
- class TextComponent extends BaseItemComponent {
3260
+ class AutocompleteComponent extends BaseItemComponent {
3261
3261
  _kvDiffers;
3262
3262
  _cd;
3263
- textControl = new UntypedFormControl();
3264
3263
  constructor(_kvDiffers, _cd) {
3265
3264
  super(_kvDiffers, _cd);
3266
3265
  this._kvDiffers = _kvDiffers;
3267
3266
  this._cd = _cd;
3268
3267
  }
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 });
3268
+ displayWith = (data) => {
3269
+ return data ? data.name : data;
3270
+ };
3271
+ fetch = (keyword) => {
3272
+ return this.item.valuesFn(keyword, this.item.filter);
3273
+ };
3274
+ 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 });
3275
+ 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
3276
  }
3290
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextComponent, decorators: [{
3277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompleteComponent, decorators: [{
3291
3278
  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,
3279
+ args: [{ selector: 'filter-item-autocomplete', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3280
+ FsAutocompleteModule,
3299
3281
  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>" }]
3282
+ FormsModule,
3283
+ FsFormModule,
3284
+ ], 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
3285
  }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
3303
3286
 
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
- });
3287
+ class ActionsController {
3288
+ _breakpointObserver;
3289
+ _visible$ = new BehaviorSubject(false);
3290
+ _actions$ = new BehaviorSubject([]);
3291
+ _menuActions$ = new BehaviorSubject([]);
3292
+ _destroy$ = new Subject();
3293
+ _config;
3294
+ _mobileMedia = '(max-width: 799px)';
3295
+ _allActions = [];
3296
+ _reorderAction;
3297
+ constructor(_breakpointObserver) {
3298
+ this._breakpointObserver = _breakpointObserver;
3299
+ this._listenMobileMedia();
3312
3300
  }
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;
3301
+ get menuActions() {
3302
+ return this._menuActions$.value;
3330
3303
  }
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
- }
3304
+ get actions() {
3305
+ return this._actions$.value;
3341
3306
  }
3342
- close() {
3343
- this.select.close();
3307
+ get actions$() {
3308
+ return this._actions$.asObservable();
3344
3309
  }
3345
- markForCheck() {
3346
- this._cd.markForCheck();
3310
+ get menuActions$() {
3311
+ return this._menuActions$.asObservable();
3347
3312
  }
3348
- isolateChange(filter) {
3349
- if (filter.isolate.enabled) {
3350
- filter.model = filter.multiple ? [filter.isolate.value] : filter.isolate.value;
3313
+ get visible$() {
3314
+ return this._visible$.asObservable();
3315
+ }
3316
+ get mobileMode() {
3317
+ return this._breakpointObserver.isMatched(this._mobileMedia);
3318
+ }
3319
+ ngOnDestroy() {
3320
+ this._destroy$.next(null);
3321
+ this._destroy$.complete();
3322
+ }
3323
+ setConfig(config) {
3324
+ this._config = config;
3325
+ this.initActions(config.actions);
3326
+ }
3327
+ initActions(rawActions) {
3328
+ if (!rawActions || !Array.isArray(rawActions)) {
3329
+ return;
3351
3330
  }
3352
- else {
3353
- if (filter.multiple) {
3354
- filter.model = filter.defaultValue ? filter.defaultValue : [];
3331
+ this.show();
3332
+ this._allActions = rawActions
3333
+ .map((action) => new Action(this._config, action));
3334
+ if (this._reorderAction) {
3335
+ this._allActions.unshift(this._reorderAction);
3336
+ }
3337
+ this._classifyActions();
3338
+ }
3339
+ show() {
3340
+ this._visible$.next(true);
3341
+ }
3342
+ hide() {
3343
+ this._visible$.next(false);
3344
+ }
3345
+ addReorderAction(action) {
3346
+ this._allActions.unshift(action);
3347
+ action.isReorderAction = true;
3348
+ this._classifyAction(action);
3349
+ this._reorderAction = action;
3350
+ }
3351
+ clearActions() {
3352
+ this._allActions = [];
3353
+ this._setActions([]);
3354
+ this._setKebabActions([]);
3355
+ }
3356
+ updateActionsVisibility() {
3357
+ this._allActions.forEach((action) => action.updateVisibility());
3358
+ this._classifyActions();
3359
+ }
3360
+ updateDisabledState() {
3361
+ this.actions.forEach((action) => action.updateDisabledState());
3362
+ }
3363
+ _setKebabActions(actions) {
3364
+ this._menuActions$.next(actions);
3365
+ }
3366
+ _setActions(actions) {
3367
+ this._actions$.next(actions);
3368
+ }
3369
+ _classifyActions() {
3370
+ const kebabActions = [];
3371
+ const actions = [];
3372
+ const mobileMode = this.mobileMode;
3373
+ this._allActions
3374
+ .filter((action) => {
3375
+ return action.visible;
3376
+ })
3377
+ .forEach((action) => {
3378
+ if (action.menu !== false && (action.menu || mobileMode)) {
3379
+ kebabActions.push(action);
3355
3380
  }
3356
3381
  else {
3357
- filter.model = filter.defaultValue ? filter.defaultValue : null;
3382
+ actions.push(action);
3358
3383
  }
3384
+ });
3385
+ this._setKebabActions(kebabActions);
3386
+ this._setActions(actions);
3387
+ }
3388
+ _classifyAction(action) {
3389
+ if (action.menu) {
3390
+ this._setKebabActions([...this.menuActions, action]);
3391
+ }
3392
+ else {
3393
+ this._setActions([...this.actions, action]);
3359
3394
  }
3360
3395
  }
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 });
3396
+ _listenMobileMedia() {
3397
+ this._breakpointObserver.observe(this._mobileMedia)
3398
+ .pipe(skip(1), takeUntil(this._destroy$))
3399
+ .subscribe(() => {
3400
+ this._classifyActions();
3401
+ });
3402
+ }
3403
+ 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 });
3404
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionsController });
3363
3405
  }
3364
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectMultipleComponent, decorators: [{
3406
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionsController, decorators: [{
3407
+ type: Injectable
3408
+ }], ctorParameters: () => [{ type: i1$4.BreakpointObserver }] });
3409
+
3410
+ 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>';
3411
+
3412
+ class FsFilterSavedFilterChipsComponent {
3413
+ savedFilter;
3414
+ items = [];
3415
+ _itemStore = inject(ItemStore);
3416
+ ngOnInit() {
3417
+ this.items = [...this._itemStore.items]
3418
+ .filter((item) => !!this.savedFilter.filters[item.name])
3419
+ .map((item) => {
3420
+ item.setModel(this.savedFilter.filters[item.name]);
3421
+ return item;
3422
+ });
3423
+ }
3424
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3425
+ 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 });
3426
+ }
3427
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterChipsComponent, decorators: [{
3365
3428
  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: [{
3429
+ args: [{ selector: 'fs-saved-filter-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3430
+ FsFilterChipComponent,
3431
+ ], 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"] }]
3432
+ }], propDecorators: { savedFilter: [{
3380
3433
  type: Input
3381
- }], select: [{
3382
- type: ViewChild,
3383
- args: ['select', { static: true }]
3384
3434
  }] } });
3385
3435
 
3386
- class SelectSimpleComponent {
3387
- _cd;
3388
- item;
3389
- select;
3390
- constructor(_cd) {
3391
- this._cd = _cd;
3392
- }
3393
- changed() {
3394
- if (this.item.isolate) {
3395
- this.item.isolate.enabled = false;
3396
- }
3436
+ class FsFilterSavedFilterManageComponent {
3437
+ savedFilters;
3438
+ _savedFilterController = inject(SavedFilterController);
3439
+ _cdRef = inject(ChangeDetectorRef);
3440
+ _paramController = inject(ParamController);
3441
+ _itemStore = inject(ItemStore);
3442
+ _dialogRef = inject(MatDialogRef);
3443
+ _filterOverlayService = inject(FsFilterOverlayService);
3444
+ ngOnInit() {
3445
+ this.savedFilters = this._savedFilterController.savedFilters;
3397
3446
  }
3398
- isolateChange(filter) {
3399
- filter.model = filter.isolate.enabled ? filter.isolate.value : null;
3447
+ get items() {
3448
+ return this._itemStore.items;
3400
3449
  }
3401
- markForCheck() {
3402
- this._cd.markForCheck();
3450
+ get pluralLabelLower() {
3451
+ return this._savedFilterController.pluralLabelLower;
3403
3452
  }
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;
3453
+ get sortable() {
3454
+ return this._savedFilterController.orderable;
3434
3455
  }
3435
- compare(o1, o2) {
3436
- return o1 == o2;
3456
+ selectFilter(savedFilter) {
3457
+ this._savedFilterController.setActiveFilter(savedFilter);
3458
+ this._filterOverlayService.open();
3459
+ this._dialogRef.close();
3437
3460
  }
3438
- markForCheck() {
3439
- this.cd.markForCheck();
3461
+ remove(savedFilter) {
3462
+ this._savedFilterController.delete(savedFilter)
3463
+ .subscribe(() => {
3464
+ this.savedFilters = this._savedFilterController.savedFilters;
3465
+ this._cdRef.markForCheck();
3466
+ });
3440
3467
  }
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 });
3468
+ order(savedFilters) {
3469
+ this._savedFilterController.order(savedFilters)
3470
+ .subscribe();
3471
+ }
3472
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterManageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3473
+ 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 });
3443
3474
  }
3444
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectGroupsComponent, decorators: [{
3475
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterManageComponent, decorators: [{
3445
3476
  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
- }] } });
3477
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3478
+ MatDialogModule,
3479
+ MatButton,
3480
+ FsFilterSavedFilterChipsComponent,
3481
+ FsMenuModule,
3482
+ ], 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"] }]
3483
+ }] });
3463
3484
 
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;
3485
+ class FsSavedFilterAutocompleteChipsComponent {
3486
+ savedFiltersController;
3487
+ selectedFilter;
3488
+ _itemStore = inject(ItemStore);
3489
+ _paramController = inject(ParamController);
3490
+ _dialog = inject(MatDialog);
3491
+ _destroyRef = inject(DestroyRef);
3492
+ _injector = inject(Injector);
3493
+ _cdRef = inject(ChangeDetectorRef);
3494
+ _prompt = inject(FsPrompt);
3495
+ _message = inject(FsMessage);
3496
+ get filters$() {
3497
+ return this.savedFiltersController.savedFilters$;
3473
3498
  }
3474
- get simpleSelectItem() {
3475
- return this.item;
3499
+ get activeFilter$() {
3500
+ return this.savedFiltersController.activeFilter$;
3476
3501
  }
3477
- values$;
3478
- constructor(_kvDiffers, _cd) {
3479
- super(_kvDiffers, _cd);
3480
- this._kvDiffers = _kvDiffers;
3481
- this._cd = _cd;
3502
+ get pluralLabelLower() {
3503
+ return this.savedFiltersController.pluralLabelLower;
3482
3504
  }
3483
- ngOnChanges(changes) {
3484
- if (changes.item) {
3485
- this.values$ = this.item.values$;
3486
- }
3505
+ get pluralLabel() {
3506
+ return this.savedFiltersController.pluralLabel;
3487
3507
  }
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
- }
3496
- }
3508
+ get labelIcon() {
3509
+ return this.savedFiltersController.labelIcon;
3510
+ }
3511
+ compareWith = (o1, o2) => {
3512
+ return o1?.id === o2?.id;
3513
+ };
3514
+ selectFilter(savedFilter) {
3515
+ this.savedFiltersController.setActiveFilter(savedFilter);
3516
+ }
3517
+ selectedFilterChange(savedFilter) {
3518
+ this.savedFiltersController.setActiveFilter(savedFilter);
3519
+ if (!savedFilter) {
3520
+ this._itemStore.filtersClear();
3497
3521
  }
3498
3522
  }
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 });
3501
- }
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
- }] } });
3517
-
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;
3523
+ ngOnInit() {
3524
+ this.savedFiltersController.activeFilter$
3525
+ .pipe(takeUntilDestroyed(this._destroyRef))
3526
+ .subscribe((savedFilter) => {
3527
+ this.selectedFilter = savedFilter;
3528
+ this._cdRef.markForCheck();
3529
+ });
3525
3530
  }
3526
- compareFn = (modelValue, chipValue) => {
3527
- return String(modelValue.value) === String(chipValue.value);
3531
+ save() {
3532
+ this.savedFiltersController
3533
+ .save(this.selectedFilter)
3534
+ .pipe(tap$1(() => {
3535
+ this._message.success(`Saved ${this.savedFiltersController.singularLabel}`);
3536
+ }))
3537
+ .subscribe();
3538
+ }
3539
+ create() {
3540
+ this.savedFiltersController.create()
3541
+ .pipe(tap$1(() => {
3542
+ this._message
3543
+ .success(`Created ${this.savedFiltersController.singularLabel}`);
3544
+ }))
3545
+ .subscribe();
3546
+ }
3547
+ saveAs() {
3548
+ this._prompt.input({
3549
+ title: 'Save as new alert',
3550
+ label: 'Name',
3551
+ required: true,
3552
+ commitLabel: 'Save',
3553
+ dialogConfig: {
3554
+ restoreFocus: false,
3555
+ },
3556
+ })
3557
+ .pipe(switchMap$1((name) => {
3558
+ const data = {
3559
+ id: null,
3560
+ name,
3561
+ };
3562
+ return this.savedFiltersController.save(data);
3563
+ }), tap$1(() => {
3564
+ this._message.success(`Saved ${this.savedFiltersController.singularLabel}`);
3565
+ }))
3566
+ .subscribe();
3567
+ }
3568
+ fetch = (query) => {
3569
+ return this.savedFiltersController.savedFilters$
3570
+ .pipe(map$1((filters) => filters
3571
+ .filter((filter) => filter
3572
+ .name.toLowerCase().includes(query.toLowerCase()))));
3528
3573
  };
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 });
3574
+ manageFilters() {
3575
+ this._dialog
3576
+ .open(FsFilterSavedFilterManageComponent, {
3577
+ injector: this._injector,
3578
+ restoreFocus: false,
3579
+ });
3580
+ }
3581
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsSavedFilterAutocompleteChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3582
+ 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 });
3531
3583
  }
3532
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChipsComponent, decorators: [{
3584
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsSavedFilterAutocompleteChipsComponent, decorators: [{
3533
3585
  type: Component,
3534
- args: [{ selector: 'filter-item-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3535
- FsLabelModule,
3536
- FsChipModule,
3586
+ args: [{ selector: 'fs-saved-filter-autocomplete-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3587
+ FsAutocompleteChipsModule,
3537
3588
  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 }] });
3589
+ ], 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"] }]
3590
+ }], propDecorators: { savedFiltersController: [{
3591
+ type: Input
3592
+ }] } });
3541
3593
 
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;
3594
+ class FilterStatusBarDirective {
3595
+ templateRef;
3596
+ constructor(templateRef) {
3597
+ this.templateRef = templateRef;
3551
3598
  }
3552
- ngOnInit() {
3553
- this.listenChanges();
3599
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterStatusBarDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
3600
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FilterStatusBarDirective, isStandalone: true, selector: "[fsFilterStatusBar]", ngImport: i0 });
3601
+ }
3602
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterStatusBarDirective, decorators: [{
3603
+ type: Directive,
3604
+ args: [{
3605
+ selector: '[fsFilterStatusBar]',
3606
+ standalone: true,
3607
+ }]
3608
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
3609
+
3610
+ const FS_FILTER_CONFIG = new InjectionToken('fs.filter-config');
3611
+
3612
+ class FilterComponent {
3613
+ set setConfig(config) {
3614
+ this._initFilterWithConfig(config);
3554
3615
  }
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$))
3616
+ set setFilter(config) {
3617
+ this._initFilterWithConfig(config);
3618
+ }
3619
+ showSortBy = true;
3620
+ closed = new EventEmitter();
3621
+ opened = new EventEmitter();
3622
+ ready = new EventEmitter();
3623
+ statusBar;
3624
+ keywordMatInput;
3625
+ reloadEl;
3626
+ showFilterMenu = false;
3627
+ windowDesktop = false;
3628
+ fsFilterClass = true;
3629
+ searchPlaceholder = 'Search';
3630
+ keyword = '';
3631
+ autoReload = true;
3632
+ _config = null;
3633
+ _sort;
3634
+ _filtersBtnVisible$ = new BehaviorSubject(true);
3635
+ _keywordVisible$ = new BehaviorSubject(false);
3636
+ _hasFilterChips$ = new BehaviorSubject(false);
3637
+ _keyword$ = new Subject();
3638
+ _destroy$ = new Subject();
3639
+ _dialogRef = inject(MatDialogRef, { optional: true });
3640
+ _drawerRef = inject(DrawerRef, { optional: true });
3641
+ _defaultConfig = inject(FS_FILTER_CONFIG, { optional: true });
3642
+ _filterOverlay = inject(FsFilterOverlayService);
3643
+ _zone = inject(NgZone);
3644
+ _paramController = inject(ParamController);
3645
+ _persistanceController = inject(PersistanceController);
3646
+ _itemStore = inject(ItemStore);
3647
+ _actions = inject(ActionsController);
3648
+ _savedFilterController = inject(SavedFilterController);
3649
+ constructor() {
3650
+ this._itemStore.filter = this;
3651
+ this._listenWhenFilterReady();
3652
+ this._updateWindowWidth();
3653
+ const iconRegistry = inject(MatIconRegistry);
3654
+ const sanitizer = inject(DomSanitizer);
3655
+ iconRegistry.addSvgIconLiteral('filterOutline', sanitizer.bypassSecurityTrustHtml(FilterIcon));
3656
+ this._filterOverlay.attach$
3657
+ .pipe(takeUntil(this._destroy$))
3562
3658
  .subscribe(() => {
3563
- this.itemChange();
3659
+ this.showFilterMenu = true;
3564
3660
  });
3661
+ this._filterOverlay.detach$
3662
+ .pipe(takeUntil(this._destroy$))
3663
+ .subscribe(() => {
3664
+ this.showFilterMenu = false;
3665
+ });
3666
+ this._listenWindowResize();
3565
3667
  }
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 });
3568
- }
3569
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RangeComponent, decorators: [{
3570
- 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
- }] } });
3588
-
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;
3668
+ get config() {
3669
+ return this._config;
3596
3670
  }
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;
3671
+ get filterParams() {
3672
+ return this._itemStore.values();
3623
3673
  }
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
- }
3674
+ get inDialog() {
3675
+ return !!this._dialogRef || !!this._drawerRef;
3629
3676
  }
3630
- removeAutocompleteChipItem(event) {
3631
- remove(this.item.model, { value: event.data.value });
3632
- this.itemChange();
3677
+ get filterParamsQuery() {
3678
+ return this._itemStore.valuesAsQuery();
3633
3679
  }
3634
- clearAutocompleteChipItem() {
3635
- this.item.clear();
3636
- this.itemChange();
3680
+ get items() {
3681
+ return this._itemStore.items;
3637
3682
  }
3638
- fetch = (keyword) => {
3639
- return this.item.valuesFn(keyword, this.item.filter);
3640
- };
3641
- compareItems(item1, item2) {
3642
- return item1?.value === item2?.value;
3683
+ get visibleItems() {
3684
+ return this._itemStore.visibleItems;
3643
3685
  }
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;
3686
+ get keywordItem() {
3687
+ return this._itemStore.keywordItem;
3669
3688
  }
3670
- 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
- }
3689
+ get itemsReady$() {
3690
+ return this._itemStore.ready$;
3675
3691
  }
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;
3692
+ get hasFilterChips$() {
3693
+ return this._hasFilterChips$.asObservable();
3700
3694
  }
3701
- ngOnInit() {
3702
- if (this.item.type === ItemType.DateTimeRange) {
3703
- this.viewType = PickerViewType.DateTime;
3704
- }
3705
- else {
3706
- this.viewType = PickerViewType.Date;
3707
- }
3695
+ get hasVisibleItemOrSorting() {
3696
+ return this.visibleItems.length > 0 || !!this._itemStore.sortByItem;
3708
3697
  }
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;
3732
- }
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 });
3736
- }
3737
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WeekComponent, decorators: [{
3738
- type: Component,
3739
- args: [{ selector: 'filter-item-week', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3740
- MatFormField,
3741
- MatLabel,
3742
- MatInput,
3743
- 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 }] });
3749
-
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;
3757
- }
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 });
3760
- }
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 }] });
3770
-
3771
- class FilterItemComponent {
3772
- _cdRef;
3773
- item;
3774
- itemType = ItemType;
3775
- get textItem() {
3776
- return this.item;
3777
- }
3778
- get chipsItem() {
3779
- return this.item;
3780
- }
3781
- get baseSelectItem() {
3782
- return this.item;
3698
+ get filtersBtnVisible$() {
3699
+ return this._filtersBtnVisible$.asObservable();
3783
3700
  }
3784
- get rangeItem() {
3785
- return this.item;
3701
+ get inlineToolbar$() {
3702
+ return combineLatest({
3703
+ keywordVisible: this._keywordVisible$.asObservable(),
3704
+ activeFilter: of(this.savedFiltersController.enabled),
3705
+ })
3706
+ .pipe(map(({ keywordVisible, activeFilter }) => {
3707
+ return !keywordVisible && !activeFilter;
3708
+ }));
3786
3709
  }
3787
- get autocompleteItem() {
3788
- return this.item;
3710
+ get notInlineToolbar$() {
3711
+ return this.inlineToolbar$
3712
+ .pipe(map((inline) => !inline));
3789
3713
  }
3790
- get autocompleteChipsItem() {
3791
- return this.item;
3714
+ get keywordVisible$() {
3715
+ return this._keywordVisible$.asObservable();
3792
3716
  }
3793
- get dateItem() {
3794
- return this.item;
3717
+ get actionsVisible$() {
3718
+ return this._actions.visible$;
3795
3719
  }
3796
- get dateRangeItem() {
3797
- return this.item;
3720
+ get actions$() {
3721
+ return this._actions.actions$;
3798
3722
  }
3799
- get dateTimeItem() {
3800
- return this.item;
3723
+ get menuActions$() {
3724
+ return this._actions.menuActions$;
3801
3725
  }
3802
- get dateTimeRangeItem() {
3803
- return this.item;
3726
+ set activeSavedFilter(savedFilter) {
3727
+ this._savedFilterController.setActiveFilter(savedFilter);
3804
3728
  }
3805
- get weekItem() {
3806
- return this.item;
3729
+ get activeSavedFilter() {
3730
+ return this._savedFilterController.activeFilter;
3807
3731
  }
3808
- get checkboxItem() {
3809
- return this.item;
3732
+ get savedFilters() {
3733
+ return this._savedFilterController.savedFilters;
3810
3734
  }
3811
- _destroy$ = new Subject();
3812
- constructor(_cdRef) {
3813
- this._cdRef = _cdRef;
3735
+ get savedFiltersController() {
3736
+ return this._savedFilterController;
3814
3737
  }
3815
3738
  ngOnInit() {
3816
- this.item.value$
3817
- .pipe(takeUntil(this._destroy$))
3818
- .subscribe(() => {
3819
- this._cdRef.markForCheck();
3820
- });
3739
+ this._initAutoFocus();
3740
+ this._initAutoReload();
3741
+ this._listenInputChanges();
3742
+ this._listenInternalItemsChange();
3743
+ this._initKeywordVisibility();
3744
+ this._initOverlay();
3821
3745
  }
3822
3746
  ngOnDestroy() {
3747
+ this._destroyFilterDrawer();
3823
3748
  this._destroy$.next(null);
3824
3749
  this._destroy$.complete();
3825
3750
  }
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();
3751
+ focus() {
3752
+ this.keywordMatInput?.focus();
3865
3753
  }
3866
- updateWindowWidth() {
3867
- this.windowDesktop = window.innerWidth > 1200;
3754
+ updateSort(sort) {
3755
+ this._itemStore.updateSort(sort);
3868
3756
  }
3869
- get items$() {
3870
- return this._itemStore.visibleItems$;
3757
+ /**
3758
+ *
3759
+ * Do update value of some field
3760
+ *
3761
+ * @param values - values for update
3762
+ *
3763
+ * To update text value just pass new text value
3764
+ *
3765
+ * public updateSelectValue(val) {
3766
+ * this.filterEl.updateValues({ keyword: val });
3767
+ * }
3768
+ *
3769
+ * To update select or observable select you could pass suitable value
3770
+ *
3771
+ * public updateSelectValue(val: number) {
3772
+ * this.filterEl.updateValues({ simple_select: val }, { observable_select: val });
3773
+ * }
3774
+ *
3775
+ * To update checkbox value just pass true/false as value
3776
+ *
3777
+ * public updateCheckox(val: boolean) {
3778
+ * this.filterEl.updateValues({ checkbox: val });
3779
+ * }
3780
+ *
3781
+ * To update range value just pass object with min&max object or just with one of targets
3782
+ *
3783
+ * Ex.: { min: 10, max 15 }, { min: 5 }, { max 5 }
3784
+ *
3785
+ * public updateRange(val) {
3786
+ * this.filterEl.updateValues({ range: val });
3787
+ * }
3788
+ *
3789
+ * To update autocomplete just pass object with name/value fields
3790
+ *
3791
+ * Ex.: { name: 'John Doe', value: 1 }
3792
+ *
3793
+ * public updateAutocomplete(val) {
3794
+ * this.filterEl.updateValues({ autocomplete_user_id: val });
3795
+ * }
3796
+ *
3797
+ * To update autocompletechips just pass:
3798
+ *
3799
+ * 1) object with name/value fields - will be appended to existing set of values
3800
+ *
3801
+ * { name: 'John Doe', value: 1 }
3802
+ *
3803
+ * 2) array of objects - will be appended to existing set of values
3804
+ *
3805
+ * [{ name: 'John Doe', value: 1 }, { name: 'Darya Filipova', value: 2 }]
3806
+ *
3807
+ * 3) null - clear existing set of values
3808
+ *
3809
+ * public updateAutocomplete(val) {
3810
+ * this.filterEl.updateValues({ autocompletechips_user_id: val });
3811
+ * }
3812
+ *
3813
+ */
3814
+ updateValues(values) {
3815
+ Object.keys(values).forEach((key) => {
3816
+ const filterItem = this.items
3817
+ .find((item) => item.name === key);
3818
+ if (!filterItem) {
3819
+ return;
3820
+ }
3821
+ filterItem.model = values[key];
3822
+ });
3871
3823
  }
3872
- get paramCointroller() {
3873
- return this._paramController;
3824
+ hide() {
3825
+ this.changeVisibility(false);
3874
3826
  }
3875
- get savedFiltersController() {
3876
- return this._savedFilterController;
3827
+ show() {
3828
+ this.changeVisibility(true);
3877
3829
  }
3878
- ngOnInit() {
3879
- this._savedFilterController.activeFilter$
3880
- .pipe(takeUntilDestroyed(this._destroyRef))
3881
- .subscribe((activeFilter) => {
3882
- this.savedFilterName = activeFilter?.name || '';
3883
- });
3830
+ changeVisibilityClick(value, event = null) {
3831
+ if (event) {
3832
+ event.stopPropagation();
3833
+ }
3834
+ this.changeVisibility(value);
3884
3835
  }
3885
- clear() {
3886
- this._clear();
3836
+ get itemValues() {
3837
+ return this.items
3838
+ .map((item) => item.value);
3887
3839
  }
3888
- done() {
3889
- this._done();
3890
- this._overlayRef.detach();
3840
+ get nonEmptyItemValues() {
3841
+ return this.items
3842
+ .filter((item) => item.value !== undefined)
3843
+ .map((item) => item.value);
3891
3844
  }
3892
- backdropClick() {
3893
- this.done();
3845
+ get hasItemValues() {
3846
+ return this.items
3847
+ .some((item) => item.value !== undefined);
3894
3848
  }
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
- });
3904
- }));
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();
3849
+ getItemValue(name) {
3850
+ const item = this.items
3851
+ .find((_item) => _item.name === name);
3852
+ return item?.value;
3943
3853
  }
3944
- get menuActions() {
3945
- return this._menuActions$.value;
3854
+ showItem(name) {
3855
+ const item = this.getItem(name);
3856
+ if (item) {
3857
+ item.hide = false;
3858
+ this._itemStore.updateItemsVisiblity();
3859
+ }
3946
3860
  }
3947
- get actions() {
3948
- return this._actions$.value;
3861
+ hideItem(name) {
3862
+ const item = this.getItem(name);
3863
+ if (!item) {
3864
+ return;
3865
+ }
3866
+ item.hide = true;
3867
+ this._itemStore.updateItemsVisiblity();
3949
3868
  }
3950
- get actions$() {
3951
- return this._actions$.asObservable();
3869
+ clearItem(name) {
3870
+ const item = this.getItem(name);
3871
+ if (!item) {
3872
+ return;
3873
+ }
3874
+ item.clear();
3952
3875
  }
3953
- get menuActions$() {
3954
- return this._menuActions$.asObservable();
3876
+ updateItemConfig(name, params) {
3877
+ const item = this.getItem(name);
3878
+ if (!item) {
3879
+ return;
3880
+ }
3881
+ item.label = params.label ?? item.label;
3882
+ item.chipLabel = params.chipLabel ?? item.chipLabel;
3883
+ this._itemStore.updateItemsVisiblity();
3955
3884
  }
3956
- get visible$() {
3957
- return this._visible$.asObservable();
3885
+ getItemValueChange$(name) {
3886
+ const item = this.items.find((i) => i.name === name);
3887
+ if (item) {
3888
+ return item.value$
3889
+ .pipe(map(() => {
3890
+ return item.model;
3891
+ }));
3892
+ }
3893
+ return null;
3958
3894
  }
3959
- get mobileMode() {
3960
- return this._breakpointObserver.isMatched(this._mobileMedia);
3895
+ changeVisibility(state) {
3896
+ if (state === this.showFilterMenu) {
3897
+ return;
3898
+ }
3899
+ if (!state) {
3900
+ this.closed.emit();
3901
+ return this._destroyFilterDrawer();
3902
+ }
3903
+ if (!this.hasVisibleItemOrSorting) {
3904
+ return;
3905
+ }
3906
+ this._listenEscButton();
3907
+ this.opened.emit();
3908
+ this._filterOverlay.open();
3961
3909
  }
3962
- ngOnDestroy() {
3963
- this._destroy$.next(null);
3964
- this._destroy$.complete();
3910
+ init() {
3911
+ const data = this._itemStore.valuesAsQuery();
3912
+ this._sort = this._itemStore.getSort();
3913
+ if (this.config.init) {
3914
+ this.config.init(data, this._sort, this);
3915
+ }
3916
+ this._updateChipsVisibility();
3917
+ this.items
3918
+ .forEach((item) => {
3919
+ item.init(item, this);
3920
+ });
3965
3921
  }
3966
- setConfig(config) {
3967
- this._config = config;
3968
- this.initActions(config.actions);
3922
+ clear(event = null) {
3923
+ if (event) {
3924
+ event.stopPropagation();
3925
+ }
3926
+ this._itemStore.filtersClear();
3927
+ if (this.config.clear) {
3928
+ this.config.clear();
3929
+ }
3930
+ this.keyword = '';
3969
3931
  }
3970
- initActions(rawActions) {
3971
- if (!rawActions || !Array.isArray(rawActions)) {
3972
- return;
3932
+ reload(event = null) {
3933
+ if (event) {
3934
+ event.preventDefault();
3935
+ event.stopPropagation();
3973
3936
  }
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);
3937
+ const data = this._itemStore.valuesAsQuery();
3938
+ const el = this.reloadEl?.nativeElement;
3939
+ if (el) {
3940
+ el.style.transition = 'all 0.75s 0.0s';
3941
+ el.style.transform = 'rotate(360deg)';
3942
+ setTimeout(() => {
3943
+ el.style.transition = null;
3944
+ el.style.transform = null;
3945
+ }, 1000);
3946
+ }
3947
+ if (this.config.reload) {
3948
+ this.config.reload(data, this._itemStore.getSort());
3979
3949
  }
3980
- this._classifyActions();
3981
3950
  }
3982
- show() {
3983
- this._visible$.next(true);
3951
+ getItem(name) {
3952
+ return this.items
3953
+ .find((item) => item.name === name);
3984
3954
  }
3985
- hide() {
3986
- this._visible$.next(false);
3955
+ fetchQueryParams() {
3956
+ this._paramController.fetchQueryParams();
3987
3957
  }
3988
- addReorderAction(action) {
3989
- this._allActions.unshift(action);
3990
- action.isReorderAction = true;
3991
- this._classifyAction(action);
3992
- this._reorderAction = action;
3958
+ /**
3959
+ * Call change callback and apply new filter values
3960
+ */
3961
+ change() {
3962
+ const valuesAsQuery = this._itemStore.valuesAsQuery();
3963
+ const sort = this._itemStore.getSort();
3964
+ const sortingChanged = ((!sort || !this._sort) && sort !== this._sort)
3965
+ || (sort && this._sort && !objectsAreEquals(this._sort, sort));
3966
+ if (sortingChanged) {
3967
+ this._sort = sort;
3968
+ if (this.config.sortChange) {
3969
+ this.config.sortChange(valuesAsQuery, sort);
3970
+ }
3971
+ }
3972
+ if (this.config.change) {
3973
+ this.config.change(valuesAsQuery, sort);
3974
+ }
3975
+ this._updateChipsVisibility();
3976
+ // visibility for actions can depend on filters state
3977
+ this._actions.updateActionsVisibility();
3993
3978
  }
3994
- clearActions() {
3995
- this._allActions = [];
3996
- this._setActions([]);
3997
- this._setKebabActions([]);
3979
+ /**
3980
+ * Update filter actions config
3981
+ *
3982
+ * @param actions
3983
+ */
3984
+ updateActions(actions) {
3985
+ this._actions.initActions(actions);
3998
3986
  }
3999
- updateActionsVisibility() {
4000
- this._allActions.forEach((action) => action.updateVisibility());
4001
- this._classifyActions();
3987
+ /**
3988
+ * Show "Filters" button
3989
+ */
3990
+ showFiltersBtn() {
3991
+ this._filtersBtnVisible$.next(true);
4002
3992
  }
4003
- updateDisabledState() {
4004
- this.actions.forEach((action) => action.updateDisabledState());
3993
+ /**
3994
+ * Hide "Filters" button
3995
+ */
3996
+ hideFiltersBtn() {
3997
+ this._filtersBtnVisible$.next(false);
4005
3998
  }
4006
- _setKebabActions(actions) {
4007
- this._menuActions$.next(actions);
3999
+ /**
4000
+ * Show "Keyword" field if it present
4001
+ */
4002
+ showKeywordField() {
4003
+ this._keywordVisible$.next(true);
4008
4004
  }
4009
- _setActions(actions) {
4010
- this._actions$.next(actions);
4005
+ /**
4006
+ * Hide "Keyword" field if it present
4007
+ */
4008
+ hideKeywordField() {
4009
+ this._keywordVisible$.next(false);
4011
4010
  }
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);
4026
- }
4027
- });
4028
- this._setKebabActions(kebabActions);
4029
- this._setActions(actions);
4011
+ /**
4012
+ * Go through actions and check show() callback and update visible actions
4013
+ */
4014
+ updateActionsVisibility() {
4015
+ this._actions.updateActionsVisibility();
4030
4016
  }
4031
- _classifyAction(action) {
4032
- if (action.menu) {
4033
- this._setKebabActions([...this.menuActions, action]);
4034
- }
4035
- else {
4036
- this._setActions([...this.actions, action]);
4037
- }
4017
+ /**
4018
+ * Go through actions and check disabled() callback and update disabled state
4019
+ */
4020
+ updateDisabledState() {
4021
+ this._actions.updateDisabledState();
4038
4022
  }
4039
- _listenMobileMedia() {
4040
- this._breakpointObserver.observe(this._mobileMedia)
4041
- .pipe(skip(1), takeUntil(this._destroy$))
4042
- .subscribe(() => {
4043
- this._classifyActions();
4044
- });
4023
+ setItems(items) {
4024
+ this._itemStore.destroyItems();
4025
+ this.config.items = items;
4026
+ this._itemStore.setConfig(this._config);
4027
+ this._paramController.initItems();
4028
+ this._updateKeyword();
4045
4029
  }
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
- });
4030
+ keywordChange(keyword) {
4031
+ this._keyword$.next(keyword);
4066
4032
  }
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;
4033
+ updateSortings(items) {
4034
+ this._itemStore.updateSortingItemsValues(items);
4089
4035
  }
4090
- get items() {
4091
- return this._itemStore.items;
4036
+ _initFilterWithConfig(config) {
4037
+ if (this.config) {
4038
+ this._itemStore.destroyItems();
4039
+ }
4040
+ config = {
4041
+ ...(this._defaultConfig || {}),
4042
+ ...config,
4043
+ };
4044
+ this._config = new FsFilterConfig(config);
4045
+ this._actions.setConfig(this._config);
4046
+ this._persistanceController.setConfig(this._config, this.inDialog);
4047
+ this._itemStore.setConfig(this._config);
4048
+ this._paramController.setConfig(this._config);
4049
+ this._updateKeyword();
4050
+ if (this.config.reloadWhenConfigChanged) {
4051
+ this.change();
4052
+ }
4092
4053
  }
4093
- get pluralLabelLower() {
4094
- return this._savedFilterController.pluralLabelLower;
4054
+ _destroyFilterDrawer() {
4055
+ this._filterOverlay.close();
4095
4056
  }
4096
- get sortable() {
4097
- return this._savedFilterController.orderable;
4057
+ _updateWindowWidth() {
4058
+ this.windowDesktop = window.innerWidth > 1200;
4098
4059
  }
4099
- selectFilter(savedFilter) {
4100
- this._savedFilterController.setActiveFilter(savedFilter);
4101
- this._filterOverlayService.open();
4102
- this._dialogRef.close();
4060
+ _listenEscButton() {
4061
+ this._zone.runOutsideAngular(() => {
4062
+ fromEvent(window, 'keyup')
4063
+ .pipe(filter$1((event) => event.code === 'Escape'), takeUntil(this.closed), takeUntil(this._destroy$))
4064
+ .subscribe(() => {
4065
+ this._zone.run(() => {
4066
+ this.changeVisibility(false);
4067
+ });
4068
+ });
4069
+ });
4103
4070
  }
4104
- remove(savedFilter) {
4105
- this._savedFilterController.delete(savedFilter)
4106
- .subscribe(() => {
4107
- this.savedFilters = this._savedFilterController.savedFilters;
4108
- this._cdRef.markForCheck();
4071
+ _listenWindowResize() {
4072
+ this._zone.runOutsideAngular(() => {
4073
+ fromEvent(window, 'resize')
4074
+ .pipe(debounceTime(100), takeUntil(this._destroy$))
4075
+ .subscribe(() => {
4076
+ this._zone.run(() => {
4077
+ this._updateWindowWidth();
4078
+ });
4079
+ });
4109
4080
  });
4110
4081
  }
4111
- order(savedFilters) {
4112
- this._savedFilterController.order(savedFilters)
4113
- .subscribe();
4082
+ _initAutoReload() {
4083
+ if (this.config.autoReload) {
4084
+ interval(this.config.autoReload.seconds * 1000)
4085
+ .pipe(filter$1(() => this.autoReload), takeUntil(this._destroy$))
4086
+ .subscribe(() => {
4087
+ this.reload(null);
4088
+ });
4089
+ }
4114
4090
  }
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$;
4091
+ _listenInputChanges() {
4092
+ this._keyword$
4093
+ .pipe(debounceTime(200), distinctUntilChanged(), takeUntil(this._destroy$))
4094
+ .subscribe((value) => {
4095
+ const keywordItem = this._itemStore.keywordItem;
4096
+ keywordItem.model = value;
4097
+ this.change();
4098
+ });
4141
4099
  }
4142
- get activeFilter$() {
4143
- return this.savedFiltersController.activeFilter$;
4100
+ _initKeywordVisibility() {
4101
+ this._keywordVisible$.next(!!this.keywordItem && !this.keywordItem?.hide);
4144
4102
  }
4145
- get pluralLabelLower() {
4146
- return this.savedFiltersController.pluralLabelLower;
4103
+ _initAutoFocus() {
4104
+ // Avoid ngChanges error
4105
+ setTimeout(() => {
4106
+ if (this.config.autofocus) {
4107
+ this.focus();
4108
+ }
4109
+ });
4147
4110
  }
4148
- get pluralLabel() {
4149
- return this.savedFiltersController.pluralLabel;
4111
+ _listenInternalItemsChange() {
4112
+ this._itemStore
4113
+ .itemsChange$
4114
+ .pipe(takeUntil(this._destroy$))
4115
+ .subscribe(() => {
4116
+ this.keyword = this._itemStore.keywordItem?.model;
4117
+ this.change();
4118
+ });
4150
4119
  }
4151
- get labelIcon() {
4152
- return this.savedFiltersController.labelIcon;
4120
+ _initOverlay() {
4121
+ this._filterOverlay.setClearFn(this.clear.bind(this));
4122
+ this._filterOverlay.setDoneFn(this.hide.bind(this));
4153
4123
  }
4154
- compareWith = (o1, o2) => {
4155
- return o1?.id === o2?.id;
4156
- };
4157
- selectFilter(savedFilter) {
4158
- this.savedFiltersController.setActiveFilter(savedFilter);
4124
+ // We may need some time to recieve external params and after that ready can be emitted
4125
+ _listenWhenFilterReady() {
4126
+ combineLatest([
4127
+ this._paramController.pending$,
4128
+ this.itemsReady$,
4129
+ ])
4130
+ .pipe(filter$1(([pendingParams, itemsReady]) => !pendingParams && itemsReady), takeUntil(this._destroy$))
4131
+ .subscribe(() => {
4132
+ this.init();
4133
+ this._updateKeyword();
4134
+ this.ready.emit();
4135
+ });
4159
4136
  }
4160
- selectedFilterChange(savedFilter) {
4161
- this.savedFiltersController.setActiveFilter(savedFilter);
4162
- if (!savedFilter) {
4163
- this._itemStore.filtersClear();
4164
- }
4137
+ _updateKeyword() {
4138
+ this.keyword = this._itemStore.keywordItem?.model;
4165
4139
  }
4166
- ngOnInit() {
4167
- this.savedFiltersController.activeFilter$
4168
- .pipe(takeUntilDestroyed(this._destroyRef))
4169
- .subscribe((savedFilter) => {
4170
- this.selectedFilter = savedFilter;
4171
- this._cdRef.markForCheck();
4140
+ _updateChipsVisibility() {
4141
+ const hasFilterChips = this._itemStore.items
4142
+ .some((item) => {
4143
+ return item.isChipVisible;
4172
4144
  });
4145
+ this._hasFilterChips$.next(hasFilterChips);
4173
4146
  }
4174
- save() {
4175
- this.savedFiltersController
4176
- .save(this.selectedFilter)
4177
- .pipe(tap$1(() => {
4178
- this._message.success(`Saved ${this.savedFiltersController.singularLabel}`);
4179
- }))
4180
- .subscribe();
4181
- }
4182
- create() {
4183
- this.savedFiltersController.create()
4184
- .pipe(tap$1(() => {
4185
- this._message
4186
- .success(`Created ${this.savedFiltersController.singularLabel}`);
4187
- }))
4188
- .subscribe();
4189
- }
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();
4210
- }
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
- });
4223
- }
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 });
4147
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4148
+ 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: [
4149
+ FsFilterOverlayService,
4150
+ ParamController,
4151
+ PersistanceController,
4152
+ QueryParamController,
4153
+ FocusControllerService,
4154
+ ItemStore,
4155
+ SavedFilterController,
4156
+ ActionsController,
4157
+ ], 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$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 });
4226
4158
  }
4227
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsSavedFilterAutocompleteChipsComponent, decorators: [{
4159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, decorators: [{
4228
4160
  type: Component,
4229
- args: [{ selector: 'fs-saved-filter-autocomplete-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4230
- FsAutocompleteChipsModule,
4161
+ args: [{ selector: 'fs-filter', providers: [
4162
+ FsFilterOverlayService,
4163
+ ParamController,
4164
+ PersistanceController,
4165
+ QueryParamController,
4166
+ FocusControllerService,
4167
+ ItemStore,
4168
+ SavedFilterController,
4169
+ ActionsController,
4170
+ ], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4171
+ NgTemplateOutlet,
4172
+ FsSavedFilterAutocompleteChipsComponent,
4173
+ MatFormField,
4174
+ NgClass,
4175
+ MatPrefix,
4176
+ MatIcon,
4177
+ MatInput,
4231
4178
  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: [{
4179
+ FsFormModule,
4180
+ FsClearModule,
4181
+ FsFilterChipsComponent,
4182
+ FsFilterActionsComponent,
4183
+ MatIconAnchor,
4184
+ MatSlideToggle,
4185
+ AsyncPipe,
4186
+ ], 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"] }]
4187
+ }], ctorParameters: () => [], propDecorators: { setConfig: [{
4188
+ type: Input,
4189
+ args: ['config']
4190
+ }], setFilter: [{
4191
+ type: Input,
4192
+ args: ['filter']
4193
+ }], showSortBy: [{
4234
4194
  type: Input
4195
+ }], closed: [{
4196
+ type: Output
4197
+ }], opened: [{
4198
+ type: Output
4199
+ }], ready: [{
4200
+ type: Output
4201
+ }], statusBar: [{
4202
+ type: ContentChild,
4203
+ args: [FilterStatusBarDirective]
4204
+ }], keywordMatInput: [{
4205
+ type: ViewChild,
4206
+ args: ['keywordMatInput', { read: MatInput }]
4207
+ }], reloadEl: [{
4208
+ type: ViewChild,
4209
+ args: ['reloadEl', { read: ElementRef }]
4210
+ }], showFilterMenu: [{
4211
+ type: HostBinding,
4212
+ args: ['class.filters-open']
4213
+ }], windowDesktop: [{
4214
+ type: HostBinding,
4215
+ args: ['class.window-desktop']
4216
+ }], fsFilterClass: [{
4217
+ type: HostBinding,
4218
+ args: ['class.fs-filter']
4235
4219
  }] } });
4236
4220
 
4237
- class FilterStatusBarDirective {
4238
- templateRef;
4239
- constructor(templateRef) {
4240
- this.templateRef = templateRef;
4241
- }
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);
4258
- }
4259
- set setFilter(config) {
4260
- this._initFilterWithConfig(config);
4261
- }
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();
4316
- }
4317
- get inDialog() {
4318
- return !!this._dialogRef || !!this._drawerRef;
4319
- }
4320
- get filterParamsQuery() {
4321
- return this._itemStore.valuesAsQuery();
4322
- }
4323
- get items() {
4324
- return this._itemStore.items;
4325
- }
4326
- get visibleItems() {
4327
- return this._itemStore.visibleItems;
4328
- }
4329
- get keywordItem() {
4330
- return this._itemStore.keywordItem;
4331
- }
4332
- get itemsReady$() {
4333
- return this._itemStore.ready$;
4334
- }
4335
- get hasFilterChips$() {
4336
- return this._hasFilterChips$.asObservable();
4337
- }
4338
- get hasVisibleItemOrSorting() {
4339
- return this.visibleItems.length > 0 || !!this._itemStore.sortByItem;
4340
- }
4341
- get filtersBtnVisible$() {
4342
- return this._filtersBtnVisible$.asObservable();
4343
- }
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
- }));
4352
- }
4353
- get notInlineToolbar$() {
4354
- return this.inlineToolbar$
4355
- .pipe(map((inline) => !inline));
4221
+ class AutocompletechipsComponent extends BaseItemComponent {
4222
+ _kvDiffers;
4223
+ _cd;
4224
+ _injector = inject(Injector);
4225
+ constructor(_kvDiffers, _cd) {
4226
+ super(_kvDiffers, _cd);
4227
+ this._kvDiffers = _kvDiffers;
4228
+ this._cd = _cd;
4356
4229
  }
4357
- get keywordVisible$() {
4358
- return this._keywordVisible$.asObservable();
4230
+ addAutocompleteChipItem(event) {
4231
+ if (event.data && this.item.model.indexOf(event.data.value) === -1) {
4232
+ this.item.model.push(event.data);
4233
+ this.itemChange();
4234
+ }
4359
4235
  }
4360
- get actionsVisible$() {
4361
- return this._actions.visible$;
4236
+ removeAutocompleteChipItem(event) {
4237
+ remove(this.item.model, { value: event.data.value });
4238
+ this.itemChange();
4362
4239
  }
4363
- get actions$() {
4364
- return this._actions.actions$;
4240
+ clearAutocompleteChipItem() {
4241
+ this.item.clear();
4242
+ this.itemChange();
4365
4243
  }
4366
- get menuActions$() {
4367
- return this._actions.menuActions$;
4244
+ fetch = (keyword) => {
4245
+ return this.item.valuesFn(keyword, this.item.filter);
4246
+ };
4247
+ compareItems(item1, item2) {
4248
+ return item1?.value === item2?.value;
4368
4249
  }
4369
- set activeSavedFilter(savedFilter) {
4370
- this._savedFilterController.setActiveFilter(savedFilter);
4250
+ actionClick(action) {
4251
+ const filterComponent = this._injector.get(FilterComponent);
4252
+ action.click(filterComponent);
4371
4253
  }
4372
- get activeSavedFilter() {
4373
- return this._savedFilterController.activeFilter;
4254
+ 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 });
4255
+ 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 });
4256
+ }
4257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AutocompletechipsComponent, decorators: [{
4258
+ type: Component,
4259
+ args: [{ selector: 'filter-item-autocompletechips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4260
+ FsAutocompleteChipsModule,
4261
+ FocusToItemDirective,
4262
+ FormsModule,
4263
+ FsFormModule,
4264
+ ], 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>" }]
4265
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4266
+
4267
+ class CheckboxComponent extends BaseItemComponent {
4268
+ _kvDiffers;
4269
+ _cd;
4270
+ constructor(_kvDiffers, _cd) {
4271
+ super(_kvDiffers, _cd);
4272
+ this._kvDiffers = _kvDiffers;
4273
+ this._cd = _cd;
4374
4274
  }
4375
- get savedFilters() {
4376
- return this._savedFilterController.savedFilters;
4275
+ 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 });
4276
+ 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 });
4277
+ }
4278
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CheckboxComponent, decorators: [{
4279
+ type: Component,
4280
+ args: [{ selector: 'filter-item-checkbox', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4281
+ FsLabelModule,
4282
+ MatCheckbox,
4283
+ FormsModule,
4284
+ FsFormModule,
4285
+ ], 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"] }]
4286
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4287
+
4288
+ class ChipsComponent extends BaseItemComponent {
4289
+ _kvDiffers;
4290
+ _cd;
4291
+ constructor(_kvDiffers, _cd) {
4292
+ super(_kvDiffers, _cd);
4293
+ this._kvDiffers = _kvDiffers;
4294
+ this._cd = _cd;
4377
4295
  }
4378
- get savedFiltersController() {
4379
- return this._savedFilterController;
4296
+ compareFn = (modelValue, chipValue) => {
4297
+ return String(modelValue.value) === String(chipValue.value);
4298
+ };
4299
+ 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 });
4300
+ 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 });
4301
+ }
4302
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChipsComponent, decorators: [{
4303
+ type: Component,
4304
+ args: [{ selector: 'filter-item-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4305
+ FsLabelModule,
4306
+ FsChipModule,
4307
+ FormsModule,
4308
+ FsFormModule,
4309
+ ], 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"] }]
4310
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4311
+
4312
+ class DateRangeComponent extends BaseItemComponent {
4313
+ _kvDiffers;
4314
+ _cd;
4315
+ viewType = PickerViewType.Date;
4316
+ constructor(_kvDiffers, _cd) {
4317
+ super(_kvDiffers, _cd);
4318
+ this._kvDiffers = _kvDiffers;
4319
+ this._cd = _cd;
4380
4320
  }
4381
4321
  ngOnInit() {
4382
- this._initAutoFocus();
4383
- this._initAutoReload();
4384
- this._listenInputChanges();
4385
- this._listenInternalItemsChange();
4386
- this._initKeywordVisibility();
4387
- this._initOverlay();
4388
- }
4389
- ngOnDestroy() {
4390
- this._destroyFilterDrawer();
4391
- this._destroy$.next(null);
4392
- this._destroy$.complete();
4322
+ if (this.item.type === ItemType.DateTimeRange) {
4323
+ this.viewType = PickerViewType.DateTime;
4324
+ }
4325
+ else {
4326
+ this.viewType = PickerViewType.Date;
4327
+ }
4393
4328
  }
4394
- focus() {
4395
- this.keywordMatInput?.focus();
4329
+ 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 });
4330
+ 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 });
4331
+ }
4332
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateRangeComponent, decorators: [{
4333
+ type: Component,
4334
+ args: [{ selector: 'filter-item-date-range', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4335
+ MatFormField,
4336
+ MatLabel,
4337
+ MatInput,
4338
+ FormsModule,
4339
+ FocusToItemDirective,
4340
+ FsDatePickerModule,
4341
+ FsFormModule,
4342
+ ], 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" }]
4343
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4344
+
4345
+ class DateComponent extends BaseItemComponent {
4346
+ _kvDiffers;
4347
+ _cd;
4348
+ viewType = PickerViewType.Date;
4349
+ itemDateMode = ItemDateMode;
4350
+ showYear = true;
4351
+ showMonth = true;
4352
+ showDay = true;
4353
+ constructor(_kvDiffers, _cd) {
4354
+ super(_kvDiffers, _cd);
4355
+ this._kvDiffers = _kvDiffers;
4356
+ this._cd = _cd;
4396
4357
  }
4397
- updateSort(sort) {
4398
- this._itemStore.updateSort(sort);
4358
+ ngOnInit() {
4359
+ this.viewType = this.item.type === ItemType.DateTime ? PickerViewType.DateTime : PickerViewType.Date;
4360
+ if (this.item.mode === ItemDateMode.ScrollMonthYear) {
4361
+ this.showDay = false;
4362
+ }
4399
4363
  }
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
- });
4364
+ 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 });
4365
+ 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 });
4366
+ }
4367
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateComponent, decorators: [{
4368
+ type: Component,
4369
+ args: [{ selector: 'filter-item-date', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4370
+ MatFormField,
4371
+ MatLabel,
4372
+ MatInput,
4373
+ FormsModule,
4374
+ FsDatePickerModule,
4375
+ FocusToItemDirective,
4376
+ FsFormModule,
4377
+ ], 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}" }]
4378
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4379
+
4380
+ class RangeComponent extends BaseItemComponent {
4381
+ _kvDiffers;
4382
+ _cd;
4383
+ from;
4384
+ to;
4385
+ constructor(_kvDiffers, _cd) {
4386
+ super(_kvDiffers, _cd);
4387
+ this._kvDiffers = _kvDiffers;
4388
+ this._cd = _cd;
4466
4389
  }
4467
- hide() {
4468
- this.changeVisibility(false);
4390
+ ngOnInit() {
4391
+ this.listenChanges();
4469
4392
  }
4470
- show() {
4471
- this.changeVisibility(true);
4393
+ listenChanges() {
4394
+ const fromListener = fromEvent(this.from.nativeElement, 'keyup')
4395
+ .pipe(distinctUntilChanged());
4396
+ const toListener = fromEvent(this.to.nativeElement, 'keyup')
4397
+ .pipe(distinctUntilChanged());
4398
+ merge(fromListener, toListener)
4399
+ .pipe(takeUntil(this.destroy$))
4400
+ .subscribe(() => {
4401
+ this.itemChange();
4402
+ });
4472
4403
  }
4473
- changeVisibilityClick(value, event = null) {
4474
- if (event) {
4475
- event.stopPropagation();
4404
+ 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 });
4405
+ 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 });
4406
+ }
4407
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RangeComponent, decorators: [{
4408
+ type: Component,
4409
+ args: [{ selector: 'filter-item-range', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4410
+ MatFormField,
4411
+ MatLabel,
4412
+ MatPrefix,
4413
+ MatInput,
4414
+ FormsModule,
4415
+ FocusToItemDirective,
4416
+ FsFormModule,
4417
+ MatSuffix,
4418
+ ], 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"] }]
4419
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }], propDecorators: { from: [{
4420
+ type: ViewChild,
4421
+ args: ['from', { static: true }]
4422
+ }], to: [{
4423
+ type: ViewChild,
4424
+ args: ['to', { static: true }]
4425
+ }] } });
4426
+
4427
+ class FsFilterIsolateValues {
4428
+ transform(values, isolate) {
4429
+ if (!isolate) {
4430
+ return values;
4476
4431
  }
4477
- this.changeVisibility(value);
4432
+ return values.filter((value) => {
4433
+ return value.value !== isolate.value;
4434
+ });
4478
4435
  }
4479
- get itemValues() {
4480
- return this.items
4481
- .map((item) => item.value);
4436
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterIsolateValues, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
4437
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FsFilterIsolateValues, isStandalone: true, name: "fsFilterIsolateValues" });
4438
+ }
4439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterIsolateValues, decorators: [{
4440
+ type: Pipe,
4441
+ args: [{
4442
+ name: 'fsFilterIsolateValues',
4443
+ standalone: true,
4444
+ }]
4445
+ }] });
4446
+
4447
+ class SelectMultipleComponent {
4448
+ _cd;
4449
+ item;
4450
+ select;
4451
+ constructor(_cd) {
4452
+ this._cd = _cd;
4482
4453
  }
4483
- get nonEmptyItemValues() {
4484
- return this.items
4485
- .filter((item) => item.value !== undefined)
4486
- .map((item) => item.value);
4454
+ changed() {
4455
+ if (this.item.isolate) {
4456
+ this.item.isolate.enabled = false;
4457
+ if (this.item.multiple && Array.isArray(this.item.model)) {
4458
+ const index = this.item.model.indexOf(this.item.isolate.value);
4459
+ if (index > -1) {
4460
+ this.item.model.splice(index, 1);
4461
+ }
4462
+ }
4463
+ }
4487
4464
  }
4488
- get hasItemValues() {
4489
- return this.items
4490
- .some((item) => item.value !== undefined);
4465
+ close() {
4466
+ this.select.close();
4491
4467
  }
4492
- getItemValue(name) {
4493
- const item = this.items
4494
- .find((_item) => _item.name === name);
4495
- return item?.value;
4468
+ markForCheck() {
4469
+ this._cd.markForCheck();
4496
4470
  }
4497
- showItem(name) {
4498
- const item = this.getItem(name);
4499
- if (item) {
4500
- item.hide = false;
4501
- this._itemStore.updateItemsVisiblity();
4471
+ isolateChange(filter) {
4472
+ if (filter.isolate.enabled) {
4473
+ filter.model = filter.multiple ? [filter.isolate.value] : filter.isolate.value;
4502
4474
  }
4503
- }
4504
- hideItem(name) {
4505
- const item = this.getItem(name);
4506
- if (!item) {
4507
- return;
4475
+ else {
4476
+ if (filter.multiple) {
4477
+ filter.model = filter.defaultValue ? filter.defaultValue : [];
4478
+ }
4479
+ else {
4480
+ filter.model = filter.defaultValue ? filter.defaultValue : null;
4481
+ }
4508
4482
  }
4509
- item.hide = true;
4510
- this._itemStore.updateItemsVisiblity();
4511
4483
  }
4512
- clearItem(name) {
4513
- const item = this.getItem(name);
4514
- if (!item) {
4515
- return;
4516
- }
4517
- item.clear();
4484
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectMultipleComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4485
+ 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 });
4486
+ }
4487
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectMultipleComponent, decorators: [{
4488
+ type: Component,
4489
+ args: [{ selector: 'filter-item-select-multiple', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4490
+ MatFormField,
4491
+ NgClass,
4492
+ MatLabel,
4493
+ MatSelect,
4494
+ FocusToItemDirective,
4495
+ FormsModule,
4496
+ FsFormModule,
4497
+ MatOption,
4498
+ MatHint,
4499
+ MatCheckbox,
4500
+ FsFilterIsolateValues,
4501
+ ], 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>" }]
4502
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
4503
+ type: Input
4504
+ }], select: [{
4505
+ type: ViewChild,
4506
+ args: ['select', { static: true }]
4507
+ }] } });
4508
+
4509
+ class SelectSimpleComponent {
4510
+ _cd;
4511
+ item;
4512
+ select;
4513
+ constructor(_cd) {
4514
+ this._cd = _cd;
4518
4515
  }
4519
- updateItemConfig(name, params) {
4520
- const item = this.getItem(name);
4521
- if (!item) {
4522
- return;
4516
+ changed() {
4517
+ if (this.item.isolate) {
4518
+ this.item.isolate.enabled = false;
4523
4519
  }
4524
- item.label = params.label ?? item.label;
4525
- item.chipLabel = params.chipLabel ?? item.chipLabel;
4526
- this._itemStore.updateItemsVisiblity();
4527
4520
  }
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
- }));
4535
- }
4536
- return null;
4521
+ isolateChange(filter) {
4522
+ filter.model = filter.isolate.enabled ? filter.isolate.value : null;
4537
4523
  }
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();
4524
+ markForCheck() {
4525
+ this._cd.markForCheck();
4526
+ }
4527
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectSimpleComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4528
+ 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 });
4529
+ }
4530
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectSimpleComponent, decorators: [{
4531
+ type: Component,
4532
+ args: [{ selector: 'filter-item-select-simple', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4533
+ MatFormField,
4534
+ NgClass,
4535
+ MatLabel,
4536
+ MatSelect,
4537
+ FocusToItemDirective,
4538
+ FormsModule,
4539
+ FsFormModule,
4540
+ MatOption,
4541
+ MatCheckbox,
4542
+ FsFilterIsolateValues,
4543
+ ], 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}" }]
4544
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
4545
+ type: Input
4546
+ }], select: [{
4547
+ type: ViewChild,
4548
+ args: ['select', { static: true }]
4549
+ }] } });
4550
+
4551
+ class SelectGroupsComponent {
4552
+ cd;
4553
+ select;
4554
+ item;
4555
+ constructor(cd) {
4556
+ this.cd = cd;
4557
+ }
4558
+ compare(o1, o2) {
4559
+ return o1 == o2;
4560
+ }
4561
+ markForCheck() {
4562
+ this.cd.markForCheck();
4563
+ }
4564
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectGroupsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4565
+ 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 });
4566
+ }
4567
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectGroupsComponent, decorators: [{
4568
+ type: Component,
4569
+ args: [{ selector: 'filter-item-select-groups', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4570
+ MatFormField,
4571
+ MatLabel,
4572
+ MatSelect,
4573
+ FocusToItemDirective,
4574
+ FormsModule,
4575
+ FsFormModule,
4576
+ MatOptgroup,
4577
+ MatOption,
4578
+ NgStyle,
4579
+ ], 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" }]
4580
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { select: [{
4581
+ type: ViewChild,
4582
+ args: ['select', { static: true }]
4583
+ }], item: [{
4584
+ type: Input
4585
+ }] } });
4586
+
4587
+ class SelectComponent extends BaseItemComponent {
4588
+ _kvDiffers;
4589
+ _cd;
4590
+ selectedItem;
4591
+ // For case when we have multiple selection with __all option
4592
+ // If _all has been selected than we must disable all other items
4593
+ allItemsOptionSelected = false;
4594
+ get multipleSelectItem() {
4595
+ return this.item;
4552
4596
  }
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
- });
4597
+ get simpleSelectItem() {
4598
+ return this.item;
4564
4599
  }
4565
- clear(event = null) {
4566
- if (event) {
4567
- event.stopPropagation();
4568
- }
4569
- this._itemStore.filtersClear();
4570
- if (this.config.clear) {
4571
- this.config.clear();
4572
- }
4573
- this.keyword = '';
4600
+ values$;
4601
+ constructor(_kvDiffers, _cd) {
4602
+ super(_kvDiffers, _cd);
4603
+ this._kvDiffers = _kvDiffers;
4604
+ this._cd = _cd;
4574
4605
  }
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());
4606
+ ngOnChanges(changes) {
4607
+ if (changes.item) {
4608
+ this.values$ = this.item.values$;
4592
4609
  }
4593
4610
  }
4594
- getItem(name) {
4595
- return this.items
4596
- .find((item) => item.name === name);
4597
- }
4598
- fetchQueryParams() {
4599
- this._paramController.fetchQueryParams();
4600
- }
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);
4611
+ ngDoCheck() {
4612
+ if (this._kvDiffer) {
4613
+ const changes = this._kvDiffer.diff(this.item);
4614
+ if (changes) {
4615
+ this._cd.markForCheck();
4616
+ if (this.selectedItem) {
4617
+ this.selectedItem.markForCheck();
4618
+ }
4613
4619
  }
4614
4620
  }
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();
4621
- }
4622
- /**
4623
- * Update filter actions config
4624
- *
4625
- * @param actions
4626
- */
4627
- updateActions(actions) {
4628
- this._actions.initActions(actions);
4629
4621
  }
4630
- /**
4631
- * Show "Filters" button
4632
- */
4633
- showFiltersBtn() {
4634
- this._filtersBtnVisible$.next(true);
4622
+ 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 });
4623
+ 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 });
4624
+ }
4625
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectComponent, decorators: [{
4626
+ type: Component,
4627
+ args: [{ selector: 'filter-item-select', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4628
+ MatFormField,
4629
+ MatLabel,
4630
+ MatSelect,
4631
+ SelectMultipleComponent,
4632
+ SelectSimpleComponent,
4633
+ SelectGroupsComponent,
4634
+ AsyncPipe,
4635
+ ], 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"] }]
4636
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }], propDecorators: { selectedItem: [{
4637
+ type: ViewChild,
4638
+ args: ['selectItem']
4639
+ }] } });
4640
+
4641
+ class TextComponent extends BaseItemComponent {
4642
+ _kvDiffers;
4643
+ _cd;
4644
+ textControl = new UntypedFormControl();
4645
+ constructor(_kvDiffers, _cd) {
4646
+ super(_kvDiffers, _cd);
4647
+ this._kvDiffers = _kvDiffers;
4648
+ this._cd = _cd;
4635
4649
  }
4636
- /**
4637
- * Hide "Filters" button
4638
- */
4639
- hideFiltersBtn() {
4640
- this._filtersBtnVisible$.next(false);
4650
+ ngOnInit() {
4651
+ this._listenControlValueChanges();
4652
+ this._listenModelChanges();
4641
4653
  }
4642
- /**
4643
- * Show "Keyword" field if it present
4644
- */
4645
- showKeywordField() {
4646
- this._keywordVisible$.next(true);
4654
+ _listenControlValueChanges() {
4655
+ this.textControl.valueChanges
4656
+ .pipe(distinctUntilChanged(), debounceTime(200), takeUntil(this.destroy$))
4657
+ .subscribe((value) => {
4658
+ this.item.model = value;
4659
+ });
4647
4660
  }
4648
- /**
4649
- * Hide "Keyword" field if it present
4650
- */
4651
- hideKeywordField() {
4652
- this._keywordVisible$.next(false);
4661
+ _listenModelChanges() {
4662
+ this._item.value$
4663
+ .pipe(takeUntil(this.destroy$))
4664
+ .subscribe(() => {
4665
+ this.textControl.setValue(this.item.model, { emitEvent: false });
4666
+ });
4653
4667
  }
4654
- /**
4655
- * Go through actions and check show() callback and update visible actions
4656
- */
4657
- updateActionsVisibility() {
4658
- this._actions.updateActionsVisibility();
4668
+ 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 });
4669
+ 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 });
4670
+ }
4671
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextComponent, decorators: [{
4672
+ type: Component,
4673
+ args: [{ selector: 'filter-item-text', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4674
+ MatFormField,
4675
+ MatLabel,
4676
+ MatPrefix,
4677
+ MatInput,
4678
+ FormsModule,
4679
+ ReactiveFormsModule,
4680
+ FocusToItemDirective,
4681
+ MatSuffix,
4682
+ ], 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>" }]
4683
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4684
+
4685
+ class WeekComponent extends BaseItemComponent {
4686
+ _kvDiffers;
4687
+ _cd;
4688
+ constructor(_kvDiffers, _cd) {
4689
+ super(_kvDiffers, _cd);
4690
+ this._kvDiffers = _kvDiffers;
4691
+ this._cd = _cd;
4659
4692
  }
4660
- /**
4661
- * Go through actions and check disabled() callback and update disabled state
4662
- */
4663
- updateDisabledState() {
4664
- this._actions.updateDisabledState();
4693
+ ngOnInit() { }
4694
+ 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 });
4695
+ 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 });
4696
+ }
4697
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WeekComponent, decorators: [{
4698
+ type: Component,
4699
+ args: [{ selector: 'filter-item-week', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4700
+ MatFormField,
4701
+ MatLabel,
4702
+ MatInput,
4703
+ FormsModule,
4704
+ FsDatePickerModule,
4705
+ FocusToItemDirective,
4706
+ FsFormModule,
4707
+ ], 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" }]
4708
+ }], ctorParameters: () => [{ type: i0.KeyValueDiffers }, { type: i0.ChangeDetectorRef }] });
4709
+
4710
+ class FilterItemComponent {
4711
+ _cdRef;
4712
+ item;
4713
+ itemType = ItemType;
4714
+ get textItem() {
4715
+ return this.item;
4665
4716
  }
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();
4717
+ get chipsItem() {
4718
+ return this.item;
4672
4719
  }
4673
- keywordChange(keyword) {
4674
- this._keyword$.next(keyword);
4720
+ get baseSelectItem() {
4721
+ return this.item;
4675
4722
  }
4676
- updateSortings(items) {
4677
- this._itemStore.updateSortingItemsValues(items);
4723
+ get rangeItem() {
4724
+ return this.item;
4678
4725
  }
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
- }
4726
+ get autocompleteItem() {
4727
+ return this.item;
4696
4728
  }
4697
- _destroyFilterDrawer() {
4698
- this._filterOverlay.close();
4729
+ get autocompleteChipsItem() {
4730
+ return this.item;
4699
4731
  }
4700
- _updateWindowWidth() {
4701
- this.windowDesktop = window.innerWidth > 1200;
4732
+ get dateItem() {
4733
+ return this.item;
4702
4734
  }
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
- });
4735
+ get dateRangeItem() {
4736
+ return this.item;
4713
4737
  }
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
- });
4738
+ get dateTimeItem() {
4739
+ return this.item;
4724
4740
  }
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
- }
4741
+ get dateTimeRangeItem() {
4742
+ return this.item;
4733
4743
  }
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
- });
4744
+ get weekItem() {
4745
+ return this.item;
4742
4746
  }
4743
- _initKeywordVisibility() {
4744
- this._keywordVisible$.next(!!this.keywordItem && !this.keywordItem?.hide);
4747
+ get checkboxItem() {
4748
+ return this.item;
4745
4749
  }
4746
- _initAutoFocus() {
4747
- // Avoid ngChanges error
4748
- setTimeout(() => {
4749
- if (this.config.autofocus) {
4750
- this.focus();
4751
- }
4752
- });
4750
+ _destroy$ = new Subject();
4751
+ constructor(_cdRef) {
4752
+ this._cdRef = _cdRef;
4753
4753
  }
4754
- _listenInternalItemsChange() {
4755
- this._itemStore
4756
- .itemsChange$
4754
+ ngOnInit() {
4755
+ this.item.value$
4757
4756
  .pipe(takeUntil(this._destroy$))
4758
4757
  .subscribe(() => {
4759
- this.keyword = this._itemStore.keywordItem?.model;
4760
- this.change();
4758
+ this._cdRef.markForCheck();
4761
4759
  });
4762
4760
  }
4763
- _initOverlay() {
4764
- this._filterOverlay.setClearFn(this.clear.bind(this));
4765
- this._filterOverlay.setDoneFn(this.hide.bind(this));
4761
+ ngOnDestroy() {
4762
+ this._destroy$.next(null);
4763
+ this._destroy$.complete();
4766
4764
  }
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
- });
4765
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterItemComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4766
+ 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 });
4767
+ }
4768
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterItemComponent, decorators: [{
4769
+ type: Component,
4770
+ args: [{ selector: 'filter-item', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4771
+ TextComponent,
4772
+ SelectComponent,
4773
+ ChipsComponent,
4774
+ RangeComponent,
4775
+ AutocompleteComponent,
4776
+ AutocompletechipsComponent,
4777
+ DateComponent,
4778
+ DateRangeComponent,
4779
+ WeekComponent,
4780
+ CheckboxComponent,
4781
+ ], 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"] }]
4782
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
4783
+ type: Input
4784
+ }] } });
4785
+
4786
+ class FilterDrawerComponent {
4787
+ inline = false;
4788
+ windowDesktop = false;
4789
+ savedFilterName = '';
4790
+ _clear;
4791
+ _done;
4792
+ _destroyRef = inject(DestroyRef);
4793
+ _savedFilterController = inject(SavedFilterController);
4794
+ _message = inject(FsMessage);
4795
+ _itemStore = inject(ItemStore);
4796
+ _overlayRef = inject(FILTER_DRAWER_OVERLAY);
4797
+ _data = inject(FILTER_DRAWER_DATA);
4798
+ _paramController = inject(ParamController);
4799
+ constructor() {
4800
+ this._itemStore.prepareItems();
4801
+ this._clear = this._data.clear;
4802
+ this._done = this._data.done;
4803
+ this.updateWindowWidth();
4779
4804
  }
4780
- _updateKeyword() {
4781
- this.keyword = this._itemStore.keywordItem?.model;
4805
+ updateWindowWidth() {
4806
+ this.windowDesktop = window.innerWidth > 1200;
4782
4807
  }
4783
- _updateChipsVisibility() {
4784
- const hasFilterChips = this._itemStore.items
4785
- .some((item) => {
4786
- return item.isChipVisible;
4808
+ get items$() {
4809
+ return this._itemStore.visibleItems$;
4810
+ }
4811
+ get paramCointroller() {
4812
+ return this._paramController;
4813
+ }
4814
+ get savedFiltersController() {
4815
+ return this._savedFilterController;
4816
+ }
4817
+ ngOnInit() {
4818
+ this._savedFilterController.activeFilter$
4819
+ .pipe(takeUntilDestroyed(this._destroyRef))
4820
+ .subscribe((activeFilter) => {
4821
+ this.savedFilterName = activeFilter?.name || '';
4787
4822
  });
4788
- this._hasFilterChips$.next(hasFilterChips);
4789
4823
  }
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 });
4824
+ clear() {
4825
+ this._clear();
4826
+ }
4827
+ done() {
4828
+ this._done();
4829
+ this._overlayRef.detach();
4830
+ }
4831
+ backdropClick() {
4832
+ this.done();
4833
+ }
4834
+ saveSavedFilter = () => {
4835
+ return this._savedFilterController
4836
+ .save({ name: this.savedFilterName })
4837
+ .pipe(tap$1((savedFilter) => {
4838
+ this._savedFilterController.setActiveFilter(savedFilter);
4839
+ this._message
4840
+ .success(`Saved ${this._savedFilterController.singularLabel}`, {
4841
+ positionClass: 'toast-bottom-left',
4842
+ });
4843
+ }));
4844
+ };
4845
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4846
+ 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
4847
  }
4802
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, decorators: [{
4848
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterDrawerComponent, decorators: [{
4803
4849
  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,
4850
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4821
4851
  FormsModule,
4822
4852
  FsFormModule,
4823
- FsClearModule,
4824
- FsFilterChipsComponent,
4825
- FsFilterActionsComponent,
4826
- MatIconAnchor,
4827
- MatSlideToggle,
4853
+ MatIcon,
4854
+ MatFormField,
4855
+ MatLabel,
4856
+ MatInput,
4857
+ FsSkeletonModule,
4858
+ FilterItemComponent,
4859
+ FsFilterDrawerActionsComponent,
4828
4860
  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: [{
4861
+ ], 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"] }]
4862
+ }], ctorParameters: () => [], propDecorators: { inline: [{
4837
4863
  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']
4864
+ }], updateWindowWidth: [{
4865
+ type: HostListener,
4866
+ args: ['window:resize']
4862
4867
  }] } });
4863
4868
 
4864
4869
  class SelectBackdropComponent {