@recursyve/nice-data-filter-kit 14.3.0 → 14.3.2

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 (33) hide show
  1. package/esm2020/lib/components/nice-filter-view/components/advanced-filters/advanced-filters.component.mjs +19 -3
  2. package/esm2020/lib/components/nice-filter-view/components/advanced-filters/advanced-filters.form.mjs +4 -10
  3. package/esm2020/lib/components/nice-filter-view/components/advanced-filters/advanced-filters.module.mjs +8 -5
  4. package/esm2020/lib/components/nice-filter-view/components/advanced-filters/button/advanced-filters-button.component.mjs +6 -6
  5. package/esm2020/lib/components/nice-filter-view/components/advanced-filters/models/icons.model.mjs +4 -1
  6. package/esm2020/lib/components/nice-filter-view/components/advanced-filters/providers/async-typeahead.provider.mjs +32 -0
  7. package/esm2020/lib/components/nice-filter-view/components/advanced-filters/rule/components/select/select-filter.component.mjs +12 -43
  8. package/esm2020/lib/components/nice-filter-view/components/export-buttons/export-buttons.component.mjs +10 -7
  9. package/esm2020/lib/components/nice-filter-view/directives/query-params.directive.mjs +17 -10
  10. package/esm2020/lib/components/nice-filter-view/nice-base-filter-view.component.mjs +46 -12
  11. package/esm2020/lib/directive/selectable-list/providers/selectable-list-content.service.mjs +11 -1
  12. package/esm2020/lib/directive/selectable-list/selectable-list-checkbox.directive.mjs +10 -2
  13. package/esm2020/lib/directive/selectable-list/selectable-list.directive.mjs +55 -12
  14. package/esm2020/lib/directive/selectable-list/store/selectable-list-state.service.mjs +45 -16
  15. package/esm2020/lib/directive/selectable-list/store/selectable-list.service.mjs +10 -6
  16. package/fesm2015/recursyve-nice-data-filter-kit.mjs +251 -112
  17. package/fesm2015/recursyve-nice-data-filter-kit.mjs.map +1 -1
  18. package/fesm2020/recursyve-nice-data-filter-kit.mjs +246 -108
  19. package/fesm2020/recursyve-nice-data-filter-kit.mjs.map +1 -1
  20. package/lib/components/nice-filter-view/components/advanced-filters/advanced-filters.form.d.ts +0 -1
  21. package/lib/components/nice-filter-view/components/advanced-filters/advanced-filters.module.d.ts +1 -1
  22. package/lib/components/nice-filter-view/components/advanced-filters/button/advanced-filters-button.component.d.ts +3 -3
  23. package/lib/components/nice-filter-view/components/advanced-filters/models/icons.model.d.ts +1 -0
  24. package/lib/components/nice-filter-view/components/advanced-filters/providers/async-typeahead.provider.d.ts +18 -0
  25. package/lib/components/nice-filter-view/components/advanced-filters/rule/components/select/select-filter.component.d.ts +3 -11
  26. package/lib/components/nice-filter-view/components/export-buttons/export-buttons.component.d.ts +2 -1
  27. package/lib/components/nice-filter-view/directives/query-params.directive.d.ts +2 -1
  28. package/lib/components/nice-filter-view/nice-base-filter-view.component.d.ts +7 -0
  29. package/lib/directive/selectable-list/providers/selectable-list-content.service.d.ts +5 -0
  30. package/lib/directive/selectable-list/selectable-list.directive.d.ts +13 -4
  31. package/lib/directive/selectable-list/store/selectable-list-state.service.d.ts +12 -2
  32. package/lib/directive/selectable-list/store/selectable-list.service.d.ts +5 -2
  33. package/package.json +1 -1
@@ -2,11 +2,11 @@ import { plainToInstance } from 'class-transformer';
2
2
  import { map, takeUntil, debounceTime, switchMap, distinctUntilChanged } from 'rxjs/operators';
3
3
  import { HttpParams } from '@angular/common/http';
4
4
  import * as i5 from '@recursyve/nice-ui-kit.v2';
5
- import { isNullOrUndefined, ObjectUtils, FileUtils, ArrayUtils, ExportBottomSheetComponent, NiceLoadingSpinnerModule, NiceTypeaheadModule, NiceExportBottomSheetModule } from '@recursyve/nice-ui-kit.v2';
5
+ import { isNullOrUndefined, ObjectUtils, FileUtils, ArrayUtils, ExportBottomSheetComponent, NiceLoadingSpinnerModule, NiceTypeaheadModule, NiceExportBottomSheetModule, NiceAsyncTypeaheadProvider, NICE_ASYNC_TYPEAHEAD_PROVIDER, NiceAsyncTypeaheadModule } from '@recursyve/nice-ui-kit.v2';
6
6
  import * as i0 from '@angular/core';
7
7
  import { Directive, Input, NgModule, Injectable, Inject, InjectionToken, Optional, Pipe, EventEmitter, Component, ViewEncapsulation, ChangeDetectionStrategy, Output, HostListener, forwardRef, TemplateRef, ContentChild, ContentChildren, ViewChild, QueryList } from '@angular/core';
8
8
  import { Store, StoreConfig, Query, arrayAdd, arrayUpsert, arrayRemove, EntityStore, QueryEntity, EntityActions } from '@datorama/akita';
9
- import { combineLatest, Subject, firstValueFrom, of, startWith, tap } from 'rxjs';
9
+ import { combineLatest, Subject, firstValueFrom, of, lastValueFrom, startWith, tap, distinct, take } from 'rxjs';
10
10
  import { __decorate, __metadata } from 'tslib';
11
11
  import * as i2 from '@angular/router';
12
12
  import { RouterModule } from '@angular/router';
@@ -3219,6 +3219,8 @@ AdvancedFiltersUtils.doubleInputOperators = [
3219
3219
  FilterOperatorTypes.NotBetween
3220
3220
  ];
3221
3221
 
3222
+ const ADVANCED_FILTER_ICONS = new InjectionToken("advanced_filter_icons");
3223
+
3222
3224
  class NiceFilterGroupIconPipe {
3223
3225
  constructor(service) {
3224
3226
  this.service = service;
@@ -3371,20 +3373,18 @@ class NiceAdvancedFiltersButtonComponent {
3371
3373
  this.service.updateSubState("showAdvancedFilters", true);
3372
3374
  }
3373
3375
  }
3374
- NiceAdvancedFiltersButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedFiltersButtonComponent, deps: [{ token: FILTER_VIEW_ICONS, optional: true }, { token: NiceFilterViewQuery }, { token: NiceFilterViewService }], target: i0.ɵɵFactoryTarget.Component });
3375
- NiceAdvancedFiltersButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceAdvancedFiltersButtonComponent, selector: "nice-advanced-filters-button", ngImport: i0, template: "<div class=\"relative\">\n <ng-container *ngIf=\"(hasParameters$ | async) && (shouldShowAdvancedFilters$ | async) !== true\">\n <div class=\"absolute top-2 right-2 w-1 h-1 rounded bg-accent\"></div>\n\n <button mat-icon-button (click)=\"clickToggleShowAdvancedFilters()\">\n <mat-icon [svgIcon]=\"icons.queryBuilder.svgIcon\">{{ icons.queryBuilder.matIcon }}</mat-icon>\n </button>\n </ng-container>\n\n <ng-container *ngIf=\"shouldShowAdvancedFilters$ | async\">\n <button mat-icon-button (click)=\"clickToggleShowAdvancedFilters()\">\n <mat-icon [svgIcon]=\"icons.close.svgIcon\">{{ icons.close.matIcon }}</mat-icon>\n </button>\n </ng-container>\n\n <ng-container *ngIf=\"(hasParameters$ | async) !== true && (shouldShowAdvancedFilters$ | async) !== true\">\n <button mat-icon-button niceAdvancedFiltersTrigger (advancedFilterSelected)=\"onSelectedFilter($event)\">\n <mat-icon>filter_list</mat-icon>\n </button>\n </ng-container>\n</div>\n", styles: ["nice-advanced-filters-button{width:40px;height:40px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i8.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: AdvancedFiltersTriggerDirective, selector: "[niceAdvancedFiltersTrigger]", inputs: ["position"], outputs: ["advancedFilterSelected"], exportAs: ["niceAdvancedFiltersTrigger"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3376
+ NiceAdvancedFiltersButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedFiltersButtonComponent, deps: [{ token: ADVANCED_FILTER_ICONS, optional: true }, { token: NiceFilterViewQuery }, { token: NiceFilterViewService }], target: i0.ɵɵFactoryTarget.Component });
3377
+ NiceAdvancedFiltersButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceAdvancedFiltersButtonComponent, selector: "nice-advanced-filters-button", ngImport: i0, template: "<div class=\"relative\">\n <ng-container *ngIf=\"(hasParameters$ | async) && (shouldShowAdvancedFilters$ | async) !== true\">\n <div class=\"absolute top-2 right-2 w-1 h-1 rounded bg-accent\"></div>\n\n <button mat-icon-button (click)=\"clickToggleShowAdvancedFilters()\">\n <mat-icon [svgIcon]=\"icons.queryBuilder.svgIcon\">{{ icons.queryBuilder.matIcon }}</mat-icon>\n </button>\n </ng-container>\n\n <ng-container *ngIf=\"shouldShowAdvancedFilters$ | async\">\n <button mat-icon-button (click)=\"clickToggleShowAdvancedFilters()\">\n <mat-icon [svgIcon]=\"icons.close.svgIcon\">{{ icons.close.matIcon }}</mat-icon>\n </button>\n </ng-container>\n\n <ng-container *ngIf=\"(hasParameters$ | async) !== true && (shouldShowAdvancedFilters$ | async) !== true\">\n <button mat-icon-button niceAdvancedFiltersTrigger (advancedFilterSelected)=\"onSelectedFilter($event)\">\n <mat-icon [svgIcon]=\"icons.queryBuilder.svgIcon\">{{ icons.queryBuilder.matIcon }}</mat-icon>\n </button>\n </ng-container>\n</div>\n", styles: ["nice-advanced-filters-button{width:40px;height:40px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i8.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: AdvancedFiltersTriggerDirective, selector: "[niceAdvancedFiltersTrigger]", inputs: ["position"], outputs: ["advancedFilterSelected"], exportAs: ["niceAdvancedFiltersTrigger"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3376
3378
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedFiltersButtonComponent, decorators: [{
3377
3379
  type: Component,
3378
- args: [{ selector: "nice-advanced-filters-button", encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative\">\n <ng-container *ngIf=\"(hasParameters$ | async) && (shouldShowAdvancedFilters$ | async) !== true\">\n <div class=\"absolute top-2 right-2 w-1 h-1 rounded bg-accent\"></div>\n\n <button mat-icon-button (click)=\"clickToggleShowAdvancedFilters()\">\n <mat-icon [svgIcon]=\"icons.queryBuilder.svgIcon\">{{ icons.queryBuilder.matIcon }}</mat-icon>\n </button>\n </ng-container>\n\n <ng-container *ngIf=\"shouldShowAdvancedFilters$ | async\">\n <button mat-icon-button (click)=\"clickToggleShowAdvancedFilters()\">\n <mat-icon [svgIcon]=\"icons.close.svgIcon\">{{ icons.close.matIcon }}</mat-icon>\n </button>\n </ng-container>\n\n <ng-container *ngIf=\"(hasParameters$ | async) !== true && (shouldShowAdvancedFilters$ | async) !== true\">\n <button mat-icon-button niceAdvancedFiltersTrigger (advancedFilterSelected)=\"onSelectedFilter($event)\">\n <mat-icon>filter_list</mat-icon>\n </button>\n </ng-container>\n</div>\n", styles: ["nice-advanced-filters-button{width:40px;height:40px}\n"] }]
3380
+ args: [{ selector: "nice-advanced-filters-button", encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative\">\n <ng-container *ngIf=\"(hasParameters$ | async) && (shouldShowAdvancedFilters$ | async) !== true\">\n <div class=\"absolute top-2 right-2 w-1 h-1 rounded bg-accent\"></div>\n\n <button mat-icon-button (click)=\"clickToggleShowAdvancedFilters()\">\n <mat-icon [svgIcon]=\"icons.queryBuilder.svgIcon\">{{ icons.queryBuilder.matIcon }}</mat-icon>\n </button>\n </ng-container>\n\n <ng-container *ngIf=\"shouldShowAdvancedFilters$ | async\">\n <button mat-icon-button (click)=\"clickToggleShowAdvancedFilters()\">\n <mat-icon [svgIcon]=\"icons.close.svgIcon\">{{ icons.close.matIcon }}</mat-icon>\n </button>\n </ng-container>\n\n <ng-container *ngIf=\"(hasParameters$ | async) !== true && (shouldShowAdvancedFilters$ | async) !== true\">\n <button mat-icon-button niceAdvancedFiltersTrigger (advancedFilterSelected)=\"onSelectedFilter($event)\">\n <mat-icon [svgIcon]=\"icons.queryBuilder.svgIcon\">{{ icons.queryBuilder.matIcon }}</mat-icon>\n </button>\n </ng-container>\n</div>\n", styles: ["nice-advanced-filters-button{width:40px;height:40px}\n"] }]
3379
3381
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
3380
3382
  type: Optional
3381
3383
  }, {
3382
3384
  type: Inject,
3383
- args: [FILTER_VIEW_ICONS]
3385
+ args: [ADVANCED_FILTER_ICONS]
3384
3386
  }] }, { type: NiceFilterViewQuery }, { type: NiceFilterViewService }]; } });
3385
3387
 
3386
- const ADVANCED_FILTER_ICONS = new InjectionToken("advanced_filter_icons");
3387
-
3388
3388
  class FilterFormValues {
3389
3389
  }
3390
3390
  __decorate([
@@ -3394,7 +3394,7 @@ __decorate([
3394
3394
  ], FilterFormValues.prototype, "value", void 0);
3395
3395
  __decorate([
3396
3396
  Control(),
3397
- AddValidatorIf(({ parent }) => parent.needsTwoValues, Validators.required),
3397
+ AddValidatorIf(({ parent }) => QBFilterUtils.isDoubleInput(parent.operation), Validators.required),
3398
3398
  __metadata("design:type", Object)
3399
3399
  ], FilterFormValues.prototype, "secondValue", void 0);
3400
3400
  class FilterForm {
@@ -3409,7 +3409,6 @@ class FilterForm {
3409
3409
  id: rule.id,
3410
3410
  operation: rule.operation,
3411
3411
  condition: "or",
3412
- needsTwoValues,
3413
3412
  values: [
3414
3413
  {
3415
3414
  value: needsTwoValues ? rule.value[0] : rule.value,
@@ -3429,7 +3428,6 @@ class FilterForm {
3429
3428
  id: firstRule.id,
3430
3429
  operation: firstRule.operation,
3431
3430
  condition: query.condition,
3432
- needsTwoValues: firstRuleNeedsTwoValues,
3433
3431
  values: query.rules.map((rule) => ({
3434
3432
  value: firstRuleNeedsTwoValues ? rule.value[0] : rule.value,
3435
3433
  secondValue: firstRuleNeedsTwoValues ? rule.value[1] : undefined
@@ -3443,7 +3441,7 @@ class FilterForm {
3443
3441
  return {
3444
3442
  id: this.id,
3445
3443
  operation: this.operation,
3446
- value: this.needsTwoValues ? [value.value, value.secondValue] : value.value
3444
+ value: QBFilterUtils.isDoubleInput(this.operation) ? [value.value, value.secondValue] : value.value
3447
3445
  };
3448
3446
  }
3449
3447
  return {
@@ -3451,7 +3449,7 @@ class FilterForm {
3451
3449
  rules: this.values.map((value) => ({
3452
3450
  id: this.id,
3453
3451
  operation: this.operation,
3454
- value: this.needsTwoValues ? [value.value, value.secondValue] : value.value
3452
+ value: QBFilterUtils.isDoubleInput(this.operation) ? [value.value, value.secondValue] : value.value
3455
3453
  }))
3456
3454
  };
3457
3455
  }
@@ -3466,10 +3464,6 @@ __decorate([
3466
3464
  Required(),
3467
3465
  __metadata("design:type", String)
3468
3466
  ], FilterForm.prototype, "operation", void 0);
3469
- __decorate([
3470
- Control(),
3471
- __metadata("design:type", Boolean)
3472
- ], FilterForm.prototype, "needsTwoValues", void 0);
3473
3467
  __decorate([
3474
3468
  Control(),
3475
3469
  Required(),
@@ -3508,6 +3502,32 @@ __decorate([
3508
3502
  __metadata("design:type", String)
3509
3503
  ], AdvancedFiltersForm.prototype, "condition", void 0);
3510
3504
 
3505
+ class AdvancedFiltersAsyncTypeaheadProvider extends NiceAsyncTypeaheadProvider {
3506
+ constructor(filterService) {
3507
+ super();
3508
+ this.filterService = filterService;
3509
+ this.resource = "advancedFilter";
3510
+ }
3511
+ getById(id, options) {
3512
+ return lastValueFrom(this.filterService.searchFilterResourceValue(options.filterConfig, id));
3513
+ }
3514
+ async search(searchQuery, page, options) {
3515
+ const res = await lastValueFrom(this.filterService.searchFilterValue(options.filterConfig, searchQuery));
3516
+ return {
3517
+ items: res,
3518
+ nextPage: null
3519
+ };
3520
+ }
3521
+ format(item) {
3522
+ return item.name;
3523
+ }
3524
+ }
3525
+ AdvancedFiltersAsyncTypeaheadProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: AdvancedFiltersAsyncTypeaheadProvider, deps: [{ token: NiceFilterService }], target: i0.ɵɵFactoryTarget.Injectable });
3526
+ AdvancedFiltersAsyncTypeaheadProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: AdvancedFiltersAsyncTypeaheadProvider });
3527
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: AdvancedFiltersAsyncTypeaheadProvider, decorators: [{
3528
+ type: Injectable
3529
+ }], ctorParameters: function () { return [{ type: NiceFilterService }]; } });
3530
+
3511
3531
  class FilterComponent {
3512
3532
  constructor() {
3513
3533
  this.propagateChanges = (_) => { };
@@ -3610,26 +3630,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
3610
3630
  }] } });
3611
3631
 
3612
3632
  class NiceAdvancedSelectFilterComponent extends FilterComponent {
3613
- constructor(filterService) {
3614
- super();
3615
- this.filterService = filterService;
3633
+ constructor() {
3634
+ super(...arguments);
3616
3635
  this.values = [];
3617
- this.search$ = new Subject();
3618
3636
  }
3619
3637
  async ngOnInit() {
3620
3638
  if (!this.filterConfig.lazyLoading) {
3621
3639
  this.values = this.filterConfig.values;
3622
3640
  }
3623
- this.searchSub$ = this.search$
3624
- .pipe(debounceTime(300), switchMap(value => {
3625
- if (this.filterConfig.lazyLoading) {
3626
- return this.filterService.searchFilterValue(this.filterConfig, value);
3627
- }
3628
- return of(this.filterConfig.values);
3629
- }))
3630
- .subscribe(values => {
3631
- this.values = values;
3632
- });
3633
3641
  }
3634
3642
  ngOnChanges(changes) {
3635
3643
  if ("filterConfig" in changes) {
@@ -3641,34 +3649,21 @@ class NiceAdvancedSelectFilterComponent extends FilterComponent {
3641
3649
  }
3642
3650
  }
3643
3651
  }
3644
- async searchValue() {
3645
- if (this.value && !this.values.find(v => v.id === this.value)) {
3646
- const value = await this.filterService
3647
- .searchFilterResourceValue(this.filterConfig, this.value)
3648
- .toPromise();
3649
- this.values = [...this.values, value];
3650
- }
3651
- }
3652
3652
  onValueChange(value) {
3653
3653
  super.onValueChange(value);
3654
- this.searchValue();
3655
- }
3656
- ngOnDestroy() {
3657
- this.searchSub$.unsubscribe();
3658
3654
  }
3659
3655
  writeValue(value) {
3660
3656
  super.writeValue(value);
3661
- this.searchValue();
3662
3657
  }
3663
3658
  }
3664
- NiceAdvancedSelectFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedSelectFilterComponent, deps: [{ token: NiceFilterService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
3659
+ NiceAdvancedSelectFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedSelectFilterComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
3665
3660
  NiceAdvancedSelectFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceAdvancedSelectFilterComponent, selector: "nice-advanced-select-filter", inputs: { filterConfig: "filterConfig" }, providers: [
3666
3661
  {
3667
3662
  provide: NG_VALUE_ACCESSOR,
3668
3663
  useExisting: forwardRef(() => NiceAdvancedSelectFilterComponent),
3669
3664
  multi: true
3670
3665
  }
3671
- ], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field appearance=\"outline\" class=\"flex-auto\">\n <nice-typeahead *ngIf=\"!filterConfig.lazyLoading\"\n [ngModel]=\"value\"\n (ngModelChange)=\"onValueChange($event)\"\n [items]=\"values\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></nice-typeahead>\n\n <nice-typeahead *ngIf=\"filterConfig.lazyLoading\"\n [ngModel]=\"value\"\n (ngModelChange)=\"onValueChange($event)\"\n [items]=\"values\"\n [typeahead]=\"search$\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></nice-typeahead>\n</mat-form-field>\n", dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.NiceTypeaheadComponent, selector: "nice-typeahead", inputs: ["items", "labelFormatFn", "required", "disabled", "placeholder", "emptyPlaceholder", "allowNotFoundItems", "panelClass", "bindValue", "bindLabel", "typeahead", "page$", "loading", "loadingPage", "searchFn", "optionTemplate"], outputs: ["change"] }], encapsulation: i0.ViewEncapsulation.None });
3666
+ ], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field appearance=\"outline\" class=\"flex-auto\">\n <nice-typeahead\n *ngIf=\"!filterConfig.lazyLoading\"\n [ngModel]=\"value\"\n (ngModelChange)=\"onValueChange($event)\"\n [items]=\"values\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></nice-typeahead>\n\n <nice-async-typeahead\n *ngIf=\"filterConfig.lazyLoading\"\n resource=\"advancedFilter\"\n [searchOptions]=\"{ filterConfig }\"\n [ngModel]=\"value\"\n (ngModelChange)=\"onValueChange($event)\"\n ></nice-async-typeahead>\n</mat-form-field>\n", dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.NiceTypeaheadComponent, selector: "nice-typeahead", inputs: ["items", "labelFormatFn", "required", "disabled", "placeholder", "emptyPlaceholder", "allowNotFoundItems", "panelClass", "bindValue", "bindLabel", "typeahead", "page$", "loading", "loadingPage", "searchFn", "optionTemplate"], outputs: ["change"] }, { kind: "component", type: i5.NiceAsyncTypeaheadComponent, selector: "nice-async-typeahead", inputs: ["resource", "searchOptions", "preloadResource", "allowNotFoundItems", "panelClass", "bindValue", "bindLabel", "placeholder", "emptyPlaceholder", "optionTemplate", "filterFn", "labelFormatFn", "disabled", "value", "required"], outputs: ["entityRemoved", "selected"] }], encapsulation: i0.ViewEncapsulation.None });
3672
3667
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedSelectFilterComponent, decorators: [{
3673
3668
  type: Component,
3674
3669
  args: [{ selector: "nice-advanced-select-filter", encapsulation: ViewEncapsulation.None, providers: [
@@ -3677,10 +3672,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
3677
3672
  useExisting: forwardRef(() => NiceAdvancedSelectFilterComponent),
3678
3673
  multi: true
3679
3674
  }
3680
- ], template: "<mat-form-field appearance=\"outline\" class=\"flex-auto\">\n <nice-typeahead *ngIf=\"!filterConfig.lazyLoading\"\n [ngModel]=\"value\"\n (ngModelChange)=\"onValueChange($event)\"\n [items]=\"values\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></nice-typeahead>\n\n <nice-typeahead *ngIf=\"filterConfig.lazyLoading\"\n [ngModel]=\"value\"\n (ngModelChange)=\"onValueChange($event)\"\n [items]=\"values\"\n [typeahead]=\"search$\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></nice-typeahead>\n</mat-form-field>\n" }]
3681
- }], ctorParameters: function () { return [{ type: NiceFilterService, decorators: [{
3682
- type: Optional
3683
- }] }]; }, propDecorators: { filterConfig: [{
3675
+ ], template: "<mat-form-field appearance=\"outline\" class=\"flex-auto\">\n <nice-typeahead\n *ngIf=\"!filterConfig.lazyLoading\"\n [ngModel]=\"value\"\n (ngModelChange)=\"onValueChange($event)\"\n [items]=\"values\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></nice-typeahead>\n\n <nice-async-typeahead\n *ngIf=\"filterConfig.lazyLoading\"\n resource=\"advancedFilter\"\n [searchOptions]=\"{ filterConfig }\"\n [ngModel]=\"value\"\n (ngModelChange)=\"onValueChange($event)\"\n ></nice-async-typeahead>\n</mat-form-field>\n" }]
3676
+ }], propDecorators: { filterConfig: [{
3684
3677
  type: Input
3685
3678
  }] } });
3686
3679
 
@@ -3791,10 +3784,24 @@ class NiceAdvancedFiltersComponent {
3791
3784
  }
3792
3785
  }
3793
3786
  NiceAdvancedFiltersComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedFiltersComponent, deps: [{ token: ADVANCED_FILTER_ICONS, optional: true }, { token: i1$3.GeneratedFormGroup }, { token: NiceFilterViewQuery }, { token: NiceFilterViewService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3794
- NiceAdvancedFiltersComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceAdvancedFiltersComponent, selector: "nice-advanced-filters", providers: [NgxFormGeneratorProvider.forFeature([AdvancedFiltersForm])], ngImport: i0, template: "<div class=\"flex flex-col gap-4\" [formGroup]=\"formGroup\">\n <div class=\"advanced-filter-title\">{{ \"components.nice_advanced_filters.title\" | translate }}</div>\n\n <div class=\"flex flex-row gap-12\">\n <div class=\"advanced-filter-condition\">{{ \"components.nice_advanced_filters.conditions.should_match\" | translate }}</div>\n\n <mat-radio-group formControlName=\"condition\">\n <mat-radio-button value=\"and\"><span class=\"ml-4 mr-8\">{{ \"components.nice_advanced_filters.conditions.every\" | translate }}</span></mat-radio-button>\n <mat-radio-button value=\"or\"><span class=\"ml-4 mr-8\">{{ \"components.nice_advanced_filters.conditions.some\" | translate }}</span></mat-radio-button>\n </mat-radio-group>\n </div>\n\n <div class=\"flex flex-col gap-4\" formArrayName=\"rules\" *ngFor=\"let _ of rulesFormArray.controls; let i = index\">\n <nice-advanced-rule [filterConfigs]=\"config$ | async\" [formGroupName]=\"i\" (remove)=\"onClickDeleteRule(i)\"></nice-advanced-rule>\n </div>\n\n <div>\n <button class=\"add-condition\" mat-stroked-button color=\"accent\" niceAdvancedFiltersTrigger position=\"topRight\" (advancedFilterSelected)=\"onClickAddRule($event)\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.add.svgIcon\">{{ icons.add.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.add_condition\" | translate }}</div>\n </div>\n </button>\n </div>\n\n <div class=\"flex gap-6 justify-end pt-4\">\n <button class=\"close-button\" mat-button color=\"accent\" (click)=\"onClose()\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.close.svgIcon\">{{ icons.close.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.close\" | translate }}</div>\n </div>\n </button>\n\n <button class=\"refresh-button\" mat-flat-button color=\"accent\" (click)=\"onRefresh()\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.refresh.svgIcon\">{{ icons.refresh.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.refresh\" | translate }}</div>\n </div>\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i3$3.MatRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i3$3.MatRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i8.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: NiceAdvancedRuleComponent, selector: "nice-advanced-rule", inputs: ["filterConfigs"], outputs: ["remove"] }, { kind: "directive", type: AdvancedFiltersTriggerDirective, selector: "[niceAdvancedFiltersTrigger]", inputs: ["position"], outputs: ["advancedFilterSelected"], exportAs: ["niceAdvancedFiltersTrigger"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3787
+ NiceAdvancedFiltersComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceAdvancedFiltersComponent, selector: "nice-advanced-filters", providers: [
3788
+ NgxFormGeneratorProvider.forFeature([AdvancedFiltersForm]),
3789
+ {
3790
+ provide: NICE_ASYNC_TYPEAHEAD_PROVIDER,
3791
+ useClass: AdvancedFiltersAsyncTypeaheadProvider,
3792
+ multi: true
3793
+ }
3794
+ ], ngImport: i0, template: "<div class=\"flex flex-col gap-4\" [formGroup]=\"formGroup\">\n <div class=\"advanced-filter-title\">{{ \"components.nice_advanced_filters.title\" | translate }}</div>\n\n <div class=\"flex flex-row gap-12\">\n <div class=\"advanced-filter-condition\">{{ \"components.nice_advanced_filters.conditions.should_match\" | translate }}</div>\n\n <mat-radio-group formControlName=\"condition\">\n <mat-radio-button value=\"and\"><span class=\"ml-4 mr-8\">{{ \"components.nice_advanced_filters.conditions.every\" | translate }}</span></mat-radio-button>\n <mat-radio-button value=\"or\"><span class=\"ml-4 mr-8\">{{ \"components.nice_advanced_filters.conditions.some\" | translate }}</span></mat-radio-button>\n </mat-radio-group>\n </div>\n\n <div class=\"flex flex-col gap-4\" formArrayName=\"rules\" *ngFor=\"let _ of rulesFormArray.controls; let i = index\">\n <nice-advanced-rule [filterConfigs]=\"config$ | async\" [formGroupName]=\"i\" (remove)=\"onClickDeleteRule(i)\"></nice-advanced-rule>\n </div>\n\n <div>\n <button class=\"add-condition\" mat-stroked-button color=\"accent\" niceAdvancedFiltersTrigger position=\"topRight\" (advancedFilterSelected)=\"onClickAddRule($event)\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.add.svgIcon\">{{ icons.add.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.add_condition\" | translate }}</div>\n </div>\n </button>\n </div>\n\n <div class=\"flex gap-6 justify-end pt-4\">\n <button class=\"close-button\" mat-button color=\"accent\" (click)=\"onClose()\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.close.svgIcon\">{{ icons.close.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.close\" | translate }}</div>\n </div>\n </button>\n\n <button class=\"refresh-button\" mat-flat-button color=\"accent\" (click)=\"onRefresh()\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.refresh.svgIcon\">{{ icons.refresh.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.refresh\" | translate }}</div>\n </div>\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i3$3.MatRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i3$3.MatRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i8.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: NiceAdvancedRuleComponent, selector: "nice-advanced-rule", inputs: ["filterConfigs"], outputs: ["remove"] }, { kind: "directive", type: AdvancedFiltersTriggerDirective, selector: "[niceAdvancedFiltersTrigger]", inputs: ["position"], outputs: ["advancedFilterSelected"], exportAs: ["niceAdvancedFiltersTrigger"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3795
3795
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedFiltersComponent, decorators: [{
3796
3796
  type: Component,
3797
- args: [{ selector: "nice-advanced-filters", encapsulation: ViewEncapsulation.None, providers: [NgxFormGeneratorProvider.forFeature([AdvancedFiltersForm])], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-4\" [formGroup]=\"formGroup\">\n <div class=\"advanced-filter-title\">{{ \"components.nice_advanced_filters.title\" | translate }}</div>\n\n <div class=\"flex flex-row gap-12\">\n <div class=\"advanced-filter-condition\">{{ \"components.nice_advanced_filters.conditions.should_match\" | translate }}</div>\n\n <mat-radio-group formControlName=\"condition\">\n <mat-radio-button value=\"and\"><span class=\"ml-4 mr-8\">{{ \"components.nice_advanced_filters.conditions.every\" | translate }}</span></mat-radio-button>\n <mat-radio-button value=\"or\"><span class=\"ml-4 mr-8\">{{ \"components.nice_advanced_filters.conditions.some\" | translate }}</span></mat-radio-button>\n </mat-radio-group>\n </div>\n\n <div class=\"flex flex-col gap-4\" formArrayName=\"rules\" *ngFor=\"let _ of rulesFormArray.controls; let i = index\">\n <nice-advanced-rule [filterConfigs]=\"config$ | async\" [formGroupName]=\"i\" (remove)=\"onClickDeleteRule(i)\"></nice-advanced-rule>\n </div>\n\n <div>\n <button class=\"add-condition\" mat-stroked-button color=\"accent\" niceAdvancedFiltersTrigger position=\"topRight\" (advancedFilterSelected)=\"onClickAddRule($event)\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.add.svgIcon\">{{ icons.add.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.add_condition\" | translate }}</div>\n </div>\n </button>\n </div>\n\n <div class=\"flex gap-6 justify-end pt-4\">\n <button class=\"close-button\" mat-button color=\"accent\" (click)=\"onClose()\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.close.svgIcon\">{{ icons.close.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.close\" | translate }}</div>\n </div>\n </button>\n\n <button class=\"refresh-button\" mat-flat-button color=\"accent\" (click)=\"onRefresh()\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.refresh.svgIcon\">{{ icons.refresh.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.refresh\" | translate }}</div>\n </div>\n </button>\n </div>\n</div>\n" }]
3797
+ args: [{ selector: "nice-advanced-filters", encapsulation: ViewEncapsulation.None, providers: [
3798
+ NgxFormGeneratorProvider.forFeature([AdvancedFiltersForm]),
3799
+ {
3800
+ provide: NICE_ASYNC_TYPEAHEAD_PROVIDER,
3801
+ useClass: AdvancedFiltersAsyncTypeaheadProvider,
3802
+ multi: true
3803
+ }
3804
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-4\" [formGroup]=\"formGroup\">\n <div class=\"advanced-filter-title\">{{ \"components.nice_advanced_filters.title\" | translate }}</div>\n\n <div class=\"flex flex-row gap-12\">\n <div class=\"advanced-filter-condition\">{{ \"components.nice_advanced_filters.conditions.should_match\" | translate }}</div>\n\n <mat-radio-group formControlName=\"condition\">\n <mat-radio-button value=\"and\"><span class=\"ml-4 mr-8\">{{ \"components.nice_advanced_filters.conditions.every\" | translate }}</span></mat-radio-button>\n <mat-radio-button value=\"or\"><span class=\"ml-4 mr-8\">{{ \"components.nice_advanced_filters.conditions.some\" | translate }}</span></mat-radio-button>\n </mat-radio-group>\n </div>\n\n <div class=\"flex flex-col gap-4\" formArrayName=\"rules\" *ngFor=\"let _ of rulesFormArray.controls; let i = index\">\n <nice-advanced-rule [filterConfigs]=\"config$ | async\" [formGroupName]=\"i\" (remove)=\"onClickDeleteRule(i)\"></nice-advanced-rule>\n </div>\n\n <div>\n <button class=\"add-condition\" mat-stroked-button color=\"accent\" niceAdvancedFiltersTrigger position=\"topRight\" (advancedFilterSelected)=\"onClickAddRule($event)\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.add.svgIcon\">{{ icons.add.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.add_condition\" | translate }}</div>\n </div>\n </button>\n </div>\n\n <div class=\"flex gap-6 justify-end pt-4\">\n <button class=\"close-button\" mat-button color=\"accent\" (click)=\"onClose()\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.close.svgIcon\">{{ icons.close.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.close\" | translate }}</div>\n </div>\n </button>\n\n <button class=\"refresh-button\" mat-flat-button color=\"accent\" (click)=\"onRefresh()\">\n <div class=\"flex items-center gap-4\">\n <mat-icon [svgIcon]=\"icons.refresh.svgIcon\">{{ icons.refresh.matIcon }}</mat-icon>\n\n <div>{{ \"components.nice_advanced_filters.refresh\" | translate }}</div>\n </div>\n </button>\n </div>\n</div>\n" }]
3798
3805
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
3799
3806
  type: Optional
3800
3807
  }, {
@@ -3820,6 +3827,9 @@ const defaultIcons = {
3820
3827
  },
3821
3828
  datePicker: {
3822
3829
  matIcon: "today"
3830
+ },
3831
+ queryBuilder: {
3832
+ matIcon: "filter_list"
3823
3833
  }
3824
3834
  };
3825
3835
 
@@ -3872,7 +3882,8 @@ NiceAdvancedFiltersModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0
3872
3882
  TranslateModule,
3873
3883
  MatDatepickerModule,
3874
3884
  NiceTypeaheadModule,
3875
- NgxMaskModule], exports: [NiceAdvancedFiltersComponent, NiceAdvancedFiltersButtonComponent, AdvancedFiltersTriggerDirective] });
3885
+ NgxMaskModule,
3886
+ NiceAsyncTypeaheadModule], exports: [NiceAdvancedFiltersComponent, NiceAdvancedFiltersButtonComponent, AdvancedFiltersTriggerDirective] });
3876
3887
  NiceAdvancedFiltersModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedFiltersModule, imports: [CommonModule,
3877
3888
  ReactiveFormsModule,
3878
3889
  MatRadioModule,
@@ -3891,7 +3902,8 @@ NiceAdvancedFiltersModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0
3891
3902
  TranslateModule,
3892
3903
  MatDatepickerModule,
3893
3904
  NiceTypeaheadModule,
3894
- NgxMaskModule] });
3905
+ NgxMaskModule,
3906
+ NiceAsyncTypeaheadModule] });
3895
3907
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedFiltersModule, decorators: [{
3896
3908
  type: NgModule,
3897
3909
  args: [{
@@ -3914,7 +3926,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
3914
3926
  TranslateModule,
3915
3927
  MatDatepickerModule,
3916
3928
  NiceTypeaheadModule,
3917
- NgxMaskModule
3929
+ NgxMaskModule,
3930
+ NiceAsyncTypeaheadModule
3918
3931
  ],
3919
3932
  declarations: [
3920
3933
  NiceAdvancedFiltersComponent,
@@ -3971,6 +3984,7 @@ class NiceFilterExportButtonsComponent {
3971
3984
  this.bottomSheet = bottomSheet;
3972
3985
  this.customExport = [];
3973
3986
  this.downloadFileName = "data";
3987
+ this.canPrint = true;
3974
3988
  this.loading$ = this.query.selectLoading();
3975
3989
  }
3976
3990
  clickExport() {
@@ -4016,10 +4030,10 @@ class NiceFilterExportButtonsComponent {
4016
4030
  }
4017
4031
  }
4018
4032
  NiceFilterExportButtonsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceFilterExportButtonsComponent, deps: [{ token: FILTER_VIEW_ICONS }, { token: EXPORTS_SETTINGS }, { token: NiceFilterViewQuery }, { token: NiceFilterViewService }, { token: i3$4.MatBottomSheet }], target: i0.ɵɵFactoryTarget.Component });
4019
- NiceFilterExportButtonsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceFilterExportButtonsComponent, selector: "nice-filter-export-buttons, div[nice-filter-export-buttons]", inputs: { customExport: "customExport", downloadFileName: "downloadFileName" }, ngImport: i0, template: "<button\n (click)=\"clickPrint()\"\n [disabled]=\"loading$ | async\"\n [matTooltip]=\"'general.print' | translate\"\n class=\"export-button\"\n mat-mini-fab\n>\n <mat-icon [svgIcon]=\"icons.print.svgIcon\">{{ icons.print.matIcon }}</mat-icon>\n</button>\n\n<button\n (click)=\"clickExport()\"\n [disabled]=\"loading$ | async\"\n [matTooltip]=\"'general.export' | translate\"\n class=\"export-button\"\n mat-mini-fab\n>\n <mat-icon [svgIcon]=\"icons.download.svgIcon\">{{ icons.download.matIcon }}</mat-icon>\n</button>\n", styles: [""], dependencies: [{ kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i8.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "pipe", type: i1$2.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
4033
+ NiceFilterExportButtonsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceFilterExportButtonsComponent, selector: "nice-filter-export-buttons, div[nice-filter-export-buttons]", inputs: { customExport: "customExport", downloadFileName: "downloadFileName", canPrint: "canPrint" }, ngImport: i0, template: "<button\n *ngIf=\"canPrint\"\n (click)=\"clickPrint()\"\n [disabled]=\"loading$ | async\"\n [matTooltip]=\"'general.print' | translate\"\n class=\"export-button\"\n mat-mini-fab\n>\n <mat-icon [svgIcon]=\"icons.print.svgIcon\">{{ icons.print.matIcon }}</mat-icon>\n</button>\n\n<button\n (click)=\"clickExport()\"\n [disabled]=\"loading$ | async\"\n [matTooltip]=\"'general.export' | translate\"\n class=\"export-button\"\n mat-mini-fab\n>\n <mat-icon [svgIcon]=\"icons.download.svgIcon\">{{ icons.download.matIcon }}</mat-icon>\n</button>\n", styles: [""], dependencies: [{ kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i8.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "pipe", type: i1$2.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
4020
4034
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceFilterExportButtonsComponent, decorators: [{
4021
4035
  type: Component,
4022
- args: [{ selector: "nice-filter-export-buttons, div[nice-filter-export-buttons]", encapsulation: ViewEncapsulation.None, template: "<button\n (click)=\"clickPrint()\"\n [disabled]=\"loading$ | async\"\n [matTooltip]=\"'general.print' | translate\"\n class=\"export-button\"\n mat-mini-fab\n>\n <mat-icon [svgIcon]=\"icons.print.svgIcon\">{{ icons.print.matIcon }}</mat-icon>\n</button>\n\n<button\n (click)=\"clickExport()\"\n [disabled]=\"loading$ | async\"\n [matTooltip]=\"'general.export' | translate\"\n class=\"export-button\"\n mat-mini-fab\n>\n <mat-icon [svgIcon]=\"icons.download.svgIcon\">{{ icons.download.matIcon }}</mat-icon>\n</button>\n" }]
4036
+ args: [{ selector: "nice-filter-export-buttons, div[nice-filter-export-buttons]", encapsulation: ViewEncapsulation.None, template: "<button\n *ngIf=\"canPrint\"\n (click)=\"clickPrint()\"\n [disabled]=\"loading$ | async\"\n [matTooltip]=\"'general.print' | translate\"\n class=\"export-button\"\n mat-mini-fab\n>\n <mat-icon [svgIcon]=\"icons.print.svgIcon\">{{ icons.print.matIcon }}</mat-icon>\n</button>\n\n<button\n (click)=\"clickExport()\"\n [disabled]=\"loading$ | async\"\n [matTooltip]=\"'general.export' | translate\"\n class=\"export-button\"\n mat-mini-fab\n>\n <mat-icon [svgIcon]=\"icons.download.svgIcon\">{{ icons.download.matIcon }}</mat-icon>\n</button>\n" }]
4023
4037
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
4024
4038
  type: Inject,
4025
4039
  args: [FILTER_VIEW_ICONS]
@@ -4030,6 +4044,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
4030
4044
  type: Input
4031
4045
  }], downloadFileName: [{
4032
4046
  type: Input
4047
+ }], canPrint: [{
4048
+ type: Input
4033
4049
  }] } });
4034
4050
 
4035
4051
  class NiceFilterExportDirective {
@@ -4238,7 +4254,10 @@ class NiceFilterQueryParamsDirective {
4238
4254
  this.router = router;
4239
4255
  this.init = new EventEmitter();
4240
4256
  this.unsubscribeAll$ = new Subject();
4241
- this.initialized = false;
4257
+ this._initialized = false;
4258
+ }
4259
+ get initialized() {
4260
+ return this._initialized;
4242
4261
  }
4243
4262
  ngOnInit() {
4244
4263
  this.query.selectFilterParameters().pipe(takeUntil(this.unsubscribeAll$)).subscribe((parameters) => {
@@ -4267,13 +4286,18 @@ class NiceFilterQueryParamsDirective {
4267
4286
  });
4268
4287
  }
4269
4288
  loadQueryParams() {
4270
- this.route.queryParams
4271
- .pipe(takeUntil(this.unsubscribeAll$), map((params) => {
4289
+ combineLatest([
4290
+ this.route.queryParams.pipe(map((params) => params.start), distinct()),
4291
+ this.route.queryParams.pipe(map((params) => params.length), distinct()),
4292
+ this.route.queryParams.pipe(map((params) => params.order), distinct()),
4293
+ this.route.queryParams.pipe(map((params) => params.search), distinct()),
4294
+ this.route.queryParams.pipe(map((params) => params.rules), distinct()),
4295
+ ]).pipe(takeUntil(this.unsubscribeAll$), map(() => {
4296
+ const params = this.route.snapshot.queryParams;
4272
4297
  return {
4273
4298
  params: QueryParamsUtils.extractFilterParameters(params)
4274
4299
  };
4275
- }))
4276
- .subscribe(({ params }) => {
4300
+ })).subscribe(({ params }) => {
4277
4301
  if (!QueryParamsUtils.hasFilterParameters(params) || Object.keys(params).length === 0) {
4278
4302
  params = { ...this.query.getValue().filterParameters };
4279
4303
  }
@@ -4282,10 +4306,9 @@ class NiceFilterQueryParamsDirective {
4282
4306
  !filterResult) {
4283
4307
  this.service.setParameters(params, false);
4284
4308
  }
4285
- if (!this.initialized) {
4286
- this.initialized = true;
4309
+ if (!this._initialized) {
4310
+ this._initialized = true;
4287
4311
  this.init.emit();
4288
- this.service.filter();
4289
4312
  }
4290
4313
  });
4291
4314
  }
@@ -4332,16 +4355,8 @@ class NiceBaseFilterViewComponent {
4332
4355
  if (mode) {
4333
4356
  this.filterViewService.setMode(mode);
4334
4357
  }
4335
- const { autoLoad: defaultAutoLoad } = this.filterViewQuery.getValue();
4336
- if (autoLoad && defaultAutoLoad) {
4337
- this.filterViewService.filter();
4338
- }
4339
- else {
4340
- this.filterViewService.setAutoLoad(autoLoad);
4341
- }
4342
- if (loadConfig) {
4343
- this.filterViewService.loadConfig(configQueryParams);
4344
- }
4358
+ this.autoLoad(autoLoad);
4359
+ this.loadConfig(loadConfig, configQueryParams);
4345
4360
  this.filterViewLoading$ = this.filterViewQuery.selectLoading();
4346
4361
  }
4347
4362
  /**
@@ -4395,9 +4410,38 @@ class NiceBaseFilterViewComponent {
4395
4410
  removeRule(id, reload = true) {
4396
4411
  this.filterViewService.removeRule(id, reload);
4397
4412
  }
4413
+ autoLoad(autoLoad) {
4414
+ const { autoLoad: defaultAutoLoad } = this.filterViewQuery.getValue();
4415
+ if (!this.queryParams) {
4416
+ if (autoLoad && defaultAutoLoad) {
4417
+ this.filterViewService.filter();
4418
+ }
4419
+ else {
4420
+ this.filterViewService.setAutoLoad(autoLoad);
4421
+ }
4422
+ return;
4423
+ }
4424
+ if (!autoLoad && defaultAutoLoad) {
4425
+ this.filterViewService.setAutoLoad(autoLoad);
4426
+ return;
4427
+ }
4428
+ this.queryParams.init.pipe(take(1)).subscribe(() => this.loadData());
4429
+ }
4430
+ loadConfig(loadConfig, configQueryParams) {
4431
+ if (loadConfig === true) {
4432
+ this.filterViewService.loadConfig(configQueryParams);
4433
+ return;
4434
+ }
4435
+ if (loadConfig === false) {
4436
+ return;
4437
+ }
4438
+ if (this.advancedFiltersButton || this.advancedFilters) {
4439
+ this.filterViewService.loadConfig(configQueryParams);
4440
+ }
4441
+ }
4398
4442
  }
4399
4443
  NiceBaseFilterViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceBaseFilterViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4400
- NiceBaseFilterViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceBaseFilterViewComponent, selector: "ng-component", viewQueries: [{ propertyName: "filterViewService", first: true, predicate: NiceFilterViewComponent, descendants: true, read: NiceFilterViewService, static: true }, { propertyName: "filterViewQuery", first: true, predicate: NiceFilterViewComponent, descendants: true, read: NiceFilterViewQuery, static: true }], ngImport: i0, template: ``, isInline: true });
4444
+ NiceBaseFilterViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceBaseFilterViewComponent, selector: "ng-component", viewQueries: [{ propertyName: "filterViewService", first: true, predicate: NiceFilterViewComponent, descendants: true, read: NiceFilterViewService, static: true }, { propertyName: "filterViewQuery", first: true, predicate: NiceFilterViewComponent, descendants: true, read: NiceFilterViewQuery, static: true }, { propertyName: "queryParams", first: true, predicate: NiceFilterQueryParamsDirective, descendants: true, static: true }, { propertyName: "advancedFiltersButton", first: true, predicate: NiceAdvancedFiltersButtonComponent, descendants: true, static: true }, { propertyName: "advancedFilters", first: true, predicate: NiceAdvancedFiltersComponent, descendants: true, static: true }], ngImport: i0, template: ``, isInline: true });
4401
4445
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceBaseFilterViewComponent, decorators: [{
4402
4446
  type: Component,
4403
4447
  args: [{
@@ -4409,6 +4453,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
4409
4453
  }], filterViewQuery: [{
4410
4454
  type: ViewChild,
4411
4455
  args: [NiceFilterViewComponent, { read: NiceFilterViewQuery, static: true }]
4456
+ }], queryParams: [{
4457
+ type: ViewChild,
4458
+ args: [NiceFilterQueryParamsDirective, { static: true }]
4459
+ }], advancedFiltersButton: [{
4460
+ type: ViewChild,
4461
+ args: [NiceAdvancedFiltersButtonComponent, { static: true }]
4462
+ }], advancedFilters: [{
4463
+ type: ViewChild,
4464
+ args: [NiceAdvancedFiltersComponent, { static: true }]
4412
4465
  }] } });
4413
4466
 
4414
4467
  class NiceFilterViewModule {
@@ -4573,8 +4626,10 @@ class SelectableListStateQuery extends QueryEntity {
4573
4626
  }
4574
4627
 
4575
4628
  class SelectableListStateService {
4576
- constructor(store, preloadService, options) {
4629
+ constructor(store, route, router, preloadService, options) {
4577
4630
  this.store = store;
4631
+ this.route = route;
4632
+ this.router = router;
4578
4633
  this.preloadService = preloadService;
4579
4634
  this.options = options;
4580
4635
  }
@@ -4611,34 +4666,44 @@ class SelectableListStateService {
4611
4666
  this.store.update((state) => ({
4612
4667
  unselectedEntity: arrayRemove(state.unselectedEntity, id)
4613
4668
  }));
4614
- if (!this.preloadService) {
4615
- this.store.add({
4616
- [this.idKey]: id,
4617
- loaded: false
4669
+ this.store.add({
4670
+ [this.idKey]: id,
4671
+ loaded: false
4672
+ });
4673
+ if (this.preloadService) {
4674
+ const entity = await this.preloadService.loadEntityById(id);
4675
+ this.store.upsert(id, {
4676
+ ...entity,
4677
+ loaded: true
4618
4678
  });
4619
4679
  }
4620
- const entity = await this.preloadService.loadEntityById(id);
4621
- return this.store.add({
4622
- ...entity,
4623
- loaded: true
4624
- });
4680
+ }
4681
+ async selectMany(ids, active) {
4682
+ this.store.add(ids.map((id) => ({
4683
+ [this.idKey]: id,
4684
+ loaded: false
4685
+ })));
4686
+ if (active) {
4687
+ this.store.setActive(active);
4688
+ await this.loadEntities(true);
4689
+ }
4625
4690
  }
4626
4691
  async selectEntity(entity) {
4627
4692
  this.store.update((state) => ({
4628
4693
  unselectedEntity: arrayRemove(state.unselectedEntity, entity[this.idKey])
4629
4694
  }));
4630
- if (!this.preloadService) {
4631
- return this.store.upsert(entity[this.idKey], { ...entity, loaded: true });
4695
+ this.store.upsert(entity[this.idKey], { ...entity, loaded: true });
4696
+ if (this.preloadService) {
4697
+ const preloadedEntity = await this.preloadService.reloadEntity(entity);
4698
+ this.store.upsert(preloadedEntity[this.idKey], { ...preloadedEntity, loaded: true });
4632
4699
  }
4633
- const preloadedEntity = await this.preloadService.reloadEntity(entity);
4634
- return this.store.upsert(preloadedEntity[this.idKey], { ...preloadedEntity, loaded: true });
4635
4700
  }
4636
4701
  async selectManyEntities(entities) {
4637
4702
  if (!this.preloadService) {
4638
4703
  return this.store.upsertMany(entities.map((entity) => ({ ...entity, loaded: true })));
4639
4704
  }
4640
4705
  const preloadedEntities = await this.preloadService.reloadEntities(entities);
4641
- return this.store.upsertMany(preloadedEntities.map((preloadedEntity) => ({ ...preloadedEntity, loaded: true })));
4706
+ this.store.upsertMany(preloadedEntities.map((preloadedEntity) => ({ ...preloadedEntity, loaded: true })));
4642
4707
  }
4643
4708
  unselectAll() {
4644
4709
  this.store.set([]);
@@ -4662,6 +4727,9 @@ class SelectableListStateService {
4662
4727
  unselectManyEntities(entities) {
4663
4728
  this.store.remove(entities.map((entity) => entity[this.idKey]));
4664
4729
  }
4730
+ updateEntity(entity) {
4731
+ this.store.update(entity[this.idKey], entity);
4732
+ }
4665
4733
  async setEntities(ids, activeId) {
4666
4734
  this.store.update({
4667
4735
  unselectedEntity: [],
@@ -4674,6 +4742,7 @@ class SelectableListStateService {
4674
4742
  if (activeId) {
4675
4743
  this.store.setActive(activeId);
4676
4744
  }
4745
+ await this.loadEntities(true);
4677
4746
  }
4678
4747
  async next() {
4679
4748
  const { ids, active } = this.store.getValue();
@@ -4750,11 +4819,26 @@ class SelectableListStateService {
4750
4819
  }
4751
4820
  return toLoad;
4752
4821
  }
4822
+ generateQueryParams() {
4823
+ const { ids, active } = this.store.getValue();
4824
+ return {
4825
+ selection: ids.length ? ids : null,
4826
+ selected: active ?? null
4827
+ };
4828
+ }
4829
+ setQueryParams() {
4830
+ this.router.navigate([], {
4831
+ queryParams: this.generateQueryParams(),
4832
+ queryParamsHandling: "merge"
4833
+ });
4834
+ }
4753
4835
  }
4754
4836
 
4755
4837
  class SelectableListService {
4756
- constructor(providers) {
4838
+ constructor(providers, route, router) {
4757
4839
  this.providers = providers;
4840
+ this.route = route;
4841
+ this.router = router;
4758
4842
  this.stores = new Map();
4759
4843
  }
4760
4844
  createState(name, options) {
@@ -4771,10 +4855,10 @@ class SelectableListService {
4771
4855
  const provider = this.providers?.find((p) => p.state === stateName);
4772
4856
  const state = this.getState(stateName);
4773
4857
  if (state) {
4774
- return new SelectableListStateService(state.store, provider, options);
4858
+ return new SelectableListStateService(state.store, this.route, this.router, provider, options);
4775
4859
  }
4776
4860
  const newState = this.createState(stateName, options);
4777
- return new SelectableListStateService(newState.store, provider, options);
4861
+ return new SelectableListStateService(newState.store, this.route, this.router, provider, options);
4778
4862
  }
4779
4863
  query(stateName) {
4780
4864
  const state = this.getState(stateName);
@@ -4784,7 +4868,7 @@ class SelectableListService {
4784
4868
  return state.query;
4785
4869
  }
4786
4870
  }
4787
- SelectableListService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: SelectableListService, deps: [{ token: NICE_PRELOAD_SELECTED_ENTITIES_PROVIDER, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
4871
+ SelectableListService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: SelectableListService, deps: [{ token: NICE_PRELOAD_SELECTED_ENTITIES_PROVIDER, optional: true }, { token: i2.ActivatedRoute }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Injectable });
4788
4872
  SelectableListService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: SelectableListService, providedIn: "root" });
4789
4873
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: SelectableListService, decorators: [{
4790
4874
  type: Injectable,
@@ -4794,12 +4878,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
4794
4878
  }, {
4795
4879
  type: Inject,
4796
4880
  args: [NICE_PRELOAD_SELECTED_ENTITIES_PROVIDER]
4797
- }] }]; } });
4881
+ }] }, { type: i2.ActivatedRoute }, { type: i2.Router }]; } });
4798
4882
 
4799
4883
  class SelectableListContentService {
4800
4884
  constructor() {
4801
4885
  this._state = null;
4802
4886
  this._checkboxes = new QueryList();
4887
+ this.defaultOptions = { idKey: "id", preloadWindow: 2 };
4888
+ }
4889
+ get options() {
4890
+ return this._options ?? this.defaultOptions;
4803
4891
  }
4804
4892
  get state() {
4805
4893
  return this._state;
@@ -4807,6 +4895,12 @@ class SelectableListContentService {
4807
4895
  get checkboxes() {
4808
4896
  return this._checkboxes;
4809
4897
  }
4898
+ setOptions(options) {
4899
+ this._options = {
4900
+ ...this.defaultOptions,
4901
+ ...options
4902
+ };
4903
+ }
4810
4904
  setState(state) {
4811
4905
  this._state = state;
4812
4906
  }
@@ -4848,6 +4942,7 @@ class NiceSelectableListCheckboxDirective {
4848
4942
  ngOnDestroy() {
4849
4943
  this.unsubscribeAll$.next();
4850
4944
  this.unsubscribeAll$.complete();
4945
+ this.initialized = false;
4851
4946
  }
4852
4947
  ngDoCheck() {
4853
4948
  if (this.selectPage && !this.initialized) {
@@ -4902,12 +4997,19 @@ class NiceSelectableListCheckboxDirective {
4902
4997
  });
4903
4998
  }
4904
4999
  updateCheckboxState() {
5000
+ const count = this.selectableListStateQuery.getCount();
4905
5001
  const checkboxes = this.service.checkboxes.filter((checkbox) => !checkbox.selectPage);
4906
5002
  if (!checkboxes.length) {
5003
+ if (!count) {
5004
+ this.checkbox.indeterminate = false;
5005
+ this.checkbox.checked = false;
5006
+ return;
5007
+ }
5008
+ this.checkbox.indeterminate = true;
5009
+ this.checkbox.checked = false;
4907
5010
  return;
4908
5011
  }
4909
5012
  this.initialized = true;
4910
- const count = this.selectableListStateQuery.getCount();
4911
5013
  if (!count) {
4912
5014
  this.checkbox.indeterminate = false;
4913
5015
  this.checkbox.checked = false;
@@ -4978,31 +5080,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
4978
5080
 
4979
5081
  // tslint:disable-next-line:directive-class-suffix
4980
5082
  class NiceSelectableListDirective {
4981
- constructor(service) {
5083
+ constructor(service, selectableListService, route) {
4982
5084
  this.service = service;
4983
- this.defaultOptions = { idKey: "id", preloadWindow: 2 };
5085
+ this.selectableListService = selectableListService;
5086
+ this.route = route;
5087
+ this.unsubscribeAll$ = new Subject();
5088
+ this.unsubscribeQuerySub$ = new Subject();
4984
5089
  }
4985
5090
  ngOnInit() {
4986
- if (!this.options) {
4987
- this.options = { ...this.defaultOptions };
4988
- }
5091
+ combineLatest([
5092
+ this.route.queryParams.pipe(map((params) => params.selection), distinct()),
5093
+ this.route.queryParams.pipe(map((params) => params.selected), distinct())
5094
+ ]).pipe(takeUntil(this.unsubscribeAll$)).subscribe(([selection, selected]) => {
5095
+ if (!selection) {
5096
+ this.stateService.setQueryParams();
5097
+ return;
5098
+ }
5099
+ const newSelection = typeof selection === "string" ? [+selection] : selection.map((s) => +s);
5100
+ const newSelected = selected ? +selected : null;
5101
+ const { ids, active } = this.stateQuery.getValue();
5102
+ if (!ids.length || !ids.every((id) => newSelection.includes(id))) {
5103
+ this.stateService.setEntities(newSelection, newSelected);
5104
+ return;
5105
+ }
5106
+ if (newSelected && active !== newSelected) {
5107
+ this.stateService.setActive(newSelected);
5108
+ }
5109
+ });
5110
+ }
5111
+ ngOnDestroy() {
5112
+ this.unsubscribeAll$.next();
5113
+ this.unsubscribeAll$.complete();
5114
+ this.unsubscribeQuerySub$.next();
5115
+ this.unsubscribeQuerySub$.complete();
4989
5116
  }
4990
5117
  ngOnChanges(changes) {
4991
5118
  if ("options" in changes) {
4992
- this.options = {
4993
- ...this.defaultOptions,
4994
- ...changes.options.currentValue
4995
- };
5119
+ this.service.setOptions(this.options);
4996
5120
  }
4997
5121
  if ("state" in changes) {
4998
5122
  this.service.setState(this.state);
5123
+ this.stateService = this.selectableListService.withState(this.state);
5124
+ this.stateQuery = this.selectableListService.query(this.state);
5125
+ this.listenOnStateChanges();
4999
5126
  }
5000
5127
  }
5001
5128
  ngAfterContentInit() {
5002
5129
  this.service.setCheckboxes(this.checkboxes);
5003
5130
  }
5131
+ listenOnStateChanges() {
5132
+ this.unsubscribeQuerySub$.next();
5133
+ this.stateQuery.selectEntityAction([
5134
+ EntityActions.Add,
5135
+ EntityActions.Remove,
5136
+ EntityActions.Set
5137
+ ]).pipe(takeUntil(this.unsubscribeQuerySub$)).subscribe(() => {
5138
+ this.stateService.setQueryParams();
5139
+ });
5140
+ this.stateQuery.selectActiveId().pipe(takeUntil(this.unsubscribeQuerySub$)).subscribe(() => this.stateService.setQueryParams());
5141
+ }
5004
5142
  }
5005
- NiceSelectableListDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceSelectableListDirective, deps: [{ token: SelectableListContentService }], target: i0.ɵɵFactoryTarget.Directive });
5143
+ NiceSelectableListDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceSelectableListDirective, deps: [{ token: SelectableListContentService }, { token: SelectableListService }, { token: i2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Directive });
5006
5144
  NiceSelectableListDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.3", type: NiceSelectableListDirective, selector: "[niceSelectableList]", inputs: { state: "state", options: "options" }, providers: [SelectableListContentService], queries: [{ propertyName: "checkboxes", predicate: NiceSelectableListCheckboxDirective, descendants: true }], usesOnChanges: true, ngImport: i0 });
5007
5145
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceSelectableListDirective, decorators: [{
5008
5146
  type: Directive,
@@ -5010,7 +5148,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
5010
5148
  selector: "[niceSelectableList]",
5011
5149
  providers: [SelectableListContentService]
5012
5150
  }]
5013
- }], ctorParameters: function () { return [{ type: SelectableListContentService }]; }, propDecorators: { state: [{
5151
+ }], ctorParameters: function () { return [{ type: SelectableListContentService }, { type: SelectableListService }, { type: i2.ActivatedRoute }]; }, propDecorators: { state: [{
5014
5152
  type: Input
5015
5153
  }], options: [{
5016
5154
  type: Input