@firestitch/filter 18.2.12 → 18.2.14

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.
Files changed (26) hide show
  1. package/app/components/filter/filter.component.d.ts +7 -6
  2. package/app/components/filter-chips/filter-chips.component.d.ts +1 -0
  3. package/app/components/saved-filter/saved-filter-manage/saved-filter-manage.component.d.ts +1 -1
  4. package/app/fs-filter.module.d.ts +8 -10
  5. package/app/helpers/create-filter-item.d.ts +1 -1
  6. package/app/models/items/base-item.d.ts +5 -2
  7. package/app/models/items/chips-item.d.ts +2 -2
  8. package/app/models/items/week-item.d.ts +0 -1
  9. package/app/services/focus-controller.service.d.ts +0 -1
  10. package/esm2022/app/components/filter/filter.component.mjs +15 -15
  11. package/esm2022/app/components/filter-chips/filter-chips.component.mjs +7 -7
  12. package/esm2022/app/components/saved-filter/saved-filter-manage/components/saved-filter-chips/saved-filter-chips.component.mjs +9 -7
  13. package/esm2022/app/components/saved-filter/saved-filter-manage/saved-filter-manage.component.mjs +3 -3
  14. package/esm2022/app/fs-filter.module.mjs +1 -8
  15. package/esm2022/app/models/items/base-item.mjs +21 -12
  16. package/esm2022/app/models/items/chips-item.mjs +8 -25
  17. package/esm2022/app/models/items/week-item.mjs +1 -16
  18. package/esm2022/app/services/filter-controller.service.mjs +2 -2
  19. package/esm2022/app/services/focus-controller.service.mjs +2 -3
  20. package/fesm2022/firestitch-filter.mjs +82 -248
  21. package/fesm2022/firestitch-filter.mjs.map +1 -1
  22. package/package.json +1 -1
  23. package/app/components/filter-chip/filter-chip.component.d.ts +0 -37
  24. package/app/components/filter-chip-content/filter-chip-content.component.d.ts +0 -18
  25. package/esm2022/app/components/filter-chip/filter-chip.component.mjs +0 -84
  26. package/esm2022/app/components/filter-chip-content/filter-chip-content.component.mjs +0 -71
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, Component, ChangeDetectionStrategy, Input, ChangeDetectorRef, HostBinding, DestroyRef, EventEmitter, Output, InjectionToken, Injector, Directive, Optional, Self, ViewChild, NgZone, ElementRef, ContentChild, Pipe, HostListener, NgModule } from '@angular/core';
2
+ import { inject, Injectable, Component, ChangeDetectionStrategy, Input, DestroyRef, Injector, EventEmitter, Output, InjectionToken, Directive, Optional, Self, ChangeDetectorRef, ViewChild, NgZone, ElementRef, ContentChild, HostBinding, Pipe, HostListener, NgModule } from '@angular/core';
3
3
  import { FsPrompt } from '@firestitch/prompt';
4
- import { BehaviorSubject, Subject, of, forkJoin, Observable, timer, combineLatest, tap as tap$1, switchMap as switchMap$1, distinctUntilChanged as distinctUntilChanged$1, merge, filter as filter$1, map as map$1, fromEvent, interval, takeUntil as takeUntil$1, debounceTime as debounceTime$1 } from 'rxjs';
5
- import { distinctUntilChanged, tap, switchMap, map, takeUntil, filter, mapTo, startWith, debounceTime, finalize, delay, skip } from 'rxjs/operators';
4
+ import { BehaviorSubject, Subject, of, forkJoin, Observable, tap as tap$1, switchMap as switchMap$1, distinctUntilChanged as distinctUntilChanged$1, merge, filter as filter$1, map as map$1, combineLatest, fromEvent, interval, takeUntil as takeUntil$1, debounceTime as debounceTime$1 } from 'rxjs';
5
+ import { distinctUntilChanged, tap, switchMap, map, filter, debounceTime, finalize, takeUntil, delay, skip } from 'rxjs/operators';
6
6
  import { FsStore } from '@firestitch/store';
7
7
  import { NgSwitch, NgSwitchCase, NgClass, NgTemplateOutlet, NgSwitchDefault, NgIf, AsyncPipe, Location } from '@angular/common';
8
8
  import { MatIconButton, MatFabButton, MatMiniFabButton, MatButton, MatIconAnchor } from '@angular/material/button';
@@ -22,10 +22,10 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
22
22
  import { MatOption, MatOptgroup } from '@angular/material/core';
23
23
  import * as i6 from '@firestitch/file';
24
24
  import { FsFileModule } from '@firestitch/file';
25
- import { isFunction, clone, toString, isObject, isString } from 'lodash-es';
26
25
  import * as i1$2 from '@firestitch/chip';
27
26
  import { FsChipModule } from '@firestitch/chip';
28
- import { iso8601, format, simpleFormat } from '@firestitch/date';
27
+ import { isFunction, clone, toString, isObject, isString } from 'lodash-es';
28
+ import { iso8601, format } from '@firestitch/date';
29
29
  import { isDate, isValid, parseISO } from 'date-fns';
30
30
  import { isEmpty, getNormalizedPath } from '@firestitch/common';
31
31
  import * as i3$2 from '@firestitch/datepicker';
@@ -655,9 +655,10 @@ class BaseItem {
655
655
  _type;
656
656
  _valuesFn;
657
657
  _hidden$ = new BehaviorSubject(false);
658
- _value$ = new BehaviorSubject(undefined);
658
+ _value$ = new BehaviorSubject({ value: undefined, emitChange: true });
659
659
  _values$ = new BehaviorSubject(null);
660
660
  _destroy$ = new Subject();
661
+ _emitChange = true;
661
662
  constructor(itemConfig, _additionalConfig, _filter) {
662
663
  this._additionalConfig = _additionalConfig;
663
664
  this._filter = _filter;
@@ -723,11 +724,11 @@ class BaseItem {
723
724
  return this.value !== null && this.value !== undefined;
724
725
  }
725
726
  get hasValue$() {
726
- return this._value$.asObservable()
727
+ return this.value$
727
728
  .pipe(map(() => this.hasValue));
728
729
  }
729
730
  get chips$() {
730
- return this._value$.asObservable()
731
+ return this.value$
731
732
  .pipe(map(() => this.chips));
732
733
  }
733
734
  set values(values) {
@@ -737,10 +738,21 @@ class BaseItem {
737
738
  return this._values$.getValue();
738
739
  }
739
740
  get values$() {
740
- return this._values$.asObservable();
741
+ return this._values$.asObservable()
742
+ .pipe(filter(() => this._emitChange));
741
743
  }
742
744
  get value$() {
743
- return this._value$.asObservable();
745
+ return this._value$.asObservable()
746
+ .pipe(filter((event) => event.emitChange), map((event) => event.value));
747
+ }
748
+ get value() {
749
+ return this._value$.getValue().value;
750
+ }
751
+ set value(value) {
752
+ this.setValue(value);
753
+ }
754
+ setValue(value, emitChange = true) {
755
+ this._value$.next({ value, emitChange });
744
756
  }
745
757
  get queryParam() {
746
758
  return this.query;
@@ -798,11 +810,8 @@ class BaseItem {
798
810
  this._destroy$.next(null);
799
811
  this._destroy$.complete();
800
812
  }
801
- get value() {
802
- return this._value$.getValue();
803
- }
804
- set value(value) {
805
- this._value$.next(value);
813
+ clone() {
814
+ return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
806
815
  }
807
816
  _initConfig(item) {
808
817
  this.name = item.name;
@@ -829,171 +838,6 @@ class BaseItem {
829
838
  }
830
839
  }
831
840
 
832
- class FsFilterChipContentComponent {
833
- _cdRef;
834
- item;
835
- type;
836
- content;
837
- _destroy$ = new Subject();
838
- constructor(_cdRef) {
839
- this._cdRef = _cdRef;
840
- }
841
- ngOnInit() {
842
- this.listenValueChangesForRanges();
843
- }
844
- ngOnDestroy() {
845
- this._destroy$.next(null);
846
- this._destroy$.complete();
847
- }
848
- listenValueChangesForRanges() {
849
- this.item.value$
850
- .pipe(takeUntil(this._destroy$))
851
- .subscribe(() => {
852
- this.content = this._getContent();
853
- this._cdRef.detectChanges();
854
- });
855
- }
856
- _getContent() {
857
- const result = this.item.chips;
858
- if (this.item.chipLabel !== undefined) {
859
- if (this.item.chipLabel === '') {
860
- return `${result}`;
861
- }
862
- if (Array.isArray(this.item.chipLabel)) {
863
- const label = getLabelFromArray(this.item.chipLabel, this.type);
864
- return `${label}: ${result}`;
865
- }
866
- return `${this.item.chipLabel}: ${result}`;
867
- }
868
- if (Array.isArray(this.item.label)) {
869
- const label = getLabelFromArray(this.item.label, this.type);
870
- return `${label}: ${result}`;
871
- }
872
- if (this.item.isTypeCheckbox) {
873
- return result;
874
- }
875
- return `${this.item.label}: ${result}`;
876
- }
877
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterChipContentComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
878
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FsFilterChipContentComponent, isStandalone: true, selector: "fs-filter-chip-content", inputs: { item: "item", type: "type" }, ngImport: i0, template: "{{ content }}\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
879
- }
880
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterChipContentComponent, decorators: [{
881
- type: Component,
882
- args: [{ selector: 'fs-filter-chip-content', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "{{ content }}\n" }]
883
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { item: [{
884
- type: Input
885
- }], type: [{
886
- type: Input
887
- }] } });
888
- function getLabelFromArray(labelArr, type) {
889
- if (type === 'from' && labelArr[0]) {
890
- return `${labelArr[0]}`;
891
- }
892
- else if (type === 'to' && labelArr[1]) {
893
- return `${labelArr[1]}`;
894
- }
895
- return '';
896
- }
897
-
898
- class FocusControllerService {
899
- _focusOn = new BehaviorSubject(null);
900
- constructor() { }
901
- get focusOn$() {
902
- return this._focusOn.asObservable();
903
- }
904
- click(item, type) {
905
- this._focusOn.next({ item, type });
906
- }
907
- listenFocusFor$(targetItem, targetType) {
908
- return this._focusOn
909
- .pipe(filter((event) => !!event), filter(({ item, type }) => {
910
- return targetItem === item && targetType === type;
911
- }), tap(() => this.clearFocus()));
912
- }
913
- clearFocus() {
914
- this._focusOn.next(null);
915
- }
916
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FocusControllerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
917
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FocusControllerService });
918
- }
919
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FocusControllerService, decorators: [{
920
- type: Injectable
921
- }], ctorParameters: () => [] });
922
-
923
- class FsFilterChipComponent {
924
- item;
925
- removable = false;
926
- chips;
927
- clickable = false;
928
- rangeItem;
929
- chipDelayedRender$;
930
- _chipRenderTimer$ = timer(500)
931
- .pipe(mapTo(true));
932
- _destroy$ = new Subject();
933
- _cdRef = inject(ChangeDetectorRef);
934
- _focusController = inject(FocusControllerService);
935
- ngOnInit() {
936
- // this.rangeItem = this.item.isTypeDateRange
937
- // || this.item.isTypeRange
938
- // || this.item.isTypeDateTimeRange;
939
- // this.listenValueChangesForRanges();
940
- // this._initDelayRender();
941
- // }
942
- }
943
- ngOnDestroy() {
944
- this._destroy$.next(null);
945
- this._destroy$.complete();
946
- }
947
- click(chip) {
948
- if (this.clickable) {
949
- this._focusController.click(this.item, chip.name);
950
- }
951
- }
952
- remove(chip) {
953
- this.item.clear(chip.name);
954
- }
955
- listenValueChangesForRanges() {
956
- // this.item.valueChange$
957
- // .pipe(
958
- // takeUntil(this._destroy$),
959
- // )
960
- // .subscribe(() => {
961
- // this._cdRef.markForCheck();
962
- // });
963
- }
964
- _initDelayRender() {
965
- this.chipDelayedRender$ = combineLatest([
966
- this.item.values$,
967
- this._chipRenderTimer$.pipe(startWith(false)),
968
- ])
969
- .pipe(map(([values, timerValue]) => {
970
- return !!values || timerValue;
971
- }));
972
- }
973
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
974
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsFilterChipComponent, isStandalone: true, selector: "fs-filter-chip", inputs: { item: "item", removable: "removable", chips: "chips", clickable: "clickable" }, host: { properties: { "class.clickable": "this.clickable" } }, ngImport: i0, template: "@for (chip of chips; track chip) {\n <fs-chip\n [selectable]=\"false\"\n [removable]=\"item.showClear && removable\"\n size=\"small\"\n (click)=\"click(chip)\"\n (removed)=\"remove(chip)\">\n {{ chip.label }}: {{ chip.value }}\n </fs-chip>\n}\n<!-- {{ item.name }}\n@if ((chipDelayedRender$ | async)) {\n @if (rangeItem) {\n @if (item.value?.min || item.value?.from) {\n <fs-chip\n [value]=\"item\"\n [selectable]=\"false\"\n [removable]=\"item.showClear\"\n size=\"small\"\n [removable]=\"removable\"\n (click)=\"click('from')\"\n (removed)=\"removeItem($event, 'from')\">\n <ng-template\n [ngTemplateOutlet]=\"chipContent\"\n [ngTemplateOutletContext]=\"{ item: item, type: 'from' }\">\n </ng-template>\n </fs-chip>\n }\n @if (item.value?.max || item.value?.to) {\n <fs-chip\n [value]=\"item\"\n [selectable]=\"false\"\n [removable]=\"item.showClear && removable\"\n size=\"small\"\n (click)=\"click('to')\"\n (removed)=\"removeItem($event, 'to')\">\n <ng-template\n [ngTemplateOutlet]=\"chipContent\"\n [ngTemplateOutletContext]=\"{ item: item, type: 'to' }\">\n </ng-template>\n </fs-chip>\n }\n } @else {\n <fs-chip\n [value]=\"item\"\n [selectable]=\"false\"\n [removable]=\"item.showClear && removable\"\n size=\"small\"\n (click)=\"click()\"\n (removed)=\"removeItem($event)\">\n <ng-template\n [ngTemplateOutlet]=\"chipContent\"\n [ngTemplateOutletContext]=\"{ item: item }\">\n </ng-template>\n </fs-chip>\n }\n <ng-template\n #chipContent\n let-item=\"item\"\n let-type=\"type\">\n @if (!item.hasPendingValues && !item.loading) {\n <fs-filter-chip-content\n [item]=\"item\"\n [type]=\"type\">\n </fs-filter-chip-content>\n } @else {\n Loading...\n }\n </ng-template>\n} -->", styles: [":host{display:flex;flex-wrap:wrap;gap:5px;max-width:100%}:host.clickable fs-chip{cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: FsChipModule }, { kind: "component", type: i1$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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
975
- }
976
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterChipComponent, decorators: [{
977
- type: Component,
978
- args: [{ selector: 'fs-filter-chip', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
979
- FsChipModule,
980
- NgTemplateOutlet,
981
- FsFilterChipContentComponent,
982
- AsyncPipe,
983
- ], template: "@for (chip of chips; track chip) {\n <fs-chip\n [selectable]=\"false\"\n [removable]=\"item.showClear && removable\"\n size=\"small\"\n (click)=\"click(chip)\"\n (removed)=\"remove(chip)\">\n {{ chip.label }}: {{ chip.value }}\n </fs-chip>\n}\n<!-- {{ item.name }}\n@if ((chipDelayedRender$ | async)) {\n @if (rangeItem) {\n @if (item.value?.min || item.value?.from) {\n <fs-chip\n [value]=\"item\"\n [selectable]=\"false\"\n [removable]=\"item.showClear\"\n size=\"small\"\n [removable]=\"removable\"\n (click)=\"click('from')\"\n (removed)=\"removeItem($event, 'from')\">\n <ng-template\n [ngTemplateOutlet]=\"chipContent\"\n [ngTemplateOutletContext]=\"{ item: item, type: 'from' }\">\n </ng-template>\n </fs-chip>\n }\n @if (item.value?.max || item.value?.to) {\n <fs-chip\n [value]=\"item\"\n [selectable]=\"false\"\n [removable]=\"item.showClear && removable\"\n size=\"small\"\n (click)=\"click('to')\"\n (removed)=\"removeItem($event, 'to')\">\n <ng-template\n [ngTemplateOutlet]=\"chipContent\"\n [ngTemplateOutletContext]=\"{ item: item, type: 'to' }\">\n </ng-template>\n </fs-chip>\n }\n } @else {\n <fs-chip\n [value]=\"item\"\n [selectable]=\"false\"\n [removable]=\"item.showClear && removable\"\n size=\"small\"\n (click)=\"click()\"\n (removed)=\"removeItem($event)\">\n <ng-template\n [ngTemplateOutlet]=\"chipContent\"\n [ngTemplateOutletContext]=\"{ item: item }\">\n </ng-template>\n </fs-chip>\n }\n <ng-template\n #chipContent\n let-item=\"item\"\n let-type=\"type\">\n @if (!item.hasPendingValues && !item.loading) {\n <fs-filter-chip-content\n [item]=\"item\"\n [type]=\"type\">\n </fs-filter-chip-content>\n } @else {\n Loading...\n }\n </ng-template>\n} -->", styles: [":host{display:flex;flex-wrap:wrap;gap:5px;max-width:100%}:host.clickable fs-chip{cursor:pointer}\n"] }]
984
- }], propDecorators: { item: [{
985
- type: Input
986
- }], removable: [{
987
- type: Input
988
- }], chips: [{
989
- type: Input
990
- }], clickable: [{
991
- type: Input
992
- }, {
993
- type: HostBinding,
994
- args: ['class.clickable']
995
- }] } });
996
-
997
841
  class BaseAutocompleteItem extends BaseItem {
998
842
  _additionalConfig;
999
843
  _filter;
@@ -1178,8 +1022,8 @@ class ChipsItem extends BaseItem {
1178
1022
  static create(config, filter) {
1179
1023
  return new ChipsItem(config, null, filter);
1180
1024
  }
1181
- get isTypeChips() {
1182
- return true;
1025
+ get hasValue() {
1026
+ return this.value.length > 0;
1183
1027
  }
1184
1028
  get queryParam() {
1185
1029
  if (!this.hasValue) {
@@ -1201,13 +1045,6 @@ class ChipsItem extends BaseItem {
1201
1045
  .join(','),
1202
1046
  };
1203
1047
  }
1204
- get persistanceObject() {
1205
- const value = this.value;
1206
- const name = this.name;
1207
- const params = {};
1208
- params[name] = Array.isArray(value) ? value.join(',') : undefined;
1209
- return params;
1210
- }
1211
1048
  get chips() {
1212
1049
  return this.hasValue ? [
1213
1050
  {
@@ -1222,22 +1059,13 @@ class ChipsItem extends BaseItem {
1222
1059
  ] : [];
1223
1060
  }
1224
1061
  set value(value) {
1225
- if (Array.isArray(value)) {
1226
- value = value.map((val) => {
1227
- if (isNaN(val)) {
1228
- return val;
1229
- }
1230
- return +val;
1231
- });
1232
- }
1233
- super.value = value;
1062
+ super.value = Array.isArray(value) ? value : [];
1234
1063
  }
1235
1064
  get value() {
1236
- const value = clone(super.value);
1237
- if (Array.isArray(value) && value.length === 0) {
1238
- return undefined;
1239
- }
1240
- return value;
1065
+ return super.value;
1066
+ }
1067
+ clear() {
1068
+ this.value = [];
1241
1069
  }
1242
1070
  init(value) {
1243
1071
  return super.init(value)
@@ -1737,20 +1565,6 @@ class WeekItem extends BaseItem {
1737
1565
  [paramPeriodName]: value?.period || undefined,
1738
1566
  };
1739
1567
  }
1740
- get persistanceObject() {
1741
- const query = this.query;
1742
- const name = this.name;
1743
- const paramFromName = getRangeName(name, 'from');
1744
- const paramFromValue = query[paramFromName] && simpleFormat(query[paramFromName]) || query[paramFromName];
1745
- const paramToName = getRangeName(name, 'to');
1746
- const paramToValue = query[paramToName] && simpleFormat(query[paramToName]) || query[paramToName];
1747
- const paramPeriodName = `${name}Period`;
1748
- return {
1749
- [paramFromName]: paramFromValue,
1750
- [paramToName]: paramToValue,
1751
- [paramPeriodName]: query[paramPeriodName],
1752
- };
1753
- }
1754
1568
  get chips() {
1755
1569
  if (!this.hasValue) {
1756
1570
  return [];
@@ -2350,7 +2164,7 @@ class FilterController {
2350
2164
  _initChanges() {
2351
2165
  merge(...this.items
2352
2166
  .map((item) => item.value$
2353
- .pipe(map((_item) => item))))
2167
+ .pipe(map(() => item))))
2354
2168
  .pipe(tap((item) => this._change$.next([item])), takeUntil(this._destroy$))
2355
2169
  .subscribe();
2356
2170
  this._change$
@@ -2373,28 +2187,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2373
2187
  type: Injectable
2374
2188
  }] });
2375
2189
 
2190
+ class FocusControllerService {
2191
+ _focusOn = new BehaviorSubject(null);
2192
+ get focusOn$() {
2193
+ return this._focusOn.asObservable();
2194
+ }
2195
+ click(item, type) {
2196
+ this._focusOn.next({ item, type });
2197
+ }
2198
+ listenFocusFor$(targetItem, targetType) {
2199
+ return this._focusOn
2200
+ .pipe(filter((event) => !!event), filter(({ item, type }) => {
2201
+ return targetItem === item && targetType === type;
2202
+ }), tap(() => this.clearFocus()));
2203
+ }
2204
+ clearFocus() {
2205
+ this._focusOn.next(null);
2206
+ }
2207
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FocusControllerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2208
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FocusControllerService });
2209
+ }
2210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FocusControllerService, decorators: [{
2211
+ type: Injectable
2212
+ }] });
2213
+
2376
2214
  class FsFilterChipsComponent {
2377
2215
  ItemType = ItemType;
2378
2216
  _filterController = inject(FilterController);
2217
+ _injector = inject(Injector);
2379
2218
  get items() {
2380
2219
  return this._filterController.items;
2381
2220
  }
2382
2221
  click(item, chip) {
2383
- //this._focusController.click(this.item, chip.name);
2222
+ this._injector.get(FocusControllerService).click(item, chip.name);
2384
2223
  }
2385
2224
  remove(item, chip) {
2386
2225
  item.clear(chip.name);
2387
2226
  }
2388
2227
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2389
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsFilterChipsComponent, isStandalone: true, selector: "fs-filter-chips", ngImport: i0, template: "@for (item of items; track item.name) {\n @let chips = item.chips$ | async;\n @if (chips.length > 0) {\n @for (chip of chips; track chip.label) {\n <fs-chip\n [removable]=\"item.showClear\"\n size=\"small\"\n (click)=\"click(item, chip)\"\n (removed)=\"remove(item, chip)\">\n {{ chip.label }}: {{ chip.value }}\n </fs-chip>\n }\n <!-- <fs-filter-chip\n [chips]=\"chips\"\n [clickable]=\"true\"\n [removable]=\"true\">\n </fs-filter-chip> -->\n }\n}", styles: [""], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: FsChipModule }, { kind: "component", type: i1$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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2228
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsFilterChipsComponent, isStandalone: true, selector: "fs-filter-chips", ngImport: i0, template: "@for (item of items; track item.name) {\n @let chips = item.chips$ | async;\n @if (chips.length > 0) {\n @for (chip of chips; track chip.label) {\n <fs-chip\n [removable]=\"item.showClear\"\n size=\"small\"\n (click)=\"click(item, chip)\"\n (removed)=\"remove(item, chip)\">\n {{ chip.value ? chip.label + ': ' + chip.value : chip.label }}\n </fs-chip>\n }\n }\n}", styles: [""], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: FsChipModule }, { kind: "component", type: i1$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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2390
2229
  }
2391
2230
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterChipsComponent, decorators: [{
2392
2231
  type: Component,
2393
2232
  args: [{ selector: 'fs-filter-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
2394
- FsFilterChipComponent,
2395
2233
  AsyncPipe,
2396
2234
  FsChipModule,
2397
- ], template: "@for (item of items; track item.name) {\n @let chips = item.chips$ | async;\n @if (chips.length > 0) {\n @for (chip of chips; track chip.label) {\n <fs-chip\n [removable]=\"item.showClear\"\n size=\"small\"\n (click)=\"click(item, chip)\"\n (removed)=\"remove(item, chip)\">\n {{ chip.label }}: {{ chip.value }}\n </fs-chip>\n }\n <!-- <fs-filter-chip\n [chips]=\"chips\"\n [clickable]=\"true\"\n [removable]=\"true\">\n </fs-filter-chip> -->\n }\n}" }]
2235
+ ], template: "@for (item of items; track item.name) {\n @let chips = item.chips$ | async;\n @if (chips.length > 0) {\n @for (chip of chips; track chip.label) {\n <fs-chip\n [removable]=\"item.showClear\"\n size=\"small\"\n (click)=\"click(item, chip)\"\n (removed)=\"remove(item, chip)\">\n {{ chip.value ? chip.label + ': ' + chip.value : chip.label }}\n </fs-chip>\n }\n }\n}" }]
2398
2236
  }] });
2399
2237
 
2400
2238
  class FsFilterDrawerActionsComponent {
@@ -3072,18 +2910,19 @@ class FsFilterSavedFilterChipsComponent {
3072
2910
  this.items = [...this._filterController.items]
3073
2911
  .filter((item) => !!this.savedFilter.filters[item.name])
3074
2912
  .map((item) => {
3075
- item.value = this.savedFilter.filters[item.name];
3076
- return item;
2913
+ const object = item.clone();
2914
+ object.setValue(this.savedFilter.filters[item.name], false);
2915
+ return object;
3077
2916
  });
3078
2917
  }
3079
2918
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3080
- 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", "chips", "clickable"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2919
+ 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 @for (chip of item.chips; track chip.label) {\n <fs-chip size=\"small\">\n {{ chip.value ? chip.label + ': ' + chip.value : chip.label }}\n </fs-chip>\n }\n }\n</div>", styles: [".filter-chips{display:flex;flex-wrap:wrap;gap:4px}\n"], dependencies: [{ kind: "ngmodule", type: FsChipModule }, { kind: "component", type: i1$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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3081
2920
  }
3082
2921
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterSavedFilterChipsComponent, decorators: [{
3083
2922
  type: Component,
3084
2923
  args: [{ selector: 'fs-saved-filter-chips', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3085
- FsFilterChipComponent,
3086
- ], 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"] }]
2924
+ FsChipModule,
2925
+ ], template: "<div class=\"filter-chips\">\n @for (item of items; track item.name) {\n @for (chip of item.chips; track chip.label) {\n <fs-chip size=\"small\">\n {{ chip.value ? chip.label + ': ' + chip.value : chip.label }}\n </fs-chip>\n }\n }\n</div>", styles: [".filter-chips{display:flex;flex-wrap:wrap;gap:4px}\n"] }]
3087
2926
  }], propDecorators: { savedFilter: [{
3088
2927
  type: Input
3089
2928
  }] } });
@@ -3092,14 +2931,14 @@ class FsFilterSavedFilterManageComponent {
3092
2931
  savedFilters;
3093
2932
  _savedFilterController = inject(SavedFilterController);
3094
2933
  _cdRef = inject(ChangeDetectorRef);
3095
- filterController = inject(FilterController);
2934
+ _filterController = inject(FilterController);
3096
2935
  _dialogRef = inject(MatDialogRef);
3097
2936
  _filterOverlayService = inject(FsFilterOverlayService);
3098
2937
  ngOnInit() {
3099
2938
  this.savedFilters = this._savedFilterController.savedFilters;
3100
2939
  }
3101
2940
  get items() {
3102
- return this.filterController.items;
2941
+ return this._filterController.items;
3103
2942
  }
3104
2943
  get pluralLabelLower() {
3105
2944
  return this._savedFilterController.pluralLabelLower;
@@ -3264,6 +3103,12 @@ const FS_FILTER_CONFIG = new InjectionToken('fs.filter-config');
3264
3103
 
3265
3104
  class FilterComponent {
3266
3105
  keywordInput;
3106
+ /**
3107
+ * @deprecated Use set config instead
3108
+ */
3109
+ set filterConfig(value) {
3110
+ this.config = value;
3111
+ }
3267
3112
  set config(value) {
3268
3113
  this._config = new FsFilterConfig(value);
3269
3114
  }
@@ -3390,7 +3235,7 @@ class FilterComponent {
3390
3235
  get inlineToolbar$() {
3391
3236
  return combineLatest({
3392
3237
  keywordVisible: this.keywordVisible$,
3393
- activeFilter: of(this.savedFiltersController.enabled),
3238
+ activeFilter: of(this.savedFilterController.enabled),
3394
3239
  })
3395
3240
  .pipe(map(({ keywordVisible, activeFilter }) => {
3396
3241
  return !keywordVisible && !activeFilter;
@@ -3409,16 +3254,7 @@ class FilterComponent {
3409
3254
  get menuActions$() {
3410
3255
  return this._actionsController.menuActions$;
3411
3256
  }
3412
- set activeSavedFilter(savedFilter) {
3413
- this._savedFilterController.setActiveFilter(savedFilter);
3414
- }
3415
- get activeSavedFilter() {
3416
- return this._savedFilterController.activeFilter;
3417
- }
3418
- get savedFilters() {
3419
- return this._savedFilterController.savedFilters;
3420
- }
3421
- get savedFiltersController() {
3257
+ get savedFilterController() {
3422
3258
  return this._savedFilterController;
3423
3259
  }
3424
3260
  ngOnInit() {
@@ -3639,7 +3475,7 @@ class FilterComponent {
3639
3475
  this._filterOverlay.setDoneFn(this.hideDrawer.bind(this));
3640
3476
  }
3641
3477
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3642
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilterComponent, isStandalone: true, selector: "fs-filter", inputs: { config: "config" }, 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: [
3478
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilterComponent, isStandalone: true, selector: "fs-filter", inputs: { filterConfig: "filterConfig", config: "config" }, 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: [
3643
3479
  FsFilterOverlayService,
3644
3480
  PersistanceController,
3645
3481
  QueryParamController,
@@ -3649,7 +3485,7 @@ class FilterComponent {
3649
3485
  ActionsController,
3650
3486
  KeywordController,
3651
3487
  SortController,
3652
- ], queries: [{ propertyName: "statusBar", first: true, predicate: FilterStatusBarDirective, descendants: true }], viewQueries: [{ propertyName: "keywordInput", first: true, predicate: KeywordInputComponent, descendants: true }, { 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 <fs-keyword-input [autofocus]=\"config.autofocus\"></fs-keyword-input>\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) {\n <fs-filter-chips class=\"filter-chips\"></fs-filter-chips>\n }\n</ng-template>\n<ng-template #filterActions>\n @if (actionsVisible$ | async) {\n <div class=\"filter-actions\">\n <fs-filter-actions\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n }\n</ng-template>\n<ng-template #filterToolbar>\n @if (config.reload || config.autoReload || ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting)) {\n <div class=\"filter-toolbar\">\n @if ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting) {\n <a\n mat-icon-button\n class=\"button-filters\"\n (click)=\"filterButtonClick($event)\"\n [color]=\"config.button.color\">\n @if (config.button.icon) {\n <mat-icon [svgIcon]=\"'filterOutline'\"></mat-icon>\n }\n </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-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: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: i3.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: FsFilterChipsComponent, selector: "fs-filter-chips" }, { 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" }, { kind: "component", type: KeywordInputComponent, selector: "fs-keyword-input", inputs: ["autofocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3488
+ ], queries: [{ propertyName: "statusBar", first: true, predicate: FilterStatusBarDirective, descendants: true }], viewQueries: [{ propertyName: "keywordInput", first: true, predicate: KeywordInputComponent, descendants: true }, { 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 <fs-keyword-input [autofocus]=\"config.autofocus\"></fs-keyword-input>\n }\n @if (savedFilterController.enabled) {\n <fs-saved-filter-autocomplete-chips [savedFiltersController]=\"savedFilterController\"></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) {\n <fs-filter-chips class=\"filter-chips\"></fs-filter-chips>\n }\n</ng-template>\n<ng-template #filterActions>\n @if (actionsVisible$ | async) {\n <div class=\"filter-actions\">\n <fs-filter-actions\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n }\n</ng-template>\n<ng-template #filterToolbar>\n @if (config.reload || config.autoReload || ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting)) {\n <div class=\"filter-toolbar\">\n @if ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting) {\n <a\n mat-icon-button\n class=\"button-filters\"\n (click)=\"filterButtonClick($event)\"\n [color]=\"config.button.color\">\n @if (config.button.icon) {\n <mat-icon [svgIcon]=\"'filterOutline'\"></mat-icon>\n }\n </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-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: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: i3.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: FsFilterChipsComponent, selector: "fs-filter-chips" }, { 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" }, { kind: "component", type: KeywordInputComponent, selector: "fs-keyword-input", inputs: ["autofocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3653
3489
  }
3654
3490
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, decorators: [{
3655
3491
  type: Component,
@@ -3677,10 +3513,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3677
3513
  MatSlideToggle,
3678
3514
  AsyncPipe,
3679
3515
  KeywordInputComponent,
3680
- ], 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 <fs-keyword-input [autofocus]=\"config.autofocus\"></fs-keyword-input>\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) {\n <fs-filter-chips class=\"filter-chips\"></fs-filter-chips>\n }\n</ng-template>\n<ng-template #filterActions>\n @if (actionsVisible$ | async) {\n <div class=\"filter-actions\">\n <fs-filter-actions\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n }\n</ng-template>\n<ng-template #filterToolbar>\n @if (config.reload || config.autoReload || ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting)) {\n <div class=\"filter-toolbar\">\n @if ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting) {\n <a\n mat-icon-button\n class=\"button-filters\"\n (click)=\"filterButtonClick($event)\"\n [color]=\"config.button.color\">\n @if (config.button.icon) {\n <mat-icon [svgIcon]=\"'filterOutline'\"></mat-icon>\n }\n </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-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"] }]
3516
+ ], 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 <fs-keyword-input [autofocus]=\"config.autofocus\"></fs-keyword-input>\n }\n @if (savedFilterController.enabled) {\n <fs-saved-filter-autocomplete-chips [savedFiltersController]=\"savedFilterController\"></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) {\n <fs-filter-chips class=\"filter-chips\"></fs-filter-chips>\n }\n</ng-template>\n<ng-template #filterActions>\n @if (actionsVisible$ | async) {\n <div class=\"filter-actions\">\n <fs-filter-actions\n [actions]=\"actions$ | async\"\n [kebabActions]=\"menuActions$ | async\">\n </fs-filter-actions>\n </div>\n }\n</ng-template>\n<ng-template #filterToolbar>\n @if (config.reload || config.autoReload || ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting)) {\n <div class=\"filter-toolbar\">\n @if ((filtersBtnVisible$ | async) && hasVisibleItemOrSorting) {\n <a\n mat-icon-button\n class=\"button-filters\"\n (click)=\"filterButtonClick($event)\"\n [color]=\"config.button.color\">\n @if (config.button.icon) {\n <mat-icon [svgIcon]=\"'filterOutline'\"></mat-icon>\n }\n </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-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"] }]
3681
3517
  }], ctorParameters: () => [], propDecorators: { keywordInput: [{
3682
3518
  type: ViewChild,
3683
3519
  args: [KeywordInputComponent]
3520
+ }], filterConfig: [{
3521
+ type: Input,
3522
+ args: ['filterConfig']
3684
3523
  }], config: [{
3685
3524
  type: Input,
3686
3525
  args: ['config']
@@ -4274,8 +4113,6 @@ class FsFilterModule {
4274
4113
  DateRangeComponent,
4275
4114
  CheckboxComponent,
4276
4115
  FilterDrawerComponent,
4277
- FsFilterChipComponent,
4278
- FsFilterChipContentComponent,
4279
4116
  FsFilterDrawerActionsComponent,
4280
4117
  FsFilterActionsComponent,
4281
4118
  FsFilterActionButtonComponent,
@@ -4301,7 +4138,6 @@ class FsFilterModule {
4301
4138
  DateRangeComponent,
4302
4139
  CheckboxComponent,
4303
4140
  FilterDrawerComponent,
4304
- FsFilterChipComponent,
4305
4141
  FsFilterDrawerActionsComponent,
4306
4142
  FsFilterActionsComponent,
4307
4143
  FsFilterActionButtonComponent,
@@ -4327,8 +4163,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
4327
4163
  DateRangeComponent,
4328
4164
  CheckboxComponent,
4329
4165
  FilterDrawerComponent,
4330
- FsFilterChipComponent,
4331
- FsFilterChipContentComponent,
4332
4166
  FsFilterDrawerActionsComponent,
4333
4167
  FsFilterActionsComponent,
4334
4168
  FsFilterActionButtonComponent,