@recursyve/nice-data-filter-kit 14.5.1 → 14.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { plainToInstance } from 'class-transformer';
2
- import { map, takeUntil, debounceTime, switchMap, distinctUntilChanged, withLatestFrom } from 'rxjs/operators';
2
+ import { map, takeUntil, debounceTime, switchMap, distinctUntilChanged, combineLatestWith } from 'rxjs/operators';
3
3
  import { HttpParams } from '@angular/common/http';
4
4
  import * as i5$1 from '@recursyve/nice-ui-kit.v2';
5
5
  import { isNullOrUndefined, ObjectUtils, FileUtils, ArrayUtils, ExportBottomSheetComponent, NiceLoadingSpinnerModule, NiceTypeaheadModule, NiceExportBottomSheetModule, NiceAsyncTypeaheadProvider, NICE_ASYNC_TYPEAHEAD_PROVIDER, NiceAsyncTypeaheadModule } from '@recursyve/nice-ui-kit.v2';
@@ -3263,83 +3263,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
3263
3263
  args: [NiceFilterService]
3264
3264
  }] }]; }, propDecorators: { resetResult: [] } });
3265
3265
 
3266
- class AdvancedFiltersUtils {
3267
- static isSingleInput(filterOperator) {
3268
- if (!filterOperator) {
3269
- return false;
3270
- }
3271
- return AdvancedFiltersUtils.singleInputOperators.includes(filterOperator);
3272
- }
3273
- static isDoubleInput(filterOperator) {
3274
- if (!filterOperator) {
3275
- return false;
3276
- }
3277
- return AdvancedFiltersUtils.doubleInputOperators.includes(filterOperator);
3278
- }
3279
- static isNoInput(filterOperator) {
3280
- if (!filterOperator) {
3281
- return false;
3282
- }
3283
- return AdvancedFiltersUtils.noInputOperators.includes(filterOperator);
3284
- }
3285
- static createRule(config, operator) {
3286
- const base = {
3287
- id: config.id,
3288
- operation: operator || config.operators[0].id
3289
- };
3290
- switch (config.type) {
3291
- case FilterType.Text:
3292
- return {
3293
- ...base,
3294
- value: AdvancedFiltersUtils.isDoubleInput(operator) ? ["", ""] : ""
3295
- };
3296
- case FilterType.Number:
3297
- case FilterType.Select:
3298
- return {
3299
- ...base,
3300
- value: AdvancedFiltersUtils.isDoubleInput(operator) ? [null, null] : null
3301
- };
3302
- case FilterType.Date:
3303
- return {
3304
- ...base,
3305
- value: AdvancedFiltersUtils.isDoubleInput(operator) ? [new Date(), new Date()] : new Date()
3306
- };
3307
- case FilterType.Radio:
3308
- return {
3309
- ...base,
3310
- value: AdvancedFiltersUtils.isDoubleInput(operator)
3311
- ? [config.options?.[0].key, config.options?.[0].key]
3312
- : config.options?.[0].key
3313
- };
3314
- }
3315
- }
3316
- }
3317
- AdvancedFiltersUtils.noInputOperators = [
3318
- FilterOperatorTypes.IsEmpty,
3319
- FilterOperatorTypes.IsNotEmpty,
3320
- FilterOperatorTypes.IsNull,
3321
- FilterOperatorTypes.IsNotNull,
3322
- FilterOperatorTypes.None
3323
- ];
3324
- AdvancedFiltersUtils.singleInputOperators = [
3325
- FilterOperatorTypes.Equal,
3326
- FilterOperatorTypes.NotEqual,
3327
- FilterOperatorTypes.Less,
3328
- FilterOperatorTypes.LessOrEqual,
3329
- FilterOperatorTypes.Greater,
3330
- FilterOperatorTypes.GreaterOrEqual,
3331
- FilterOperatorTypes.BeginsWith,
3332
- FilterOperatorTypes.NotBeginsWith,
3333
- FilterOperatorTypes.EndsWith,
3334
- FilterOperatorTypes.NotEndsWith,
3335
- FilterOperatorTypes.Contains,
3336
- FilterOperatorTypes.NotContains
3337
- ];
3338
- AdvancedFiltersUtils.doubleInputOperators = [
3339
- FilterOperatorTypes.Between,
3340
- FilterOperatorTypes.NotBetween
3341
- ];
3342
-
3343
3266
  const ADVANCED_FILTER_ICONS = new InjectionToken("advanced_filter_icons");
3344
3267
 
3345
3268
  class NiceFilterGroupIconPipe {
@@ -3483,7 +3406,7 @@ class NiceAdvancedFiltersButtonComponent {
3483
3406
  this.query = query;
3484
3407
  this.service = service;
3485
3408
  this.shouldShowAdvancedFilters$ = this.query.selectSubState("showAdvancedFilters");
3486
- this.hasParameters$ = this.query.selectFilterParameters().pipe(withLatestFrom(this.query.selectFilterConfig()), map(([parameter, config]) => !!parameter
3409
+ this.hasParameters$ = this.query.selectFilterParameters().pipe(combineLatestWith(this.query.selectFilterConfig()), map(([parameter, config]) => !!parameter
3487
3410
  .rules
3488
3411
  ?.filter((rule) => config.some((conf) => conf?.id === rule.rules[0]?.id))
3489
3412
  ?.length));
@@ -3492,16 +3415,15 @@ class NiceAdvancedFiltersButtonComponent {
3492
3415
  this.service.updateSubState("showAdvancedFilters", !this.query.getSubState("showAdvancedFilters"));
3493
3416
  }
3494
3417
  onSelectedFilter(filter) {
3495
- const rule = AdvancedFiltersUtils.createRule(filter);
3496
- this.service.setRules([{ condition: "and", rules: [rule] }]);
3497
3418
  this.service.updateSubState("showAdvancedFilters", true);
3419
+ this.service.updateSubState("selectedFilter", filter);
3498
3420
  }
3499
3421
  }
3500
3422
  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 });
3501
- 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: i5.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 });
3423
+ 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-1 right-1 w-2 h-2 z-10 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: i5.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 });
3502
3424
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: NiceAdvancedFiltersButtonComponent, decorators: [{
3503
3425
  type: Component,
3504
- 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"] }]
3426
+ 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-1 right-1 w-2 h-2 z-10 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"] }]
3505
3427
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
3506
3428
  type: Optional
3507
3429
  }, {
@@ -3652,6 +3574,83 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
3652
3574
  type: Injectable
3653
3575
  }], ctorParameters: function () { return [{ type: NiceFilterService }]; } });
3654
3576
 
3577
+ class AdvancedFiltersUtils {
3578
+ static isSingleInput(filterOperator) {
3579
+ if (!filterOperator) {
3580
+ return false;
3581
+ }
3582
+ return AdvancedFiltersUtils.singleInputOperators.includes(filterOperator);
3583
+ }
3584
+ static isDoubleInput(filterOperator) {
3585
+ if (!filterOperator) {
3586
+ return false;
3587
+ }
3588
+ return AdvancedFiltersUtils.doubleInputOperators.includes(filterOperator);
3589
+ }
3590
+ static isNoInput(filterOperator) {
3591
+ if (!filterOperator) {
3592
+ return false;
3593
+ }
3594
+ return AdvancedFiltersUtils.noInputOperators.includes(filterOperator);
3595
+ }
3596
+ static createRule(config, operator) {
3597
+ const base = {
3598
+ id: config.id,
3599
+ operation: operator || config.operators[0].id
3600
+ };
3601
+ switch (config.type) {
3602
+ case FilterType.Text:
3603
+ return {
3604
+ ...base,
3605
+ value: AdvancedFiltersUtils.isDoubleInput(operator) ? ["", ""] : ""
3606
+ };
3607
+ case FilterType.Number:
3608
+ case FilterType.Select:
3609
+ return {
3610
+ ...base,
3611
+ value: AdvancedFiltersUtils.isDoubleInput(operator) ? [null, null] : null
3612
+ };
3613
+ case FilterType.Date:
3614
+ return {
3615
+ ...base,
3616
+ value: AdvancedFiltersUtils.isDoubleInput(operator) ? [new Date(), new Date()] : new Date()
3617
+ };
3618
+ case FilterType.Radio:
3619
+ return {
3620
+ ...base,
3621
+ value: AdvancedFiltersUtils.isDoubleInput(operator)
3622
+ ? [config.options?.[0].key, config.options?.[0].key]
3623
+ : config.options?.[0].key
3624
+ };
3625
+ }
3626
+ }
3627
+ }
3628
+ AdvancedFiltersUtils.noInputOperators = [
3629
+ FilterOperatorTypes.IsEmpty,
3630
+ FilterOperatorTypes.IsNotEmpty,
3631
+ FilterOperatorTypes.IsNull,
3632
+ FilterOperatorTypes.IsNotNull,
3633
+ FilterOperatorTypes.None
3634
+ ];
3635
+ AdvancedFiltersUtils.singleInputOperators = [
3636
+ FilterOperatorTypes.Equal,
3637
+ FilterOperatorTypes.NotEqual,
3638
+ FilterOperatorTypes.Less,
3639
+ FilterOperatorTypes.LessOrEqual,
3640
+ FilterOperatorTypes.Greater,
3641
+ FilterOperatorTypes.GreaterOrEqual,
3642
+ FilterOperatorTypes.BeginsWith,
3643
+ FilterOperatorTypes.NotBeginsWith,
3644
+ FilterOperatorTypes.EndsWith,
3645
+ FilterOperatorTypes.NotEndsWith,
3646
+ FilterOperatorTypes.Contains,
3647
+ FilterOperatorTypes.NotContains
3648
+ ];
3649
+ AdvancedFiltersUtils.doubleInputOperators = [
3650
+ FilterOperatorTypes.Between,
3651
+ FilterOperatorTypes.NotBetween
3652
+ ];
3653
+
3655
3654
  class FilterComponent {
3656
3655
  constructor() {
3657
3656
  this.propagateChanges = (_) => { };
@@ -3884,10 +3883,17 @@ class NiceAdvancedFiltersComponent {
3884
3883
  this.rules$ = this.rulesFormArray.valueChanges.pipe(startWith(this.rulesFormArray.value));
3885
3884
  }
3886
3885
  ngOnInit() {
3887
- const { filterParameters } = this.query.getValue();
3886
+ const { filterParameters, subStates } = this.query.getValue();
3888
3887
  if (filterParameters.rules?.length) {
3889
3888
  this.formGroup.patchValue(new AdvancedFiltersForm(filterParameters.rules[0]));
3890
3889
  }
3890
+ if (subStates.selectedFilter) {
3891
+ this.onClickAddRule(subStates.selectedFilter);
3892
+ return;
3893
+ }
3894
+ }
3895
+ ngOnDestroy() {
3896
+ this.removeEmptyRules({ reload: false });
3891
3897
  }
3892
3898
  onClickAddRule(filterConfigurationModel) {
3893
3899
  this.rulesFormArray.push(new FilterForm(AdvancedFiltersUtils.createRule(filterConfigurationModel)));
@@ -3902,6 +3908,7 @@ class NiceAdvancedFiltersComponent {
3902
3908
  }
3903
3909
  }
3904
3910
  onClose() {
3911
+ this.removeEmptyRules();
3905
3912
  this.service.updateSubState("showAdvancedFilters", false);
3906
3913
  }
3907
3914
  onRefresh() {
@@ -3909,6 +3916,31 @@ class NiceAdvancedFiltersComponent {
3909
3916
  this.service.resetResult(true);
3910
3917
  this.service.filter();
3911
3918
  }
3919
+ removeEmptyRules({ reload } = { reload: true }) {
3920
+ if (this.rulesFormArray.length !== 1) {
3921
+ return;
3922
+ }
3923
+ const values = this.rulesFormArray.get([0, "values"]).getRawValue();
3924
+ if (values.length !== 1) {
3925
+ return;
3926
+ }
3927
+ const value = values[0];
3928
+ if (value.value || value.value === false || value.secondValue || value.secondValue === true) {
3929
+ return;
3930
+ }
3931
+ this.rulesFormArray.removeAt(0);
3932
+ const { filterParameters } = this.query.getValue();
3933
+ if (!filterParameters.rules.length || !filterParameters.rules[0].rules.length) {
3934
+ return;
3935
+ }
3936
+ this.service.setRules([]);
3937
+ if (!reload) {
3938
+ return;
3939
+ }
3940
+ if (filterParameters.rules[0].rules[0].value) {
3941
+ this.service.filter();
3942
+ }
3943
+ }
3912
3944
  }
3913
3945
  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 });
3914
3946
  NiceAdvancedFiltersComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: NiceAdvancedFiltersComponent, selector: "nice-advanced-filters", providers: [