@firestitch/filter 18.2.71 → 18.2.72
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.
- package/app/components/filter-chips/filter-chips.component.d.ts +14 -3
- package/app/helpers/create-filter-item.d.ts +1 -1
- package/app/interfaces/config.interface.d.ts +1 -0
- package/app/interfaces/items/base.interface.d.ts +1 -0
- package/app/models/filter-config.d.ts +1 -0
- package/app/models/items/base-item.d.ts +7 -0
- package/app/services/filter-controller.service.d.ts +1 -2
- package/esm2022/app/components/filter-chips/filter-chips.component.mjs +62 -25
- package/esm2022/app/components/filters-item/select/select.component.mjs +4 -5
- package/esm2022/app/interfaces/config.interface.mjs +1 -1
- package/esm2022/app/interfaces/items/base.interface.mjs +1 -1
- package/esm2022/app/models/filter-config.mjs +3 -1
- package/esm2022/app/models/items/base-item.mjs +29 -4
- package/esm2022/app/services/filter-controller.service.mjs +31 -10
- package/fesm2022/firestitch-filter.mjs +122 -39
- package/fesm2022/firestitch-filter.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Injectable, Directive, Input, TemplateRef, DestroyRef, Component, ChangeDetectionStrategy, InjectionToken, KeyValueDiffers, ChangeDetectorRef, Injector, ViewChild, EventEmitter, NgZone,
|
|
2
|
+
import { inject, Injectable, Directive, Input, TemplateRef, DestroyRef, Component, ChangeDetectionStrategy, InjectionToken, KeyValueDiffers, ChangeDetectorRef, Injector, ViewChild, ElementRef, EventEmitter, NgZone, Output, ContentChild, HostBinding, NgModule } from '@angular/core';
|
|
3
3
|
import { FsMessage } from '@firestitch/message';
|
|
4
4
|
import { FsPrompt } from '@firestitch/prompt';
|
|
5
5
|
import { BehaviorSubject, Subject, of, forkJoin, Observable, tap as tap$1, map as map$1, switchMap as switchMap$1, distinctUntilChanged as distinctUntilChanged$1, merge, filter, takeUntil as takeUntil$1, debounceTime as debounceTime$1, fromEvent, combineLatest, interval } from 'rxjs';
|
|
@@ -50,7 +50,7 @@ import { FsChipModule } from '@firestitch/chip';
|
|
|
50
50
|
import { FsSkeletonModule } from '@firestitch/skeleton';
|
|
51
51
|
import * as i1$4 from '@firestitch/label';
|
|
52
52
|
import { FsLabelModule } from '@firestitch/label';
|
|
53
|
-
import { MatFormField, MatLabel, MatPrefix, MatSuffix
|
|
53
|
+
import { MatFormField, MatLabel, MatPrefix, MatSuffix } from '@angular/material/form-field';
|
|
54
54
|
import { MatCheckbox } from '@angular/material/checkbox';
|
|
55
55
|
|
|
56
56
|
class SavedFilterController {
|
|
@@ -792,6 +792,7 @@ class FsFilterConfig {
|
|
|
792
792
|
namespace; // for persistance
|
|
793
793
|
heading;
|
|
794
794
|
subheading;
|
|
795
|
+
maxEnabled;
|
|
795
796
|
constructor(data = {}) {
|
|
796
797
|
this._init(data);
|
|
797
798
|
}
|
|
@@ -802,6 +803,7 @@ class FsFilterConfig {
|
|
|
802
803
|
savedFilters: data.savedFilters,
|
|
803
804
|
autofocus: data.autofocus ?? false,
|
|
804
805
|
chips: data.chips ?? false,
|
|
806
|
+
maxEnabled: data.maxEnabled ?? 0,
|
|
805
807
|
sort: data.sort,
|
|
806
808
|
queryParam: data.queryParam ?? false,
|
|
807
809
|
init: data.init,
|
|
@@ -1002,6 +1004,7 @@ class BaseItem {
|
|
|
1002
1004
|
persistanceDisabled;
|
|
1003
1005
|
queryParamsDisabled;
|
|
1004
1006
|
primary;
|
|
1007
|
+
secondary;
|
|
1005
1008
|
changeCallback;
|
|
1006
1009
|
initCallback;
|
|
1007
1010
|
_type;
|
|
@@ -1009,12 +1012,25 @@ class BaseItem {
|
|
|
1009
1012
|
_hidden$ = new BehaviorSubject(false);
|
|
1010
1013
|
_value$ = new BehaviorSubject({ value: undefined, emitChange: true });
|
|
1011
1014
|
_values$ = new BehaviorSubject(null);
|
|
1015
|
+
_secondaryVisible$ = new BehaviorSubject(false);
|
|
1012
1016
|
_destroy$ = new Subject();
|
|
1013
1017
|
constructor(itemConfig, _filter) {
|
|
1014
1018
|
this._filter = _filter;
|
|
1015
1019
|
this._type = itemConfig.type;
|
|
1016
1020
|
this._initConfig(itemConfig);
|
|
1017
1021
|
}
|
|
1022
|
+
secondaryShow() {
|
|
1023
|
+
this._secondaryVisible$.next(true);
|
|
1024
|
+
}
|
|
1025
|
+
secondaryHide() {
|
|
1026
|
+
this._secondaryVisible$.next(false);
|
|
1027
|
+
}
|
|
1028
|
+
get secondaryVisible$() {
|
|
1029
|
+
return this._secondaryVisible$.asObservable();
|
|
1030
|
+
}
|
|
1031
|
+
get secondaryVisible() {
|
|
1032
|
+
return this._secondaryVisible$.getValue();
|
|
1033
|
+
}
|
|
1018
1034
|
get filter() {
|
|
1019
1035
|
return this._filter;
|
|
1020
1036
|
}
|
|
@@ -1079,6 +1095,10 @@ class BaseItem {
|
|
|
1079
1095
|
get hasValue() {
|
|
1080
1096
|
return this.value !== null && this.value !== undefined;
|
|
1081
1097
|
}
|
|
1098
|
+
get notValue$() {
|
|
1099
|
+
return this.value$
|
|
1100
|
+
.pipe(map(() => !this.hasValue));
|
|
1101
|
+
}
|
|
1082
1102
|
get hasValue$() {
|
|
1083
1103
|
return this.value$
|
|
1084
1104
|
.pipe(map(() => this.hasValue));
|
|
@@ -1122,9 +1142,15 @@ class BaseItem {
|
|
|
1122
1142
|
return this.query;
|
|
1123
1143
|
}
|
|
1124
1144
|
hide() {
|
|
1145
|
+
if (!this.primary) {
|
|
1146
|
+
this.secondaryHide();
|
|
1147
|
+
}
|
|
1125
1148
|
this._hidden$.next(true);
|
|
1126
1149
|
}
|
|
1127
1150
|
show() {
|
|
1151
|
+
if (!this.primary) {
|
|
1152
|
+
this.secondaryShow();
|
|
1153
|
+
}
|
|
1128
1154
|
this._hidden$.next(false);
|
|
1129
1155
|
}
|
|
1130
1156
|
get query() {
|
|
@@ -1190,12 +1216,13 @@ class BaseItem {
|
|
|
1190
1216
|
}
|
|
1191
1217
|
}
|
|
1192
1218
|
_initConfig(item) {
|
|
1193
|
-
const hidden = item.hide ?? !(item.show ?? true);
|
|
1194
1219
|
this.name = item.name;
|
|
1195
1220
|
this.label = item.label;
|
|
1196
|
-
this.primary = item.primary ?? false;
|
|
1221
|
+
this.primary = this.isTypeKeyword || (item.primary ?? false);
|
|
1222
|
+
this.secondary = item.secondary ?? false;
|
|
1197
1223
|
this.chipLabel = item.chipLabel;
|
|
1198
|
-
this._hidden$.next(
|
|
1224
|
+
this._hidden$.next(item.hide ?? !(item.show ?? true));
|
|
1225
|
+
this._secondaryVisible$.next(item.secondary ?? false);
|
|
1199
1226
|
this.clearable = item.clear ?? true;
|
|
1200
1227
|
this.persistanceDisabled = item.disablePersist ?? false;
|
|
1201
1228
|
this.queryParamsDisabled = item.disableQueryParams ?? false;
|
|
@@ -2260,7 +2287,6 @@ class FilterController {
|
|
|
2260
2287
|
_ready$ = new BehaviorSubject(false);
|
|
2261
2288
|
_items = new Map();
|
|
2262
2289
|
_config;
|
|
2263
|
-
_add$ = new Subject();
|
|
2264
2290
|
_init$ = new Subject();
|
|
2265
2291
|
_change$ = new Subject();
|
|
2266
2292
|
_destroy$ = new Subject();
|
|
@@ -2281,9 +2307,6 @@ class FilterController {
|
|
|
2281
2307
|
get init$() {
|
|
2282
2308
|
return this._init$.asObservable();
|
|
2283
2309
|
}
|
|
2284
|
-
get add$() {
|
|
2285
|
-
return this._add$.asObservable();
|
|
2286
|
-
}
|
|
2287
2310
|
get change$() {
|
|
2288
2311
|
return this._change$
|
|
2289
2312
|
.pipe(debounceTime(30));
|
|
@@ -2404,13 +2427,38 @@ class FilterController {
|
|
|
2404
2427
|
.map((item) => {
|
|
2405
2428
|
return item.init(values[item.name]);
|
|
2406
2429
|
}))
|
|
2407
|
-
.pipe(tap(() =>
|
|
2430
|
+
.pipe(tap(() => {
|
|
2431
|
+
this._initEnabledItems();
|
|
2432
|
+
}), tap(() => this.items
|
|
2433
|
+
.forEach((item) => {
|
|
2408
2434
|
item.initCallback(item, this.filter);
|
|
2409
2435
|
})));
|
|
2410
2436
|
}
|
|
2437
|
+
_initEnabledItems() {
|
|
2438
|
+
let enabled = 0;
|
|
2439
|
+
this.items
|
|
2440
|
+
.forEach((item) => {
|
|
2441
|
+
if (!item.primary) {
|
|
2442
|
+
if (item.hasValue) {
|
|
2443
|
+
item.secondaryShow();
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
});
|
|
2447
|
+
this.items
|
|
2448
|
+
.forEach((item) => {
|
|
2449
|
+
if (!item.primary) {
|
|
2450
|
+
if (item.secondaryVisible) {
|
|
2451
|
+
enabled++;
|
|
2452
|
+
}
|
|
2453
|
+
else if (enabled < this._config.maxEnabled) {
|
|
2454
|
+
item.secondaryShow();
|
|
2455
|
+
enabled++;
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
});
|
|
2459
|
+
}
|
|
2411
2460
|
_addItems(items) {
|
|
2412
|
-
|
|
2413
|
-
this._items = new Map(items
|
|
2461
|
+
const itemMap = items
|
|
2414
2462
|
.filter((item) => {
|
|
2415
2463
|
if (this._items.has(item.name)) {
|
|
2416
2464
|
throw Error('Filter init error. Items name must be unique.');
|
|
@@ -2422,9 +2470,9 @@ class FilterController {
|
|
|
2422
2470
|
if (filterItem instanceof KeywordItem) {
|
|
2423
2471
|
this._keywordController.keywordItem = filterItem;
|
|
2424
2472
|
}
|
|
2425
|
-
this._items.set(item.name, filterItem);
|
|
2426
2473
|
return [item.name, filterItem];
|
|
2427
|
-
})
|
|
2474
|
+
});
|
|
2475
|
+
this._items = new Map(itemMap);
|
|
2428
2476
|
}
|
|
2429
2477
|
_initChanges() {
|
|
2430
2478
|
merge(...this.items
|
|
@@ -2948,7 +2996,7 @@ class SelectComponent {
|
|
|
2948
2996
|
}
|
|
2949
2997
|
}
|
|
2950
2998
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2951
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectComponent, isStandalone: true, selector: "filter-item-select", inputs: { autofocus: "autofocus", floatLabel: "floatLabel", item: "item" }, viewQueries: [{ propertyName: "select", first: true, predicate: MatSelect, descendants: true, static: true }], ngImport: i0, template: "<mat-form-field\n [ngClass]=\"{ isolate: item.isolate }\"\n [floatLabel]=\"floatLabel\"\n class=\"form-field-padless\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n [fsFilterFocusTrigger]=\"autofocus\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"changed()\"\n [multiple]=\"item.multiple\">\n @if (item.children) {\n @for (option of item.values$ | async; track option) {\n @if (option[item.children]) {\n <mat-optgroup [label]=\"option.name\">\n @for (childOption of option[item.children]; track childOption.value) {\n <mat-option [value]=\"childOption.value\">\n {{ childOption.name }}\n </mat-option>\n }\n </mat-optgroup>\n } @else {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n }\n } @else {\n @for (option of item.values$ | async; track option) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n }\n </mat-select>\n
|
|
2999
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectComponent, isStandalone: true, selector: "filter-item-select", inputs: { autofocus: "autofocus", floatLabel: "floatLabel", item: "item" }, viewQueries: [{ propertyName: "select", first: true, predicate: MatSelect, descendants: true, static: true }], ngImport: i0, template: "<mat-form-field\n [ngClass]=\"{ isolate: item.isolate }\"\n [floatLabel]=\"floatLabel\"\n class=\"form-field-padless\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n [fsFilterFocusTrigger]=\"autofocus && !item.isolate\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"changed()\"\n [multiple]=\"item.multiple\">\n @if (item.children) {\n @for (option of item.values$ | async; track option) {\n @if (option[item.children]) {\n <mat-optgroup [label]=\"option.name\">\n @for (childOption of option[item.children]; track childOption.value) {\n <mat-option [value]=\"childOption.value\">\n {{ childOption.name }}\n </mat-option>\n }\n </mat-optgroup>\n } @else {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n }\n } @else {\n @for (option of item.values$ | async; track option) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n }\n </mat-select>\n</mat-form-field>\n@if (item.isolate) {\n <div class=\"isolate-checkbox\">\n <mat-checkbox\n (change)=\"isolateChange($event)\"\n [(ngModel)]=\"item.isolated\">\n <span class=\"checkbox-label\">\n {{ item.isolateLabel }}\n </span>\n </mat-checkbox>\n </div>\n}", styles: [":host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper{padding-left:0;padding-right:0;padding-top:8px}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field{position:relative}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-checkbox{position:absolute}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-label{margin-left:32px;font-size:smaller;line-height:normal}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: FocusToItemDirective, selector: "[fsFilterFocusTrigger]", inputs: ["fsFilterFocusTrigger"] }, { 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: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2952
3000
|
}
|
|
2953
3001
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectComponent, decorators: [{
|
|
2954
3002
|
type: Component,
|
|
@@ -2962,10 +3010,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
2962
3010
|
FsFormModule,
|
|
2963
3011
|
MatOption,
|
|
2964
3012
|
MatOptgroup,
|
|
2965
|
-
MatHint,
|
|
2966
3013
|
MatCheckbox,
|
|
2967
3014
|
AsyncPipe,
|
|
2968
|
-
], template: "<mat-form-field\n [ngClass]=\"{ isolate: item.isolate }\"\n [floatLabel]=\"floatLabel\"\n class=\"form-field-padless\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n [fsFilterFocusTrigger]=\"autofocus\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"changed()\"\n [multiple]=\"item.multiple\">\n @if (item.children) {\n @for (option of item.values$ | async; track option) {\n @if (option[item.children]) {\n <mat-optgroup [label]=\"option.name\">\n @for (childOption of option[item.children]; track childOption.value) {\n <mat-option [value]=\"childOption.value\">\n {{ childOption.name }}\n </mat-option>\n }\n </mat-optgroup>\n } @else {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n }\n } @else {\n @for (option of item.values$ | async; track option) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n }\n </mat-select>\n
|
|
3015
|
+
], template: "<mat-form-field\n [ngClass]=\"{ isolate: item.isolate }\"\n [floatLabel]=\"floatLabel\"\n class=\"form-field-padless\">\n <mat-label>\n {{ item.label }}\n </mat-label>\n <mat-select\n [fsFilterFocusTrigger]=\"autofocus && !item.isolate\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"changed()\"\n [multiple]=\"item.multiple\">\n @if (item.children) {\n @for (option of item.values$ | async; track option) {\n @if (option[item.children]) {\n <mat-optgroup [label]=\"option.name\">\n @for (childOption of option[item.children]; track childOption.value) {\n <mat-option [value]=\"childOption.value\">\n {{ childOption.name }}\n </mat-option>\n }\n </mat-optgroup>\n } @else {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n }\n } @else {\n @for (option of item.values$ | async; track option) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n }\n </mat-select>\n</mat-form-field>\n@if (item.isolate) {\n <div class=\"isolate-checkbox\">\n <mat-checkbox\n (change)=\"isolateChange($event)\"\n [(ngModel)]=\"item.isolated\">\n <span class=\"checkbox-label\">\n {{ item.isolateLabel }}\n </span>\n </mat-checkbox>\n </div>\n}", styles: [":host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper{padding-left:0;padding-right:0;padding-top:8px}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field{position:relative}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-checkbox{position:absolute}:host ::ng-deep .isolate .mat-mdc-form-field-hint-wrapper mat-hint .mat-internal-form-field .mdc-label{margin-left:32px;font-size:smaller;line-height:normal}\n"] }]
|
|
2969
3016
|
}], propDecorators: { autofocus: [{
|
|
2970
3017
|
type: Input
|
|
2971
3018
|
}], floatLabel: [{
|
|
@@ -3239,6 +3286,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
3239
3286
|
|
|
3240
3287
|
class FsFilterChipsComponent {
|
|
3241
3288
|
ItemType = ItemType;
|
|
3289
|
+
secondaryItems = [];
|
|
3242
3290
|
_filterController = inject(FilterController);
|
|
3243
3291
|
_dialog = inject(MatDialog);
|
|
3244
3292
|
_message = inject(FsMessage);
|
|
@@ -3246,45 +3294,54 @@ class FsFilterChipsComponent {
|
|
|
3246
3294
|
_injector = inject(Injector);
|
|
3247
3295
|
_overlay = inject(Overlay);
|
|
3248
3296
|
_overlayRef;
|
|
3297
|
+
_destroyRef = inject(DestroyRef);
|
|
3298
|
+
_elementRef = inject(ElementRef);
|
|
3299
|
+
_hasSecondaryValue$ = new BehaviorSubject(false);
|
|
3249
3300
|
get items() {
|
|
3250
3301
|
return this._filterController.items
|
|
3251
3302
|
.filter((item) => !item.isTypeKeyword);
|
|
3252
3303
|
}
|
|
3253
|
-
|
|
3304
|
+
addFilter(event) {
|
|
3305
|
+
const item = event.value;
|
|
3306
|
+
item.secondaryShow();
|
|
3307
|
+
setTimeout(() => {
|
|
3308
|
+
this.openChip(item);
|
|
3309
|
+
});
|
|
3310
|
+
}
|
|
3311
|
+
get disabledItems() {
|
|
3254
3312
|
return this.items
|
|
3255
|
-
.filter((item) => !item.primary)
|
|
3256
|
-
|
|
3313
|
+
.filter((item) => !item.secondaryVisible && !item.hasValue && !item.primary);
|
|
3314
|
+
}
|
|
3315
|
+
get hasSecondaryValue$() {
|
|
3316
|
+
return this._hasSecondaryValue$.asObservable();
|
|
3257
3317
|
}
|
|
3258
3318
|
get savedFilterController() {
|
|
3259
3319
|
return this._savedFilterController;
|
|
3260
3320
|
}
|
|
3321
|
+
get hasSecondaryValue() {
|
|
3322
|
+
return this._filterController.items
|
|
3323
|
+
.some((item) => item.hasValue && item.visible && !item.primary);
|
|
3324
|
+
}
|
|
3261
3325
|
ngOnInit() {
|
|
3262
|
-
|
|
3263
|
-
.
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
return !!this.getNestedElement(element, 'cdk-overlay-pane');
|
|
3267
|
-
});
|
|
3268
|
-
const item2 = elements.some((element) => {
|
|
3269
|
-
return !!this.getNestedElement(element, 'filter-chip');
|
|
3270
|
-
});
|
|
3271
|
-
if (!item1 && !item2) {
|
|
3272
|
-
this._destroyOverlay();
|
|
3273
|
-
}
|
|
3274
|
-
});
|
|
3326
|
+
this.secondaryItems = this.items
|
|
3327
|
+
.filter((item) => !item.primary);
|
|
3328
|
+
this._initHasSecondaryValue();
|
|
3329
|
+
this._initChipClick();
|
|
3275
3330
|
}
|
|
3276
3331
|
clear() {
|
|
3277
3332
|
this.items
|
|
3278
3333
|
.filter((item) => item.clearable)
|
|
3279
3334
|
.forEach((item) => {
|
|
3335
|
+
if (!item.secondary) {
|
|
3336
|
+
item.secondaryHide();
|
|
3337
|
+
}
|
|
3280
3338
|
item.clear(false);
|
|
3281
3339
|
});
|
|
3282
3340
|
this._filterController.change();
|
|
3283
|
-
this._savedFilterController.setActiveFilter(null);
|
|
3284
3341
|
}
|
|
3285
|
-
|
|
3342
|
+
openChip(item, name = null) {
|
|
3286
3343
|
this._destroyOverlay();
|
|
3287
|
-
el = this.
|
|
3344
|
+
const el = this._elementRef.nativeElement.querySelector(`[data-filter-item="${item.name}"]`);
|
|
3288
3345
|
const positions = [
|
|
3289
3346
|
{
|
|
3290
3347
|
originX: 'start',
|
|
@@ -3365,7 +3422,10 @@ class FsFilterChipsComponent {
|
|
|
3365
3422
|
this._overlayRef.dispose();
|
|
3366
3423
|
}
|
|
3367
3424
|
}
|
|
3368
|
-
|
|
3425
|
+
removeChip(item, chip) {
|
|
3426
|
+
if (!item.secondary) {
|
|
3427
|
+
item.secondaryHide();
|
|
3428
|
+
}
|
|
3369
3429
|
if (chip.name) {
|
|
3370
3430
|
item.clearByName(chip.name);
|
|
3371
3431
|
}
|
|
@@ -3388,8 +3448,31 @@ class FsFilterChipsComponent {
|
|
|
3388
3448
|
parent: this._injector,
|
|
3389
3449
|
});
|
|
3390
3450
|
}
|
|
3451
|
+
_initChipClick() {
|
|
3452
|
+
fromEvent(document, 'click')
|
|
3453
|
+
.subscribe((event) => {
|
|
3454
|
+
const elements = document.elementsFromPoint(event.clientX, event.clientY);
|
|
3455
|
+
const item1 = elements.some((element) => {
|
|
3456
|
+
return !!this.getNestedElement(element, 'cdk-overlay-pane');
|
|
3457
|
+
});
|
|
3458
|
+
const item2 = elements.some((element) => {
|
|
3459
|
+
return !!this.getNestedElement(element, 'filter-chip');
|
|
3460
|
+
});
|
|
3461
|
+
if (!item1 && !item2) {
|
|
3462
|
+
this._destroyOverlay();
|
|
3463
|
+
}
|
|
3464
|
+
});
|
|
3465
|
+
}
|
|
3466
|
+
_initHasSecondaryValue() {
|
|
3467
|
+
this._hasSecondaryValue$.next(this.hasSecondaryValue);
|
|
3468
|
+
this._filterController.change$
|
|
3469
|
+
.pipe(tap$1(() => {
|
|
3470
|
+
this._hasSecondaryValue$.next(this.hasSecondaryValue);
|
|
3471
|
+
}), takeUntilDestroyed(this._destroyRef))
|
|
3472
|
+
.subscribe();
|
|
3473
|
+
}
|
|
3391
3474
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3392
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsFilterChipsComponent, isStandalone: true, selector: "fs-filter-chips", ngImport: i0, template: "@if (items.length !== 0) {\n @for (item of
|
|
3475
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FsFilterChipsComponent, isStandalone: true, selector: "fs-filter-chips", ngImport: i0, template: "@if (items.length !== 0) {\n @for (item of secondaryItems; track item.name) {\n @if ((item.visible$ | async) && (item.hasValue$ | async)) {\n @for (chip of item.chips$ | async; track chip.label) {\n <fs-chip\n class=\"filter-chip selected\"\n [size]=\"'medium'\"\n [attr.data-filter-item]=\"item.name\"\n (click)=\"openChip(item, chip.name)\">\n @if (chip.value) {\n {{ chip.label + ': ' + chip.value }}\n } @else {\n {{ chip.label }}\n }\n <ng-template\n fsChipSuffix\n [icon]=\"'cancel_circle_outline'\"\n (click)=\"removeChip(item, chip)\">\n </ng-template>\n </fs-chip>\n }\n }\n }\n @for (item of secondaryItems; track item.name) {\n @if ((item.visible$ | async) && (item.notValue$ | async) && (item.secondaryVisible$ | async)) {\n <fs-chip\n class=\"filter-chip\"\n [attr.data-filter-item]=\"item.name\"\n [size]=\"'medium'\"\n (click)=\"openChip(item)\"\n [outlined]=\"true\">\n {{ item.mergedLabel }}\n <ng-template\n fsChipSuffix\n [icon]=\"'add_circle_outline'\"\n (click)=\"openChip(item)\">\n </ng-template>\n </fs-chip>\n }\n }\n <mat-select\n class=\"more-filters-select mat-mdc-outlined-button\"\n [buttonType]=\"'basic'\"\n fsSelectButton\n [placeholder]=\"'More filters'\"\n (selectionChange)=\"addFilter($event)\"\n [deselectOnChange]=\"true\">\n @for (item of disabledItems; track item.name) {\n <mat-option [value]=\"item\">\n {{ item.mergedLabel }}\n </mat-option>\n }\n </mat-select>\n @if (hasSecondaryValue$ | async) {\n <a\n class=\"clear\"\n mat-stroked-button\n (click)=\"clear()\">\n Clear filters\n </a>\n }\n <mat-select\n class=\"saved-filters-select mat-mdc-outlined-button\"\n [buttonType]=\"'basic'\"\n fsSelectButton\n [placeholder]=\"(savedFilterController.activeFilter$ | async) ? savedFilterController.singularLabel + ': ' + (savedFilterController.activeFilter$ | async).name : savedFilterController.pluralLabel\"\n [deselectOnChange]=\"true\">\n @if (savedFilterController.activeFilter$ | async) {\n <mat-option (click)=\"saveActiveFilter()\">\n Update filters\n </mat-option>\n <mat-option (click)=\"saveAs()\">\n Save as new\n </mat-option>\n } @else {\n <mat-option (click)=\"createSavedFilter()\">\n Create new\n </mat-option>\n }\n <mat-option (click)=\"manageSavedFilters()\">\n View all\n </mat-option>\n </mat-select>\n}", styles: [":host{display:flex;flex-wrap:wrap;align-items:center;gap:5px;max-width:100%;margin-top:4px}.saved-filters-select,.more-filters-select,.clear{display:flex;color:inherit;height:30px}.saved-filters-select.clear,.more-filters-select.clear,.clear.clear{padding:0 10px}.saved-filters-select ::ng-deep .mat-mdc-select-value,.more-filters-select ::ng-deep .mat-mdc-select-value,.clear ::ng-deep .mat-mdc-select-value{padding:0 10px}.saved-filters-select ::ng-deep .mat-mdc-select-arrow-wrapper,.more-filters-select ::ng-deep .mat-mdc-select-arrow-wrapper,.clear ::ng-deep .mat-mdc-select-arrow-wrapper{padding-right:10px}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: FsChipModule }, { kind: "component", type: i1$5.FsChipComponent, selector: "fs-chip", inputs: ["selectable", "removable", "value", "maxWidth", "width", "backgroundColor", "borderColor", "color", "shape", "outlined", "outlineDash", "icon", "image", "selected", "padding", "contrastColor", "size"], outputs: ["selectedToggled", "removed", "click"] }, { kind: "directive", type: i1$5.FsChipSuffixDirective, selector: "[fsChipSuffix]", inputs: ["icon", "link", "linkTarget", "color", "data", "tooltip"], outputs: ["click"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption$1, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: FsSelectButtonModule }, { kind: "directive", type: i3$1.FsSelectButtonDirective, selector: "[fsSelectButton]", inputs: ["color", "minWidth", "maxWidth", "width", "buttonType", "deselectOnChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$2.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: FsButtonDirective, selector: "[mat-raised-button],[mat-button],[mat-flat-button],[mat-stroked-button]", inputs: ["name", "dirtySubmit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3393
3476
|
}
|
|
3394
3477
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FsFilterChipsComponent, decorators: [{
|
|
3395
3478
|
type: Component,
|
|
@@ -3401,7 +3484,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
3401
3484
|
FsSelectButtonModule,
|
|
3402
3485
|
MatButtonModule,
|
|
3403
3486
|
FsButtonDirective,
|
|
3404
|
-
], template: "@if (items.length !== 0) {\n @for (item of
|
|
3487
|
+
], template: "@if (items.length !== 0) {\n @for (item of secondaryItems; track item.name) {\n @if ((item.visible$ | async) && (item.hasValue$ | async)) {\n @for (chip of item.chips$ | async; track chip.label) {\n <fs-chip\n class=\"filter-chip selected\"\n [size]=\"'medium'\"\n [attr.data-filter-item]=\"item.name\"\n (click)=\"openChip(item, chip.name)\">\n @if (chip.value) {\n {{ chip.label + ': ' + chip.value }}\n } @else {\n {{ chip.label }}\n }\n <ng-template\n fsChipSuffix\n [icon]=\"'cancel_circle_outline'\"\n (click)=\"removeChip(item, chip)\">\n </ng-template>\n </fs-chip>\n }\n }\n }\n @for (item of secondaryItems; track item.name) {\n @if ((item.visible$ | async) && (item.notValue$ | async) && (item.secondaryVisible$ | async)) {\n <fs-chip\n class=\"filter-chip\"\n [attr.data-filter-item]=\"item.name\"\n [size]=\"'medium'\"\n (click)=\"openChip(item)\"\n [outlined]=\"true\">\n {{ item.mergedLabel }}\n <ng-template\n fsChipSuffix\n [icon]=\"'add_circle_outline'\"\n (click)=\"openChip(item)\">\n </ng-template>\n </fs-chip>\n }\n }\n <mat-select\n class=\"more-filters-select mat-mdc-outlined-button\"\n [buttonType]=\"'basic'\"\n fsSelectButton\n [placeholder]=\"'More filters'\"\n (selectionChange)=\"addFilter($event)\"\n [deselectOnChange]=\"true\">\n @for (item of disabledItems; track item.name) {\n <mat-option [value]=\"item\">\n {{ item.mergedLabel }}\n </mat-option>\n }\n </mat-select>\n @if (hasSecondaryValue$ | async) {\n <a\n class=\"clear\"\n mat-stroked-button\n (click)=\"clear()\">\n Clear filters\n </a>\n }\n <mat-select\n class=\"saved-filters-select mat-mdc-outlined-button\"\n [buttonType]=\"'basic'\"\n fsSelectButton\n [placeholder]=\"(savedFilterController.activeFilter$ | async) ? savedFilterController.singularLabel + ': ' + (savedFilterController.activeFilter$ | async).name : savedFilterController.pluralLabel\"\n [deselectOnChange]=\"true\">\n @if (savedFilterController.activeFilter$ | async) {\n <mat-option (click)=\"saveActiveFilter()\">\n Update filters\n </mat-option>\n <mat-option (click)=\"saveAs()\">\n Save as new\n </mat-option>\n } @else {\n <mat-option (click)=\"createSavedFilter()\">\n Create new\n </mat-option>\n }\n <mat-option (click)=\"manageSavedFilters()\">\n View all\n </mat-option>\n </mat-select>\n}", styles: [":host{display:flex;flex-wrap:wrap;align-items:center;gap:5px;max-width:100%;margin-top:4px}.saved-filters-select,.more-filters-select,.clear{display:flex;color:inherit;height:30px}.saved-filters-select.clear,.more-filters-select.clear,.clear.clear{padding:0 10px}.saved-filters-select ::ng-deep .mat-mdc-select-value,.more-filters-select ::ng-deep .mat-mdc-select-value,.clear ::ng-deep .mat-mdc-select-value{padding:0 10px}.saved-filters-select ::ng-deep .mat-mdc-select-arrow-wrapper,.more-filters-select ::ng-deep .mat-mdc-select-arrow-wrapper,.clear ::ng-deep .mat-mdc-select-arrow-wrapper{padding-right:10px}\n"] }]
|
|
3405
3488
|
}] });
|
|
3406
3489
|
|
|
3407
3490
|
class KeywordInputComponent {
|