@ecodev/natural 66.0.6 → 66.0.8

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.
@@ -8,9 +8,9 @@ import * as i1 from '@angular/material/dialog';
8
8
  import { MAT_DIALOG_DATA, MatDialogModule, MatDialog, MatDialogRef } from '@angular/material/dialog';
9
9
  import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
10
10
  import { MatButton, MatIconButton, MatFabButton } from '@angular/material/button';
11
- import { Observable, switchMap, take, BehaviorSubject, of, timer, tap, endWith, last, EMPTY, finalize, Subject, merge as merge$1, first as first$1, takeUntil as takeUntil$1, map as map$1, ReplaySubject, debounceTime, raceWith, mergeMap, shareReplay, catchError, forkJoin, combineLatest, from, fromEvent, filter as filter$1, startWith as startWith$1, asyncScheduler, throwError } from 'rxjs';
11
+ import { Observable, switchMap, take, BehaviorSubject, of, timer, tap, endWith, last, EMPTY, finalize, Subject, merge as merge$1, startWith, first as first$1, takeUntil as takeUntil$1, map as map$1, ReplaySubject, debounceTime, raceWith, mergeMap, shareReplay, catchError, forkJoin, combineLatest, from, fromEvent, filter as filter$1, asyncScheduler, throwError } from 'rxjs';
12
12
  import { takeUntilDestroyed, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
13
- import { filter, switchMap as switchMap$1, first, map, takeUntil, takeWhile, debounceTime as debounceTime$1, tap as tap$1, shareReplay as shareReplay$1, startWith, distinctUntilChanged, finalize as finalize$1, throttleTime } from 'rxjs/operators';
13
+ import { filter, switchMap as switchMap$1, first, map, takeUntil, takeWhile, debounceTime as debounceTime$1, tap as tap$1, shareReplay as shareReplay$1, startWith as startWith$1, distinctUntilChanged, finalize as finalize$1, throttleTime } from 'rxjs/operators';
14
14
  import { mergeWith, defaultsDeep, pick, defaults, isEmpty, isEqual as isEqual$1 } from 'es-toolkit/compat';
15
15
  import { MatTableDataSource, MatTable, MatHeaderCellDef, MatHeaderRowDef, MatColumnDef, MatCellDef, MatRowDef, MatHeaderCell, MatCell, MatHeaderRow, MatRow } from '@angular/material/table';
16
16
  import { DataSource, SelectionModel } from '@angular/cdk/collections';
@@ -27,7 +27,7 @@ import { ApolloLink, NetworkStatus } from '@apollo/client/core';
27
27
  import extractFiles from 'extract-files/extractFiles.mjs';
28
28
  import isExtractableFile from 'extract-files/isExtractableFile.mjs';
29
29
  import { Kind, OperationTypeNode } from 'graphql/language';
30
- import { isPlatformBrowser, AsyncPipe, NgTemplateOutlet, NgClass, UpperCasePipe, DatePipe, NgStyle, CommonModule } from '@angular/common';
30
+ import { isPlatformBrowser, AsyncPipe, NgTemplateOutlet, NgClass, UpperCasePipe, DatePipe, NgStyle } from '@angular/common';
31
31
  import { Apollo, gql } from 'apollo-angular';
32
32
  import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
33
33
  import { MatIconRegistry, MatIcon } from '@angular/material/icon';
@@ -193,12 +193,10 @@ function formatIsoDate(date) {
193
193
  * So something like: "2021-09-23T17:57:16+09:00"
194
194
  */
195
195
  function formatIsoDateTime(date) {
196
- const timezoneOffsetInMinutes = date.getTimezoneOffset();
196
+ const timezoneOffsetInMinutes = Math.round(date.getTimezoneOffset());
197
197
  const timezoneOffsetInHours = -Math.trunc(timezoneOffsetInMinutes / 60); // UTC minus local time
198
198
  const sign = timezoneOffsetInHours >= 0 ? '+' : '-';
199
- const hoursLeadingZero = Math.abs(timezoneOffsetInHours) < 10 ? '0' : '';
200
199
  const remainderMinutes = -(timezoneOffsetInMinutes % 60);
201
- const minutesLeadingZero = Math.abs(remainderMinutes) < 10 ? '0' : '';
202
200
  // It's a bit unfortunate that we need to construct a new Date instance,
203
201
  // but we don't want the original Date instance to be modified
204
202
  const correctedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
@@ -207,13 +205,9 @@ function formatIsoDateTime(date) {
207
205
  .toISOString()
208
206
  .replace(/\.\d{3}Z/, '')
209
207
  .replace('Z', '');
210
- return (iso +
211
- sign +
212
- hoursLeadingZero +
213
- Math.abs(timezoneOffsetInHours).toString() +
214
- ':' +
215
- minutesLeadingZero +
216
- remainderMinutes);
208
+ const hours = Math.abs(timezoneOffsetInHours).toString().padStart(2, '0');
209
+ const minutes = remainderMinutes.toString().padStart(2, '0');
210
+ return iso + sign + hours + ':' + minutes;
217
211
  }
218
212
  /**
219
213
  * Relations to full objects are converted to their IDs only.
@@ -3012,6 +3006,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
3012
3006
  }]
3013
3007
  }] });
3014
3008
 
3009
+ const possibleNullableOperators = [
3010
+ {
3011
+ key: 'any',
3012
+ label: $localize `avec`,
3013
+ },
3014
+ {
3015
+ key: 'none',
3016
+ label: $localize `sans`,
3017
+ },
3018
+ ];
3015
3019
  const possibleComparableOperators = [
3016
3020
  {
3017
3021
  key: 'less',
@@ -3034,6 +3038,10 @@ const possibleComparableOperators = [
3034
3038
  label: '>',
3035
3039
  },
3036
3040
  ];
3041
+ const possibleNullComparableOperators = [
3042
+ ...possibleComparableOperators,
3043
+ ...possibleNullableOperators,
3044
+ ];
3037
3045
  const possibleDiscreteOperators = [
3038
3046
  {
3039
3047
  key: 'is',
@@ -3043,14 +3051,7 @@ const possibleDiscreteOperators = [
3043
3051
  key: 'isnot',
3044
3052
  label: $localize `n'est pas`,
3045
3053
  },
3046
- {
3047
- key: 'any',
3048
- label: $localize `avec`,
3049
- },
3050
- {
3051
- key: 'none',
3052
- label: $localize `sans`,
3053
- },
3054
+ ...possibleNullableOperators,
3054
3055
  ];
3055
3056
 
3056
3057
  /**
@@ -3096,7 +3097,8 @@ class TypeDateComponent {
3096
3097
  operatorCtrl = new FormControl('equal', { nonNullable: true });
3097
3098
  valueCtrl = new FormControl(null);
3098
3099
  todayCtrl = new FormControl(false);
3099
- operators = possibleComparableOperators;
3100
+ requireValueCtrl = false;
3101
+ operators;
3100
3102
  form = new FormGroup({
3101
3103
  operator: this.operatorCtrl,
3102
3104
  value: this.valueCtrl,
@@ -3105,10 +3107,12 @@ class TypeDateComponent {
3105
3107
  defaults = {
3106
3108
  min: null,
3107
3109
  max: null,
3110
+ nullable: false,
3108
3111
  };
3109
3112
  constructor() {
3110
3113
  const data = inject(NATURAL_DROPDOWN_DATA);
3111
3114
  this.configuration = { ...this.defaults, ...data.configuration };
3115
+ this.operators = this.configuration.nullable ? possibleNullComparableOperators : possibleComparableOperators;
3112
3116
  this.todayCtrl.valueChanges.pipe(takeUntilDestroyed()).subscribe(isToday => {
3113
3117
  if (isToday) {
3114
3118
  this.valueCtrl.setValue(this.dateAdapter.today());
@@ -3121,15 +3125,21 @@ class TypeDateComponent {
3121
3125
  merge$1(this.operatorCtrl.valueChanges, this.valueCtrl.valueChanges, this.todayCtrl.valueChanges)
3122
3126
  .pipe(takeUntilDestroyed())
3123
3127
  .subscribe(() => this.renderedValue.next(this.getRenderedValue()));
3124
- this.initValidators();
3128
+ // Immediately initValidators and everytime the operator change later
3129
+ this.operatorCtrl.valueChanges.pipe(startWith(null)).subscribe(() => this.initValidators());
3125
3130
  this.reloadCondition(data.condition);
3126
3131
  }
3127
3132
  getCondition() {
3128
- if (!this.valueCtrl.value) {
3133
+ let operator = this.operatorCtrl.value;
3134
+ if (operator === 'any') {
3135
+ return { null: { not: true } };
3136
+ }
3137
+ else if (operator === 'none') {
3138
+ return { null: { not: false } };
3139
+ }
3140
+ else if (!this.valueCtrl.value) {
3129
3141
  return {};
3130
3142
  }
3131
- const condition = {};
3132
- let operator = this.operatorCtrl.value;
3133
3143
  let date;
3134
3144
  let dayAfter;
3135
3145
  if (this.todayCtrl.value) {
@@ -3141,8 +3151,10 @@ class TypeDateComponent {
3141
3151
  dayAfter = serialize(this.dateAdapter, this.getDayAfter(this.valueCtrl.value));
3142
3152
  }
3143
3153
  if (operator === 'equal') {
3144
- condition.greaterOrEqual = { value: date };
3145
- condition.less = { value: dayAfter };
3154
+ return {
3155
+ greaterOrEqual: { value: date },
3156
+ less: { value: dayAfter },
3157
+ };
3146
3158
  }
3147
3159
  else {
3148
3160
  // Transparently adapt exclusive/inclusive ranges
@@ -3156,9 +3168,8 @@ class TypeDateComponent {
3156
3168
  date = dayAfter;
3157
3169
  }
3158
3170
  }
3159
- condition[operator] = { value: date };
3171
+ return { [operator]: { value: date } };
3160
3172
  }
3161
- return condition;
3162
3173
  }
3163
3174
  isValid() {
3164
3175
  return this.form.valid;
@@ -3176,12 +3187,19 @@ class TypeDateComponent {
3176
3187
  this.setTodayOrDate(condition.greaterOrEqual.value);
3177
3188
  return;
3178
3189
  }
3179
- for (const operator of this.operators) {
3180
- const reloadedOperator = condition[operator.key];
3181
- if (reloadedOperator) {
3182
- this.operatorCtrl.setValue(operator.key);
3183
- this.setTodayOrDate(reloadedOperator.value);
3184
- }
3190
+ const operatorKey = this.conditionToOperatorKey(condition);
3191
+ this.operatorCtrl.setValue(operatorKey);
3192
+ this.setTodayOrDate(condition[operatorKey]?.value);
3193
+ }
3194
+ conditionToOperatorKey(condition) {
3195
+ if (condition.null?.not) {
3196
+ return 'any';
3197
+ }
3198
+ else if (condition.null && !condition.null.not) {
3199
+ return 'none';
3200
+ }
3201
+ else {
3202
+ return this.operators.find(operator => condition[operator.key])?.key ?? 'equal';
3185
3203
  }
3186
3204
  }
3187
3205
  setTodayOrDate(value) {
@@ -3195,7 +3213,9 @@ class TypeDateComponent {
3195
3213
  }
3196
3214
  }
3197
3215
  initValidators() {
3198
- const validators = [Validators.required];
3216
+ const blacklist = ['any', 'none'];
3217
+ this.requireValueCtrl = !blacklist.includes(this.operatorCtrl.value);
3218
+ const validators = this.requireValueCtrl ? [Validators.required] : [];
3199
3219
  if (this.configuration.min) {
3200
3220
  validators.push(dateMin(this.dateAdapter, this.configuration.min));
3201
3221
  }
@@ -3203,6 +3223,7 @@ class TypeDateComponent {
3203
3223
  validators.push(dateMax(this.dateAdapter, this.configuration.max));
3204
3224
  }
3205
3225
  this.valueCtrl.setValidators(validators);
3226
+ this.valueCtrl.updateValueAndValidity();
3206
3227
  }
3207
3228
  getDayAfter(date) {
3208
3229
  return this.dateAdapter.addCalendarDays(this.dateAdapter.clone(date), 1);
@@ -3216,7 +3237,10 @@ class TypeDateComponent {
3216
3237
  else if (this.valueCtrl.value) {
3217
3238
  value = this.dateAdapter.format(this.valueCtrl.value, this.dateFormats.display.dateInput);
3218
3239
  }
3219
- if (operator && value) {
3240
+ if (operator && ['any', 'none'].includes(operator.key)) {
3241
+ return operator.label;
3242
+ }
3243
+ else if (operator && value) {
3220
3244
  return operator.label + ' ' + value;
3221
3245
  }
3222
3246
  else {
@@ -3224,7 +3248,7 @@ class TypeDateComponent {
3224
3248
  }
3225
3249
  }
3226
3250
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: TypeDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3227
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: TypeDateComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field subscriptSizing=\"dynamic\">\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 subscriptSizing=\"dynamic\">\n <mat-label i18n>Date</mat-label>\n <input\n matInput\n [formControl]=\"valueCtrl\"\n [matDatepicker]=\"value\"\n [max]=\"configuration.max\"\n [min]=\"configuration.min\"\n [required]=\"true\"\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"value\" />\n <mat-datepicker #value />\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 @if (valueCtrl.hasError('required')) {\n <mat-error>*</mat-error>\n }\n </mat-form-field>\n\n <mat-checkbox i18n [formControl]=\"todayCtrl\">Aujourd'hui</mat-checkbox>\n</form>\n", styles: ["form{display:grid;grid:auto auto/4em auto;grid-gap:0 1em}form>mat-checkbox{grid-column-start:2;margin-bottom:.3em}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.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$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: 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: "component", type: MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: 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"] }] });
3251
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: TypeDateComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form [formGroup]=\"form\" [class.nullable]=\"configuration.nullable\">\n <mat-form-field subscriptSizing=\"dynamic\">\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 <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label i18n>Date</mat-label>\n <input\n matInput\n [formControl]=\"valueCtrl\"\n [matDatepicker]=\"value\"\n [max]=\"configuration.max\"\n [min]=\"configuration.min\"\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"value\" />\n <mat-datepicker #value />\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 @if (valueCtrl.hasError('required')) {\n <mat-error>*</mat-error>\n }\n </mat-form-field>\n\n <mat-checkbox i18n [formControl]=\"todayCtrl\">Aujourd'hui</mat-checkbox>\n }\n</form>\n", styles: ["form{display:grid;grid:auto auto/4em auto;grid-gap:0 1em}form.nullable{grid:auto auto/6em auto}form>mat-checkbox{grid-column-start:2;margin-bottom:.3em}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.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$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: 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: "component", type: MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: 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"] }] });
3228
3252
  }
3229
3253
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: TypeDateComponent, decorators: [{
3230
3254
  type: Component,
@@ -3242,7 +3266,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
3242
3266
  MatDatepickerInput,
3243
3267
  MatDatepickerToggle,
3244
3268
  MatCheckbox,
3245
- ], template: "<form [formGroup]=\"form\">\n <mat-form-field subscriptSizing=\"dynamic\">\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 subscriptSizing=\"dynamic\">\n <mat-label i18n>Date</mat-label>\n <input\n matInput\n [formControl]=\"valueCtrl\"\n [matDatepicker]=\"value\"\n [max]=\"configuration.max\"\n [min]=\"configuration.min\"\n [required]=\"true\"\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"value\" />\n <mat-datepicker #value />\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 @if (valueCtrl.hasError('required')) {\n <mat-error>*</mat-error>\n }\n </mat-form-field>\n\n <mat-checkbox i18n [formControl]=\"todayCtrl\">Aujourd'hui</mat-checkbox>\n</form>\n", styles: ["form{display:grid;grid:auto auto/4em auto;grid-gap:0 1em}form>mat-checkbox{grid-column-start:2;margin-bottom:.3em}\n"] }]
3269
+ ], template: "<form [formGroup]=\"form\" [class.nullable]=\"configuration.nullable\">\n <mat-form-field subscriptSizing=\"dynamic\">\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 <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label i18n>Date</mat-label>\n <input\n matInput\n [formControl]=\"valueCtrl\"\n [matDatepicker]=\"value\"\n [max]=\"configuration.max\"\n [min]=\"configuration.min\"\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"value\" />\n <mat-datepicker #value />\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 @if (valueCtrl.hasError('required')) {\n <mat-error>*</mat-error>\n }\n </mat-form-field>\n\n <mat-checkbox i18n [formControl]=\"todayCtrl\">Aujourd'hui</mat-checkbox>\n }\n</form>\n", styles: ["form{display:grid;grid:auto auto/4em auto;grid-gap:0 1em}form.nullable{grid:auto auto/6em auto}form>mat-checkbox{grid-column-start:2;margin-bottom:.3em}\n"] }]
3246
3270
  }], ctorParameters: () => [] });
3247
3271
 
3248
3272
  function toGraphQLDoctrineFilter(facets, selections) {
@@ -4931,7 +4955,7 @@ class NaturalAbstractModelService {
4931
4955
  // available. To fix that, we can rely on RxJS, which is able to emit synchronously the value we just
4932
4956
  // got from server. Once Apollo Client moves to RxJS (https://github.com/apollographql/apollo-feature-requests/issues/375),
4933
4957
  // we could try to remove `startWith()`.
4934
- return onlyNetwork.pipe(map(firstValue => onlyCache.pipe(startWith(firstValue))));
4958
+ return onlyNetwork.pipe(map(firstValue => onlyCache.pipe(startWith$1(firstValue))));
4935
4959
  }
4936
4960
  else {
4937
4961
  return of(of(this.getDefaultForServer()));
@@ -5328,34 +5352,44 @@ class NaturalThemeService {
5328
5352
  platformId = inject(PLATFORM_ID);
5329
5353
  document = inject(DOCUMENT);
5330
5354
  isDarkSystem = toSignal(isPlatformBrowser(this.platformId)
5331
- ? fromEvent(this.document.defaultView.matchMedia('(prefers-color-scheme: dark)'), 'change').pipe(startWith(this.document.defaultView.matchMedia('(prefers-color-scheme: dark)')), map$1(e => e.matches))
5355
+ ? fromEvent(this.document.defaultView.matchMedia('(prefers-color-scheme: dark)'), 'change').pipe(startWith$1(this.document.defaultView.matchMedia('(prefers-color-scheme: dark)')), map$1(e => e.matches))
5332
5356
  : of(false), { initialValue: false });
5333
5357
  isDark = computed(() => {
5334
5358
  return (this.colorScheme() === ColorScheme.Dark || (this.colorScheme() === ColorScheme.Auto && this.isDarkSystem()));
5335
5359
  }, ...(ngDevMode ? [{ debugName: "isDark" }] : []));
5336
- theme = signal(this.allThemes[0], ...(ngDevMode ? [{ debugName: "theme" }] : []));
5337
- colorScheme = signal(ColorScheme.Auto, ...(ngDevMode ? [{ debugName: "colorScheme" }] : []));
5360
+ _theme = signal(this.allThemes[0], ...(ngDevMode ? [{ debugName: "_theme" }] : []));
5361
+ /**
5362
+ * Currently selected theme. Use `setTheme()` to select a different theme.
5363
+ */
5364
+ theme = this._theme.asReadonly();
5365
+ _colorScheme = signal(ColorScheme.Auto, ...(ngDevMode ? [{ debugName: "_colorScheme" }] : []));
5366
+ /**
5367
+ * Currently selected color scheme. Use `setColorScheme()` to select a different scheme.
5368
+ */
5369
+ colorScheme = this._colorScheme.asReadonly();
5338
5370
  constructor() {
5339
5371
  effect(() => {
5340
5372
  this.document.documentElement.setAttribute('data-is-dark', this.isDark() ? 'true' : 'false');
5341
5373
  });
5342
5374
  const storedScheme = this.storage.getItem('color-scheme');
5343
5375
  const isValidScheme = storedScheme && Object.values(ColorScheme).includes(storedScheme);
5344
- this.colorScheme.set(isValidScheme ? storedScheme : ColorScheme.Auto);
5376
+ this._colorScheme.set(isValidScheme ? storedScheme : ColorScheme.Auto);
5345
5377
  }
5346
5378
  /**
5347
5379
  * Set theme in memory, local storage and dom
5348
5380
  */
5349
- setTheme(name) {
5350
- this.theme.set(name);
5351
- this.storage.setItem('theme', name);
5352
- this.document.documentElement.setAttribute('data-theme', name);
5381
+ setTheme(theme) {
5382
+ if (!this.allThemes.includes(theme)) {
5383
+ throw new Error(`Expecting one of the configured themes: ${this.allThemes.map(t => `'${t}'`).join(', ')}. But got invalid: '${theme}'`);
5384
+ }
5385
+ this._theme.set(theme);
5386
+ this.document.documentElement.setAttribute('data-theme', theme);
5353
5387
  }
5354
5388
  /**
5355
5389
  * Set dark/light/auto
5356
5390
  */
5357
5391
  setColorScheme(scheme, persistInStorage = true) {
5358
- this.colorScheme.set(scheme); // memory
5392
+ this._colorScheme.set(scheme); // memory
5359
5393
  this.document.documentElement.setAttribute('data-color-scheme', scheme); // dom
5360
5394
  if (persistInStorage) {
5361
5395
  this.storage.setItem('color-scheme', this.colorScheme()); // storage
@@ -6259,7 +6293,7 @@ class NaturalSeoService {
6259
6293
  constructor() {
6260
6294
  const configToken = inject(NATURAL_SEO_CONFIG);
6261
6295
  combineLatest({
6262
- config: configToken instanceof Observable ? configToken.pipe(startWith$1(this.config)) : of(configToken),
6296
+ config: configToken instanceof Observable ? configToken.pipe(startWith(this.config)) : of(configToken),
6263
6297
  navigationEnd: this.router.events.pipe(filter$1(event => event instanceof NavigationEnd)),
6264
6298
  })
6265
6299
  .pipe(takeUntilDestroyed(), switchMap(({ config }) => {
@@ -6545,7 +6579,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
6545
6579
  class TypeSelectComponent {
6546
6580
  destroyRef = inject(DestroyRef);
6547
6581
  renderedValue = new BehaviorSubject('');
6548
- list = viewChild(MatSelectionList, ...(ngDevMode ? [{ debugName: "list" }] : []));
6549
6582
  requireValueCtrl = false;
6550
6583
  operators = possibleDiscreteOperators;
6551
6584
  operatorCtrl = new FormControl('is', { nonNullable: true });
@@ -6565,19 +6598,13 @@ class TypeSelectComponent {
6565
6598
  const data = inject(NATURAL_DROPDOWN_DATA);
6566
6599
  this.configuration = { ...this.defaults, ...data.configuration };
6567
6600
  // Immediately initValidators and everytime the operator change later
6568
- this.operatorCtrl.valueChanges.pipe(startWith(null)).subscribe(() => this.initValidators());
6601
+ this.operatorCtrl.valueChanges.pipe(startWith$1(null)).subscribe(() => this.initValidators());
6569
6602
  merge$1(this.operatorCtrl.valueChanges, this.valueCtrl.valueChanges).subscribe(() => {
6570
6603
  const rendered = this.getRenderedValue();
6571
6604
  this.renderedValue.next(rendered);
6572
6605
  });
6573
6606
  this.reloadCondition(data.condition);
6574
6607
  }
6575
- ngAfterViewInit() {
6576
- const list = this.list();
6577
- if (!this.isMultiple() && list) {
6578
- list.selectedOptions._multiple = false;
6579
- }
6580
- }
6581
6608
  getId(item) {
6582
6609
  if (typeof item === 'object' && item) {
6583
6610
  return item.id || item.value;
@@ -6691,7 +6718,7 @@ class TypeSelectComponent {
6691
6718
  }
6692
6719
  }
6693
6720
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: TypeSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6694
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: TypeSelectComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "list", first: true, predicate: MatSelectionList, descendants: true, isSignal: true }], ngImport: i0, template: "<form [formGroup]=\"form\">\n @if (configuration.operators) {\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\" subscriptSizing=\"dynamic\">\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\n @if (requireValueCtrl) {\n <mat-selection-list [formControl]=\"valueCtrl\">\n @for (item of items; track item) {\n <mat-list-option togglePosition=\"before\" [value]=\"getId(item)\">\n {{ getDisplay(item) }}\n </mat-list-option>\n }\n </mat-selection-list>\n }\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.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$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatSelectionList, selector: "mat-selection-list", inputs: ["color", "compareWith", "multiple", "hideSingleSelectionIndicator", "disabled"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: MatListOption, selector: "mat-list-option", inputs: ["togglePosition", "checkboxPosition", "color", "value", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }] });
6721
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: TypeSelectComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form [formGroup]=\"form\">\n @if (configuration.operators) {\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\" subscriptSizing=\"dynamic\">\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\n @if (requireValueCtrl) {\n <mat-selection-list [formControl]=\"valueCtrl\" [multiple]=\"configuration.multiple\">\n @for (item of items; track item) {\n <mat-list-option togglePosition=\"before\" [value]=\"getId(item)\">\n {{ getDisplay(item) }}\n </mat-list-option>\n }\n </mat-selection-list>\n }\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.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$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatSelectionList, selector: "mat-selection-list", inputs: ["color", "compareWith", "multiple", "hideSingleSelectionIndicator", "disabled"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: MatListOption, selector: "mat-list-option", inputs: ["togglePosition", "checkboxPosition", "color", "value", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }] });
6695
6722
  }
6696
6723
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: TypeSelectComponent, decorators: [{
6697
6724
  type: Component,
@@ -6704,8 +6731,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
6704
6731
  MatOption,
6705
6732
  MatSelectionList,
6706
6733
  MatListOption,
6707
- ], template: "<form [formGroup]=\"form\">\n @if (configuration.operators) {\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\" subscriptSizing=\"dynamic\">\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\n @if (requireValueCtrl) {\n <mat-selection-list [formControl]=\"valueCtrl\">\n @for (item of items; track item) {\n <mat-list-option togglePosition=\"before\" [value]=\"getId(item)\">\n {{ getDisplay(item) }}\n </mat-list-option>\n }\n </mat-selection-list>\n }\n</form>\n" }]
6708
- }], ctorParameters: () => [], propDecorators: { list: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatSelectionList), { isSignal: true }] }] } });
6734
+ ], template: "<form [formGroup]=\"form\">\n @if (configuration.operators) {\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\" subscriptSizing=\"dynamic\">\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\n @if (requireValueCtrl) {\n <mat-selection-list [formControl]=\"valueCtrl\" [multiple]=\"configuration.multiple\">\n @for (item of items; track item) {\n <mat-list-option togglePosition=\"before\" [value]=\"getId(item)\">\n {{ getDisplay(item) }}\n </mat-list-option>\n }\n </mat-selection-list>\n }\n</form>\n" }]
6735
+ }], ctorParameters: () => [] });
6709
6736
 
6710
6737
  class AbstractAssociationSelectComponent {
6711
6738
  configuration;
@@ -6722,7 +6749,7 @@ class AbstractAssociationSelectComponent {
6722
6749
  const data = inject(NATURAL_DROPDOWN_DATA);
6723
6750
  this.configuration = data.configuration;
6724
6751
  // Immediately initValidators and everytime the operator change later
6725
- this.operatorCtrl.valueChanges.pipe(startWith(null)).subscribe(() => this.initValidators());
6752
+ this.operatorCtrl.valueChanges.pipe(startWith$1(null)).subscribe(() => this.initValidators());
6726
6753
  merge$1(this.operatorCtrl.valueChanges, this.valueCtrl.valueChanges).subscribe(() => {
6727
6754
  const rendered = this.getRenderedValue();
6728
6755
  this.renderedValue.next(rendered);
@@ -7374,34 +7401,44 @@ class TypeNumberComponent {
7374
7401
  renderedValue = new BehaviorSubject('');
7375
7402
  configuration;
7376
7403
  operatorCtrl = new FormControl('equal', { nonNullable: true });
7377
- valueCtrl = new FormControl();
7404
+ valueCtrl = new FormControl(null);
7378
7405
  matcher = new InvalidWithValueStateMatcher$1();
7379
7406
  form = new FormGroup({
7380
7407
  operator: this.operatorCtrl,
7381
7408
  value: this.valueCtrl,
7382
7409
  });
7383
- operators = possibleComparableOperators;
7410
+ requireValueCtrl = false;
7411
+ operators;
7384
7412
  defaults = {
7385
7413
  min: null,
7386
7414
  max: null,
7387
7415
  step: null,
7416
+ nullable: false,
7388
7417
  };
7389
7418
  constructor() {
7390
7419
  const data = inject(NATURAL_DROPDOWN_DATA);
7391
7420
  this.configuration = { ...this.defaults, ...data.configuration };
7421
+ this.operators = this.configuration.nullable ? possibleNullComparableOperators : possibleComparableOperators;
7392
7422
  merge$1(this.operatorCtrl.valueChanges, this.valueCtrl.valueChanges).subscribe(() => {
7393
7423
  const rendered = this.getRenderedValue();
7394
7424
  this.renderedValue.next(rendered);
7395
7425
  });
7396
- this.initValidators();
7426
+ // Immediately initValidators and everytime the operator change later
7427
+ this.operatorCtrl.valueChanges.pipe(startWith$1(null)).subscribe(() => this.initValidators());
7397
7428
  this.reloadCondition(data.condition);
7398
7429
  }
7399
7430
  getCondition() {
7400
- const condition = {};
7401
- condition[this.operatorCtrl.value] = {
7402
- value: this.valueCtrl.value,
7403
- };
7404
- return condition;
7431
+ const key = this.operatorCtrl.value;
7432
+ const value = this.valueCtrl.value;
7433
+ switch (key) {
7434
+ case 'any':
7435
+ return { null: { not: true } };
7436
+ case 'none':
7437
+ return { null: { not: false } };
7438
+ default: {
7439
+ return { [key]: { value: value } };
7440
+ }
7441
+ }
7405
7442
  }
7406
7443
  isValid() {
7407
7444
  return this.form.valid;
@@ -7418,7 +7455,9 @@ class TypeNumberComponent {
7418
7455
  }
7419
7456
  }
7420
7457
  initValidators() {
7421
- const validators = [Validators.required];
7458
+ const blacklist = ['any', 'none'];
7459
+ this.requireValueCtrl = !blacklist.includes(this.operatorCtrl.value);
7460
+ const validators = this.requireValueCtrl ? [Validators.required] : [];
7422
7461
  if (typeof this.configuration.min === 'number') {
7423
7462
  validators.push(Validators.min(this.configuration.min));
7424
7463
  }
@@ -7431,34 +7470,45 @@ class TypeNumberComponent {
7431
7470
  validators.push(decimal(decimalCount));
7432
7471
  }
7433
7472
  this.valueCtrl.setValidators(validators);
7473
+ this.valueCtrl.updateValueAndValidity();
7434
7474
  }
7435
7475
  reloadCondition(condition) {
7436
7476
  if (!condition) {
7437
7477
  return;
7438
7478
  }
7439
- for (const operator of this.operators) {
7440
- const reloadedCondition = condition[operator.key];
7441
- if (reloadedCondition) {
7442
- this.operatorCtrl.setValue(operator.key);
7443
- this.valueCtrl.setValue(reloadedCondition.value);
7444
- }
7445
- }
7479
+ const operatorKey = this.conditionToOperatorKey(condition);
7480
+ this.operatorCtrl.setValue(operatorKey);
7481
+ this.valueCtrl.setValue(condition[operatorKey]?.value);
7446
7482
  }
7447
7483
  getRenderedValue() {
7448
7484
  const operator = this.operators.find(v => v.key === this.operatorCtrl.value);
7449
- if (this.valueCtrl.value === null || !operator) {
7485
+ if (operator && ['any', 'none'].includes(operator.key)) {
7486
+ return operator.label;
7487
+ }
7488
+ else if (operator && this.valueCtrl.value !== null) {
7489
+ return operator.label + ' ' + this.valueCtrl.value;
7490
+ }
7491
+ else {
7450
7492
  return '';
7451
7493
  }
7494
+ }
7495
+ conditionToOperatorKey(condition) {
7496
+ if (condition.null?.not) {
7497
+ return 'any';
7498
+ }
7499
+ else if (condition.null && !condition.null.not) {
7500
+ return 'none';
7501
+ }
7452
7502
  else {
7453
- return operator.label + ' ' + this.valueCtrl.value;
7503
+ return this.operators.find(operator => condition[operator.key])?.key ?? 'equal';
7454
7504
  }
7455
7505
  }
7456
7506
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: TypeNumberComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7457
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: TypeNumberComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 4em; margin-right: 1em\" subscriptSizing=\"dynamic\">\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 subscriptSizing=\"dynamic\">\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"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.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$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: 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"] }] });
7507
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: TypeNumberComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field\n style=\"margin-right: 1em\"\n subscriptSizing=\"dynamic\"\n [style.max-width]=\"configuration.nullable ? '6em' : '4em'\"\n >\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 <mat-form-field subscriptSizing=\"dynamic\">\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 }\n</form>\n", styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.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$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: 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"] }] });
7458
7508
  }
7459
7509
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: TypeNumberComponent, decorators: [{
7460
7510
  type: Component,
7461
- args: [{ imports: [FormsModule, ReactiveFormsModule, MatFormField, MatLabel, MatError, MatSelect, MatOption, MatInput], template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 4em; margin-right: 1em\" subscriptSizing=\"dynamic\">\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 subscriptSizing=\"dynamic\">\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"] }]
7511
+ args: [{ imports: [FormsModule, ReactiveFormsModule, MatFormField, MatLabel, MatError, MatSelect, MatOption, MatInput], template: "<form [formGroup]=\"form\">\n <mat-form-field\n style=\"margin-right: 1em\"\n subscriptSizing=\"dynamic\"\n [style.max-width]=\"configuration.nullable ? '6em' : '4em'\"\n >\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 <mat-form-field subscriptSizing=\"dynamic\">\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 }\n</form>\n", styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"] }]
7462
7512
  }], ctorParameters: () => [] });
7463
7513
 
7464
7514
  class FacetSelectorComponent {
@@ -8335,13 +8385,13 @@ class NaturalHierarchicSelectorComponent {
8335
8385
  * Get list of children, considering given FlatNode id as a parent.
8336
8386
  * Mark loading status individually on nodes.
8337
8387
  */
8338
- loadChildren(node, contextFilter = null) {
8388
+ loadChildren(node) {
8339
8389
  if (node.hasChildren) {
8340
8390
  return;
8341
8391
  }
8342
8392
  node.isLoading = true;
8343
8393
  this.hierarchicSelectorService
8344
- .getList(node, contextFilter, null, this.config())
8394
+ .getList(node, this.filters(), null, this.config())
8345
8395
  .pipe(finalize$1(() => (node.isLoading = false)))
8346
8396
  .subscribe(items => node.childrenChange.next(items));
8347
8397
  }
@@ -8712,13 +8762,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
8712
8762
  */
8713
8763
  const commonImageMimeTypes = 'image/avif,image/bmp,image/x-ms-bmp,image/gif,image/heic,image/heif,image/jpeg,image/pjpeg,image/png,image/svg+xml,image/svg,image/webp';
8714
8764
  function acceptType(accept, type, filename) {
8715
- if (!accept.trim()) {
8765
+ const mimeAndExtensions = accept
8766
+ .trim()
8767
+ .toLowerCase()
8768
+ .split(',')
8769
+ .map(s => s.trim())
8770
+ .filter(s => s);
8771
+ if (!mimeAndExtensions.length) {
8716
8772
  return true;
8717
8773
  }
8718
8774
  type = type.toLowerCase();
8719
8775
  filename = filename.toLowerCase();
8720
- return accept.split(',').some(mimeOrExtension => {
8721
- mimeOrExtension = mimeOrExtension.trim().toLowerCase();
8776
+ const mimeAsExtensions = mimeAndExtensions
8777
+ .map(s => /^[^/]+\/(.*)$/.exec(s)?.[1])
8778
+ .filter(s => s)
8779
+ .map(s => '.' + s);
8780
+ return [...mimeAndExtensions, ...mimeAsExtensions].some(mimeOrExtension => {
8722
8781
  if (mimeOrExtension.startsWith('.')) {
8723
8782
  return filename.endsWith(mimeOrExtension);
8724
8783
  }
@@ -9272,6 +9331,7 @@ class NaturalFileComponent {
9272
9331
  formCtrlValue.setValue(this.model);
9273
9332
  }
9274
9333
  this.modelChange.emit(this.model);
9334
+ this.updateImage();
9275
9335
  });
9276
9336
  }
9277
9337
  getDownloadLink() {
@@ -11316,11 +11376,11 @@ class NaturalColorSchemerComponent {
11316
11376
  themeService = inject(NaturalThemeService);
11317
11377
  ColorScheme = ColorScheme;
11318
11378
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: NaturalColorSchemerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11319
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.7", type: NaturalColorSchemerComponent, isStandalone: true, selector: "natural-color-schemer", ngImport: i0, template: "<div class=\"nat-horizontal wrapper\">\n <button\n matIconButton\n matTooltip=\"Switch to auto mode\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Auto)\"\n >\n <mat-icon naturalIcon=\"routine\" />\n </button>\n <button\n matIconButton\n matTooltip=\"Switch to light mode\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Light)\"\n >\n <mat-icon naturalIcon=\"light_mode\" />\n </button>\n <button\n matIconButton\n matTooltip=\"Switch to dark mode\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Dark)\"\n >\n <mat-icon naturalIcon=\"dark_mode\" />\n </button>\n</div>\n", styles: [":host{display:block;width:fit-content}.wrapper{border-radius:var(--mat-sys-corner-full);background:var(--mat-sys-surface-bright);padding:5px}\n"], dependencies: [{ kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
11379
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.7", type: NaturalColorSchemerComponent, isStandalone: true, selector: "natural-color-schemer", ngImport: i0, template: "<div class=\"nat-horizontal wrapper\">\n <button\n matIconButton\n matTooltip=\"Th\u00E8me de l'appareil\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Auto)\"\n >\n <mat-icon naturalIcon=\"routine\" />\n </button>\n <button\n matIconButton\n matTooltip=\"Th\u00E8me clair\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Light)\"\n >\n <mat-icon naturalIcon=\"light_mode\" />\n </button>\n <button\n matIconButton\n matTooltip=\"Th\u00E8me sombre\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Dark)\"\n >\n <mat-icon naturalIcon=\"dark_mode\" />\n </button>\n</div>\n", styles: [":host{display:block;width:fit-content}.wrapper{border-radius:var(--mat-sys-corner-full);background:var(--mat-sys-surface-bright);padding:5px}\n"], dependencies: [{ kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11320
11380
  }
11321
11381
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: NaturalColorSchemerComponent, decorators: [{
11322
11382
  type: Component,
11323
- args: [{ selector: 'natural-color-schemer', imports: [MatIconButton, MatTooltip, NaturalIconDirective, FormsModule, MatIcon], template: "<div class=\"nat-horizontal wrapper\">\n <button\n matIconButton\n matTooltip=\"Switch to auto mode\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Auto)\"\n >\n <mat-icon naturalIcon=\"routine\" />\n </button>\n <button\n matIconButton\n matTooltip=\"Switch to light mode\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Light)\"\n >\n <mat-icon naturalIcon=\"light_mode\" />\n </button>\n <button\n matIconButton\n matTooltip=\"Switch to dark mode\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Dark)\"\n >\n <mat-icon naturalIcon=\"dark_mode\" />\n </button>\n</div>\n", styles: [":host{display:block;width:fit-content}.wrapper{border-radius:var(--mat-sys-corner-full);background:var(--mat-sys-surface-bright);padding:5px}\n"] }]
11383
+ args: [{ selector: 'natural-color-schemer', imports: [MatIconButton, MatTooltip, NaturalIconDirective, FormsModule, MatIcon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"nat-horizontal wrapper\">\n <button\n matIconButton\n matTooltip=\"Th\u00E8me de l'appareil\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Auto)\"\n >\n <mat-icon naturalIcon=\"routine\" />\n </button>\n <button\n matIconButton\n matTooltip=\"Th\u00E8me clair\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Light)\"\n >\n <mat-icon naturalIcon=\"light_mode\" />\n </button>\n <button\n matIconButton\n matTooltip=\"Th\u00E8me sombre\"\n i18n-matTooltip\n matTooltipPosition=\"below\"\n (click)=\"themeService.setColorScheme(ColorScheme.Dark)\"\n >\n <mat-icon naturalIcon=\"dark_mode\" />\n </button>\n</div>\n", styles: [":host{display:block;width:fit-content}.wrapper{border-radius:var(--mat-sys-corner-full);background:var(--mat-sys-surface-bright);padding:5px}\n"] }]
11324
11384
  }] });
11325
11385
 
11326
11386
  /*
@@ -11331,20 +11391,11 @@ class NaturalThemeChangerComponent {
11331
11391
  themeService = inject(NaturalThemeService);
11332
11392
  allThemes = inject(NATURAL_THEMES_CONFIG);
11333
11393
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: NaturalThemeChangerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11334
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: NaturalThemeChangerComponent, isStandalone: true, selector: "natural-theme-changer", ngImport: i0, template: "<button matButton=\"filled\" [matMenuTriggerFor]=\"menu\"\n ><mat-icon naturalIcon=\"colors\" /> {{ themeService.theme() }}</button\n>\n<mat-menu #menu=\"matMenu\">\n @for (theme of allThemes; track $index) {\n <button mat-menu-item (click)=\"themeService.setTheme(theme)\">{{ theme }}</button>\n }\n</mat-menu>\n", styles: [":host{display:block;width:fit-content}.wrapper{border-radius:var(--mat-sys-corner-full);background:var(--mat-sys-surface-bright);padding:5px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: 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: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }] });
11394
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: NaturalThemeChangerComponent, isStandalone: true, selector: "natural-theme-changer", ngImport: i0, template: "<button matButton=\"filled\" [matMenuTriggerFor]=\"menu\"\n ><mat-icon naturalIcon=\"colors\" /> {{ themeService.theme() }}</button\n>\n<mat-menu #menu=\"matMenu\">\n @for (theme of allThemes; track $index) {\n <button mat-menu-item (click)=\"themeService.setTheme(theme)\">\n <mat-icon [fontIcon]=\"themeService.theme() === theme ? 'check' : ''\" />\n {{ theme }}</button\n >\n }\n</mat-menu>\n", styles: [":host{display:block;width:fit-content}.wrapper{border-radius:var(--mat-sys-corner-full);background:var(--mat-sys-surface-bright);padding:5px}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: 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: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11335
11395
  }
11336
11396
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: NaturalThemeChangerComponent, decorators: [{
11337
11397
  type: Component,
11338
- args: [{ selector: 'natural-theme-changer', imports: [
11339
- CommonModule,
11340
- FormsModule,
11341
- MatButton,
11342
- MatMenuTrigger,
11343
- MatMenu,
11344
- MatMenuItem,
11345
- MatIcon,
11346
- NaturalIconDirective,
11347
- ], template: "<button matButton=\"filled\" [matMenuTriggerFor]=\"menu\"\n ><mat-icon naturalIcon=\"colors\" /> {{ themeService.theme() }}</button\n>\n<mat-menu #menu=\"matMenu\">\n @for (theme of allThemes; track $index) {\n <button mat-menu-item (click)=\"themeService.setTheme(theme)\">{{ theme }}</button>\n }\n</mat-menu>\n", styles: [":host{display:block;width:fit-content}.wrapper{border-radius:var(--mat-sys-corner-full);background:var(--mat-sys-surface-bright);padding:5px}\n"] }]
11398
+ args: [{ selector: 'natural-theme-changer', imports: [MatButton, MatMenuTrigger, MatMenu, MatMenuItem, MatIcon, NaturalIconDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button matButton=\"filled\" [matMenuTriggerFor]=\"menu\"\n ><mat-icon naturalIcon=\"colors\" /> {{ themeService.theme() }}</button\n>\n<mat-menu #menu=\"matMenu\">\n @for (theme of allThemes; track $index) {\n <button mat-menu-item (click)=\"themeService.setTheme(theme)\">\n <mat-icon [fontIcon]=\"themeService.theme() === theme ? 'check' : ''\" />\n {{ theme }}</button\n >\n }\n</mat-menu>\n", styles: [":host{display:block;width:fit-content}.wrapper{border-radius:var(--mat-sys-corner-full);background:var(--mat-sys-surface-bright);padding:5px}\n"] }]
11348
11399
  }] });
11349
11400
 
11350
11401
  /*
@@ -11454,5 +11505,5 @@ function graphqlQuerySigner(key) {
11454
11505
  * Generated bundle index. Do not edit.
11455
11506
  */
11456
11507
 
11457
- export { AvatarService, ColorScheme, InvalidWithValueStateMatcher$1 as InvalidWithValueStateMatcher, LOCAL_STORAGE, NATURAL_DROPDOWN_DATA, NATURAL_ICONS_CONFIG, NATURAL_PERSISTENCE_VALIDATOR, NATURAL_SEO_CONFIG, NaturalAbstractDetail, NaturalAbstractEditableList, NaturalAbstractList, NaturalAbstractModelService, NaturalAbstractNavigableList, NaturalAbstractPanel, NaturalAlertService, NaturalAvatarComponent, NaturalBackgroundDensityDirective, NaturalCapitalizePipe, NaturalColorSchemerComponent, NaturalColumnsPickerComponent, NaturalConfirmComponent, NaturalDataSource, NaturalDebounceService, NaturalDetailHeaderComponent, NaturalDialogTriggerComponent, NaturalDropdownRef, NaturalEllipsisPipe, NaturalEnumPipe, NaturalEnumService, NaturalErrorHandler, NaturalErrorMessagePipe, NaturalFileComponent, NaturalFileDropDirective, NaturalFileSelectDirective, NaturalFileService, NaturalFixedButtonComponent, NaturalFixedButtonDetailComponent, NaturalHierarchicSelectorComponent, NaturalHierarchicSelectorDialogComponent, NaturalHierarchicSelectorDialogService, NaturalHierarchicSelectorService, NaturalHttpPrefixDirective, NaturalIconDirective, NaturalLinkMutationService, NaturalLinkableTabDirective, NaturalLoggerConfigExtra, NaturalLoggerConfigUrl, NaturalMatomoService, NaturalMemoryStorage, NaturalPanelsComponent, NaturalPanelsService, NaturalPersistenceService, NaturalQueryVariablesManager, NaturalRelationsComponent, NaturalSearchComponent, NaturalSelectComponent, NaturalSelectEnumComponent, NaturalSelectHierarchicComponent, NaturalSeoService, NaturalSidenavComponent, NaturalSidenavContainerComponent, NaturalSidenavContentComponent, NaturalSidenavService, NaturalSidenavStackService, NaturalSrcDensityDirective, NaturalStampComponent, NaturalSwissParsingDateAdapter, NaturalTableButtonComponent, NaturalThemeChangerComponent, NaturalThemeService, NaturalTimeAgoPipe, NetworkActivityService, PanelsHooksConfig, SESSION_STORAGE, SortingOrder, TypeBooleanComponent, TypeDateComponent, TypeDateRangeComponent, TypeHierarchicSelectorComponent, TypeNaturalSelectComponent, TypeNumberComponent, TypeOptionsComponent, TypeSelectComponent, TypeTextComponent, activityInterceptor, available, cancellableTimeout, cloneDeepButSkipFile, collectErrors, commonImageMimeTypes, copyToClipboard, createHttpLink, debug, decimal, deepFreeze, deliverableEmail, ensureHttpPrefix, fallbackIfNoOpenedPanels, formatIsoDate, formatIsoDateTime, fromUrl, getForegroundColor, graphqlQuerySigner, greaterThan, hasFilesAndProcessDate, ifValid, integer, isFile, localStorageFactory, localStorageProvider, makePlural, memoryLocalStorageProvider, memorySessionStorageProvider, mergeOverrideArray, money, naturalPanelsUrlMatcher, naturalProviders, nfcCardHex, onHistoryEvent, possibleComparableOperators, provideErrorHandler, provideIcons, providePanels, provideSeo, provideThemes, relationsToIds, replaceObjectKeepingReference, replaceOperatorByField, replaceOperatorByName, rgbToHex, sessionStorageFactory, sessionStorageProvider, time, toGraphQLDoctrineFilter, toNavigationParameters, toUrl, unique, upperCaseFirstLetter, url, urlPattern, validTlds, validateAllFormControls, validateColumns, validatePagination, validateSorting, wrapLike, wrapPrefix, wrapSuffix };
11508
+ export { AvatarService, ColorScheme, InvalidWithValueStateMatcher$1 as InvalidWithValueStateMatcher, LOCAL_STORAGE, NATURAL_DROPDOWN_DATA, NATURAL_ICONS_CONFIG, NATURAL_PERSISTENCE_VALIDATOR, NATURAL_SEO_CONFIG, NaturalAbstractDetail, NaturalAbstractEditableList, NaturalAbstractList, NaturalAbstractModelService, NaturalAbstractNavigableList, NaturalAbstractPanel, NaturalAlertService, NaturalAvatarComponent, NaturalBackgroundDensityDirective, NaturalCapitalizePipe, NaturalColorSchemerComponent, NaturalColumnsPickerComponent, NaturalConfirmComponent, NaturalDataSource, NaturalDebounceService, NaturalDetailHeaderComponent, NaturalDialogTriggerComponent, NaturalDropdownRef, NaturalEllipsisPipe, NaturalEnumPipe, NaturalEnumService, NaturalErrorHandler, NaturalErrorMessagePipe, NaturalFileComponent, NaturalFileDropDirective, NaturalFileSelectDirective, NaturalFileService, NaturalFixedButtonComponent, NaturalFixedButtonDetailComponent, NaturalHierarchicSelectorComponent, NaturalHierarchicSelectorDialogComponent, NaturalHierarchicSelectorDialogService, NaturalHierarchicSelectorService, NaturalHttpPrefixDirective, NaturalIconDirective, NaturalLinkMutationService, NaturalLinkableTabDirective, NaturalLoggerConfigExtra, NaturalLoggerConfigUrl, NaturalMatomoService, NaturalMemoryStorage, NaturalPanelsComponent, NaturalPanelsService, NaturalPersistenceService, NaturalQueryVariablesManager, NaturalRelationsComponent, NaturalSearchComponent, NaturalSelectComponent, NaturalSelectEnumComponent, NaturalSelectHierarchicComponent, NaturalSeoService, NaturalSidenavComponent, NaturalSidenavContainerComponent, NaturalSidenavContentComponent, NaturalSidenavService, NaturalSidenavStackService, NaturalSrcDensityDirective, NaturalStampComponent, NaturalSwissParsingDateAdapter, NaturalTableButtonComponent, NaturalThemeChangerComponent, NaturalThemeService, NaturalTimeAgoPipe, NetworkActivityService, PanelsHooksConfig, SESSION_STORAGE, SortingOrder, TypeBooleanComponent, TypeDateComponent, TypeDateRangeComponent, TypeHierarchicSelectorComponent, TypeNaturalSelectComponent, TypeNumberComponent, TypeOptionsComponent, TypeSelectComponent, TypeTextComponent, activityInterceptor, available, cancellableTimeout, cloneDeepButSkipFile, collectErrors, commonImageMimeTypes, copyToClipboard, createHttpLink, debug, decimal, deepFreeze, deliverableEmail, ensureHttpPrefix, fallbackIfNoOpenedPanels, formatIsoDate, formatIsoDateTime, fromUrl, getForegroundColor, graphqlQuerySigner, greaterThan, hasFilesAndProcessDate, ifValid, integer, isFile, localStorageFactory, localStorageProvider, makePlural, memoryLocalStorageProvider, memorySessionStorageProvider, mergeOverrideArray, money, naturalPanelsUrlMatcher, naturalProviders, nfcCardHex, onHistoryEvent, possibleComparableOperators, possibleNullComparableOperators, provideErrorHandler, provideIcons, providePanels, provideSeo, provideThemes, relationsToIds, replaceObjectKeepingReference, replaceOperatorByField, replaceOperatorByName, rgbToHex, sessionStorageFactory, sessionStorageProvider, time, toGraphQLDoctrineFilter, toNavigationParameters, toUrl, unique, upperCaseFirstLetter, url, urlPattern, validTlds, validateAllFormControls, validateColumns, validatePagination, validateSorting, wrapLike, wrapPrefix, wrapSuffix };
11458
11509
  //# sourceMappingURL=ecodev-natural.mjs.map