@firestitch/filter 18.2.18 → 18.2.20

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.
@@ -805,7 +805,13 @@ class BaseItem {
805
805
  return values instanceof Observable ? values : of(values);
806
806
  }
807
807
  return of(this.values);
808
- }), tap((values) => this.values = values || []));
808
+ }), tap((values) => {
809
+ this.values = (values || [])
810
+ .map((item) => ({
811
+ ...item,
812
+ value: (item.value ?? null) === null ? null : `${item.value}`,
813
+ }));
814
+ }));
809
815
  }
810
816
  initValue(value) {
811
817
  this.setValue(value === undefined ? this.defaultValue : value);
@@ -1041,7 +1047,7 @@ class ChipsItem extends BaseItem {
1041
1047
  };
1042
1048
  }
1043
1049
  get query() {
1044
- if (!this.value) {
1050
+ if (!this.hasValue) {
1045
1051
  return {};
1046
1052
  }
1047
1053
  return {
@@ -1051,17 +1057,19 @@ class ChipsItem extends BaseItem {
1051
1057
  };
1052
1058
  }
1053
1059
  get chips() {
1054
- return this.hasValue ? [
1055
- {
1056
- value: this.value
1057
- .reduce((acc, i) => {
1058
- acc.push((`${i.name}`).trim());
1059
- return acc;
1060
- }, [])
1061
- .join(', '),
1060
+ if (!this.hasValue) {
1061
+ return [];
1062
+ }
1063
+ const chips = this.value
1064
+ .reduce((acc, i) => {
1065
+ acc.push((`${i.name}`).trim());
1066
+ return acc;
1067
+ }, [])
1068
+ .join(', ');
1069
+ return [{
1070
+ value: chips,
1062
1071
  label: this.label,
1063
- },
1064
- ] : [];
1072
+ }];
1065
1073
  }
1066
1074
  setValue(value, emitChange = true) {
1067
1075
  super.setValue(Array.isArray(value) ? value : [], emitChange);
@@ -1346,22 +1354,14 @@ class SelectItem extends BaseItem {
1346
1354
  this.value = this.multiple ? [] : null;
1347
1355
  }
1348
1356
  init(value) {
1349
- return super.init(value)
1350
- .pipe(tap$1(() => {
1351
- if (this.isolate) {
1352
- // this.values = this.values
1353
- // .filter((item) => {
1354
- // return !this.isolateValues.includes(item.value as never);
1355
- // });
1356
- }
1357
- }));
1357
+ return super.init(value);
1358
1358
  }
1359
1359
  setValue(value, emitChange = true) {
1360
1360
  if (this.multiple) {
1361
1361
  value = Array.isArray(value) ? value : [];
1362
1362
  }
1363
1363
  else {
1364
- value = Array.isArray(value) ? undefined : value;
1364
+ value = Array.isArray(value) ? value[0] : value;
1365
1365
  }
1366
1366
  super.setValue(value, emitChange);
1367
1367
  }
@@ -1374,15 +1374,6 @@ class SelectItem extends BaseItem {
1374
1374
  };
1375
1375
  }
1376
1376
  get query() {
1377
- if (!this.hasValue && this.isolate) {
1378
- return {
1379
- [this.name]: this.values
1380
- .map((item) => {
1381
- return item.value;
1382
- })
1383
- .join(','),
1384
- };
1385
- }
1386
1377
  if (!this.hasValue) {
1387
1378
  return {};
1388
1379
  }
@@ -1414,7 +1405,7 @@ class SelectItem extends BaseItem {
1414
1405
  return true;
1415
1406
  }
1416
1407
  return this.multiple ? this.value
1417
- .includes(item.value) : +this.value === +item.value;
1408
+ .includes(item.value) : `${this.value}` === `${item.value}`;
1418
1409
  })
1419
1410
  .map((item) => {
1420
1411
  return item.name;
@@ -1571,12 +1562,12 @@ class KeywordController {
1571
1562
  this._keywordItem$
1572
1563
  .pipe(
1573
1564
  // when item changes, unsubscribe from the previous visible$
1574
- switchMap$1((item) => item ? item.visible$ : of(false)),
1565
+ switchMap$1((item) => item.visible$),
1575
1566
  // avoid redundant writes
1576
1567
  distinctUntilChanged$1(),
1577
1568
  // clean up on destroy,
1578
1569
  takeUntilDestroyed(this._destroyRef))
1579
- .subscribe((v) => this._keywordVisible$.next(v));
1570
+ .subscribe((visible) => this._keywordVisible$.next(visible));
1580
1571
  }
1581
1572
  get keywordItem$() {
1582
1573
  return this._keywordItem$.asObservable();
@@ -1622,17 +1613,17 @@ class PersistanceController {
1622
1613
  }
1623
1614
  init(filterController) {
1624
1615
  this._filterController = filterController;
1625
- const config = this._initConfig(filterController.config.persist, this.inDialog);
1626
- if (config) {
1627
- this.enabled = config.persistQuery;
1628
- this._name = config.name;
1616
+ const persistanceConfig = this._initConfig(filterController.config.persist);
1617
+ if (persistanceConfig) {
1618
+ this.enabled = !this.inDialog;
1619
+ this._name = persistanceConfig.name;
1629
1620
  this._data = this._get() || {};
1621
+ this._filterController.change$
1622
+ .pipe(takeUntilDestroyed(this._destroyRef))
1623
+ .subscribe(() => {
1624
+ this._set('query', this._filterController.values);
1625
+ });
1630
1626
  }
1631
- this._filterController.change$
1632
- .pipe(takeUntilDestroyed(this._destroyRef))
1633
- .subscribe(() => {
1634
- this._set('query', this._filterController.values);
1635
- });
1636
1627
  return of(null);
1637
1628
  }
1638
1629
  setQuery(value) {
@@ -1654,12 +1645,11 @@ class PersistanceController {
1654
1645
  }
1655
1646
  return {};
1656
1647
  }
1657
- _initConfig(config, inDialog) {
1648
+ _initConfig(config) {
1658
1649
  let persistanceConfig = this._getConfig(config);
1659
1650
  if (persistanceConfig) {
1660
1651
  persistanceConfig = {
1661
1652
  name: persistanceConfig.name || getNormalizedPath(this._location),
1662
- persistQuery: !inDialog || !!persistanceConfig.name,
1663
1653
  ...persistanceConfig,
1664
1654
  };
1665
1655
  }
@@ -1900,7 +1890,8 @@ class QueryParamController {
1900
1890
  }
1901
1891
  updateQueryParams() {
1902
1892
  const queryParams = {
1903
- ...this._filterController.items.reduce((acc, item) => {
1893
+ ...this._filterController.items
1894
+ .reduce((acc, item) => {
1904
1895
  return {
1905
1896
  ...acc,
1906
1897
  [item.name]: undefined,
@@ -1921,7 +1912,7 @@ class QueryParamController {
1921
1912
  url.searchParams.set(name, data[name]);
1922
1913
  }
1923
1914
  });
1924
- history.replaceState({}, null, url.pathname + url.search);
1915
+ history.replaceState({}, null, url.pathname + decodeURIComponent(url.search));
1925
1916
  }
1926
1917
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QueryParamController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1927
1918
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QueryParamController });
@@ -2692,10 +2683,8 @@ class FsFilterConfig {
2692
2683
  load: data.load ?? true,
2693
2684
  persist: data.persist,
2694
2685
  savedFilters: data.savedFilters,
2695
- inline: data.inline ?? false,
2696
2686
  autofocus: data.autofocus ?? false,
2697
2687
  chips: data.chips ?? false,
2698
- sortValues: data.sorts,
2699
2688
  sort: data.sort,
2700
2689
  queryParam: data.queryParam ?? false,
2701
2690
  init: data.init,
@@ -3058,7 +3047,7 @@ class FilterComponent {
3058
3047
  windowDesktop = false;
3059
3048
  fsFilterClass = true;
3060
3049
  _config;
3061
- _filtersBtnVisible$ = new BehaviorSubject(true);
3050
+ _filtersVisible$ = new BehaviorSubject(true);
3062
3051
  _hasFilterChips$ = new BehaviorSubject(false);
3063
3052
  _destroy$ = new Subject();
3064
3053
  _defaultConfig = inject(FS_FILTER_CONFIG, { optional: true });
@@ -3150,18 +3139,19 @@ class FilterComponent {
3150
3139
  change() {
3151
3140
  this._filterController.change();
3152
3141
  }
3153
- get visibleItems() {
3154
- return this._filterController.items
3155
- .filter((item) => !item.hidden);
3156
- }
3157
3142
  get hasFilterChips$() {
3158
3143
  return this._hasFilterChips$.asObservable();
3159
3144
  }
3160
- get hasVisibleItemOrSorting() {
3161
- return this.visibleItems.length > 0;
3162
- }
3163
- get filtersBtnVisible$() {
3164
- return this._filtersBtnVisible$.asObservable();
3145
+ get filtersVisible$() {
3146
+ return combineLatest({
3147
+ filtersVisible: this._filtersVisible$.asObservable(),
3148
+ hasVisibleItems: of(this.items
3149
+ .filter((item) => !item.hidden && !item.isTypeKeyword)
3150
+ .length > 0),
3151
+ })
3152
+ .pipe(map(({ filtersVisible, hasVisibleItems }) => {
3153
+ return filtersVisible && hasVisibleItems;
3154
+ }));
3165
3155
  }
3166
3156
  get keywordVisible$() {
3167
3157
  return this._keywordController.keywordVisible$;
@@ -3218,9 +3208,6 @@ class FilterComponent {
3218
3208
  this._destroyFilterDrawer();
3219
3209
  }
3220
3210
  showDrawer() {
3221
- if (!this.hasVisibleItemOrSorting) {
3222
- return;
3223
- }
3224
3211
  this._listenEscButton();
3225
3212
  this.opened.emit();
3226
3213
  this._filterOverlay.open();
@@ -3322,26 +3309,26 @@ class FilterComponent {
3322
3309
  /**
3323
3310
  * Show "Filters" button
3324
3311
  */
3325
- showFiltersBtn() {
3326
- this._filtersBtnVisible$.next(true);
3312
+ showFilters() {
3313
+ this._filtersVisible$.next(true);
3327
3314
  }
3328
3315
  /**
3329
3316
  * Hide "Filters" button
3330
3317
  */
3331
- hideFiltersBtn() {
3332
- this._filtersBtnVisible$.next(false);
3318
+ hideFilters() {
3319
+ this._filtersVisible$.next(false);
3333
3320
  }
3334
3321
  /**
3335
3322
  * Show "Keyword" field if it present
3336
3323
  */
3337
3324
  showKeywordField() {
3338
- this.keywordInput.show();
3325
+ this._keywordController.show();
3339
3326
  }
3340
3327
  /**
3341
3328
  * Hide "Keyword" field if it present
3342
3329
  */
3343
3330
  hideKeywordField() {
3344
- this.keywordInput.hide();
3331
+ this._keywordController.hide();
3345
3332
  }
3346
3333
  /**
3347
3334
  * Go through actions and check show() callback and update visible actions
@@ -3425,7 +3412,7 @@ class FilterComponent {
3425
3412
  ActionsController,
3426
3413
  KeywordController,
3427
3414
  SortController,
3428
- ], 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 <mat-slide-toggle\n name=\"autoReload\"\n class=\"auto-reload\"\n [ngModel]=\"config.autoReload.enabled\"\n (ngModelChange)=\"config.autoReload.enabled = $event\">\n <span>\n Auto refresh\n </span>\n </mat-slide-toggle>\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;margin:3px 0}.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 });
3415
+ ], 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 || (filtersVisible$ | async)) {\n <div class=\"filter-toolbar\">\n @if ((filtersVisible$ | async)) {\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 <mat-slide-toggle\n name=\"autoReload\"\n class=\"auto-reload\"\n [ngModel]=\"config.autoReload.enabled\"\n (ngModelChange)=\"config.autoReload.enabled = $event\">\n <span>\n Auto refresh\n </span>\n </mat-slide-toggle>\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;margin:3px 0}.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 });
3429
3416
  }
3430
3417
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilterComponent, decorators: [{
3431
3418
  type: Component,
@@ -3453,7 +3440,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3453
3440
  MatSlideToggle,
3454
3441
  AsyncPipe,
3455
3442
  KeywordInputComponent,
3456
- ], 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 <mat-slide-toggle\n name=\"autoReload\"\n class=\"auto-reload\"\n [ngModel]=\"config.autoReload.enabled\"\n (ngModelChange)=\"config.autoReload.enabled = $event\">\n <span>\n Auto refresh\n </span>\n </mat-slide-toggle>\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;margin:3px 0}.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"] }]
3443
+ ], 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 || (filtersVisible$ | async)) {\n <div class=\"filter-toolbar\">\n @if ((filtersVisible$ | async)) {\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 <mat-slide-toggle\n name=\"autoReload\"\n class=\"auto-reload\"\n [ngModel]=\"config.autoReload.enabled\"\n (ngModelChange)=\"config.autoReload.enabled = $event\">\n <span>\n Auto refresh\n </span>\n </mat-slide-toggle>\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;margin:3px 0}.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"] }]
3457
3444
  }], ctorParameters: () => [], propDecorators: { keywordInput: [{
3458
3445
  type: ViewChild,
3459
3446
  args: [KeywordInputComponent]