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