@ecodev/natural 63.8.0 → 63.9.1

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 * as i0 from '@angular/core';
2
- import { inject, Component, Injectable, DestroyRef, HostListener, HostBinding, Directive, InjectionToken, ElementRef, viewChild, ViewEncapsulation, Injector, Input, PLATFORM_ID, signal, output, Pipe, Optional, Inject, LOCALE_ID, provideAppInitializer, input, computed, contentChild, TemplateRef, EnvironmentInjector, createEnvironmentInjector, createComponent, runInInjectionContext, ChangeDetectionStrategy, linkedSignal, ErrorHandler, importProvidersFrom } from '@angular/core';
2
+ import { inject, Component, Injectable, DestroyRef, HostListener, HostBinding, Directive, InjectionToken, ElementRef, viewChild, ViewEncapsulation, Injector, Input, PLATFORM_ID, signal, output, Pipe, LOCALE_ID, provideAppInitializer, input, computed, contentChild, TemplateRef, EnvironmentInjector, createEnvironmentInjector, createComponent, Inject, runInInjectionContext, ChangeDetectionStrategy, linkedSignal, ErrorHandler, importProvidersFrom } from '@angular/core';
3
3
  import * as i1$2 from '@angular/forms';
4
4
  import { FormGroup, FormArray, Validators, UntypedFormGroup, UntypedFormArray, FormControl, FormsModule, ReactiveFormsModule, UntypedFormControl, NgControl, FormControlDirective, FormControlName } from '@angular/forms';
5
5
  import { NavigationStart, NavigationEnd, ActivatedRoute, Router, RouteConfigLoadStart, RouteConfigLoadEnd, PRIMARY_OUTLET, RouterLink, NavigationError, DefaultUrlSerializer, UrlTree } from '@angular/router';
@@ -56,10 +56,10 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
56
56
  import * as i8 from '@angular/material/progress-spinner';
57
57
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
58
58
  import { FlatTreeControl } from '@angular/cdk/tree';
59
- import * as i3$2 from '@angular/material/tree';
60
- import { MatTreeFlattener, MatTreeFlatDataSource, MatTreeModule } from '@angular/material/tree';
61
59
  import * as i7 from '@angular/material/chips';
62
60
  import { MatChipsModule } from '@angular/material/chips';
61
+ import * as i3$2 from '@angular/material/tree';
62
+ import { MatTreeFlattener, MatTreeFlatDataSource, MatTreeModule } from '@angular/material/tree';
63
63
  import { MatDividerModule } from '@angular/material/divider';
64
64
  import * as i2$2 from '@angular/material/button-toggle';
65
65
  import { MatButtonToggleModule } from '@angular/material/button-toggle';
@@ -2383,7 +2383,11 @@ class NaturalAbstractDetail extends NaturalAbstractPanel {
2383
2383
  */
2384
2384
  _isUpdatePage = false;
2385
2385
  changes = new CumulativeChanges();
2386
- constructor(key, service) {
2386
+ constructor(
2387
+ // eslint-disable-next-line @angular-eslint/prefer-inject
2388
+ key,
2389
+ // eslint-disable-next-line @angular-eslint/prefer-inject
2390
+ service) {
2387
2391
  super();
2388
2392
  this.key = key;
2389
2393
  this.service = service;
@@ -2592,6 +2596,7 @@ class NaturalAbstractEditableList {
2592
2596
  formArray = new UntypedFormArray([]);
2593
2597
  variablesManager = new NaturalQueryVariablesManager();
2594
2598
  dataSource = new MatTableDataSource();
2599
+ // eslint-disable-next-line @angular-eslint/prefer-inject
2595
2600
  constructor(service) {
2596
2601
  this.service = service;
2597
2602
  // Create a form group with a line attributes that contain an array of formGroups (one by line = one by model)
@@ -2893,7 +2898,7 @@ class NaturalDropdownContainerComponent extends BasePortalOutlet {
2893
2898
  }
2894
2899
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalDropdownContainerComponent, decorators: [{
2895
2900
  type: Component,
2896
- args: [{ encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, imports: [PortalModule, MatButtonModule], template: "<div\n class=\"natural-dropdown-container mat-elevation-z2\"\n role=\"menu\"\n tabindex=\"-1\"\n [class.mat-menu-panel-exit-animation]=\"panelAnimationState === 'void'\"\n (animationend)=\"onAnimationDone($event.animationName)\"\n (animationcancel)=\"onAnimationDone($event.animationName)\"\n>\n <div class=\"natural-dropdown-container-content\">\n <ng-template cdkPortalOutlet />\n </div>\n\n @if (data.showValidateButton) {\n <div class=\"natural-dropdown-validate-button\">\n <button color=\"primary\" mat-raised-button i18n (click)=\"close()\">Valider</button>\n </div>\n }\n</div>\n", styles: ["@keyframes _mat-menu-enter{0%{transform:scale(.8);opacity:0}to{transform:none;opacity:1}}@keyframes _mat-menu-exit{0%{opacity:1}to{opacity:0}}.natural-dropdown-container{display:flex;flex-direction:column;animation:_mat-menu-enter .12s cubic-bezier(0,0,.2,1);border-radius:2px;height:100%}.natural-dropdown-container-content{flex:1;padding:5px;overflow:auto}.natural-dropdown-container .natural-dropdown-validate-button{display:flex;flex:none;flex-direction:row;justify-content:flex-end;margin:5px}.natural-dropdown-container.mat-menu-panel-exit-animation{animation:_mat-menu-exit .1s 25ms linear forwards}\n"] }]
2901
+ args: [{ imports: [PortalModule, MatButtonModule], encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, template: "<div\n class=\"natural-dropdown-container mat-elevation-z2\"\n role=\"menu\"\n tabindex=\"-1\"\n [class.mat-menu-panel-exit-animation]=\"panelAnimationState === 'void'\"\n (animationend)=\"onAnimationDone($event.animationName)\"\n (animationcancel)=\"onAnimationDone($event.animationName)\"\n>\n <div class=\"natural-dropdown-container-content\">\n <ng-template cdkPortalOutlet />\n </div>\n\n @if (data.showValidateButton) {\n <div class=\"natural-dropdown-validate-button\">\n <button color=\"primary\" mat-raised-button i18n (click)=\"close()\">Valider</button>\n </div>\n }\n</div>\n", styles: ["@keyframes _mat-menu-enter{0%{transform:scale(.8);opacity:0}to{transform:none;opacity:1}}@keyframes _mat-menu-exit{0%{opacity:1}to{opacity:0}}.natural-dropdown-container{display:flex;flex-direction:column;animation:_mat-menu-enter .12s cubic-bezier(0,0,.2,1);border-radius:2px;height:100%}.natural-dropdown-container-content{flex:1;padding:5px;overflow:auto}.natural-dropdown-container .natural-dropdown-validate-button{display:flex;flex:none;flex-direction:row;justify-content:flex-end;margin:5px}.natural-dropdown-container.mat-menu-panel-exit-animation{animation:_mat-menu-exit .1s 25ms linear forwards}\n"] }]
2897
2902
  }] });
2898
2903
 
2899
2904
  class NaturalDropdownRef {
@@ -3762,6 +3767,7 @@ class NaturalAbstractList extends NaturalAbstractPanel {
3762
3767
  route = inject(ActivatedRoute);
3763
3768
  alertService = inject(NaturalAlertService);
3764
3769
  persistenceService = inject(NaturalPersistenceService);
3770
+ // eslint-disable-next-line @angular-eslint/prefer-inject
3765
3771
  constructor(service) {
3766
3772
  super();
3767
3773
  this.service = service;
@@ -3864,7 +3870,7 @@ class NaturalAbstractList extends NaturalAbstractPanel {
3864
3870
  */
3865
3871
  getPagination() {
3866
3872
  const paginationChannel = this.variablesManager.get('pagination');
3867
- if (paginationChannel && paginationChannel.pagination) {
3873
+ if (paginationChannel?.pagination) {
3868
3874
  // The cast should not be necessary because Typescript correctly narrow down the type to `PaginationInput`
3869
3875
  // but somehow still get confused when returning it
3870
3876
  return paginationChannel.pagination;
@@ -4122,6 +4128,7 @@ class NaturalAbstractNavigableList extends NaturalAbstractList {
4122
4128
  ancestorRelationName = 'parent';
4123
4129
  oldAncertorId = null;
4124
4130
  breadcrumbs = [];
4131
+ // eslint-disable-next-line @angular-eslint/prefer-inject
4125
4132
  constructor(service) {
4126
4133
  super(service);
4127
4134
  }
@@ -5544,7 +5551,7 @@ class NaturalColumnsPickerComponent {
5544
5551
  }
5545
5552
  }
5546
5553
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalColumnsPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5547
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: NaturalColumnsPickerComponent, isStandalone: true, selector: "natural-columns-picker", inputs: { buttons: "buttons", availableColumns: "availableColumns", selections: "selections" }, outputs: { selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "<div>\n @if ((isMobile | async) && someVisibleButtons()) {\n <button mat-icon-button [matMenuTriggerFor]=\"mobileMenu\">\n <mat-icon naturalIcon=\"more_vert\" />\n </button>\n <mat-menu #mobileMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (button of buttons; track button) {\n @if (defaultTrue(button.show)) {\n @if (button.href) {\n <a\n mat-menu-item\n [href]=\"button.href\"\n [disabled]=\"button.disabled\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </a>\n } @else if (button.buttons) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"subMenu\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </button>\n <mat-menu #subMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (subButton of button.buttons; track subButton) {\n <a\n mat-menu-item\n [disabled]=\"subButton.disabled\"\n (click)=\"subButton.click(subButton, $event)\"\n >\n {{ subButton.label }}\n </a>\n }\n </ng-template>\n </mat-menu>\n } @else {\n <button\n mat-menu-item\n [disabled]=\"button.disabled\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </button>\n }\n }\n }\n\n @if (displayedColumns.length) {\n <button mat-menu-item [matMenuTriggerFor]=\"columnMenu\" [ngClass]=\"needMargin(null)\">\n <span i18n>Colonnes</span>\n </button>\n }\n </ng-template>\n </mat-menu>\n } @else {\n @for (button of buttons; track button) {\n @if (defaultTrue(button.show)) {\n @if (button.href) {\n <a\n mat-icon-button\n [href]=\"button.href\"\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </a>\n } @else if (button.buttons) {\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"menu\"\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </button>\n <mat-menu #menu=\"matMenu\">\n <ng-template matMenuContent>\n @for (subButton of button.buttons; track subButton) {\n <a\n mat-menu-item\n [disabled]=\"subButton.disabled\"\n (click)=\"subButton.click(subButton, $event)\"\n >\n {{ subButton.label }}\n </a>\n }\n </ng-template>\n </mat-menu>\n } @else {\n <button\n mat-icon-button\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </button>\n }\n }\n }\n\n @if (displayedColumns.length) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"S\u00E9lectionner les colonnes\"\n [matMenuTriggerFor]=\"columnMenu\"\n >\n <mat-icon naturalIcon=\"view_column\" />\n </button>\n }\n }\n</div>\n\n<mat-menu #columnMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (column of displayedColumns; track column) {\n <div mat-menu-item (click)=\"menuItemClicked($event, column)\">\n <mat-checkbox\n [(ngModel)]=\"column.checked\"\n (click)=\"checkboxClicked($event, column)\"\n (change)=\"updateColumns()\"\n >{{ column.label }}</mat-checkbox\n >\n </div>\n }\n </ng-template>\n</mat-menu>\n", styles: [".align-with-checkbox{padding-left:61px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconAnchor, selector: "a[mat-icon-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3$1.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i3$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
5554
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: NaturalColumnsPickerComponent, isStandalone: true, selector: "natural-columns-picker", inputs: { buttons: "buttons", availableColumns: "availableColumns", selections: "selections" }, outputs: { selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "<!-- eslint-disable @angular-eslint/template/cyclomatic-complexity -->\n<div>\n @if ((isMobile | async) && someVisibleButtons()) {\n <button mat-icon-button [matMenuTriggerFor]=\"mobileMenu\">\n <mat-icon naturalIcon=\"more_vert\" />\n </button>\n <mat-menu #mobileMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (button of buttons; track button) {\n @if (defaultTrue(button.show)) {\n @if (button.href) {\n <a\n mat-menu-item\n [href]=\"button.href\"\n [disabled]=\"button.disabled\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </a>\n } @else if (button.buttons) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"subMenu\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </button>\n <mat-menu #subMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (subButton of button.buttons; track subButton) {\n <a\n mat-menu-item\n [disabled]=\"subButton.disabled\"\n (click)=\"subButton.click(subButton, $event)\"\n >\n {{ subButton.label }}\n </a>\n }\n </ng-template>\n </mat-menu>\n } @else {\n <button\n mat-menu-item\n [disabled]=\"button.disabled\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </button>\n }\n }\n }\n\n @if (displayedColumns.length) {\n <button mat-menu-item [matMenuTriggerFor]=\"columnMenu\" [ngClass]=\"needMargin(null)\">\n <span i18n>Colonnes</span>\n </button>\n }\n </ng-template>\n </mat-menu>\n } @else {\n @for (button of buttons; track button) {\n @if (defaultTrue(button.show)) {\n @if (button.href) {\n <a\n mat-icon-button\n [href]=\"button.href\"\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </a>\n } @else if (button.buttons) {\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"menu\"\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </button>\n <mat-menu #menu=\"matMenu\">\n <ng-template matMenuContent>\n @for (subButton of button.buttons; track subButton) {\n <a\n mat-menu-item\n [disabled]=\"subButton.disabled\"\n (click)=\"subButton.click(subButton, $event)\"\n >\n {{ subButton.label }}\n </a>\n }\n </ng-template>\n </mat-menu>\n } @else {\n <button\n mat-icon-button\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </button>\n }\n }\n }\n\n @if (displayedColumns.length) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"S\u00E9lectionner les colonnes\"\n [matMenuTriggerFor]=\"columnMenu\"\n >\n <mat-icon naturalIcon=\"view_column\" />\n </button>\n }\n }\n</div>\n\n<mat-menu #columnMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (column of displayedColumns; track column) {\n <div mat-menu-item (click)=\"menuItemClicked($event, column)\">\n <mat-checkbox\n [(ngModel)]=\"column.checked\"\n (click)=\"checkboxClicked($event, column)\"\n (change)=\"updateColumns()\"\n >{{ column.label }}</mat-checkbox\n >\n </div>\n }\n </ng-template>\n</mat-menu>\n", styles: [".align-with-checkbox{padding-left:61px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconAnchor, selector: "a[mat-icon-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3$1.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i3$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
5548
5555
  }
5549
5556
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalColumnsPickerComponent, decorators: [{
5550
5557
  type: Component,
@@ -5557,7 +5564,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
5557
5564
  MatCheckboxModule,
5558
5565
  MatTooltipModule,
5559
5566
  FormsModule,
5560
- ], template: "<div>\n @if ((isMobile | async) && someVisibleButtons()) {\n <button mat-icon-button [matMenuTriggerFor]=\"mobileMenu\">\n <mat-icon naturalIcon=\"more_vert\" />\n </button>\n <mat-menu #mobileMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (button of buttons; track button) {\n @if (defaultTrue(button.show)) {\n @if (button.href) {\n <a\n mat-menu-item\n [href]=\"button.href\"\n [disabled]=\"button.disabled\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </a>\n } @else if (button.buttons) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"subMenu\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </button>\n <mat-menu #subMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (subButton of button.buttons; track subButton) {\n <a\n mat-menu-item\n [disabled]=\"subButton.disabled\"\n (click)=\"subButton.click(subButton, $event)\"\n >\n {{ subButton.label }}\n </a>\n }\n </ng-template>\n </mat-menu>\n } @else {\n <button\n mat-menu-item\n [disabled]=\"button.disabled\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </button>\n }\n }\n }\n\n @if (displayedColumns.length) {\n <button mat-menu-item [matMenuTriggerFor]=\"columnMenu\" [ngClass]=\"needMargin(null)\">\n <span i18n>Colonnes</span>\n </button>\n }\n </ng-template>\n </mat-menu>\n } @else {\n @for (button of buttons; track button) {\n @if (defaultTrue(button.show)) {\n @if (button.href) {\n <a\n mat-icon-button\n [href]=\"button.href\"\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </a>\n } @else if (button.buttons) {\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"menu\"\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </button>\n <mat-menu #menu=\"matMenu\">\n <ng-template matMenuContent>\n @for (subButton of button.buttons; track subButton) {\n <a\n mat-menu-item\n [disabled]=\"subButton.disabled\"\n (click)=\"subButton.click(subButton, $event)\"\n >\n {{ subButton.label }}\n </a>\n }\n </ng-template>\n </mat-menu>\n } @else {\n <button\n mat-icon-button\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </button>\n }\n }\n }\n\n @if (displayedColumns.length) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"S\u00E9lectionner les colonnes\"\n [matMenuTriggerFor]=\"columnMenu\"\n >\n <mat-icon naturalIcon=\"view_column\" />\n </button>\n }\n }\n</div>\n\n<mat-menu #columnMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (column of displayedColumns; track column) {\n <div mat-menu-item (click)=\"menuItemClicked($event, column)\">\n <mat-checkbox\n [(ngModel)]=\"column.checked\"\n (click)=\"checkboxClicked($event, column)\"\n (change)=\"updateColumns()\"\n >{{ column.label }}</mat-checkbox\n >\n </div>\n }\n </ng-template>\n</mat-menu>\n", styles: [".align-with-checkbox{padding-left:61px}\n"] }]
5567
+ ], template: "<!-- eslint-disable @angular-eslint/template/cyclomatic-complexity -->\n<div>\n @if ((isMobile | async) && someVisibleButtons()) {\n <button mat-icon-button [matMenuTriggerFor]=\"mobileMenu\">\n <mat-icon naturalIcon=\"more_vert\" />\n </button>\n <mat-menu #mobileMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (button of buttons; track button) {\n @if (defaultTrue(button.show)) {\n @if (button.href) {\n <a\n mat-menu-item\n [href]=\"button.href\"\n [disabled]=\"button.disabled\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </a>\n } @else if (button.buttons) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"subMenu\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </button>\n <mat-menu #subMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (subButton of button.buttons; track subButton) {\n <a\n mat-menu-item\n [disabled]=\"subButton.disabled\"\n (click)=\"subButton.click(subButton, $event)\"\n >\n {{ subButton.label }}\n </a>\n }\n </ng-template>\n </mat-menu>\n } @else {\n <button\n mat-menu-item\n [disabled]=\"button.disabled\"\n [ngClass]=\"needMargin(button)\"\n (click)=\"button.click?.(button, $event)\"\n >\n @if (useCheckbox(button)) {\n <mat-checkbox [checked]=\"button.checked\" />\n }\n {{ button.label }}\n </button>\n }\n }\n }\n\n @if (displayedColumns.length) {\n <button mat-menu-item [matMenuTriggerFor]=\"columnMenu\" [ngClass]=\"needMargin(null)\">\n <span i18n>Colonnes</span>\n </button>\n }\n </ng-template>\n </mat-menu>\n } @else {\n @for (button of buttons; track button) {\n @if (defaultTrue(button.show)) {\n @if (button.href) {\n <a\n mat-icon-button\n [href]=\"button.href\"\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </a>\n } @else if (button.buttons) {\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"menu\"\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </button>\n <mat-menu #menu=\"matMenu\">\n <ng-template matMenuContent>\n @for (subButton of button.buttons; track subButton) {\n <a\n mat-menu-item\n [disabled]=\"subButton.disabled\"\n (click)=\"subButton.click(subButton, $event)\"\n >\n {{ subButton.label }}\n </a>\n }\n </ng-template>\n </mat-menu>\n } @else {\n <button\n mat-icon-button\n [disabled]=\"button.disabled\"\n [color]=\"color(button)\"\n [matTooltip]=\"button.label\"\n (click)=\"button.click?.(button, $event)\"\n >\n <mat-icon [naturalIcon]=\"button.icon\" />\n </button>\n }\n }\n }\n\n @if (displayedColumns.length) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"S\u00E9lectionner les colonnes\"\n [matMenuTriggerFor]=\"columnMenu\"\n >\n <mat-icon naturalIcon=\"view_column\" />\n </button>\n }\n }\n</div>\n\n<mat-menu #columnMenu=\"matMenu\">\n <ng-template matMenuContent>\n @for (column of displayedColumns; track column) {\n <div mat-menu-item (click)=\"menuItemClicked($event, column)\">\n <mat-checkbox\n [(ngModel)]=\"column.checked\"\n (click)=\"checkboxClicked($event, column)\"\n (change)=\"updateColumns()\"\n >{{ column.label }}</mat-checkbox\n >\n </div>\n }\n </ng-template>\n</mat-menu>\n", styles: [".align-with-checkbox{padding-left:61px}\n"] }]
5561
5568
  }], propDecorators: { buttons: [{
5562
5569
  type: Input
5563
5570
  }], availableColumns: [{
@@ -5727,10 +5734,7 @@ function isDate(value) {
5727
5734
  * - "dans 3 ans"
5728
5735
  */
5729
5736
  class NaturalTimeAgoPipe {
5730
- fakedNow;
5731
- constructor(fakedNow = null) {
5732
- this.fakedNow = fakedNow;
5733
- }
5737
+ fakedNow = null;
5734
5738
  getNow() {
5735
5739
  return this.fakedNow ?? Date.now();
5736
5740
  }
@@ -5836,7 +5840,7 @@ class NaturalTimeAgoPipe {
5836
5840
  throw new Error('Time travelling just happened');
5837
5841
  }
5838
5842
  }
5839
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalTimeAgoPipe, deps: [{ token: 'SHOULD_NEVER_BE_INJECTED', optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
5843
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalTimeAgoPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
5840
5844
  static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.13", ngImport: i0, type: NaturalTimeAgoPipe, isStandalone: true, name: "timeAgo" });
5841
5845
  }
5842
5846
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalTimeAgoPipe, decorators: [{
@@ -5845,12 +5849,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
5845
5849
  name: 'timeAgo',
5846
5850
  standalone: true,
5847
5851
  }]
5848
- }], ctorParameters: () => [{ type: undefined, decorators: [{
5849
- type: Optional
5850
- }, {
5851
- type: Inject,
5852
- args: ['SHOULD_NEVER_BE_INJECTED']
5853
- }] }] });
5852
+ }] });
5854
5853
 
5855
5854
  function densities(src, forImageSet) {
5856
5855
  const match = /^(.*\/)(\d+)$/.exec(src);
@@ -6045,8 +6044,8 @@ class NaturalDialogTriggerComponent {
6045
6044
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalDialogTriggerComponent, decorators: [{
6046
6045
  type: Component,
6047
6046
  args: [{
6048
- template: '',
6049
6047
  standalone: true,
6048
+ template: '',
6050
6049
  }]
6051
6050
  }], ctorParameters: () => [] });
6052
6051
 
@@ -6544,7 +6543,8 @@ class AbstractAssociationSelectComponent {
6544
6543
  operator: this.operatorCtrl,
6545
6544
  value: this.valueCtrl,
6546
6545
  });
6547
- constructor(data) {
6546
+ constructor() {
6547
+ const data = inject(NATURAL_DROPDOWN_DATA);
6548
6548
  this.configuration = data.configuration;
6549
6549
  // Immediately initValidators and everytime the operator change later
6550
6550
  this.operatorCtrl.valueChanges.pipe(startWith(null)).subscribe(() => this.initValidators());
@@ -6615,16 +6615,13 @@ class AbstractAssociationSelectComponent {
6615
6615
  throw new Error('Unsupported operator key: ' + key);
6616
6616
  }
6617
6617
  }
6618
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: AbstractAssociationSelectComponent, deps: [{ token: NATURAL_DROPDOWN_DATA }], target: i0.ɵɵFactoryTarget.Directive });
6618
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: AbstractAssociationSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6619
6619
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.13", type: AbstractAssociationSelectComponent, isStandalone: true, ngImport: i0 });
6620
6620
  }
6621
6621
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: AbstractAssociationSelectComponent, decorators: [{
6622
6622
  type: Directive,
6623
6623
  args: [{ standalone: true }]
6624
- }], ctorParameters: () => [{ type: undefined, decorators: [{
6625
- type: Inject,
6626
- args: [NATURAL_DROPDOWN_DATA]
6627
- }] }] });
6624
+ }], ctorParameters: () => [] });
6628
6625
 
6629
6626
  /**
6630
6627
  * This will completely ignore internal formControl and instead use the one from the component
@@ -7090,7 +7087,7 @@ class NaturalSelectComponent extends AbstractSelect {
7090
7087
  return this.variablesManager.variables.value;
7091
7088
  }
7092
7089
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
7093
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: NaturalSelectComponent, isStandalone: true, selector: "natural-select", inputs: { service: "service", optionRequired: "optionRequired", searchField: "searchField", searchOperator: "searchOperator", filter: "filter", pageSize: "pageSize", disabled: "disabled" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "autoTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- Autocomplete menu -->\n<mat-autocomplete\n #ac=\"matAutocomplete\"\n panelWidth=\"auto !important\"\n [displayWith]=\"getDisplayFn()\"\n (optionSelected)=\"propagateValue($event.option.value)\"\n>\n @for (item of items | async; track $index) {\n <mat-option [value]=\"item\">\n @let customTemplate = itemTemplate();\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"customTemplate ? customTemplate : defaultACItem\"\n />\n </mat-option>\n }\n @if (hasMoreItems) {\n <div class=\"mat-caption\" i18n style=\"padding: 5px 10px\">Saisir pour chercher parmi {{ nbTotal }} r\u00E9sultats</div>\n }\n</mat-autocomplete>\n\n<ng-template #defaultACItem let-item=\"item\">\n <span>{{ getDisplayFn()(item) }}</span>\n</ng-template>\n\n<!-- Input for autocomplete -->\n<mat-form-field [subscriptSizing]=\"subscriptSizing()\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <input\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n [formControl]=\"internalCtrl\"\n [matAutocomplete]=\"ac\"\n [errorStateMatcher]=\"matcher\"\n (blur)=\"onBlur()\"\n (change)=\"onInternalFormChange()\"\n (click)=\"autoTrigger().openPanel()\"\n (focus)=\"startSearch()\"\n (keydown.esc)=\"reset()\"\n (keydown.enter)=\"onKeyEnter()\"\n />\n\n @if (hint()) {\n <mat-hint>{{ hint() }}</mat-hint>\n }\n\n <!-- Meta data -->\n @if (!loading && showIcon) {\n <mat-icon matIconPrefix [naturalIcon]=\"icon\" />\n }\n\n @if (loading) {\n <div class=\"loading-wrapper\" matIconPrefix>\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"21\" [strokeWidth]=\"5\" />\n </div>\n }\n\n <!-- Clear button -->\n <div matIconSuffix>\n @if (internalCtrl.pristine && internalCtrl.value && internalCtrl.enabled && !clearLabel) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"D\u00E9s\u00E9lectionner\" (click)=\"clear()\">\n <mat-icon naturalIcon=\"close\" />\n </button>\n }\n @if (internalCtrl.dirty && internalCtrl.enabled && optionRequired) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"Annuler la recherche\" (click)=\"reset()\">\n <mat-icon naturalIcon=\"undo\" />\n </button>\n }\n @if (internalCtrl.pristine && internalCtrl.value && navigateTo) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n [routerLink]=\"navigateTo\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon naturalIcon=\"open_in_browser\" />\n </button>\n }\n </div>\n\n @if (hasRequiredError()) {\n <mat-error i18n>Ce champ est requis</mat-error>\n } @else if (error) {\n <mat-error>{{ error }}</mat-error>\n }\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n@if (showClearButton()) {\n <div class=\"external-buttons\">\n @if (showClearButton()) {\n <button color=\"warn\" mat-button (click)=\"clear()\">{{ clearLabel }}</button>\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}:host .loading-wrapper{display:flex;justify-content:center;align-items:center;width:48px;height:48px}\n"], dependencies: [{ kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i1$5.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i1$5.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i1$3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1$3.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
7090
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: NaturalSelectComponent, isStandalone: true, selector: "natural-select", inputs: { service: "service", optionRequired: "optionRequired", searchField: "searchField", searchOperator: "searchOperator", filter: "filter", pageSize: "pageSize", disabled: "disabled" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "autoTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- eslint-disable @angular-eslint/template/cyclomatic-complexity -->\n<!-- Autocomplete menu -->\n<mat-autocomplete\n #ac=\"matAutocomplete\"\n panelWidth=\"auto !important\"\n [displayWith]=\"getDisplayFn()\"\n (optionSelected)=\"propagateValue($event.option.value)\"\n>\n @for (item of items | async; track $index) {\n <mat-option [value]=\"item\">\n @let customTemplate = itemTemplate();\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"customTemplate ? customTemplate : defaultACItem\"\n />\n </mat-option>\n }\n @if (hasMoreItems) {\n <div class=\"mat-caption\" i18n style=\"padding: 5px 10px\">Saisir pour chercher parmi {{ nbTotal }} r\u00E9sultats</div>\n }\n</mat-autocomplete>\n\n<ng-template #defaultACItem let-item=\"item\">\n <span>{{ getDisplayFn()(item) }}</span>\n</ng-template>\n\n<!-- Input for autocomplete -->\n<mat-form-field [subscriptSizing]=\"subscriptSizing()\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <input\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n [formControl]=\"internalCtrl\"\n [matAutocomplete]=\"ac\"\n [errorStateMatcher]=\"matcher\"\n (blur)=\"onBlur()\"\n (change)=\"onInternalFormChange()\"\n (click)=\"autoTrigger().openPanel()\"\n (focus)=\"startSearch()\"\n (keydown.esc)=\"reset()\"\n (keydown.enter)=\"onKeyEnter()\"\n />\n\n @if (hint()) {\n <mat-hint>{{ hint() }}</mat-hint>\n }\n\n <!-- Meta data -->\n @if (!loading && showIcon) {\n <mat-icon matIconPrefix [naturalIcon]=\"icon\" />\n }\n\n @if (loading) {\n <div class=\"loading-wrapper\" matIconPrefix>\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"21\" [strokeWidth]=\"5\" />\n </div>\n }\n\n <!-- Clear button -->\n <div matIconSuffix>\n @if (internalCtrl.pristine && internalCtrl.value && internalCtrl.enabled && !clearLabel) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"D\u00E9s\u00E9lectionner\" (click)=\"clear()\">\n <mat-icon naturalIcon=\"close\" />\n </button>\n }\n @if (internalCtrl.dirty && internalCtrl.enabled && optionRequired) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"Annuler la recherche\" (click)=\"reset()\">\n <mat-icon naturalIcon=\"undo\" />\n </button>\n }\n @if (internalCtrl.pristine && internalCtrl.value && navigateTo) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n [routerLink]=\"navigateTo\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon naturalIcon=\"open_in_browser\" />\n </button>\n }\n </div>\n\n @if (hasRequiredError()) {\n <mat-error i18n>Ce champ est requis</mat-error>\n } @else if (error) {\n <mat-error>{{ error }}</mat-error>\n }\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n@if (showClearButton()) {\n <div class=\"external-buttons\">\n @if (showClearButton()) {\n <button color=\"warn\" mat-button (click)=\"clear()\">{{ clearLabel }}</button>\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}:host .loading-wrapper{display:flex;justify-content:center;align-items:center;width:48px;height:48px}\n"], dependencies: [{ kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i1$5.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i1$5.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i1$3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1$3.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
7094
7091
  }
7095
7092
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalSelectComponent, decorators: [{
7096
7093
  type: Component,
@@ -7108,7 +7105,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
7108
7105
  MatButtonModule,
7109
7106
  MatTooltipModule,
7110
7107
  RouterLink,
7111
- ], template: "<!-- Autocomplete menu -->\n<mat-autocomplete\n #ac=\"matAutocomplete\"\n panelWidth=\"auto !important\"\n [displayWith]=\"getDisplayFn()\"\n (optionSelected)=\"propagateValue($event.option.value)\"\n>\n @for (item of items | async; track $index) {\n <mat-option [value]=\"item\">\n @let customTemplate = itemTemplate();\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"customTemplate ? customTemplate : defaultACItem\"\n />\n </mat-option>\n }\n @if (hasMoreItems) {\n <div class=\"mat-caption\" i18n style=\"padding: 5px 10px\">Saisir pour chercher parmi {{ nbTotal }} r\u00E9sultats</div>\n }\n</mat-autocomplete>\n\n<ng-template #defaultACItem let-item=\"item\">\n <span>{{ getDisplayFn()(item) }}</span>\n</ng-template>\n\n<!-- Input for autocomplete -->\n<mat-form-field [subscriptSizing]=\"subscriptSizing()\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <input\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n [formControl]=\"internalCtrl\"\n [matAutocomplete]=\"ac\"\n [errorStateMatcher]=\"matcher\"\n (blur)=\"onBlur()\"\n (change)=\"onInternalFormChange()\"\n (click)=\"autoTrigger().openPanel()\"\n (focus)=\"startSearch()\"\n (keydown.esc)=\"reset()\"\n (keydown.enter)=\"onKeyEnter()\"\n />\n\n @if (hint()) {\n <mat-hint>{{ hint() }}</mat-hint>\n }\n\n <!-- Meta data -->\n @if (!loading && showIcon) {\n <mat-icon matIconPrefix [naturalIcon]=\"icon\" />\n }\n\n @if (loading) {\n <div class=\"loading-wrapper\" matIconPrefix>\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"21\" [strokeWidth]=\"5\" />\n </div>\n }\n\n <!-- Clear button -->\n <div matIconSuffix>\n @if (internalCtrl.pristine && internalCtrl.value && internalCtrl.enabled && !clearLabel) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"D\u00E9s\u00E9lectionner\" (click)=\"clear()\">\n <mat-icon naturalIcon=\"close\" />\n </button>\n }\n @if (internalCtrl.dirty && internalCtrl.enabled && optionRequired) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"Annuler la recherche\" (click)=\"reset()\">\n <mat-icon naturalIcon=\"undo\" />\n </button>\n }\n @if (internalCtrl.pristine && internalCtrl.value && navigateTo) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n [routerLink]=\"navigateTo\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon naturalIcon=\"open_in_browser\" />\n </button>\n }\n </div>\n\n @if (hasRequiredError()) {\n <mat-error i18n>Ce champ est requis</mat-error>\n } @else if (error) {\n <mat-error>{{ error }}</mat-error>\n }\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n@if (showClearButton()) {\n <div class=\"external-buttons\">\n @if (showClearButton()) {\n <button color=\"warn\" mat-button (click)=\"clear()\">{{ clearLabel }}</button>\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}:host .loading-wrapper{display:flex;justify-content:center;align-items:center;width:48px;height:48px}\n"] }]
7108
+ ], template: "<!-- eslint-disable @angular-eslint/template/cyclomatic-complexity -->\n<!-- Autocomplete menu -->\n<mat-autocomplete\n #ac=\"matAutocomplete\"\n panelWidth=\"auto !important\"\n [displayWith]=\"getDisplayFn()\"\n (optionSelected)=\"propagateValue($event.option.value)\"\n>\n @for (item of items | async; track $index) {\n <mat-option [value]=\"item\">\n @let customTemplate = itemTemplate();\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"customTemplate ? customTemplate : defaultACItem\"\n />\n </mat-option>\n }\n @if (hasMoreItems) {\n <div class=\"mat-caption\" i18n style=\"padding: 5px 10px\">Saisir pour chercher parmi {{ nbTotal }} r\u00E9sultats</div>\n }\n</mat-autocomplete>\n\n<ng-template #defaultACItem let-item=\"item\">\n <span>{{ getDisplayFn()(item) }}</span>\n</ng-template>\n\n<!-- Input for autocomplete -->\n<mat-form-field [subscriptSizing]=\"subscriptSizing()\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <input\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n [formControl]=\"internalCtrl\"\n [matAutocomplete]=\"ac\"\n [errorStateMatcher]=\"matcher\"\n (blur)=\"onBlur()\"\n (change)=\"onInternalFormChange()\"\n (click)=\"autoTrigger().openPanel()\"\n (focus)=\"startSearch()\"\n (keydown.esc)=\"reset()\"\n (keydown.enter)=\"onKeyEnter()\"\n />\n\n @if (hint()) {\n <mat-hint>{{ hint() }}</mat-hint>\n }\n\n <!-- Meta data -->\n @if (!loading && showIcon) {\n <mat-icon matIconPrefix [naturalIcon]=\"icon\" />\n }\n\n @if (loading) {\n <div class=\"loading-wrapper\" matIconPrefix>\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"21\" [strokeWidth]=\"5\" />\n </div>\n }\n\n <!-- Clear button -->\n <div matIconSuffix>\n @if (internalCtrl.pristine && internalCtrl.value && internalCtrl.enabled && !clearLabel) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"D\u00E9s\u00E9lectionner\" (click)=\"clear()\">\n <mat-icon naturalIcon=\"close\" />\n </button>\n }\n @if (internalCtrl.dirty && internalCtrl.enabled && optionRequired) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"Annuler la recherche\" (click)=\"reset()\">\n <mat-icon naturalIcon=\"undo\" />\n </button>\n }\n @if (internalCtrl.pristine && internalCtrl.value && navigateTo) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n [routerLink]=\"navigateTo\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon naturalIcon=\"open_in_browser\" />\n </button>\n }\n </div>\n\n @if (hasRequiredError()) {\n <mat-error i18n>Ce champ est requis</mat-error>\n } @else if (error) {\n <mat-error>{{ error }}</mat-error>\n }\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n@if (showClearButton()) {\n <div class=\"external-buttons\">\n @if (showClearButton()) {\n <button color=\"warn\" mat-button (click)=\"clear()\">{{ clearLabel }}</button>\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}:host .loading-wrapper{display:flex;justify-content:center;align-items:center;width:48px;height:48px}\n"] }]
7112
7109
  }], propDecorators: { service: [{
7113
7110
  type: Input,
7114
7111
  args: [{ required: true }]
@@ -7177,7 +7174,7 @@ class TypeTextComponent {
7177
7174
  constructor() {
7178
7175
  const data = inject(NATURAL_DROPDOWN_DATA);
7179
7176
  this.formCtrl.valueChanges.subscribe(value => {
7180
- this.renderedValue.next(value === null ? '' : this.formCtrl.value + '');
7177
+ this.renderedValue.next(value === null ? '' : this.formCtrl.value);
7181
7178
  });
7182
7179
  this.formCtrl.setValidators([Validators.required]);
7183
7180
  if (data.condition?.like) {
@@ -7304,361 +7301,94 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
7304
7301
  args: [{ imports: [FormsModule, ReactiveFormsModule, MatFormFieldModule, MatSelectModule, MatOptionModule, MatInputModule], template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 4em; margin-right: 1em\">\n <mat-label i18n=\"Mathematical operator < > =\">Op\u00E9rateur</mat-label>\n <mat-select panelWidth=\"\" [formControl]=\"operatorCtrl\" [required]=\"true\">\n @for (item of operators; track item) {\n <mat-option [value]=\"item.key\">\n {{ item.label }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label i18n>Valeur</mat-label>\n <input\n matInput\n type=\"number\"\n [errorStateMatcher]=\"matcher\"\n [formControl]=\"valueCtrl\"\n [attr.max]=\"configuration.max\"\n [attr.min]=\"configuration.min\"\n [required]=\"true\"\n [step]=\"configuration.step\"\n (keydown.enter)=\"close()\"\n />\n @if (valueCtrl.hasError('min')) {\n <mat-error>< {{ configuration.min }}</mat-error>\n }\n @if (valueCtrl.hasError('max')) {\n <mat-error>> {{ configuration.max }}</mat-error>\n }\n </mat-form-field>\n</form>\n", styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"] }]
7305
7302
  }], ctorParameters: () => [] });
7306
7303
 
7307
- class HierarchicFlatNode {
7308
- node;
7309
- name;
7310
- level;
7311
- expandable;
7312
- selectable;
7313
- deselectable;
7314
- loading = false;
7315
- constructor(node, name, level = 0, expandable = false, selectable = true, deselectable = true) {
7316
- this.node = node;
7317
- this.name = name;
7318
- this.level = level;
7319
- this.expandable = expandable;
7320
- this.selectable = selectable;
7321
- this.deselectable = deselectable;
7304
+ class FacetSelectorComponent {
7305
+ data = inject(NATURAL_DROPDOWN_DATA);
7306
+ dropdownRef = inject(NaturalDropdownRef);
7307
+ // Never has a real value
7308
+ renderedValue = new BehaviorSubject('');
7309
+ facets = this.data.configuration.facets;
7310
+ selection = null;
7311
+ /**
7312
+ * Get value, including rich object types
7313
+ */
7314
+ getCondition() {
7315
+ return {};
7322
7316
  }
7323
- }
7324
-
7325
- class HierarchicModelNode {
7326
- model;
7327
- config;
7328
- childrenChange = new BehaviorSubject([]);
7329
- constructor(model, config) {
7330
- this.model = model;
7331
- this.config = config;
7317
+ /**
7318
+ * Allow to close the dropdown with a valid value
7319
+ */
7320
+ close() {
7321
+ if (this.selection) {
7322
+ this.dropdownRef.close({
7323
+ condition: {},
7324
+ facet: this.selection,
7325
+ });
7326
+ }
7332
7327
  }
7333
- get children() {
7334
- return this.childrenChange.value;
7328
+ isValid() {
7329
+ return !!this.selection;
7335
7330
  }
7331
+ isDirty() {
7332
+ return true;
7333
+ }
7334
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: FacetSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7335
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: FacetSelectorComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "@if (data.title) {\n <div class=\"dropdown-title mat-body-2\">{{ data.title }}</div>\n}\n<mat-nav-list>\n @for (facet of facets; track $index) {\n <mat-list-item (click)=\"selection = facet; close()\">\n <a>{{ facet.display }}</a>\n </mat-list-item>\n }\n</mat-nav-list>\n", styles: [".mat-nav-list{padding:0}.dropdown-title{opacity:.7;padding:5px;font-variant:all-small-caps;font-size:18px}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i4$1.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i4$1.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }] });
7336
7336
  }
7337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: FacetSelectorComponent, decorators: [{
7338
+ type: Component,
7339
+ args: [{ imports: [MatListModule], template: "@if (data.title) {\n <div class=\"dropdown-title mat-body-2\">{{ data.title }}</div>\n}\n<mat-nav-list>\n @for (facet of facets; track $index) {\n <mat-list-item (click)=\"selection = facet; close()\">\n <a>{{ facet.display }}</a>\n </mat-list-item>\n }\n</mat-nav-list>\n", styles: [".mat-nav-list{padding:0}.dropdown-title{opacity:.7;padding:5px;font-variant:all-small-caps;font-size:18px}\n"] }]
7340
+ }] });
7337
7341
 
7338
- class NaturalHierarchicSelectorService {
7339
- injector = inject(Injector);
7342
+ // Required to check invalid fields when initializing natural-search
7343
+ class AlwaysErrorStateMatcher {
7344
+ isErrorState(control) {
7345
+ return !!control && control.invalid;
7346
+ }
7347
+ }
7348
+ function isComponentValid(component) {
7349
+ return () => {
7350
+ if (!component.isValid()) {
7351
+ return { component: true };
7352
+ }
7353
+ return null;
7354
+ };
7355
+ }
7356
+ class NaturalInputComponent {
7357
+ element = inject(ElementRef);
7358
+ dropdownService = inject(NaturalDropdownService);
7359
+ injector = inject(EnvironmentInjector);
7340
7360
  /**
7341
- * Stores the global result of the tree
7342
- * This observable contains Node.
7343
- * When it's updated, the TreeController and TreeFlattener process the new array to generate the flat tree.
7361
+ * Controls the ripple effect, used when opening a dropdown
7344
7362
  */
7345
- dataChange = new BehaviorSubject([]);
7363
+ ripple = viewChild.required(MatRipple);
7346
7364
  /**
7347
- * Configuration for relations and selection constraints
7348
- *
7349
- * The list should be sorted in the order of the hierarchic (list first parent rules, then child rules)
7365
+ * Native element ref for <input> related to this <natural-input> component
7350
7366
  */
7351
- configuration = [];
7367
+ input = viewChild.required('input');
7352
7368
  /**
7353
- * Init component by saving the complete configuration, and then retrieving root elements.
7354
- * Updates **another** observable (this.dataChange) when data is retrieved.
7369
+ * Label for this field
7355
7370
  */
7356
- init(config, contextFilter = null, searchVariables = null) {
7357
- this.validateConfiguration(config);
7358
- this.configuration = config;
7359
- return this.getList(null, contextFilter, searchVariables).pipe(map(data => this.dataChange.next(data)));
7360
- }
7371
+ placeholder;
7361
7372
  /**
7362
- * Get list of children, considering given FlatNode id as a parent.
7363
- * Mark loading status individually on nodes.
7373
+ * Name of the field on which do a global search (without facet)
7364
7374
  */
7365
- loadChildren(flatNode, contextFilter = null) {
7366
- // Dont refetch children. Improve performances
7367
- // Prevents interferences between HierarchicModelNode structure and angular components navigation.
7368
- // Prevents a bug where grand children were lost if closing root
7369
- if (flatNode.node.children.length) {
7370
- return;
7371
- }
7372
- flatNode.loading = true;
7373
- this.getList(flatNode, contextFilter)
7374
- .pipe(finalize$1(() => (flatNode.loading = false)))
7375
- .subscribe(items => {
7376
- flatNode.node.childrenChange.next(items);
7377
- this.dataChange.next(this.dataChange.value);
7378
- });
7379
- }
7380
- search(searchVariables, contextFilter = null) {
7381
- this.getList(null, contextFilter, searchVariables).subscribe(items => {
7382
- this.dataChange.next(items);
7383
- });
7384
- }
7375
+ searchFieldName = 'search';
7385
7376
  /**
7386
- * Retrieve elements from the server
7387
- * Get root elements if node is null, or child elements if node is given
7377
+ * Selected setted for this component
7388
7378
  */
7389
- getList(node = null, contextFilters = null, searchVariables = null) {
7390
- const configurations = this.getContextualizedConfigs(node, contextFilters, searchVariables);
7391
- const observables = configurations.map(c => c.injectedService.getAll(c.variablesManager));
7392
- // Fire queries, and merge results, transforming apollo items into Node Object.
7393
- return forkJoin(observables).pipe(map(results => {
7394
- const listing = [];
7395
- // For each result of an observable
7396
- for (let i = 0; i < results.length; i++) {
7397
- // For each item of the result, convert into Node object
7398
- for (const item of results[i].items) {
7399
- listing.push(this.getOrCreateModelNode(item, configurations[i].configuration));
7400
- }
7401
- }
7402
- return listing;
7403
- }));
7404
- }
7405
- countItems(node, contextFilters = null) {
7406
- const configurations = this.getContextualizedConfigs(node, contextFilters, null);
7407
- const observables = configurations.map(c => c.injectedService.count(c.variablesManager).pipe(first$1()));
7408
- forkJoin(observables).subscribe(results => {
7409
- const totalItems = results.reduce((total, length) => total + length, 0);
7410
- node.expandable = totalItems > 0;
7411
- });
7412
- }
7413
- getContextualizedConfigs(node = null, contextFilters = null, searchVariables = null) {
7414
- const configsAndServices = [];
7415
- // Considering the whole configuration may cause queries with no/wrong results we have imperatively to avoid !
7416
- // e.g there are cross dependencies between equipments and taxonomies filters. Both have "parents" and "taxonomies" filters...
7417
- // When clicking on a equipment, the configuration of taxonomies with match "parents" filter, but use the id of the equipment
7418
- // To fix this, we should only consider configuration after the one given by the node passed as argument.
7419
- // That would mean : no child can affect parent.
7420
- // That would mean : sorting in the configuration have semantic/hierarchy implications
7421
- const configs = node ? this.getNextConfigs(node.node.config) : this.configuration;
7422
- const pagination = { pageIndex: 0, pageSize: 999 };
7423
- for (const config of configs) {
7424
- const contextFilter = this.getFilterByService(config, contextFilters);
7425
- const filter = this.getServiceFilter(node, config, contextFilter, !!searchVariables);
7426
- if (!filter) {
7427
- continue;
7428
- }
7429
- const variablesManager = new NaturalQueryVariablesManager();
7430
- variablesManager.set('variables', { filter: filter, pagination: pagination });
7431
- variablesManager.set('config-filter', { filter: config.filter });
7432
- if (searchVariables) {
7433
- variablesManager.set('natural-search', searchVariables);
7434
- }
7435
- const injectedService = this.injector.get(config.service);
7436
- configsAndServices.push({
7437
- configuration: config,
7438
- injectedService: injectedService,
7439
- variablesManager: variablesManager,
7440
- });
7441
- }
7442
- return configsAndServices;
7443
- }
7379
+ selection = null;
7444
7380
  /**
7445
- * Return models matching given FlatNodes
7446
- * Returns a Literal of models grouped by their configuration attribute "selectableAtKey"
7381
+ * Available facets, allows the user to pick one, than generated then a selection
7447
7382
  */
7448
- toOrganizedSelection(nodes) {
7449
- const selection = this.configuration.reduce((group, config) => {
7450
- if (config.selectableAtKey) {
7451
- group[config.selectableAtKey] = [];
7452
- }
7453
- return group;
7454
- }, {});
7455
- for (const node of nodes) {
7456
- if (node.config.selectableAtKey) {
7457
- selection[node.config.selectableAtKey].push(node.model);
7458
- }
7459
- }
7460
- return selection;
7461
- }
7383
+ facets;
7462
7384
  /**
7463
- * Transforms an OrganizedModelSelection into a list of ModelNodes
7385
+ * Text display in the dropdown to select the facet
7464
7386
  */
7465
- fromOrganizedSelection(organizedModelSelection) {
7466
- if (!organizedModelSelection) {
7467
- return [];
7468
- }
7469
- const result = [];
7470
- for (const selectableAtKey of Object.keys(organizedModelSelection)) {
7471
- const config = this.getConfigurationBySelectableKey(selectableAtKey);
7472
- if (config) {
7473
- for (const model of organizedModelSelection[selectableAtKey]) {
7474
- result.push(new HierarchicModelNode(model, config));
7475
- }
7476
- }
7477
- }
7478
- return result;
7479
- }
7387
+ dropdownTitle = '';
7480
7388
  /**
7481
- * Checks that each configuration.selectableAtKey attribute is unique
7389
+ * Emits when user a added/updated/deleted a search (from global context or from facet)
7482
7390
  */
7483
- validateConfiguration(configurations) {
7484
- const selectableAtKeyAttributes = [];
7485
- for (const config of configurations) {
7486
- if (config.selectableAtKey) {
7487
- const keyIndex = selectableAtKeyAttributes.indexOf(config.selectableAtKey);
7488
- if (keyIndex === -1 && config.selectableAtKey) {
7489
- selectableAtKeyAttributes.push(config.selectableAtKey);
7490
- }
7491
- // TODO : remove ?
7492
- // This behavior maybe dangerous in case we re-open hierarchical selector with the last returned config having non-unique
7493
- // keys
7494
- if (keyIndex < -1) {
7495
- console.warn('Invalid hierarchic configuration : selectableAtKey attribute should be unique');
7496
- }
7497
- }
7498
- }
7499
- }
7500
- /**
7501
- * Return configurations setup in the list after the given one
7502
- */
7503
- getNextConfigs(config) {
7504
- const configIndex = this.configuration.findIndex(c => c === config);
7505
- return this.configuration.slice(configIndex);
7506
- }
7507
- /**
7508
- * Builds queryVariables filter for children query
7509
- */
7510
- getServiceFilter(flatNode, config, contextFilter = null, allDeeps = false) {
7511
- const fieldCondition = {};
7512
- // if no parent, filter empty elements
7513
- if (!flatNode) {
7514
- if (!config.parentsRelationNames) {
7515
- return contextFilter ? contextFilter : {};
7516
- }
7517
- if (!allDeeps) {
7518
- config.parentsRelationNames.forEach(f => {
7519
- fieldCondition[f] = { empty: {} };
7520
- });
7521
- }
7522
- }
7523
- else {
7524
- if (!flatNode.node.config.childrenRelationNames || !config.parentsRelationNames) {
7525
- return null;
7526
- }
7527
- const matchingFilters = intersection(flatNode.node.config.childrenRelationNames, config.parentsRelationNames);
7528
- if (!matchingFilters.length) {
7529
- return null;
7530
- }
7531
- fieldCondition[matchingFilters[0]] = { have: { values: [flatNode.node.model.id] } };
7532
- }
7533
- const filters = { groups: [{ conditions: [fieldCondition] }] };
7534
- // todo : is it right ? shouldn't it be managed with QueryVariablesManager's channels ? ?
7535
- if (contextFilter) {
7536
- filters.groups.push(...contextFilter.groups);
7537
- }
7538
- return filters;
7539
- }
7540
- /**
7541
- * Return a context filter applicable to the service for given config
7542
- *
7543
- * @param config Applicable config
7544
- * @param contextFilters List of context filters
7545
- */
7546
- getFilterByService(config, contextFilters) {
7547
- if (!contextFilters || !config) {
7548
- return null;
7549
- }
7550
- const filter = contextFilters.find(f => f.service === config.service);
7551
- return filter ? filter.filter : null;
7552
- }
7553
- /**
7554
- * Search in configurations.selectableAtKey attribute to find given key and return the configuration
7555
- */
7556
- getConfigurationBySelectableKey(key) {
7557
- if (!this.configuration) {
7558
- return null;
7559
- }
7560
- return this.configuration.find(conf => conf.selectableAtKey === key) || null;
7561
- }
7562
- getOrCreateModelNode(item, configuration) {
7563
- const node = this.dataChange.value.find(n => n.model.id === item.id && n.model.__typename === item.__typename);
7564
- return node || new HierarchicModelNode(item, configuration);
7565
- }
7566
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7567
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorService, providedIn: 'root' });
7568
- }
7569
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorService, decorators: [{
7570
- type: Injectable,
7571
- args: [{ providedIn: 'root' }]
7572
- }] });
7573
-
7574
- class FacetSelectorComponent {
7575
- data = inject(NATURAL_DROPDOWN_DATA);
7576
- dropdownRef = inject(NaturalDropdownRef);
7577
- // Never has a real value
7578
- renderedValue = new BehaviorSubject('');
7579
- facets = this.data.configuration.facets;
7580
- selection = null;
7581
- /**
7582
- * Get value, including rich object types
7583
- */
7584
- getCondition() {
7585
- return {};
7586
- }
7587
- /**
7588
- * Allow to close the dropdown with a valid value
7589
- */
7590
- close() {
7591
- if (this.selection) {
7592
- this.dropdownRef.close({
7593
- condition: {},
7594
- facet: this.selection,
7595
- });
7596
- }
7597
- }
7598
- isValid() {
7599
- return !!this.selection;
7600
- }
7601
- isDirty() {
7602
- return true;
7603
- }
7604
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: FacetSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7605
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: FacetSelectorComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "@if (data.title) {\n <div class=\"dropdown-title mat-body-2\">{{ data.title }}</div>\n}\n<mat-nav-list>\n @for (facet of facets; track $index) {\n <mat-list-item (click)=\"selection = facet; close()\">\n <a>{{ facet.display }}</a>\n </mat-list-item>\n }\n</mat-nav-list>\n", styles: [".mat-nav-list{padding:0}.dropdown-title{opacity:.7;padding:5px;font-variant:all-small-caps;font-size:18px}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i4$1.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i4$1.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }] });
7606
- }
7607
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: FacetSelectorComponent, decorators: [{
7608
- type: Component,
7609
- args: [{ imports: [MatListModule], template: "@if (data.title) {\n <div class=\"dropdown-title mat-body-2\">{{ data.title }}</div>\n}\n<mat-nav-list>\n @for (facet of facets; track $index) {\n <mat-list-item (click)=\"selection = facet; close()\">\n <a>{{ facet.display }}</a>\n </mat-list-item>\n }\n</mat-nav-list>\n", styles: [".mat-nav-list{padding:0}.dropdown-title{opacity:.7;padding:5px;font-variant:all-small-caps;font-size:18px}\n"] }]
7610
- }] });
7611
-
7612
- // Required to check invalid fields when initializing natural-search
7613
- class AlwaysErrorStateMatcher {
7614
- isErrorState(control) {
7615
- return !!control && control.invalid;
7616
- }
7617
- }
7618
- function isComponentValid(component) {
7619
- return () => {
7620
- if (!component.isValid()) {
7621
- return { component: true };
7622
- }
7623
- return null;
7624
- };
7625
- }
7626
- class NaturalInputComponent {
7627
- element = inject(ElementRef);
7628
- dropdownService = inject(NaturalDropdownService);
7629
- injector = inject(EnvironmentInjector);
7630
- /**
7631
- * Controls the ripple effect, used when opening a dropdown
7632
- */
7633
- ripple = viewChild.required(MatRipple);
7634
- /**
7635
- * Native element ref for <input> related to this <natural-input> component
7636
- */
7637
- input = viewChild.required('input');
7638
- /**
7639
- * Label for this field
7640
- */
7641
- placeholder;
7642
- /**
7643
- * Name of the field on which do a global search (without facet)
7644
- */
7645
- searchFieldName = 'search';
7646
- /**
7647
- * Selected setted for this component
7648
- */
7649
- selection = null;
7650
- /**
7651
- * Available facets, allows the user to pick one, than generated then a selection
7652
- */
7653
- facets;
7654
- /**
7655
- * Text display in the dropdown to select the facet
7656
- */
7657
- dropdownTitle = '';
7658
- /**
7659
- * Emits when user a added/updated/deleted a search (from global context or from facet)
7660
- */
7661
- selectionChange = output();
7391
+ selectionChange = output();
7662
7392
  /**
7663
7393
  * Emits when user removes the search by pressing the cross icon
7664
7394
  */
@@ -8082,6 +7812,273 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
8082
7812
  type: Input
8083
7813
  }] } });
8084
7814
 
7815
+ class HierarchicFlatNode {
7816
+ node;
7817
+ name;
7818
+ level;
7819
+ expandable;
7820
+ selectable;
7821
+ deselectable;
7822
+ loading = false;
7823
+ constructor(node, name, level = 0, expandable = false, selectable = true, deselectable = true) {
7824
+ this.node = node;
7825
+ this.name = name;
7826
+ this.level = level;
7827
+ this.expandable = expandable;
7828
+ this.selectable = selectable;
7829
+ this.deselectable = deselectable;
7830
+ }
7831
+ }
7832
+
7833
+ class HierarchicModelNode {
7834
+ model;
7835
+ config;
7836
+ childrenChange = new BehaviorSubject([]);
7837
+ constructor(model, config) {
7838
+ this.model = model;
7839
+ this.config = config;
7840
+ }
7841
+ get children() {
7842
+ return this.childrenChange.value;
7843
+ }
7844
+ }
7845
+
7846
+ class NaturalHierarchicSelectorService {
7847
+ injector = inject(Injector);
7848
+ /**
7849
+ * Stores the global result of the tree
7850
+ * This observable contains Node.
7851
+ * When it's updated, the TreeController and TreeFlattener process the new array to generate the flat tree.
7852
+ */
7853
+ dataChange = new BehaviorSubject([]);
7854
+ /**
7855
+ * Configuration for relations and selection constraints
7856
+ *
7857
+ * The list should be sorted in the order of the hierarchic (list first parent rules, then child rules)
7858
+ */
7859
+ configuration = [];
7860
+ /**
7861
+ * Init component by saving the complete configuration, and then retrieving root elements.
7862
+ * Updates **another** observable (this.dataChange) when data is retrieved.
7863
+ */
7864
+ init(config, contextFilter = null, searchVariables = null) {
7865
+ this.validateConfiguration(config);
7866
+ this.configuration = config;
7867
+ return this.getList(null, contextFilter, searchVariables).pipe(map(data => this.dataChange.next(data)));
7868
+ }
7869
+ /**
7870
+ * Get list of children, considering given FlatNode id as a parent.
7871
+ * Mark loading status individually on nodes.
7872
+ */
7873
+ loadChildren(flatNode, contextFilter = null) {
7874
+ // Don't refetch children. Improve performances
7875
+ // Prevents interferences between HierarchicModelNode structure and angular components navigation.
7876
+ // Prevents a bug where grand children were lost if closing root
7877
+ if (flatNode.node.children.length) {
7878
+ return;
7879
+ }
7880
+ flatNode.loading = true;
7881
+ this.getList(flatNode, contextFilter)
7882
+ .pipe(finalize$1(() => (flatNode.loading = false)))
7883
+ .subscribe(items => {
7884
+ flatNode.node.childrenChange.next(items);
7885
+ this.dataChange.next(this.dataChange.value);
7886
+ });
7887
+ }
7888
+ search(searchVariables, contextFilter = null) {
7889
+ this.getList(null, contextFilter, searchVariables).subscribe(items => {
7890
+ this.dataChange.next(items);
7891
+ });
7892
+ }
7893
+ /**
7894
+ * Retrieve elements from the server
7895
+ * Get root elements if node is null, or child elements if node is given
7896
+ */
7897
+ getList(node = null, contextFilters = null, searchVariables = null) {
7898
+ const configurations = this.getContextualizedConfigs(node, contextFilters, searchVariables);
7899
+ const observables = configurations.map(c => c.injectedService.getAll(c.variablesManager));
7900
+ // Fire queries, and merge results, transforming apollo items into Node Object.
7901
+ return forkJoin(observables).pipe(map(results => {
7902
+ const listing = [];
7903
+ // For each result of an observable
7904
+ for (let i = 0; i < results.length; i++) {
7905
+ // For each item of the result, convert into Node object
7906
+ for (const item of results[i].items) {
7907
+ listing.push(this.getOrCreateModelNode(item, configurations[i].configuration));
7908
+ }
7909
+ }
7910
+ return listing;
7911
+ }));
7912
+ }
7913
+ countItems(node, contextFilters = null) {
7914
+ const configurations = this.getContextualizedConfigs(node, contextFilters, null);
7915
+ const observables = configurations.map(c => c.injectedService.count(c.variablesManager).pipe(first$1()));
7916
+ forkJoin(observables).subscribe(results => {
7917
+ const totalItems = results.reduce((total, length) => total + length, 0);
7918
+ node.expandable = totalItems > 0;
7919
+ });
7920
+ }
7921
+ getContextualizedConfigs(node = null, contextFilters = null, searchVariables = null) {
7922
+ const configsAndServices = [];
7923
+ // Considering the whole configuration may cause queries with no/wrong results we have imperatively to avoid !
7924
+ // e.g there are cross dependencies between equipments and taxonomies filters. Both have "parents" and "taxonomies" filters...
7925
+ // When clicking on a equipment, the configuration of taxonomies with match "parents" filter, but use the id of the equipment
7926
+ // To fix this, we should only consider configuration after the one given by the node passed as argument.
7927
+ // That would mean : no child can affect parent.
7928
+ // That would mean : sorting in the configuration have semantic/hierarchy implications
7929
+ const configs = node ? this.getNextConfigs(node.node.config) : this.configuration;
7930
+ const pagination = { pageIndex: 0, pageSize: 999 };
7931
+ for (const config of configs) {
7932
+ const contextFilter = this.getFilterByService(config, contextFilters);
7933
+ const filter = this.getServiceFilter(node, config, contextFilter, !!searchVariables);
7934
+ if (!filter) {
7935
+ continue;
7936
+ }
7937
+ const variablesManager = new NaturalQueryVariablesManager();
7938
+ variablesManager.set('variables', { filter: filter, pagination: pagination });
7939
+ variablesManager.set('config-filter', { filter: config.filter });
7940
+ if (searchVariables) {
7941
+ variablesManager.set('natural-search', searchVariables);
7942
+ }
7943
+ const injectedService = this.injector.get(config.service);
7944
+ configsAndServices.push({
7945
+ configuration: config,
7946
+ injectedService: injectedService,
7947
+ variablesManager: variablesManager,
7948
+ });
7949
+ }
7950
+ return configsAndServices;
7951
+ }
7952
+ /**
7953
+ * Return models matching given FlatNodes
7954
+ * Returns a Literal of models grouped by their configuration attribute "selectableAtKey"
7955
+ */
7956
+ toOrganizedSelection(nodes) {
7957
+ const selection = this.configuration.reduce((group, config) => {
7958
+ if (config.selectableAtKey) {
7959
+ group[config.selectableAtKey] = [];
7960
+ }
7961
+ return group;
7962
+ }, {});
7963
+ for (const node of nodes) {
7964
+ if (node.config.selectableAtKey) {
7965
+ selection[node.config.selectableAtKey].push(node.model);
7966
+ }
7967
+ }
7968
+ return selection;
7969
+ }
7970
+ /**
7971
+ * Transforms an OrganizedModelSelection into a list of ModelNodes
7972
+ */
7973
+ fromOrganizedSelection(organizedModelSelection) {
7974
+ if (!organizedModelSelection) {
7975
+ return [];
7976
+ }
7977
+ const result = [];
7978
+ for (const selectableAtKey of Object.keys(organizedModelSelection)) {
7979
+ const config = this.getConfigurationBySelectableKey(selectableAtKey);
7980
+ if (config) {
7981
+ for (const model of organizedModelSelection[selectableAtKey]) {
7982
+ result.push(new HierarchicModelNode(model, config));
7983
+ }
7984
+ }
7985
+ }
7986
+ return result;
7987
+ }
7988
+ /**
7989
+ * Checks that each configuration.selectableAtKey attribute is unique
7990
+ */
7991
+ validateConfiguration(configurations) {
7992
+ const selectableAtKeyAttributes = [];
7993
+ for (const config of configurations) {
7994
+ if (config.selectableAtKey) {
7995
+ const keyIndex = selectableAtKeyAttributes.indexOf(config.selectableAtKey);
7996
+ if (keyIndex === -1 && config.selectableAtKey) {
7997
+ selectableAtKeyAttributes.push(config.selectableAtKey);
7998
+ }
7999
+ // TODO : remove ?
8000
+ // This behavior maybe dangerous in case we re-open hierarchical selector with the last returned config having non-unique
8001
+ // keys
8002
+ if (keyIndex < -1) {
8003
+ console.warn('Invalid hierarchic configuration : selectableAtKey attribute should be unique');
8004
+ }
8005
+ }
8006
+ }
8007
+ }
8008
+ /**
8009
+ * Return configurations setup in the list after the given one
8010
+ */
8011
+ getNextConfigs(config) {
8012
+ const configIndex = this.configuration.findIndex(c => c === config);
8013
+ return this.configuration.slice(configIndex);
8014
+ }
8015
+ /**
8016
+ * Builds queryVariables filter for children query
8017
+ */
8018
+ getServiceFilter(flatNode, config, contextFilter = null, allDeeps = false) {
8019
+ const fieldCondition = {};
8020
+ // if no parent, filter empty elements
8021
+ if (!flatNode) {
8022
+ if (!config.parentsRelationNames) {
8023
+ return contextFilter ? contextFilter : {};
8024
+ }
8025
+ if (!allDeeps) {
8026
+ config.parentsRelationNames.forEach(f => {
8027
+ fieldCondition[f] = { empty: {} };
8028
+ });
8029
+ }
8030
+ }
8031
+ else {
8032
+ if (!flatNode.node.config.childrenRelationNames || !config.parentsRelationNames) {
8033
+ return null;
8034
+ }
8035
+ const matchingFilters = intersection(flatNode.node.config.childrenRelationNames, config.parentsRelationNames);
8036
+ if (!matchingFilters.length) {
8037
+ return null;
8038
+ }
8039
+ fieldCondition[matchingFilters[0]] = { have: { values: [flatNode.node.model.id] } };
8040
+ }
8041
+ const filters = { groups: [{ conditions: [fieldCondition] }] };
8042
+ // todo : is it right ? shouldn't it be managed with QueryVariablesManager's channels ? ?
8043
+ if (contextFilter) {
8044
+ filters.groups.push(...contextFilter.groups);
8045
+ }
8046
+ return filters;
8047
+ }
8048
+ /**
8049
+ * Return a context filter applicable to the service for given config
8050
+ *
8051
+ * @param config Applicable config
8052
+ * @param contextFilters List of context filters
8053
+ */
8054
+ getFilterByService(config, contextFilters) {
8055
+ if (!contextFilters || !config) {
8056
+ return null;
8057
+ }
8058
+ const filter = contextFilters.find(f => f.service === config.service);
8059
+ return filter ? filter.filter : null;
8060
+ }
8061
+ /**
8062
+ * Search in configurations.selectableAtKey attribute to find given key and return the configuration
8063
+ */
8064
+ getConfigurationBySelectableKey(key) {
8065
+ if (!this.configuration) {
8066
+ return null;
8067
+ }
8068
+ return this.configuration.find(conf => conf.selectableAtKey === key) || null;
8069
+ }
8070
+ getOrCreateModelNode(item, configuration) {
8071
+ const node = this.dataChange.value.find(n => n.model.id === item.id && n.model.__typename === item.__typename);
8072
+ return node || new HierarchicModelNode(item, configuration);
8073
+ }
8074
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8075
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorService, providedIn: 'root' });
8076
+ }
8077
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorService, decorators: [{
8078
+ type: Injectable,
8079
+ args: [{ providedIn: 'root' }]
8080
+ }] });
8081
+
8085
8082
  class NaturalHierarchicSelectorComponent {
8086
8083
  destroyRef = inject(DestroyRef);
8087
8084
  hierarchicSelectorService = inject(NaturalHierarchicSelectorService);
@@ -8118,6 +8115,14 @@ class NaturalHierarchicSelectorComponent {
8118
8115
  * Selections to apply on natural-search on component initialisation
8119
8116
  */
8120
8117
  searchSelections = [];
8118
+ /**
8119
+ * Select all fetched items of the current search result
8120
+ *
8121
+ * Use very carefully as recursivity is ignored. The selection includes children (if any) even if the child list has been closed
8122
+ *
8123
+ * Should be used __only__ for non-recursive use cases. Avoid with recursive because it's not intuitive for end user
8124
+ */
8125
+ allowSelectAll = input(false);
8121
8126
  /**
8122
8127
  * Emits when natural-search selections change
8123
8128
  */
@@ -8145,7 +8150,10 @@ class NaturalHierarchicSelectorComponent {
8145
8150
  /**
8146
8151
  * Cache for transformed nodes
8147
8152
  */
8148
- flatNodeMap = new Map();
8153
+ flatNodeMap = signal(new Map(), { equal: () => false });
8154
+ tooBig = computed(() => {
8155
+ return this.flatNodeMap().size === 999;
8156
+ });
8149
8157
  /**
8150
8158
  * Angular OnChange implementation
8151
8159
  */
@@ -8209,6 +8217,14 @@ class NaturalHierarchicSelectorComponent {
8209
8217
  }
8210
8218
  }
8211
8219
  }
8220
+ selectAll() {
8221
+ this.flatNodeMap().forEach(flatNode => {
8222
+ if (!this.isNodeSelected(flatNode.node)) {
8223
+ this.selectFlatNode(flatNode);
8224
+ }
8225
+ });
8226
+ this.updateSelection(this.selectedNodes);
8227
+ }
8212
8228
  /**
8213
8229
  * When unselecting an element from the mat-chips, it can be deep in the hierarchy, and the tree element may not exist...
8214
8230
  * ... but we still need to remove the element from the mat-chips list.
@@ -8316,7 +8332,7 @@ class NaturalHierarchicSelectorComponent {
8316
8332
  }
8317
8333
  loadRoots(searchVariables) {
8318
8334
  this.loading = true;
8319
- this.flatNodeMap = new Map();
8335
+ this.flatNodeMap.set(new Map());
8320
8336
  this.hierarchicSelectorService
8321
8337
  .init(this.config, this.filters, searchVariables || null)
8322
8338
  .pipe(finalize$1(() => (this.loading = false)))
@@ -8385,13 +8401,13 @@ class NaturalHierarchicSelectorComponent {
8385
8401
  replaceObjectKeepingReference(this.selected, organizedFlatNodesSelection);
8386
8402
  this.selectionChange.emit(organizedFlatNodesSelection);
8387
8403
  }
8388
- isNodeSelected(node) {
8389
- const key = this.getMapKey(node.model);
8404
+ isNodeSelected(modelNode) {
8405
+ const key = this.getMapKey(modelNode.model);
8390
8406
  return this.selectedNodes.some(n => this.getMapKey(n.model) === key);
8391
8407
  }
8392
8408
  getFlatNode(node) {
8393
8409
  const key = this.getMapKey(node.model);
8394
- return this.flatNodeMap.get(key) || null;
8410
+ return this.flatNodeMap().get(key) || null;
8395
8411
  }
8396
8412
  createFlatNode(node, level) {
8397
8413
  const key = this.getMapKey(node.model);
@@ -8411,7 +8427,10 @@ class NaturalHierarchicSelectorComponent {
8411
8427
  this.flatNodesSelection.select(flatNode);
8412
8428
  }
8413
8429
  // Cache FlatNode
8414
- this.flatNodeMap.set(key, flatNode);
8430
+ this.flatNodeMap.update(map => {
8431
+ map.set(key, flatNode);
8432
+ return map;
8433
+ });
8415
8434
  return flatNode;
8416
8435
  }
8417
8436
  /**
@@ -8422,11 +8441,11 @@ class NaturalHierarchicSelectorComponent {
8422
8441
  return model.__typename + '-' + model.id;
8423
8442
  }
8424
8443
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8425
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: NaturalHierarchicSelectorComponent, isStandalone: true, selector: "natural-hierarchic-selector", inputs: { displayWith: "displayWith", config: "config", multiple: "multiple", selected: "selected", allowUnselect: "allowUnselect", filters: "filters", searchFacets: "searchFacets", searchSelections: "searchSelections" }, outputs: { searchSelectionChange: "searchSelectionChange", selectionChange: "selectionChange" }, providers: [NaturalHierarchicSelectorService], usesOnChanges: true, ngImport: i0, template: "<div [style.margin-bottom.px]=\"20\">\n <natural-search [facets]=\"searchFacets\" [selections]=\"searchSelections\" (selectionChange)=\"search($event)\" />\n</div>\n\n<div class=\"body\">\n @if (loading) {\n <mat-progress-spinner mode=\"indeterminate\" style=\"margin: 10px\" [diameter]=\"36\" />\n }\n\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\">\n <mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodePadding [ngClass]=\"{leaf: !node.expandable}\">\n @if (node.expandable) {\n <button\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'toggle ' + node.name\"\n (click)=\"loadChildren(node)\"\n >\n @if (node.loading) {\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"24\" [strokeWidth]=\"5\" />\n }\n @if (!node.loading) {\n <mat-icon [naturalIcon]=\"treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'\" />\n }\n </button>\n }\n\n <mat-checkbox\n style=\"margin-right: 10px\"\n [checked]=\"flatNodesSelection.isSelected(node)\"\n [disabled]=\"!isNodeTogglable(node)\"\n (change)=\"toggleFlatNode(node)\"\n >\n @if (node.node.config.icon) {\n <mat-icon style=\"margin-right: 10px\" [naturalIcon]=\"node.node.config.icon\" />\n }\n <span>{{ node.name }}</span>\n </mat-checkbox>\n </mat-tree-node>\n </mat-tree>\n\n <mat-chip-listbox aria-orientation=\"vertical\" class=\"mat-mdc-chip-set-stacked\">\n @for (node of selectedNodes; track node.model.id) {\n <mat-chip-option [removable]=\"true\" [selectable]=\"false\" (removed)=\"unselectModelNode(node)\">\n @if (node.config.icon) {\n <mat-icon matChipAvatar [naturalIcon]=\"node.config.icon\" />\n }\n {{ node.model.name || node.model.fullName }}\n <button matChipRemove>\n <mat-icon naturalIcon=\"cancel\" />\n </button>\n </mat-chip-option>\n } @empty {\n <p class=\"mat-body nat-padding-horizontal\" i18n>Aucune s\u00E9lection</p>\n }\n </mat-chip-listbox>\n</div>\n\n@if (!loading && !dataSource.data.length) {\n <div i18n>Aucun r\u00E9sultat</div>\n}\n", styles: [":host{display:block}:host ul,:host li{-webkit-margin-before:0;-webkit-margin-after:0;list-style-type:none}:host mat-icon{width:18px;height:18px;font-size:18px}:host .mat-tree-node.leaf{margin-left:48px}:host .body{display:flex;flex-direction:row;justify-content:space-between}:host .body mat-tree{flex:66}:host .body mat-chip-listbox{flex:33}:host mat-tree{flex-shrink:0}:host mat-chip-listbox{margin-left:10px}\n"], dependencies: [{ kind: "component", type: NaturalSearchComponent, selector: "natural-search", inputs: ["placeholder", "facets", "multipleGroups", "dropdownTitle", "selections"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTreeModule }, { kind: "directive", type: i3$2.MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: i3$2.MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "directive", type: i3$2.MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "component", type: i3$2.MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: i3$2.MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "directive", type: i7.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i7.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i7.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "directive", type: i7.MatChipRemove, selector: "[matChipRemove]" }] });
8444
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: NaturalHierarchicSelectorComponent, isStandalone: true, selector: "natural-hierarchic-selector", inputs: { displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: false, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: false, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: false, isRequired: false, transformFunction: null }, allowUnselect: { classPropertyName: "allowUnselect", publicName: "allowUnselect", isSignal: false, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: false, isRequired: false, transformFunction: null }, searchFacets: { classPropertyName: "searchFacets", publicName: "searchFacets", isSignal: false, isRequired: false, transformFunction: null }, searchSelections: { classPropertyName: "searchSelections", publicName: "searchSelections", isSignal: false, isRequired: false, transformFunction: null }, allowSelectAll: { classPropertyName: "allowSelectAll", publicName: "allowSelectAll", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchSelectionChange: "searchSelectionChange", selectionChange: "selectionChange" }, providers: [NaturalHierarchicSelectorService], usesOnChanges: true, ngImport: i0, template: "<div [style.margin-bottom.px]=\"20\">\n <natural-search [facets]=\"searchFacets\" [selections]=\"searchSelections\" (selectionChange)=\"search($event)\" />\n</div>\n\n@if (allowSelectAll() && multiple) {\n <div class=\"select-all\" [matTooltip]=\"tooBig() ? 'Trop de r\u00E9sultats, veuillez affiner la recherche' : null\">\n <a i18n mat-button [disabled]=\"tooBig()\" (click)=\"selectAll()\">Tout s\u00E9lectionner</a>\n </div>\n}\n\n<div class=\"body\">\n @if (loading) {\n <mat-progress-spinner mode=\"indeterminate\" style=\"margin: 10px\" [diameter]=\"36\" />\n }\n\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\">\n <mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodePadding [ngClass]=\"{leaf: !node.expandable}\">\n @if (node.expandable) {\n <button\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"`toggle ${node.name}`\"\n (click)=\"loadChildren(node)\"\n >\n @if (node.loading) {\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"24\" [strokeWidth]=\"5\" />\n }\n @if (!node.loading) {\n <mat-icon [naturalIcon]=\"treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'\" />\n }\n </button>\n }\n\n <mat-checkbox\n style=\"margin-right: 10px\"\n [checked]=\"flatNodesSelection.isSelected(node)\"\n [disabled]=\"!isNodeTogglable(node)\"\n (change)=\"toggleFlatNode(node)\"\n >\n @if (node.node.config.icon) {\n <mat-icon style=\"margin-right: 10px\" [naturalIcon]=\"node.node.config.icon\" />\n }\n <span>{{ node.name }}</span>\n </mat-checkbox>\n </mat-tree-node>\n </mat-tree>\n\n <mat-chip-listbox aria-orientation=\"vertical\" class=\"mat-mdc-chip-set-stacked\">\n @for (node of selectedNodes; track node.model.id) {\n <mat-chip-option [removable]=\"true\" [selectable]=\"false\" (removed)=\"unselectModelNode(node)\">\n @if (node.config.icon) {\n <mat-icon matChipAvatar [naturalIcon]=\"node.config.icon\" />\n }\n {{ node.model.name || node.model.fullName }}\n <button matChipRemove>\n <mat-icon naturalIcon=\"cancel\" />\n </button>\n </mat-chip-option>\n } @empty {\n <p class=\"mat-body nat-padding-horizontal\" i18n>Aucune s\u00E9lection</p>\n }\n </mat-chip-listbox>\n</div>\n\n@if (!loading && !dataSource.data.length) {\n <div i18n>Aucun r\u00E9sultat</div>\n}\n", styles: [":host{display:block}:host ul,:host li{-webkit-margin-before:0;-webkit-margin-after:0;list-style-type:none}:host mat-icon{width:18px;height:18px;font-size:18px}:host .select-all{display:inline-block;margin-top:-15px;margin-bottom:5px}:host .mat-tree-node.leaf{margin-left:48px}:host .body{display:flex;flex-direction:row;justify-content:space-between}:host .body mat-tree{flex:66}:host .body mat-chip-listbox{flex:33}:host mat-tree{flex-shrink:0}:host mat-chip-listbox{margin-left:10px}\n"], dependencies: [{ kind: "component", type: NaturalSearchComponent, selector: "natural-search", inputs: ["placeholder", "facets", "multipleGroups", "dropdownTitle", "selections"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTreeModule }, { kind: "directive", type: i3$2.MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: i3$2.MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "directive", type: i3$2.MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "component", type: i3$2.MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: i3$2.MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "directive", type: i7.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i7.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i7.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "directive", type: i7.MatChipRemove, selector: "[matChipRemove]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
8426
8445
  }
8427
8446
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorComponent, decorators: [{
8428
8447
  type: Component,
8429
- args: [{ selector: 'natural-hierarchic-selector', providers: [NaturalHierarchicSelectorService], imports: [
8448
+ args: [{ selector: 'natural-hierarchic-selector', imports: [
8430
8449
  NaturalSearchComponent,
8431
8450
  CommonModule,
8432
8451
  MatProgressSpinnerModule,
@@ -8436,7 +8455,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
8436
8455
  NaturalIconDirective,
8437
8456
  MatCheckboxModule,
8438
8457
  MatChipsModule,
8439
- ], template: "<div [style.margin-bottom.px]=\"20\">\n <natural-search [facets]=\"searchFacets\" [selections]=\"searchSelections\" (selectionChange)=\"search($event)\" />\n</div>\n\n<div class=\"body\">\n @if (loading) {\n <mat-progress-spinner mode=\"indeterminate\" style=\"margin: 10px\" [diameter]=\"36\" />\n }\n\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\">\n <mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodePadding [ngClass]=\"{leaf: !node.expandable}\">\n @if (node.expandable) {\n <button\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'toggle ' + node.name\"\n (click)=\"loadChildren(node)\"\n >\n @if (node.loading) {\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"24\" [strokeWidth]=\"5\" />\n }\n @if (!node.loading) {\n <mat-icon [naturalIcon]=\"treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'\" />\n }\n </button>\n }\n\n <mat-checkbox\n style=\"margin-right: 10px\"\n [checked]=\"flatNodesSelection.isSelected(node)\"\n [disabled]=\"!isNodeTogglable(node)\"\n (change)=\"toggleFlatNode(node)\"\n >\n @if (node.node.config.icon) {\n <mat-icon style=\"margin-right: 10px\" [naturalIcon]=\"node.node.config.icon\" />\n }\n <span>{{ node.name }}</span>\n </mat-checkbox>\n </mat-tree-node>\n </mat-tree>\n\n <mat-chip-listbox aria-orientation=\"vertical\" class=\"mat-mdc-chip-set-stacked\">\n @for (node of selectedNodes; track node.model.id) {\n <mat-chip-option [removable]=\"true\" [selectable]=\"false\" (removed)=\"unselectModelNode(node)\">\n @if (node.config.icon) {\n <mat-icon matChipAvatar [naturalIcon]=\"node.config.icon\" />\n }\n {{ node.model.name || node.model.fullName }}\n <button matChipRemove>\n <mat-icon naturalIcon=\"cancel\" />\n </button>\n </mat-chip-option>\n } @empty {\n <p class=\"mat-body nat-padding-horizontal\" i18n>Aucune s\u00E9lection</p>\n }\n </mat-chip-listbox>\n</div>\n\n@if (!loading && !dataSource.data.length) {\n <div i18n>Aucun r\u00E9sultat</div>\n}\n", styles: [":host{display:block}:host ul,:host li{-webkit-margin-before:0;-webkit-margin-after:0;list-style-type:none}:host mat-icon{width:18px;height:18px;font-size:18px}:host .mat-tree-node.leaf{margin-left:48px}:host .body{display:flex;flex-direction:row;justify-content:space-between}:host .body mat-tree{flex:66}:host .body mat-chip-listbox{flex:33}:host mat-tree{flex-shrink:0}:host mat-chip-listbox{margin-left:10px}\n"] }]
8458
+ MatTooltipModule,
8459
+ ], providers: [NaturalHierarchicSelectorService], template: "<div [style.margin-bottom.px]=\"20\">\n <natural-search [facets]=\"searchFacets\" [selections]=\"searchSelections\" (selectionChange)=\"search($event)\" />\n</div>\n\n@if (allowSelectAll() && multiple) {\n <div class=\"select-all\" [matTooltip]=\"tooBig() ? 'Trop de r\u00E9sultats, veuillez affiner la recherche' : null\">\n <a i18n mat-button [disabled]=\"tooBig()\" (click)=\"selectAll()\">Tout s\u00E9lectionner</a>\n </div>\n}\n\n<div class=\"body\">\n @if (loading) {\n <mat-progress-spinner mode=\"indeterminate\" style=\"margin: 10px\" [diameter]=\"36\" />\n }\n\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\">\n <mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodePadding [ngClass]=\"{leaf: !node.expandable}\">\n @if (node.expandable) {\n <button\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"`toggle ${node.name}`\"\n (click)=\"loadChildren(node)\"\n >\n @if (node.loading) {\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"24\" [strokeWidth]=\"5\" />\n }\n @if (!node.loading) {\n <mat-icon [naturalIcon]=\"treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'\" />\n }\n </button>\n }\n\n <mat-checkbox\n style=\"margin-right: 10px\"\n [checked]=\"flatNodesSelection.isSelected(node)\"\n [disabled]=\"!isNodeTogglable(node)\"\n (change)=\"toggleFlatNode(node)\"\n >\n @if (node.node.config.icon) {\n <mat-icon style=\"margin-right: 10px\" [naturalIcon]=\"node.node.config.icon\" />\n }\n <span>{{ node.name }}</span>\n </mat-checkbox>\n </mat-tree-node>\n </mat-tree>\n\n <mat-chip-listbox aria-orientation=\"vertical\" class=\"mat-mdc-chip-set-stacked\">\n @for (node of selectedNodes; track node.model.id) {\n <mat-chip-option [removable]=\"true\" [selectable]=\"false\" (removed)=\"unselectModelNode(node)\">\n @if (node.config.icon) {\n <mat-icon matChipAvatar [naturalIcon]=\"node.config.icon\" />\n }\n {{ node.model.name || node.model.fullName }}\n <button matChipRemove>\n <mat-icon naturalIcon=\"cancel\" />\n </button>\n </mat-chip-option>\n } @empty {\n <p class=\"mat-body nat-padding-horizontal\" i18n>Aucune s\u00E9lection</p>\n }\n </mat-chip-listbox>\n</div>\n\n@if (!loading && !dataSource.data.length) {\n <div i18n>Aucun r\u00E9sultat</div>\n}\n", styles: [":host{display:block}:host ul,:host li{-webkit-margin-before:0;-webkit-margin-after:0;list-style-type:none}:host mat-icon{width:18px;height:18px;font-size:18px}:host .select-all{display:inline-block;margin-top:-15px;margin-bottom:5px}:host .mat-tree-node.leaf{margin-left:48px}:host .body{display:flex;flex-direction:row;justify-content:space-between}:host .body mat-tree{flex:66}:host .body mat-chip-listbox{flex:33}:host mat-tree{flex-shrink:0}:host mat-chip-listbox{margin-left:10px}\n"] }]
8440
8460
  }], propDecorators: { displayWith: [{
8441
8461
  type: Input
8442
8462
  }], config: [{
@@ -8507,7 +8527,7 @@ class TypeHierarchicSelectorComponent extends AbstractAssociationSelectComponent
8507
8527
  return selection[this.configuration.key].length ? selection : null;
8508
8528
  }
8509
8529
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: TypeHierarchicSelectorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
8510
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: TypeHierarchicSelectorComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\">\n <mat-label i18n=\"Mathematical operator < > =\">Op\u00E9rateur</mat-label>\n <mat-select panelWidth=\"\" [formControl]=\"operatorCtrl\" [required]=\"true\">\n @for (item of operators; track item) {\n <mat-option [value]=\"item.key\">\n {{ item.label }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (requireValueCtrl) {\n <natural-hierarchic-selector\n style=\"margin-right: 20px\"\n [config]=\"configuration.config\"\n [filters]=\"configuration.filters\"\n [multiple]=\"true\"\n [selected]=\"valueCtrl.value || {}\"\n (selectionChange)=\"selectionChange($event)\"\n />\n }\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3.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", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "component", type: NaturalHierarchicSelectorComponent, selector: "natural-hierarchic-selector", inputs: ["displayWith", "config", "multiple", "selected", "allowUnselect", "filters", "searchFacets", "searchSelections"], outputs: ["searchSelectionChange", "selectionChange"] }] });
8530
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: TypeHierarchicSelectorComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\">\n <mat-label i18n=\"Mathematical operator < > =\">Op\u00E9rateur</mat-label>\n <mat-select panelWidth=\"\" [formControl]=\"operatorCtrl\" [required]=\"true\">\n @for (item of operators; track item) {\n <mat-option [value]=\"item.key\">\n {{ item.label }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (requireValueCtrl) {\n <natural-hierarchic-selector\n style=\"margin-right: 20px\"\n [config]=\"configuration.config\"\n [filters]=\"configuration.filters\"\n [multiple]=\"true\"\n [selected]=\"valueCtrl.value || {}\"\n (selectionChange)=\"selectionChange($event)\"\n />\n }\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3.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", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "component", type: NaturalHierarchicSelectorComponent, selector: "natural-hierarchic-selector", inputs: ["displayWith", "config", "multiple", "selected", "allowUnselect", "filters", "searchFacets", "searchSelections", "allowSelectAll"], outputs: ["searchSelectionChange", "selectionChange"] }] });
8511
8531
  }
8512
8532
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: TypeHierarchicSelectorComponent, decorators: [{
8513
8533
  type: Component,
@@ -8650,7 +8670,9 @@ class TypeOptionsComponent {
8650
8670
  options: [],
8651
8671
  };
8652
8672
  dropdownRef = inject(NaturalDropdownRef);
8653
- constructor(data) {
8673
+ constructor(
8674
+ // eslint-disable-next-line @angular-eslint/prefer-inject
8675
+ data) {
8654
8676
  this.data = data;
8655
8677
  this.configuration = { ...this.defaults, ...data.configuration };
8656
8678
  if (!this.configuration.options.length) {
@@ -8907,9 +8929,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
8907
8929
  * @dynamic
8908
8930
  */
8909
8931
  class NaturalAbstractFile {
8910
- element;
8911
- naturalFileService;
8912
- document;
8913
8932
  fileElement;
8914
8933
  /**
8915
8934
  * Whether we should accept a single file or multiple files
@@ -8957,11 +8976,9 @@ class NaturalAbstractFile {
8957
8976
  * The list of files that have been selected.
8958
8977
  */
8959
8978
  filesChange = outputFromObservable(this.filesChange$);
8960
- constructor(element, naturalFileService, document) {
8961
- this.element = element;
8962
- this.naturalFileService = naturalFileService;
8963
- this.document = document;
8964
- }
8979
+ element = inject(ElementRef);
8980
+ naturalFileService = inject(NaturalFileService);
8981
+ document = inject(DOCUMENT);
8965
8982
  ngOnDestroy() {
8966
8983
  delete this.fileElement; // faster memory release of dom element
8967
8984
  }
@@ -9098,16 +9115,13 @@ class NaturalAbstractFile {
9098
9115
  this.filesChange$.observed ||
9099
9116
  (this.broadcast && this.naturalFileService.filesChanged.observed));
9100
9117
  }
9101
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalAbstractFile, deps: [{ token: i0.ElementRef }, { token: NaturalFileService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive });
9118
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalAbstractFile, deps: [], target: i0.ɵɵFactoryTarget.Directive });
9102
9119
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.13", type: NaturalAbstractFile, isStandalone: true, inputs: { multiple: "multiple", accept: "accept", maxSize: "maxSize", fileSelectionDisabled: "fileSelectionDisabled", selectable: "selectable", broadcast: "broadcast" }, outputs: { fileChange: "fileChange", filesChange: "filesChange" }, host: { listeners: { "change": "onChange($event)" } }, usesOnChanges: true, ngImport: i0 });
9103
9120
  }
9104
9121
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalAbstractFile, decorators: [{
9105
9122
  type: Directive,
9106
9123
  args: [{ standalone: true }]
9107
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: NaturalFileService }, { type: Document, decorators: [{
9108
- type: Inject,
9109
- args: [DOCUMENT]
9110
- }] }], propDecorators: { multiple: [{
9124
+ }], propDecorators: { multiple: [{
9111
9125
  type: Input
9112
9126
  }], accept: [{
9113
9127
  type: Input
@@ -9502,11 +9516,11 @@ class NaturalHierarchicSelectorDialogComponent {
9502
9516
  this.dialogRef.close(result);
9503
9517
  }
9504
9518
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9505
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.13", type: NaturalHierarchicSelectorDialogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<h2 i18n mat-dialog-title>S\u00E9lection</h2>\n\n<mat-dialog-content>\n <natural-hierarchic-selector\n [selected]=\"config.hierarchicSelection ?? {}\"\n [config]=\"config.hierarchicConfig\"\n [filters]=\"config.hierarchicFilters\"\n [multiple]=\"config.multiple ?? false\"\n [allowUnselect]=\"config.allowUnselect ?? true\"\n [searchFacets]=\"config.searchFacets ?? []\"\n [searchSelections]=\"config.searchSelections ?? []\"\n (selectionChange)=\"config.hierarchicSelection = $event\"\n (searchSelectionChange)=\"searchSelectionsOutput = $event\"\n />\n</mat-dialog-content>\n\n<mat-dialog-actions align=\"end\">\n <button mat-dialog-close mat-button i18n>Annuler</button>\n <button color=\"primary\" mat-raised-button (click)=\"close(config.hierarchicSelection)\"\n ><span i18n>Valider</span>\n </button>\n</mat-dialog-actions>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: NaturalHierarchicSelectorComponent, selector: "natural-hierarchic-selector", inputs: ["displayWith", "config", "multiple", "selected", "allowUnselect", "filters", "searchFacets", "searchSelections"], outputs: ["searchSelectionChange", "selectionChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] });
9519
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.13", type: NaturalHierarchicSelectorDialogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<h2 i18n mat-dialog-title>S\u00E9lection</h2>\n\n<mat-dialog-content>\n <natural-hierarchic-selector\n [selected]=\"config.hierarchicSelection ?? {}\"\n [config]=\"config.hierarchicConfig\"\n [filters]=\"config.hierarchicFilters\"\n [multiple]=\"config.multiple ?? false\"\n [allowUnselect]=\"config.allowUnselect ?? true\"\n [allowSelectAll]=\"config.allowSelectAll ?? false\"\n [searchFacets]=\"config.searchFacets ?? []\"\n [searchSelections]=\"config.searchSelections ?? []\"\n (selectionChange)=\"config.hierarchicSelection = $event\"\n (searchSelectionChange)=\"searchSelectionsOutput = $event\"\n />\n</mat-dialog-content>\n\n<mat-dialog-actions align=\"end\">\n <button mat-dialog-close mat-button i18n>Annuler</button>\n <button color=\"primary\" mat-raised-button (click)=\"close(config.hierarchicSelection)\"\n ><span i18n>Valider</span>\n </button>\n</mat-dialog-actions>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: NaturalHierarchicSelectorComponent, selector: "natural-hierarchic-selector", inputs: ["displayWith", "config", "multiple", "selected", "allowUnselect", "filters", "searchFacets", "searchSelections", "allowSelectAll"], outputs: ["searchSelectionChange", "selectionChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] });
9506
9520
  }
9507
9521
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalHierarchicSelectorDialogComponent, decorators: [{
9508
9522
  type: Component,
9509
- args: [{ imports: [MatDialogModule, NaturalHierarchicSelectorComponent, MatButtonModule], template: "<h2 i18n mat-dialog-title>S\u00E9lection</h2>\n\n<mat-dialog-content>\n <natural-hierarchic-selector\n [selected]=\"config.hierarchicSelection ?? {}\"\n [config]=\"config.hierarchicConfig\"\n [filters]=\"config.hierarchicFilters\"\n [multiple]=\"config.multiple ?? false\"\n [allowUnselect]=\"config.allowUnselect ?? true\"\n [searchFacets]=\"config.searchFacets ?? []\"\n [searchSelections]=\"config.searchSelections ?? []\"\n (selectionChange)=\"config.hierarchicSelection = $event\"\n (searchSelectionChange)=\"searchSelectionsOutput = $event\"\n />\n</mat-dialog-content>\n\n<mat-dialog-actions align=\"end\">\n <button mat-dialog-close mat-button i18n>Annuler</button>\n <button color=\"primary\" mat-raised-button (click)=\"close(config.hierarchicSelection)\"\n ><span i18n>Valider</span>\n </button>\n</mat-dialog-actions>\n" }]
9523
+ args: [{ imports: [MatDialogModule, NaturalHierarchicSelectorComponent, MatButtonModule], template: "<h2 i18n mat-dialog-title>S\u00E9lection</h2>\n\n<mat-dialog-content>\n <natural-hierarchic-selector\n [selected]=\"config.hierarchicSelection ?? {}\"\n [config]=\"config.hierarchicConfig\"\n [filters]=\"config.hierarchicFilters\"\n [multiple]=\"config.multiple ?? false\"\n [allowUnselect]=\"config.allowUnselect ?? true\"\n [allowSelectAll]=\"config.allowSelectAll ?? false\"\n [searchFacets]=\"config.searchFacets ?? []\"\n [searchSelections]=\"config.searchSelections ?? []\"\n (selectionChange)=\"config.hierarchicSelection = $event\"\n (searchSelectionChange)=\"searchSelectionsOutput = $event\"\n />\n</mat-dialog-content>\n\n<mat-dialog-actions align=\"end\">\n <button mat-dialog-close mat-button i18n>Annuler</button>\n <button color=\"primary\" mat-raised-button (click)=\"close(config.hierarchicSelection)\"\n ><span i18n>Valider</span>\n </button>\n</mat-dialog-actions>\n" }]
9510
9524
  }], ctorParameters: () => [] });
9511
9525
 
9512
9526
  class NaturalHierarchicSelectorDialogService {
@@ -9990,8 +10004,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
9990
10004
  type: Component,
9991
10005
  args: [{
9992
10006
  selector: 'natural-panels',
9993
- template: '',
9994
10007
  standalone: true,
10008
+ template: '',
9995
10009
  }]
9996
10010
  }], ctorParameters: () => [] });
9997
10011
 
@@ -10674,8 +10688,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
10674
10688
  type: Component,
10675
10689
  args: [{
10676
10690
  selector: 'natural-sidenav',
10677
- template: '<ng-content />',
10678
10691
  standalone: true,
10692
+ template: '<ng-content />',
10679
10693
  }]
10680
10694
  }] });
10681
10695
 
@@ -10742,7 +10756,7 @@ class NaturalSidenavContainerComponent {
10742
10756
  }
10743
10757
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalSidenavContainerComponent, decorators: [{
10744
10758
  type: Component,
10745
- args: [{ selector: 'natural-sidenav-container', providers: [NaturalSidenavService], imports: [MatSidenavModule, CommonModule], template: "<mat-sidenav-container (backdropClick)=\"sidenavService.setOpened(false)\">\n <mat-sidenav\n [mode]=\"sidenavService.activeMode\"\n [ngClass]=\"sidenavService.isMinimized ? 'menuMinimized' : ''\"\n [opened]=\"sidenavService.isOpened\"\n [style.min-width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [style.width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [position]=\"position\"\n >\n <ng-content select=\"natural-sidenav\" />\n </mat-sidenav>\n\n <mat-sidenav-content>\n <div>\n <ng-content select=\"natural-sidenav-content\" />\n </div>\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{display:flex;flex-direction:column}:host mat-sidenav-container{display:flex;flex:1;flex-direction:column}:host mat-sidenav-content>div{overflow:auto}:host .menuMinimized{overflow-x:hidden}:host .buttons{display:flex;flex-direction:row;justify-content:flex-end}\n"] }]
10759
+ args: [{ selector: 'natural-sidenav-container', imports: [MatSidenavModule, CommonModule], providers: [NaturalSidenavService], template: "<mat-sidenav-container (backdropClick)=\"sidenavService.setOpened(false)\">\n <mat-sidenav\n [mode]=\"sidenavService.activeMode\"\n [ngClass]=\"sidenavService.isMinimized ? 'menuMinimized' : ''\"\n [opened]=\"sidenavService.isOpened\"\n [style.min-width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [style.width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [position]=\"position\"\n >\n <ng-content select=\"natural-sidenav\" />\n </mat-sidenav>\n\n <mat-sidenav-content>\n <div>\n <ng-content select=\"natural-sidenav-content\" />\n </div>\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{display:flex;flex-direction:column}:host mat-sidenav-container{display:flex;flex:1;flex-direction:column}:host mat-sidenav-content>div{overflow:auto}:host .menuMinimized{overflow-x:hidden}:host .buttons{display:flex;flex-direction:row;justify-content:flex-end}\n"] }]
10746
10760
  }], propDecorators: { name: [{
10747
10761
  type: Input,
10748
10762
  args: [{ required: true }]
@@ -10765,7 +10779,7 @@ class NaturalSidenavContentComponent {
10765
10779
  }
10766
10780
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalSidenavContentComponent, decorators: [{
10767
10781
  type: Component,
10768
- args: [{ selector: 'natural-sidenav-content', template: '<ng-content />', standalone: true, styles: [":host{display:flex;flex:1;flex-direction:column;overflow:auto}\n"] }]
10782
+ args: [{ selector: 'natural-sidenav-content', standalone: true, template: '<ng-content />', styles: [":host{display:flex;flex:1;flex-direction:column;overflow:auto}\n"] }]
10769
10783
  }] });
10770
10784
 
10771
10785
  /*
@@ -10835,11 +10849,11 @@ class NaturalTableButtonComponent {
10835
10849
  }
10836
10850
  });
10837
10851
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalTableButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10838
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: NaturalTableButtonComponent, isStandalone: true, selector: "natural-table-button", inputs: { queryParams: { classPropertyName: "queryParams", publicName: "queryParams", isSignal: true, isRequired: false, transformFunction: null }, queryParamsHandling: { classPropertyName: "queryParamsHandling", publicName: "queryParamsHandling", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, navigate: { classPropertyName: "navigate", publicName: "navigate", isSignal: true, isRequired: false, transformFunction: null }, fragment: { classPropertyName: "fragment", publicName: "fragment", isSignal: true, isRequired: false, transformFunction: null }, preserveFragment: { classPropertyName: "preserveFragment", publicName: "preserveFragment", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, raised: { classPropertyName: "raised", publicName: "raised", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClick: "buttonClick" }, ngImport: i0, template: "<!-- Because directives can't be applied conditionally (routerLink, mat-button and mat-icon-button), we have to use different elements -->\n@let theIcon = icon();\n\n<!-- Edge case of a button without any kind of link at all -->\n@if (type() === 'none') {\n <span>\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n @if (label()) {\n <span>{{ label() }}</span>\n }\n </span>\n} @else if (!raised()) {\n @switch (type()) {\n <!-- App routed link -->\n @case ('routerLink') {\n @if (label()) {\n <a\n mat-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- Click -->\n @case ('click') {\n @if (label()) {\n <a mat-button [color]=\"color()\" [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a mat-icon-button [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- External link -->\n @case ('href') {\n @if (label()) {\n <a mat-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a mat-icon-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n }\n} @else {\n <!-- App routed link -->\n @switch (type()) {\n @case ('routerLink') {\n @if (label()) {\n <a\n mat-raised-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- Click -->\n @case ('click') {\n @if (label()) {\n <a mat-raised-button [color]=\"color()\" [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n [color]=\"color()\"\n [disabled]=\"disabled()\"\n (click)=\"buttonClick$.next($event)\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- External link -->\n @case ('href') {\n @if (label()) {\n <a mat-raised-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n target=\"_blank\"\n [attr.href]=\"href()\"\n [color]=\"color()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n }\n}\n", styles: ["natural-table-button{display:flex;flex:1;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button mat-icon:not(:last-child){margin-right:5px}natural-table-button a.mat-mdc-button{display:flex;flex:1;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button a.mat-mdc-button .mdc-button__label{display:flex;flex-direction:row;align-items:center}natural-table-button>span{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;padding:0 8px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconAnchor, selector: "a[mat-icon-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
10852
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.13", type: NaturalTableButtonComponent, isStandalone: true, selector: "natural-table-button", inputs: { queryParams: { classPropertyName: "queryParams", publicName: "queryParams", isSignal: true, isRequired: false, transformFunction: null }, queryParamsHandling: { classPropertyName: "queryParamsHandling", publicName: "queryParamsHandling", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, navigate: { classPropertyName: "navigate", publicName: "navigate", isSignal: true, isRequired: false, transformFunction: null }, fragment: { classPropertyName: "fragment", publicName: "fragment", isSignal: true, isRequired: false, transformFunction: null }, preserveFragment: { classPropertyName: "preserveFragment", publicName: "preserveFragment", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, raised: { classPropertyName: "raised", publicName: "raised", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClick: "buttonClick" }, ngImport: i0, template: "<!-- eslint-disable @angular-eslint/template/cyclomatic-complexity -->\n<!-- Because directives can't be applied conditionally (routerLink, mat-button and mat-icon-button), we have to use different elements -->\n@let theIcon = icon();\n\n<!-- Edge case of a button without any kind of link at all -->\n@if (type() === 'none') {\n <span>\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n @if (label()) {\n <span>{{ label() }}</span>\n }\n </span>\n} @else if (!raised()) {\n @switch (type()) {\n <!-- App routed link -->\n @case ('routerLink') {\n @if (label()) {\n <a\n mat-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- Click -->\n @case ('click') {\n @if (label()) {\n <a mat-button [color]=\"color()\" [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a mat-icon-button [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- External link -->\n @case ('href') {\n @if (label()) {\n <a mat-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a mat-icon-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n }\n} @else {\n <!-- App routed link -->\n @switch (type()) {\n @case ('routerLink') {\n @if (label()) {\n <a\n mat-raised-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- Click -->\n @case ('click') {\n @if (label()) {\n <a mat-raised-button [color]=\"color()\" [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n [color]=\"color()\"\n [disabled]=\"disabled()\"\n (click)=\"buttonClick$.next($event)\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- External link -->\n @case ('href') {\n @if (label()) {\n <a mat-raised-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n target=\"_blank\"\n [attr.href]=\"href()\"\n [color]=\"color()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n }\n}\n", styles: ["natural-table-button{display:flex;flex:1;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button mat-icon:not(:last-child){margin-right:5px}natural-table-button a.mat-mdc-button{display:flex;flex:1;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button a.mat-mdc-button .mdc-button__label{display:flex;flex-direction:row;align-items:center}natural-table-button>span{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;padding:0 8px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconAnchor, selector: "a[mat-icon-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
10839
10853
  }
10840
10854
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalTableButtonComponent, decorators: [{
10841
10855
  type: Component,
10842
- args: [{ selector: 'natural-table-button', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, NaturalIconDirective, MatButtonModule, RouterLink], template: "<!-- Because directives can't be applied conditionally (routerLink, mat-button and mat-icon-button), we have to use different elements -->\n@let theIcon = icon();\n\n<!-- Edge case of a button without any kind of link at all -->\n@if (type() === 'none') {\n <span>\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n @if (label()) {\n <span>{{ label() }}</span>\n }\n </span>\n} @else if (!raised()) {\n @switch (type()) {\n <!-- App routed link -->\n @case ('routerLink') {\n @if (label()) {\n <a\n mat-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- Click -->\n @case ('click') {\n @if (label()) {\n <a mat-button [color]=\"color()\" [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a mat-icon-button [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- External link -->\n @case ('href') {\n @if (label()) {\n <a mat-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a mat-icon-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n }\n} @else {\n <!-- App routed link -->\n @switch (type()) {\n @case ('routerLink') {\n @if (label()) {\n <a\n mat-raised-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- Click -->\n @case ('click') {\n @if (label()) {\n <a mat-raised-button [color]=\"color()\" [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n [color]=\"color()\"\n [disabled]=\"disabled()\"\n (click)=\"buttonClick$.next($event)\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- External link -->\n @case ('href') {\n @if (label()) {\n <a mat-raised-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n target=\"_blank\"\n [attr.href]=\"href()\"\n [color]=\"color()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n }\n}\n", styles: ["natural-table-button{display:flex;flex:1;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button mat-icon:not(:last-child){margin-right:5px}natural-table-button a.mat-mdc-button{display:flex;flex:1;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button a.mat-mdc-button .mdc-button__label{display:flex;flex-direction:row;align-items:center}natural-table-button>span{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;padding:0 8px}\n"] }]
10856
+ args: [{ selector: 'natural-table-button', imports: [MatIconModule, NaturalIconDirective, MatButtonModule, RouterLink], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- eslint-disable @angular-eslint/template/cyclomatic-complexity -->\n<!-- Because directives can't be applied conditionally (routerLink, mat-button and mat-icon-button), we have to use different elements -->\n@let theIcon = icon();\n\n<!-- Edge case of a button without any kind of link at all -->\n@if (type() === 'none') {\n <span>\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n @if (label()) {\n <span>{{ label() }}</span>\n }\n </span>\n} @else if (!raised()) {\n @switch (type()) {\n <!-- App routed link -->\n @case ('routerLink') {\n @if (label()) {\n <a\n mat-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- Click -->\n @case ('click') {\n @if (label()) {\n <a mat-button [color]=\"color()\" [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a mat-icon-button [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- External link -->\n @case ('href') {\n @if (label()) {\n <a mat-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a mat-icon-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n }\n} @else {\n <!-- App routed link -->\n @switch (type()) {\n @case ('routerLink') {\n @if (label()) {\n <a\n mat-raised-button\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n [color]=\"color()\"\n [queryParams]=\"queryParams()\"\n [queryParamsHandling]=\"queryParamsHandling()\"\n [routerLink]=\"navigate()\"\n [fragment]=\"fragment()\"\n [preserveFragment]=\"preserveFragment()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- Click -->\n @case ('click') {\n @if (label()) {\n <a mat-raised-button [color]=\"color()\" [disabled]=\"disabled()\" (click)=\"buttonClick$.next($event)\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n [color]=\"color()\"\n [disabled]=\"disabled()\"\n (click)=\"buttonClick$.next($event)\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n <!-- External link -->\n @case ('href') {\n @if (label()) {\n <a mat-raised-button target=\"_blank\" [attr.href]=\"href()\" [color]=\"color()\" [disabled]=\"disabled()\">\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n <span>{{ label() }}</span>\n </a>\n } @else {\n <a\n mat-icon-button\n class=\"mat-elevation-z4\"\n target=\"_blank\"\n [attr.href]=\"href()\"\n [color]=\"color()\"\n [disabled]=\"disabled()\"\n >\n @if (theIcon) {\n <mat-icon [naturalIcon]=\"theIcon\" />\n }\n </a>\n }\n }\n }\n}\n", styles: ["natural-table-button{display:flex;flex:1;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button mat-icon:not(:last-child){margin-right:5px}natural-table-button a.mat-mdc-button{display:flex;flex:1;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button a.mat-mdc-button .mdc-button__label{display:flex;flex-direction:row;align-items:center}natural-table-button>span{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;padding:0 8px}\n"] }]
10843
10857
  }] });
10844
10858
 
10845
10859
  /*
@@ -10899,7 +10913,7 @@ function isRetina() {
10899
10913
  return true;
10900
10914
  }
10901
10915
  const mediaQuery = '(-webkit-min-device-pixel-ratio: 1.25), (min--moz-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 5/4), (min-resolution: 1.25dppx)';
10902
- return !!myWindow?.matchMedia(mediaQuery).matches;
10916
+ return myWindow?.matchMedia(mediaQuery).matches;
10903
10917
  }
10904
10918
  /**
10905
10919
  * Return URL to Gravatar image from either an email or a MD5 or SHA-256 of an email
@@ -11056,8 +11070,8 @@ class NaturalAvatarComponent {
11056
11070
  const sources = this.sources();
11057
11071
  return sources.sources[sources.currentIndex];
11058
11072
  });
11059
- imageAvatar = computed(() => this.currentSource()?.getAvatar(+this.size()));
11060
- textAvatar = computed(() => this.currentSource()?.getAvatar(+this.textMaximumLength()));
11073
+ imageAvatar = computed(() => this.currentSource()?.getAvatar(this.size()));
11074
+ textAvatar = computed(() => this.currentSource()?.getAvatar(this.textMaximumLength()));
11061
11075
  /**
11062
11076
  * Try to use the next available avatar source that has not already failed in the past
11063
11077
  */
@@ -11095,7 +11109,7 @@ class NaturalAvatarComponent {
11095
11109
  textTransform: 'uppercase',
11096
11110
  color: this.fgColor(),
11097
11111
  backgroundColor: backgroundColor,
11098
- font: Math.floor(+this.size() / this.textSizeRatio()) + 'px Helvetica, Arial, sans-serif',
11112
+ font: Math.floor(this.size() / this.textSizeRatio()) + 'px Helvetica, Arial, sans-serif',
11099
11113
  lineHeight: this.size() + 'px',
11100
11114
  width: this.size() + 'px',
11101
11115
  height: this.size() + 'px',
@@ -11138,7 +11152,7 @@ class NaturalAvatarComponent {
11138
11152
  }
11139
11153
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: NaturalAvatarComponent, decorators: [{
11140
11154
  type: Component,
11141
- args: [{ selector: 'natural-avatar', template: `
11155
+ args: [{ selector: 'natural-avatar', imports: [CommonModule], template: `
11142
11156
  @let source = currentSource();
11143
11157
  <div class="avatar-container" [style.height.px]="size()" [style.width.px]="size()">
11144
11158
  @if (source && source?.isTextual()) {
@@ -11163,7 +11177,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
11163
11177
  '[style.height.px]': 'size()',
11164
11178
  '[style.width.px]': 'size()',
11165
11179
  '[class.decorated]': 'decorated()',
11166
- }, imports: [CommonModule], styles: [":host{display:block}:host.decorated{position:relative}:host.decorated .avatar-container:before{position:absolute;inset:0;border-radius:50%;background:linear-gradient(345deg,#fff0 25%,#ffffff54);content:\"\"}:host.decorated .avatar-content{text-shadow:0 1px 0 rgba(0,0,0,.6)}\n"] }]
11180
+ }, styles: [":host{display:block}:host.decorated{position:relative}:host.decorated .avatar-container:before{position:absolute;inset:0;border-radius:50%;background:linear-gradient(345deg,#fff0 25%,#ffffff54);content:\"\"}:host.decorated .avatar-content{text-shadow:0 1px 0 rgba(0,0,0,.6)}\n"] }]
11167
11181
  }] });
11168
11182
 
11169
11183
  /*