@ecodev/natural 37.1.0 → 40.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/bundles/ecodev-natural.umd.js +158 -109
  2. package/bundles/ecodev-natural.umd.js.map +1 -1
  3. package/ecodev-natural.metadata.json +1 -1
  4. package/esm2015/lib/classes/abstract-list.js +20 -22
  5. package/esm2015/lib/classes/abstract-navigable-list.js +32 -23
  6. package/esm2015/lib/classes/rxjs.js +13 -2
  7. package/esm2015/lib/classes/validators.js +15 -1
  8. package/esm2015/lib/modules/alert/confirm.component.js +1 -1
  9. package/esm2015/lib/modules/columns-picker/columns-picker.component.js +26 -8
  10. package/esm2015/lib/modules/detail-header/detail-header.component.js +1 -1
  11. package/esm2015/lib/modules/dropdown-components/type-number/type-number.component.js +1 -1
  12. package/esm2015/lib/modules/dropdown-components/type-text/type-text.component.js +1 -1
  13. package/esm2015/lib/modules/file/component/file.component.js +1 -1
  14. package/esm2015/lib/modules/file/file-drop.directive.js +2 -4
  15. package/esm2015/lib/modules/fixed-button/fixed-button.component.js +1 -1
  16. package/esm2015/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.component.js +1 -1
  17. package/esm2015/lib/modules/hierarchic-selector/hierarchic-selector-dialog/hierarchic-selector-dialog.component.js +1 -1
  18. package/esm2015/lib/modules/icon/icon.component.js +1 -1
  19. package/esm2015/lib/modules/relations/relations.component.js +1 -1
  20. package/esm2015/lib/modules/search/dropdown-container/dropdown-container.component.js +2 -2
  21. package/esm2015/lib/modules/search/dropdown-container/dropdown-ref.js +1 -1
  22. package/esm2015/lib/modules/search/facet-selector/facet-selector.component.js +1 -1
  23. package/esm2015/lib/modules/search/group/group.component.js +1 -1
  24. package/esm2015/lib/modules/search/input/input.component.js +4 -4
  25. package/esm2015/lib/modules/search/search/search.component.js +1 -1
  26. package/esm2015/lib/modules/select/select/select.component.js +1 -1
  27. package/esm2015/lib/modules/select/select-hierarchic/select-hierarchic.component.js +1 -1
  28. package/esm2015/lib/modules/sidenav/sidenav-container/sidenav-container.component.js +3 -3
  29. package/esm2015/lib/modules/sidenav/sidenav-content/sidenav-content.component.js +1 -1
  30. package/esm2015/lib/modules/table-button/table-button.component.js +1 -1
  31. package/fesm2015/ecodev-natural.js +126 -78
  32. package/fesm2015/ecodev-natural.js.map +1 -1
  33. package/lib/classes/abstract-list.d.ts +7 -10
  34. package/lib/classes/abstract-navigable-list.d.ts +4 -2
  35. package/lib/classes/rxjs.d.ts +6 -1
  36. package/lib/classes/validators.d.ts +7 -0
  37. package/lib/modules/columns-picker/columns-picker.component.d.ts +15 -5
  38. package/lib/modules/search/dropdown-container/dropdown-container.component.d.ts +1 -2
  39. package/lib/modules/sidenav/sidenav-container/sidenav-container.component.d.ts +3 -2
  40. package/package.json +5 -5
  41. package/src/lib/modules/alert/_alert.theme.scss +1 -1
  42. package/src/lib/modules/file/component/_file.theme.scss +1 -1
  43. package/src/lib/modules/icon/_icon.theme.scss +1 -1
  44. package/src/lib/modules/search/dropdown-container/_dropdown-container.theme.scss +1 -1
  45. package/src/lib/modules/sidenav/_sidenav.theme.scss +1 -1
  46. package/src/lib/styles/_table.scss +1 -1
@@ -10,7 +10,7 @@ import * as i1 from '@angular/material/dialog';
10
10
  import { MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
11
11
  import * as i2 from '@angular/material/snack-bar';
12
12
  import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
13
- import { switchMap, map, first, filter, finalize, takeUntil, take, takeWhile, debounceTime, tap, shareReplay, mergeMap, startWith, distinctUntilChanged, throttleTime } from 'rxjs/operators';
13
+ import { switchMap, map, first, filter, finalize, takeUntil, take, tap, takeWhile, debounceTime, shareReplay, mergeMap, startWith, distinctUntilChanged, throttleTime } from 'rxjs/operators';
14
14
  import { MatTableDataSource, MatTableModule } from '@angular/material/table';
15
15
  import { DataSource, SelectionModel } from '@angular/cdk/collections';
16
16
  import * as i1$2 from 'apollo-angular';
@@ -87,7 +87,7 @@ class NaturalConfirmComponent {
87
87
  NaturalConfirmComponent.decorators = [
88
88
  { type: Component, args: [{
89
89
  template: "<h2 mat-dialog-title>{{ data.title }}</h2>\n<mat-dialog-content\n ><p class=\"mat-body\">{{ data.message }}</p></mat-dialog-content\n>\n<mat-dialog-actions>\n <button [mat-dialog-close]=\"false\" mat-button>{{ data.cancelText }}</button>\n <button [mat-dialog-close]=\"true\" mat-stroked-button cdkFocusInitial>{{ data.confirmText }}</button>\n</mat-dialog-actions>\n",
90
- styles: ["mat-dialog-content{max-width:40em}mat-dialog-actions{display:flex;justify-content:flex-end}mat-dialog-actions>*{margin-left:10px}"]
90
+ styles: ["mat-dialog-content{max-width:40em}mat-dialog-actions{display:flex;justify-content:flex-end}mat-dialog-actions>*{margin-left:10px}\n"]
91
91
  },] }
92
92
  ];
93
93
  NaturalConfirmComponent.ctorParameters = () => [
@@ -2073,6 +2073,20 @@ function unique(fieldName, excludedId, modelService) {
2073
2073
  return timer(500).pipe(switchMap(() => modelService.count(qvm).pipe(map(count => (count > 0 ? { duplicateValue: count } : null)))));
2074
2074
  };
2075
2075
  }
2076
+ /**
2077
+ * Returns an async validator function that checks that the form control value is available
2078
+ *
2079
+ * Similar to `unique` validator, but allows to use a custom query for when the client does
2080
+ * not have permissions for `modelService.count()`.
2081
+ */
2082
+ function available(getAvailableQuery, excludedId = null) {
2083
+ return (control) => {
2084
+ if (!control.value || !control.dirty) {
2085
+ return of(null);
2086
+ }
2087
+ return timer(500).pipe(switchMap(() => getAvailableQuery(control.value, excludedId).pipe(map(isAvailable => (isAvailable ? null : { available: true })))));
2088
+ };
2089
+ }
2076
2090
  /**
2077
2091
  * Return all errors recursively for the given Form or control
2078
2092
  */
@@ -2927,7 +2941,7 @@ function unwrapNavigable(item) {
2927
2941
  * Components inheriting from this class can be used as standalone with input attributes.
2928
2942
  *
2929
2943
  * Usage :
2930
- * <natural-my-listing [forcedVariables]="{filter:...}" [initialColumns]="['col1']" [persistSearch]="false">
2944
+ * <natural-my-listing [forcedVariables]="{filter:...}" [selectedColumns]="['col1']" [persistSearch]="false">
2931
2945
  */
2932
2946
  // @dynamic
2933
2947
  class NaturalAbstractList extends NaturalAbstractPanel {
@@ -2942,7 +2956,7 @@ class NaturalAbstractList extends NaturalAbstractPanel {
2942
2956
  /**
2943
2957
  * Columns list after interaction with <natural-columns-picker>
2944
2958
  */
2945
- this._selectedColumns = [];
2959
+ this.columnsForTable = [];
2946
2960
  /**
2947
2961
  * The default column selection that automatically happened after <natural-columns-picker> initialization
2948
2962
  */
@@ -3007,11 +3021,13 @@ class NaturalAbstractList extends NaturalAbstractPanel {
3007
3021
  /**
3008
3022
  * Persist search and then launch whatever is required to refresh the list
3009
3023
  */
3010
- search(naturalSearchSelections, navigationExtras) {
3024
+ search(naturalSearchSelections, navigationExtras, resetPagination = true) {
3011
3025
  // Reset page index to restart the pagination (preserve pageSize)
3012
- this.variablesManager.merge('pagination', {
3013
- pagination: pick(this.defaultPagination, ['offset', 'pageIndex']),
3014
- });
3026
+ if (resetPagination) {
3027
+ this.variablesManager.merge('pagination', {
3028
+ pagination: pick(this.defaultPagination, ['offset', 'pageIndex']),
3029
+ });
3030
+ }
3015
3031
  // Persist if activated
3016
3032
  // Two parallel navigations conflict. We first persist the search, then the pagination
3017
3033
  if (this.persistSearch && !this.isPanel) {
@@ -3183,7 +3199,7 @@ class NaturalAbstractList extends NaturalAbstractPanel {
3183
3199
  * Uses data provided by router such as:
3184
3200
  *
3185
3201
  * - `route.data.forcedVariables`
3186
- * - `route.data.initialColumns`
3202
+ * - `route.data.selectedColumns`
3187
3203
  */
3188
3204
  initFromRoute() {
3189
3205
  // Variables
@@ -3191,8 +3207,8 @@ class NaturalAbstractList extends NaturalAbstractPanel {
3191
3207
  this.applyForcedVariables(this.route.snapshot.data.forcedVariables);
3192
3208
  }
3193
3209
  // Columns
3194
- if (this.route.snapshot.data.initialColumns) {
3195
- this.initialColumns = this.route.snapshot.data.initialColumns;
3210
+ if (this.route.snapshot.data.selectedColumns) {
3211
+ this.selectedColumns = this.route.snapshot.data.selectedColumns;
3196
3212
  }
3197
3213
  }
3198
3214
  getDataObservable() {
@@ -3218,6 +3234,11 @@ class NaturalAbstractList extends NaturalAbstractPanel {
3218
3234
  if (sorting) {
3219
3235
  this.variablesManager.set('sorting', { sorting });
3220
3236
  }
3237
+ // Columns
3238
+ const persistedColumns = this.persistenceService.get('col', this.route, storageKey);
3239
+ if (typeof persistedColumns === 'string') {
3240
+ this.selectedColumns = persistedColumns.split(',');
3241
+ }
3221
3242
  // Natural search : ns
3222
3243
  this.naturalSearchSelections = fromUrl(this.persistenceService.get('ns', this.route, storageKey));
3223
3244
  this.translateSearchAndRefreshList(this.naturalSearchSelections, true);
@@ -3273,23 +3294,14 @@ class NaturalAbstractList extends NaturalAbstractPanel {
3273
3294
  this.variablesManager.set('sorting', { sorting: variables.sorting });
3274
3295
  }
3275
3296
  }
3276
- get selectedColumns() {
3277
- return this._selectedColumns;
3278
- }
3279
- set selectedColumns(columns) {
3280
- this._selectedColumns = columns;
3297
+ selectColumns(columns) {
3298
+ this.columnsForTable = columns;
3281
3299
  if (!this.persistSearch || this.isPanel) {
3282
3300
  return;
3283
3301
  }
3284
3302
  // The first selection we receive is the default one made by <natural-columns-picker>
3285
3303
  if (!this.defaultSelectedColumns) {
3286
3304
  this.defaultSelectedColumns = columns;
3287
- // Now that we know the defaults, we can try to reload from persistence
3288
- const storageKey = this.getStorageKey();
3289
- const persistedColumns = this.persistenceService.get('col', this.route, storageKey);
3290
- if (typeof persistedColumns === 'string') {
3291
- this.selectedColumns = persistedColumns.split(',');
3292
- }
3293
3305
  }
3294
3306
  else {
3295
3307
  // Persist only if wanted columns are different from default selection
@@ -3307,7 +3319,7 @@ NaturalAbstractList.ctorParameters = () => [
3307
3319
  ];
3308
3320
  NaturalAbstractList.propDecorators = {
3309
3321
  persistSearch: [{ type: Input }],
3310
- initialColumns: [{ type: Input }],
3322
+ selectedColumns: [{ type: Input }],
3311
3323
  forcedVariables: [{ type: Input }]
3312
3324
  };
3313
3325
 
@@ -3325,6 +3337,7 @@ class NaturalAbstractNavigableList extends NaturalAbstractList {
3325
3337
  * Name of filter for child items to access ancestor item
3326
3338
  */
3327
3339
  this.ancestorRelationName = 'parent';
3340
+ this.oldAncertorId = null;
3328
3341
  this.breadcrumbs = [];
3329
3342
  }
3330
3343
  ngOnInit() {
@@ -3333,27 +3346,30 @@ class NaturalAbstractNavigableList extends NaturalAbstractList {
3333
3346
  // "na" is a trailing param, and should be considered only when there is no search
3334
3347
  this.route.params.subscribe(params => {
3335
3348
  // "ns" stands for natural-search to be shorter in url
3336
- if (!params['ns']) {
3337
- let navigationConditionValue = null;
3338
- // "na" stands for "navigation" (relation) in url
3339
- if (params['na']) {
3340
- navigationConditionValue = { have: { values: [params['na']] } };
3341
- this.service.getOne(params['na']).subscribe(
3342
- // TODO casting should disappear and instead this class should enforce
3343
- // the service to support Tone with a new generic
3344
- (ancestor) => (this.breadcrumbs = this.getBreadcrumb(ancestor)));
3345
- this.clearSearch();
3346
- }
3347
- else {
3348
- navigationConditionValue = { empty: {} };
3349
- this.breadcrumbs = [];
3350
- }
3351
- const condition = {};
3352
- condition[this.ancestorRelationName] = navigationConditionValue;
3353
- const variables = { filter: { groups: [{ conditions: [condition] }] } };
3354
- // todo : check why without "as Vall" it errors. Vall is supposed to be QueryVariables, and filter too.
3355
- this.variablesManager.set('navigation', variables);
3349
+ if (params['ns']) {
3350
+ return;
3351
+ }
3352
+ let navigationConditionValue = null;
3353
+ // "na" stands for "navigation" (relation) in url
3354
+ if (params['na']) {
3355
+ navigationConditionValue = { have: { values: [params['na']] } };
3356
+ this.service.getOne(params['na']).subscribe(
3357
+ // TODO casting should disappear and instead this class should enforce
3358
+ // the service to support Tone with a new generic
3359
+ (ancestor) => (this.breadcrumbs = this.getBreadcrumb(ancestor)));
3360
+ const hasAncestorChanged = params['na'] !== this.oldAncertorId;
3361
+ this.oldAncertorId = params['na'];
3362
+ this.clearSearch(hasAncestorChanged);
3363
+ }
3364
+ else {
3365
+ navigationConditionValue = { empty: {} };
3366
+ this.breadcrumbs = [];
3356
3367
  }
3368
+ const condition = {};
3369
+ condition[this.ancestorRelationName] = navigationConditionValue;
3370
+ const variables = { filter: { groups: [{ conditions: [condition] }] } };
3371
+ // todo : check why without "as Vall" it errors. Vall is supposed to be QueryVariables, and filter too.
3372
+ this.variablesManager.set('navigation', variables);
3357
3373
  });
3358
3374
  super.ngOnInit();
3359
3375
  }
@@ -3385,11 +3401,16 @@ class NaturalAbstractNavigableList extends NaturalAbstractList {
3385
3401
  }
3386
3402
  super.translateSearchAndRefreshList(naturalSearchSelections);
3387
3403
  }
3388
- clearSearch() {
3404
+ clearSearch(resetPagination = true) {
3389
3405
  this.naturalSearchSelections = [[]];
3390
- this.search([[]]);
3406
+ super.search([[]], undefined, resetPagination);
3391
3407
  this.persistenceService.persistInStorage('ns', null, this.getStorageKey());
3392
3408
  }
3409
+ search(naturalSearchSelections, navigationExtras, resetPagination = true) {
3410
+ this.persistenceService.persistInUrl('na', null, this.route).then(() => {
3411
+ super.search(naturalSearchSelections, navigationExtras, resetPagination);
3412
+ });
3413
+ }
3393
3414
  /**
3394
3415
  * Return an array for router link usage
3395
3416
  */
@@ -3487,6 +3508,17 @@ function cancellableTimeout(canceller, milliSeconds = 0) {
3487
3508
  return;
3488
3509
  }));
3489
3510
  }
3511
+ /**
3512
+ * For debugging purpose only, will dump in console everything that happen to
3513
+ * the observable
3514
+ */
3515
+ function debug(debugName) {
3516
+ return tap({
3517
+ next: value => console.log('NEXT', debugName, value),
3518
+ error: error => console.log('ERROR', debugName, error),
3519
+ complete: () => console.log('COMPLETE', debugName),
3520
+ });
3521
+ }
3490
3522
 
3491
3523
  class NaturalAbstractModelService {
3492
3524
  constructor(apollo, name, oneQuery, allQuery, createMutation, updateMutation, deleteMutation) {
@@ -4306,19 +4338,37 @@ class NaturalColumnsPickerComponent {
4306
4338
  constructor(changeDetectorRef) {
4307
4339
  this.changeDetectorRef = changeDetectorRef;
4308
4340
  /**
4309
- * Emit a list of column keys whenever the selection changes
4341
+ * Emit a list of valid and selected column keys whenever the selection changes
4310
4342
  */
4311
4343
  this.selectionChange = new EventEmitter();
4312
- this.defaultSelectionChange = new EventEmitter();
4344
+ /**
4345
+ * Available columns are defined by options in the template
4346
+ */
4313
4347
  this.availableColumns = null;
4348
+ /**
4349
+ * Displayed options in the dropdown menu
4350
+ */
4314
4351
  this.displayedColumns = [];
4315
4352
  this.ngUnsubscribe = new Subject();
4316
4353
  }
4317
- set selection(columns) {
4354
+ /**
4355
+ * Set the columns that are wanted but might be unavailable.
4356
+ *
4357
+ * If a column is unavailable it will be ignored silently. To know what columns were actually applied
4358
+ * you should use `selectionChange`.
4359
+ *
4360
+ * It is often set once on component initialization, but it can also be set again later in the lifespan of the component.
4361
+ */
4362
+ set selections(columns) {
4318
4363
  var _a;
4364
+ this._selections = columns;
4365
+ if (!columns || !this.availableColumns) {
4366
+ return;
4367
+ }
4319
4368
  (_a = this.availableColumns) === null || _a === void 0 ? void 0 : _a.forEach(col => {
4320
4369
  col.checked = columns.includes(col.key);
4321
4370
  });
4371
+ this.updateColumns();
4322
4372
  }
4323
4373
  ngAfterViewInit() {
4324
4374
  cancellableTimeout(this.ngUnsubscribe).subscribe(() => {
@@ -4330,8 +4380,10 @@ class NaturalColumnsPickerComponent {
4330
4380
  initColumns() {
4331
4381
  var _a, _b, _c;
4332
4382
  (_a = this.availableColumns) === null || _a === void 0 ? void 0 : _a.forEach(col => {
4333
- col.checked = this.initialSelection ? this.initialSelection.includes(col.key) : col.checked;
4383
+ var _a;
4384
+ col.checked = ((_a = this._selections) === null || _a === void 0 ? void 0 : _a.length) ? this._selections.includes(col.key) : col.checked;
4334
4385
  });
4386
+ // Show options only for columns that are not hidden
4335
4387
  this.displayedColumns = (_c = (_b = this.availableColumns) === null || _b === void 0 ? void 0 : _b.filter(col => !col.hidden)) !== null && _c !== void 0 ? _c : [];
4336
4388
  }
4337
4389
  updateColumns() {
@@ -4355,10 +4407,8 @@ NaturalColumnsPickerComponent.ctorParameters = () => [
4355
4407
  { type: ChangeDetectorRef }
4356
4408
  ];
4357
4409
  NaturalColumnsPickerComponent.propDecorators = {
4358
- selection: [{ type: Input }],
4410
+ selections: [{ type: Input }],
4359
4411
  selectionChange: [{ type: Output }],
4360
- defaultSelectionChange: [{ type: Output }],
4361
- initialSelection: [{ type: Input }],
4362
4412
  availableColumns: [{ type: ContentChildren, args: [NaturalColumnsPickerColumnDirective,] }]
4363
4413
  };
4364
4414
 
@@ -4415,7 +4465,7 @@ NaturalIconComponent.decorators = [
4415
4465
  { type: Component, args: [{
4416
4466
  selector: 'natural-icon',
4417
4467
  template: "<mat-icon *ngIf=\"icon?.font\" [class]=\"icon?.class\" data-nosnippet>{{ icon?.font }}</mat-icon>\n<mat-icon *ngIf=\"icon?.svg\" [class]=\"icon?.class\" [svgIcon]=\"icon.name\" class=\"svg-icon\"></mat-icon>\n\n<div *ngIf=\"label\" [ngClass]=\"labelColor + ' ' + labelPosition\" class=\"label\">{{ label }}</div>\n",
4418
- styles: [":host{position:relative}:host mat-icon{background-repeat:inherit;display:inherit;fill:inherit;height:inherit;width:inherit;font-family:inherit;font-weight:inherit;font-style:inherit;font-size:inherit;line-height:inherit;text-transform:inherit;letter-spacing:inherit;word-wrap:inherit;white-space:inherit;direction:inherit;-webkit-font-smoothing:inherit;text-rendering:inherit;-moz-osx-font-smoothing:inherit;font-feature-settings:inherit;min-height:inherit;min-width:inherit;vertical-align:unset}:host .label{position:absolute;padding:2px;border-radius:100%;font-family:Quicksand sans-serif;font-size:14px;line-height:1em;height:14px;min-width:14px;text-align:center}:host .label.top-left{top:0;left:0;transform:translateX(-50%)}:host .label.top-right{top:0;right:0;transform:translateX(50%)}:host .label.bottom-left{bottom:0;left:0;transform:translateX(-50%)}:host .label.bottom-right{bottom:0;right:0;transform:translateX(50%)}"]
4468
+ styles: [":host{position:relative}:host mat-icon{background-repeat:inherit;display:inherit;fill:inherit;height:inherit;width:inherit;font-family:inherit;font-weight:inherit;font-style:inherit;font-size:inherit;line-height:inherit;text-transform:inherit;letter-spacing:inherit;word-wrap:inherit;white-space:inherit;direction:inherit;-webkit-font-smoothing:inherit;text-rendering:inherit;-moz-osx-font-smoothing:inherit;font-feature-settings:inherit;min-height:inherit;min-width:inherit;vertical-align:unset}:host .label{position:absolute;padding:2px;border-radius:100%;font-family:Quicksand sans-serif;font-size:14px;line-height:1em;height:14px;min-width:14px;text-align:center}:host .label.top-left{top:0;left:0;transform:translate(-50%)}:host .label.top-right{top:0;right:0;transform:translate(50%)}:host .label.bottom-left{bottom:0;left:0;transform:translate(-50%)}:host .label.bottom-right{bottom:0;right:0;transform:translate(50%)}\n"]
4419
4469
  },] }
4420
4470
  ];
4421
4471
  NaturalIconComponent.ctorParameters = () => [
@@ -4929,7 +4979,7 @@ NaturalDetailHeaderComponent.decorators = [
4929
4979
  { type: Component, args: [{
4930
4980
  selector: 'natural-detail-header',
4931
4981
  template: "<div class=\"breadcrumb\">\n <a [routerLink]=\"isPanel ? [] : getRootLink()\" [fragment]=\"listFragment\" color=\"primary\" mat-button>{{\n rootLabel || label\n }}</a>\n <ng-container *ngFor=\"let parent of breadcrumbs\">\n /\n <a [routerLink]=\"isPanel ? [] : getLink(parent.id)\" color=\"primary\" mat-button>\n {{ parent?.fullName || parent?.name }}</a\n >\n </ng-container>\n</div>\n\n<div class=\"body\">\n <div *ngIf=\"icon\" style=\"width: 30px\">\n <natural-icon [name]=\"icon\"></natural-icon>\n </div>\n <div *ngIf=\"!model.id\" class=\"mat-headline no-margin newLabel\">{{ newLabel }}</div>\n <div *ngIf=\"model.id\" class=\"mat-headline no-margin label\">{{ model?.name || model?.fullName || label }}</div>\n <div>\n <ng-content></ng-content>\n </div>\n</div>\n",
4932
- styles: [":host{display:flex;flex-direction:column}:host .body,:host .breadcrumb{display:flex;flex-direction:row;align-items:center}:host .breadcrumb{position:relative;top:5px}:host .body{min-height:40px}:host .body>:not(:last-child){margin-right:5px}:host .body .label,:host .body .newLabel{flex:1}@media screen and (max-width:600px){:host .body{flex-direction:column;align-items:flex-start}:host .body>:not(:last-child){margin-bottom:10px!important}:host .body natural-icon{display:none}}"]
4982
+ styles: [":host{display:flex;flex-direction:column}:host .breadcrumb,:host .body{display:flex;flex-direction:row;align-items:center}:host .breadcrumb{position:relative;top:5px}:host .body{min-height:40px}:host .body>*:not(:last-child){margin-right:5px}:host .body .label,:host .body .newLabel{flex:1}@media screen and (max-width: 600px){:host .body{flex-direction:column;align-items:flex-start}:host .body>*:not(:last-child){margin-bottom:10px!important}:host .body natural-icon{display:none}}\n"]
4933
4983
  },] }
4934
4984
  ];
4935
4985
  NaturalDetailHeaderComponent.propDecorators = {
@@ -5072,7 +5122,7 @@ NaturalDropdownContainerComponent.decorators = [
5072
5122
  encapsulation: ViewEncapsulation.None,
5073
5123
  preserveWhitespaces: false,
5074
5124
  animations: [naturalDropdownAnimations.transformMenu, naturalDropdownAnimations.fadeInItems],
5075
- styles: [".natural-dropdown-container{display:flex;flex-direction:column;border-radius:2px;height:100%}.natural-dropdown-container-content{flex:1;padding:5px;overflow:auto}.natural-dropdown-container .natural-dropdown-validate-button{flex:none;display:flex;flex-direction:row;justify-content:flex-end;margin:5px}"]
5125
+ styles: [".natural-dropdown-container{display:flex;flex-direction:column;border-radius:2px;height:100%}.natural-dropdown-container-content{flex:1;padding:5px;overflow:auto}.natural-dropdown-container .natural-dropdown-validate-button{flex:none;display:flex;flex-direction:row;justify-content:flex-end;margin:5px}\n"]
5076
5126
  },] }
5077
5127
  ];
5078
5128
  NaturalDropdownContainerComponent.ctorParameters = () => [
@@ -5543,7 +5593,7 @@ class TypeTextComponent {
5543
5593
  TypeTextComponent.decorators = [
5544
5594
  { type: Component, args: [{
5545
5595
  template: "<mat-form-field>\n <mat-label i18n>Valeur</mat-label>\n <input\n (keydown.enter)=\"close()\"\n [errorStateMatcher]=\"matcher\"\n [formControl]=\"formCtrl\"\n [required]=\"true\"\n matInput\n type=\"text\"\n />\n <mat-error *ngIf=\"formCtrl.hasError('required')\">*</mat-error>\n</mat-form-field>\n",
5546
- styles: [":host input::-webkit-inner-spin-button,:host input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}"]
5596
+ styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"]
5547
5597
  },] }
5548
5598
  ];
5549
5599
  TypeTextComponent.ctorParameters = () => [
@@ -5634,7 +5684,7 @@ class TypeNumberComponent {
5634
5684
  TypeNumberComponent.decorators = [
5635
5685
  { type: Component, args: [{
5636
5686
  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 [formControl]=\"operatorCtrl\" [required]=\"true\">\n <mat-option *ngFor=\"let item of operators\" [value]=\"item.key\">\n {{ item.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label i18n>Valeur</mat-label>\n <input\n (keydown.enter)=\"close()\"\n [errorStateMatcher]=\"matcher\"\n [formControl]=\"valueCtrl\"\n [attr.max]=\"configuration.max\"\n [attr.min]=\"configuration.min\"\n [required]=\"true\"\n [step]=\"configuration.step\"\n matInput\n type=\"number\"\n />\n <mat-error *ngIf=\"valueCtrl.hasError('min')\">< {{ configuration.min }}</mat-error>\n <mat-error *ngIf=\"valueCtrl.hasError('max')\">> {{ configuration.max }}</mat-error>\n </mat-form-field>\n</form>\n",
5637
- styles: [":host input::-webkit-inner-spin-button,:host input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}"]
5687
+ styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"]
5638
5688
  },] }
5639
5689
  ];
5640
5690
  TypeNumberComponent.ctorParameters = () => [
@@ -6008,7 +6058,7 @@ class FacetSelectorComponent {
6008
6058
  FacetSelectorComponent.decorators = [
6009
6059
  { type: Component, args: [{
6010
6060
  template: "<mat-nav-list>\n <mat-list-item (click)=\"selection = facet; close()\" *ngFor=\"let facet of facets\">\n <a matLine>{{ facet.display }}</a>\n </mat-list-item>\n</mat-nav-list>\n",
6011
- styles: [":host .mat-nav-list{padding:0}"]
6061
+ styles: [":host .mat-nav-list{padding:0}\n"]
6012
6062
  },] }
6013
6063
  ];
6014
6064
  FacetSelectorComponent.ctorParameters = () => [
@@ -6042,7 +6092,7 @@ NaturalGroupComponent.decorators = [
6042
6092
  { type: Component, args: [{
6043
6093
  selector: 'natural-group',
6044
6094
  template: "<natural-input\n (cleared)=\"removeInput(i)\"\n (selectionChange)=\"updateInput($event, i)\"\n *ngFor=\"let selection of innerSelections; let i = index\"\n [facets]=\"facets\"\n [selection]=\"selection\"\n></natural-input>\n\n<natural-input\n #newValueInput\n (selectionChange)=\"addInput($event)\"\n [facets]=\"facets\"\n [placeholder]=\"placeholder\"\n tabIndex=\"10\"\n cdkFocusInitial\n></natural-input>\n",
6045
- styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap}:host natural-input{flex:none;display:inline-flex;margin-right:10px}:host natural-input:last-of-type{flex:1;margin-right:0;min-width:250px}"]
6095
+ styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap}:host natural-input{flex:none;display:inline-flex;margin-right:10px}:host natural-input:last-of-type{flex:1;margin-right:0;min-width:250px}\n"]
6046
6096
  },] }
6047
6097
  ];
6048
6098
  NaturalGroupComponent.propDecorators = {
@@ -6276,7 +6326,7 @@ class NaturalInputComponent {
6276
6326
  };
6277
6327
  const injectorTokens = this.createProviders(data);
6278
6328
  this.dropdownRef = this.dropdownService.open(FacetSelectorComponent, this.element, injectorTokens, false);
6279
- this.dropdownRef.closed.subscribe((result) => {
6329
+ this.dropdownRef.closed.subscribe(result => {
6280
6330
  this.dropdownRef = null;
6281
6331
  if (result !== undefined) {
6282
6332
  if (result.facet) {
@@ -6300,7 +6350,7 @@ class NaturalInputComponent {
6300
6350
  const injectorTokens = this.createProviders(data);
6301
6351
  const component = dropdownFacet.component;
6302
6352
  this.dropdownRef = this.dropdownService.open(component, this.element, injectorTokens, dropdownFacet.showValidateButton || false);
6303
- this.dropdownRef.closed.subscribe((result) => {
6353
+ this.dropdownRef.closed.subscribe(result => {
6304
6354
  this.dropdownRef = null;
6305
6355
  if (result !== undefined) {
6306
6356
  this.setValue(result);
@@ -6341,7 +6391,7 @@ NaturalInputComponent.decorators = [
6341
6391
  { type: Component, args: [{
6342
6392
  selector: 'natural-input',
6343
6393
  template: "<!-- click condition should match to allow click action only when no other button is visible -->\n<mat-form-field #field matRipple (click)=\"!selection && !(facet && !selection) ? openDropdown() : null\">\n <mat-label *ngIf=\"facet\">{{ facet.display }}</mat-label>\n <mat-label *ngIf=\"!facet\">{{ placeholder }}</mat-label>\n\n <input\n #input\n (blur)=\"search($event)\"\n (keydown.enter)=\"search($event)\"\n [attr.size]=\"length\"\n [errorStateMatcher]=\"errorMatcher\"\n [formControl]=\"formCtrl\"\n [readonly]=\"(isDropdown() && !!selection) || isFlag()\"\n autocomplete=\"off\"\n matInput\n type=\"text\"\n />\n\n <!-- TODO : replace this void button -->\n <div *ngIf=\"!facet && !selection\" class=\"search-icon\" matPrefix>\n <natural-icon name=\"search\"></natural-icon>\n </div>\n\n <button (click)=\"clear()\" *ngIf=\"selection\" mat-icon-button matSuffix>\n <natural-icon name=\"close\"></natural-icon>\n </button>\n\n <button (click)=\"clear()\" *ngIf=\"facet && !selection\" mat-icon-button matSuffix>\n <natural-icon name=\"undo\"></natural-icon>\n </button>\n</mat-form-field>\n<div class=\"hide\">{{ formCtrl.value ? formCtrl.value : facet ? facet.display : placeholder }}</div>\n",
6344
- styles: [":host{position:relative;overflow:hidden;border-top-left-radius:4px;border-top-right-radius:4px;display:flex;flex-direction:column}:host .mat-menu-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}:host .hide{color:#0000;height:0;margin:0 50px 0 10px;font-size:inherit;white-space:nowrap;font-family:Roboto,Helvetica Neue,sans-serif}:host .search-icon{display:block;width:35px;height:35px}:host .search-icon natural-icon{margin:5px auto 0}"]
6394
+ styles: [":host{position:relative;overflow:hidden;border-top-left-radius:4px;border-top-right-radius:4px;display:flex;flex-direction:column}:host .mat-menu-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}:host .hide{color:transparent;height:0;margin:0 50px 0 10px;font-size:inherit;white-space:nowrap;font-family:Roboto,\"Helvetica Neue\",sans-serif}:host .search-icon{display:block;width:35px;height:35px}:host .search-icon natural-icon{margin:5px auto 0}\n"]
6345
6395
  },] }
6346
6396
  ];
6347
6397
  NaturalInputComponent.ctorParameters = () => [
@@ -6420,7 +6470,7 @@ NaturalSearchComponent.decorators = [
6420
6470
  { type: Component, args: [{
6421
6471
  selector: 'natural-search',
6422
6472
  template: "<div class=\"natural-search\">\n <div class=\"groupsWrapper\">\n <div *ngFor=\"let groupSelections of innerSelections; let i = index; let last = last\" class=\"groupWrapper\">\n <natural-group\n (selectionChange)=\"updateGroup($event, i)\"\n [facets]=\"facets\"\n [placeholder]=\"placeholder\"\n [selections]=\"groupSelections\"\n ></natural-group>\n\n <div class=\"endOfRowButton\">\n <button (click)=\"removeGroup(i)\" *ngIf=\"innerSelections.length > 1\" mat-icon-button>\n <natural-icon name=\"remove\"></natural-icon>\n </button>\n </div>\n\n <div class=\"endOfRowButton\">\n <button (click)=\"addGroup()\" *ngIf=\"last && multipleGroups\" mat-icon-button>\n <natural-icon name=\"add\"></natural-icon>\n </button>\n </div>\n\n <!-- Spaceholder to keep fields alignment (prevent to push until end of line)--->\n <div *ngIf=\"!last\" class=\"spacer\"></div>\n </div>\n </div>\n\n <div class=\"endOfRowButton\">\n <button (click)=\"clear()\" mat-icon-button>\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <ng-content></ng-content>\n </div>\n</div>\n",
6423
- styles: [":host .natural-search{display:flex;flex-direction:row;align-items:flex-end}:host .natural-search .groupsWrapper{display:flex;flex-direction:column;flex:1}:host .natural-search .groupWrapper{display:flex;flex-direction:row;margin-bottom:10px}:host .natural-search .groupWrapper natural-group{flex:1}:host .natural-search .groupWrapper:last-of-type{margin-bottom:0}:host .natural-search .groupWrapper .spacer{width:40px;height:40px}:host .natural-search .endOfRowButton{height:53px;display:flex;flex-direction:row;align-items:center}"]
6473
+ styles: [":host .natural-search{display:flex;flex-direction:row;align-items:flex-end}:host .natural-search .groupsWrapper{display:flex;flex-direction:column;flex:1}:host .natural-search .groupWrapper{display:flex;flex-direction:row;margin-bottom:10px}:host .natural-search .groupWrapper natural-group{flex:1}:host .natural-search .groupWrapper:last-of-type{margin-bottom:0}:host .natural-search .groupWrapper .spacer{width:40px;height:40px}:host .natural-search .endOfRowButton{height:53px;display:flex;flex-direction:row;align-items:center}\n"]
6424
6474
  },] }
6425
6475
  ];
6426
6476
  NaturalSearchComponent.propDecorators = {
@@ -6482,7 +6532,7 @@ class NaturalHierarchicSelectorDialogComponent {
6482
6532
  NaturalHierarchicSelectorDialogComponent.decorators = [
6483
6533
  { type: Component, args: [{
6484
6534
  template: "<h2 i18n mat-dialog-title>S\u00E9lection</h2>\n\n<mat-dialog-content>\n <natural-hierarchic-selector\n (selectionChange)=\"config.hierarchicSelection = $event\"\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 (searchSelectionChange)=\"searchSelectionsOutput = $event\"\n ></natural-hierarchic-selector>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button [mat-dialog-close] i18n mat-button>Annuler</button>\n <button (click)=\"close(config.hierarchicSelection)\" color=\"primary\" mat-raised-button\n ><span i18n>Valider</span>\n </button>\n</mat-dialog-actions>\n",
6485
- styles: [":host mat-dialog-actions{display:flex;flex-direction:row;justify-content:flex-end}"]
6535
+ styles: [":host mat-dialog-actions{display:flex;flex-direction:row;justify-content:flex-end}\n"]
6486
6536
  },] }
6487
6537
  ];
6488
6538
  NaturalHierarchicSelectorDialogComponent.ctorParameters = () => [
@@ -7087,7 +7137,7 @@ NaturalHierarchicSelectorComponent.decorators = [
7087
7137
  selector: 'natural-hierarchic-selector',
7088
7138
  template: "<div [style.margin-bottom.px]=\"20\">\n <natural-search\n (selectionChange)=\"search($event)\"\n [facets]=\"searchFacets\"\n [selections]=\"searchSelections\"\n ></natural-search>\n</div>\n\n<div class=\"body\">\n <mat-progress-spinner\n *ngIf=\"loading\"\n [diameter]=\"36\"\n mode=\"indeterminate\"\n style=\"margin: 10px\"\n ></mat-progress-spinner>\n\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\">\n <mat-tree-node *matTreeNodeDef=\"let node\" [ngClass]=\"{leaf: !node.expandable}\" matTreeNodePadding>\n <button\n (click)=\"loadChildren(node)\"\n *ngIf=\"node.expandable\"\n [attr.aria-label]=\"'toggle ' + node.name\"\n mat-icon-button\n matTreeNodeToggle\n >\n <mat-progress-spinner\n *ngIf=\"node.loading\"\n [diameter]=\"24\"\n [strokeWidth]=\"5\"\n mode=\"indeterminate\"\n style=\"margin: 8px\"\n ></mat-progress-spinner>\n\n <natural-icon\n *ngIf=\"!node.loading\"\n [name]=\"treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'\"\n >\n </natural-icon>\n </button>\n\n <mat-checkbox\n (change)=\"toggleFlatNode(node)\"\n [checked]=\"flatNodesSelection.isSelected(node)\"\n [disabled]=\"!isNodeTogglable(node)\"\n style=\"margin-right: 10px\"\n >\n <natural-icon\n *ngIf=\"node.node.config.icon\"\n [name]=\"node.node.config.icon\"\n style=\"margin-right: 10px\"\n ></natural-icon>\n <span>{{ node.name }}</span>\n </mat-checkbox>\n </mat-tree-node>\n </mat-tree>\n\n <mat-chip-list aria-orientation=\"vertical\" class=\"mat-chip-list-stacked\">\n <mat-chip\n (removed)=\"unselectModelNode(node)\"\n *ngFor=\"let node of selectedNodes\"\n [removable]=\"true\"\n [selectable]=\"false\"\n >\n <natural-icon *ngIf=\"node.config.icon\" [name]=\"node.config.icon\"></natural-icon>\n <div class=\"mat-body chip-label\">{{ node.model.name || node.model.fullName }}</div>\n <natural-icon matChipRemove name=\"cancel\"></natural-icon>\n </mat-chip>\n </mat-chip-list>\n</div>\n\n<div *ngIf=\"!loading && !dataSource.data.length\" class=\"margin-v\" i18n>Aucun r\u00E9sultat</div>\n",
7089
7139
  providers: [NaturalHierarchicSelectorService],
7090
- styles: [":host{display:block}:host li,:host ul{-webkit-margin-before:0;-webkit-margin-after:0;list-style-type:none}:host natural-icon{width:18px;height:18px;font-size:18px;margin-right:5px}:host .mat-tree-node.leaf{margin-left:40px}:host .body{display:flex;flex-direction:row;justify-content:space-between}:host .body mat-tree{flex:66}:host .body mat-chip-list{flex:33}:host mat-tree{flex-shrink:0}:host mat-chip-list{margin-left:10px}:host mat-chip{display:flex;flex-direction:row;height:auto!important}:host mat-chip .chip-label{flex:1}"]
7140
+ styles: [":host{display:block}:host ul,:host li{-webkit-margin-before:0;-webkit-margin-after:0;list-style-type:none}:host natural-icon{width:18px;height:18px;font-size:18px;margin-right:5px}:host .mat-tree-node.leaf{margin-left:40px}:host .body{display:flex;flex-direction:row;justify-content:space-between}:host .body mat-tree{flex:66}:host .body mat-chip-list{flex:33}:host mat-tree{flex-shrink:0}:host mat-chip-list{margin-left:10px}:host mat-chip{display:flex;flex-direction:row;height:auto!important}:host mat-chip .chip-label{flex:1}\n"]
7091
7141
  },] }
7092
7142
  ];
7093
7143
  NaturalHierarchicSelectorComponent.ctorParameters = () => [
@@ -7430,7 +7480,7 @@ NaturalSelectHierarchicComponent.decorators = [
7430
7480
  { type: Component, args: [{
7431
7481
  selector: 'natural-select-hierarchic',
7432
7482
  template: "<mat-form-field [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <!-- Input for hierarchical selector -->\n <input\n (blur)=\"blur.emit()\"\n (focus)=\"openDialog()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [errorStateMatcher]=\"matcher\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\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<div *ngIf=\"showSelectButton() || showClearButton()\" class=\"external-buttons\">\n <button (click)=\"openDialog()\" *ngIf=\"showSelectButton()\" color=\"primary\" mat-flat-button>{{ selectLabel }}</button>\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n",
7433
- styles: [":host{display:flex;flex-direction:column}:host>:not(:last-child){margin-bottom:20px}:host .external-buttons,:host .suffix-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>:not(:last-child){margin-right:10px}"]
7483
+ styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"]
7434
7484
  },] }
7435
7485
  ];
7436
7486
  NaturalSelectHierarchicComponent.ctorParameters = () => [
@@ -7614,7 +7664,7 @@ NaturalSelectComponent.decorators = [
7614
7664
  { type: Component, args: [{
7615
7665
  selector: 'natural-select',
7616
7666
  template: "<!-- Autocomplete menu -->\n<mat-autocomplete\n #ac=\"matAutocomplete\"\n (optionSelected)=\"propagateValue($event?.option?.value)\"\n [displayWith]=\"getDisplayFn()\"\n panelWidth=\"auto !important\"\n>\n <mat-option *ngFor=\"let item of items | async\" [value]=\"item\">\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"itemTemplate ? itemTemplate : defaultACItem\"\n ></ng-template>\n </mat-option>\n <div *ngIf=\"moreNbItems > 0\" class=\"mat-caption\" i18n style=\"padding: 5px 10px\"\n >{{ moreNbItems }} \u00E9l\u00E9ment(s) suppl\u00E9mentaire(s)</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 [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <input\n (blur)=\"touch(); blur.emit()\"\n (change)=\"onInternalFormChange()\"\n (click)=\"autoTrigger.openPanel()\"\n (focus)=\"startSearch()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [matAutocomplete]=\"ac\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n [errorStateMatcher]=\"matcher\"\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"!loading && showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n <mat-progress-spinner\n *ngIf=\"loading\"\n [diameter]=\"21\"\n [strokeWidth]=\"5\"\n matPrefix\n mode=\"indeterminate\"\n ></mat-progress-spinner>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\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<div *ngIf=\"showClearButton()\" class=\"external-buttons\">\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n",
7617
- styles: [":host{display:flex;flex-direction:column}:host>:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .external-buttons,:host .suffix-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>:not(:last-child){margin-right:10px}"]
7667
+ styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"]
7618
7668
  },] }
7619
7669
  ];
7620
7670
  NaturalSelectComponent.propDecorators = {
@@ -8150,9 +8200,7 @@ class NaturalFileDropDirective extends NaturalAbstractFile {
8150
8200
  this.closeDrags();
8151
8201
  }
8152
8202
  hasObservers() {
8153
- return (this.fileChange.observers.length > 0 ||
8154
- this.filesChange.observers.length > 0 ||
8155
- this.naturalFileService.filesChanged.observers.length > 0);
8203
+ return this.fileChange.observed || this.filesChange.observed || this.naturalFileService.filesChanged.observed;
8156
8204
  }
8157
8205
  }
8158
8206
  NaturalFileDropDirective.decorators = [
@@ -8300,7 +8348,7 @@ FileComponent.decorators = [
8300
8348
  { type: Component, args: [{
8301
8349
  selector: 'natural-file',
8302
8350
  template: "<a\n (fileChange)=\"upload($event)\"\n naturalFileDrop\n [selectable]=\"true\"\n [accept]=\"accept\"\n [attr.href]=\"getDownloadLink()\"\n [class.has-action]=\"!!action\"\n [class.suggest-upload]=\"!model && action === 'upload'\"\n [fileSelectionDisabled]=\"action !== 'upload'\"\n [matRippleDisabled]=\"!action\"\n [style.backgroundImage]=\"imagePreview\"\n [style.backgroundSize]=\"backgroundSize\"\n matRipple\n target=\"_blank\"\n>\n <div *ngIf=\"filePreview\" class=\"file-preview\">\n <natural-icon [size]=\"height * 0.33\" name=\"attachment\"></natural-icon>\n {{ filePreview | uppercase }}\n </div>\n\n <div class=\"action-overlay\">\n <natural-icon *ngIf=\"action === 'upload'\" [size]=\"height * 0.66\" name=\"cloud_upload\"></natural-icon>\n <natural-icon *ngIf=\"action === 'download'\" [size]=\"height * 0.66\" name=\"get_app\"></natural-icon>\n {{ action | capitalize }}\n </div>\n</a>\n",
8303
- styles: [":host{display:flex;flex-direction:row;overflow:hidden;position:relative}:host>a{position:relative;flex:1;background-position:50%;background-repeat:no-repeat}:host>a.has-action{cursor:pointer}:host>a.has-action.suggest-upload .action-overlay{opacity:.66}:host>a.has-action.natural-file-over .action-overlay,:host>a.has-action:hover .action-overlay{opacity:1}:host .action-overlay,:host .file-preview{display:flex;flex-direction:column;position:absolute;top:0;left:0;right:0;bottom:0;justify-content:center;align-items:center;font-size:36px;line-height:1.3em;text-align:center}:host .action-overlay{opacity:0}:host .action-overlay>div{opacity:0;position:absolute;top:0;left:0;right:0;bottom:0;display:flex;justify-content:center;align-items:center}"]
8351
+ styles: [":host{display:flex;flex-direction:row;overflow:hidden;position:relative}:host>a{position:relative;flex:1;background-position:center;background-repeat:no-repeat}:host>a.has-action{cursor:pointer}:host>a.has-action.suggest-upload .action-overlay{opacity:.66}:host>a.has-action:hover .action-overlay,:host>a.has-action.natural-file-over .action-overlay{opacity:1}:host .action-overlay,:host .file-preview{display:flex;flex-direction:column;position:absolute;top:0;left:0;right:0;bottom:0;justify-content:center;align-items:center;font-size:36px;line-height:1.3em;text-align:center}:host .action-overlay{opacity:0}:host .action-overlay>div{opacity:0;position:absolute;top:0;left:0;right:0;bottom:0;display:flex;justify-content:center;align-items:center}\n"]
8304
8352
  },] }
8305
8353
  ];
8306
8354
  FileComponent.ctorParameters = () => [
@@ -8345,7 +8393,7 @@ NaturalFixedButtonComponent.decorators = [
8345
8393
  { type: Component, args: [{
8346
8394
  selector: 'natural-fixed-button',
8347
8395
  template: "<button\n [color]=\"color\"\n [disabled]=\"disabled\"\n [routerLink]=\"link\"\n class=\"floating-button bottom-right\"\n mat-fab\n mat-raised-button\n>\n <natural-icon [name]=\"icon\"></natural-icon>\n</button>\n",
8348
- styles: [":host{position:fixed!important;z-index:999;bottom:32px;right:32px}"]
8396
+ styles: [":host{position:fixed!important;z-index:999;bottom:32px;right:32px}\n"]
8349
8397
  },] }
8350
8398
  ];
8351
8399
  NaturalFixedButtonComponent.ctorParameters = () => [];
@@ -9026,7 +9074,7 @@ NaturalRelationsComponent.decorators = [
9026
9074
  { type: Component, args: [{
9027
9075
  selector: 'natural-relations',
9028
9076
  template: "<div class=\"body\">\n <ng-template #defaultNameCell let-item=\"item\">\n {{ getDisplayFn()(item) }}\n </ng-template>\n\n <table *ngIf=\"dataSource\" [dataSource]=\"dataSource\" class=\"natural-row-click\" mat-table>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row style=\"display: none\"></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns\" mat-row></tr>\n\n <ng-container matColumnDef=\"name\">\n <th *matHeaderCellDef i18n mat-header-cell>Titre</th>\n <td *matCellDef=\"let item\" mat-cell>\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"itemTemplate ? itemTemplate : defaultNameCell\"\n ></ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"unlink\">\n <th *matHeaderCellDef mat-header-cell></th>\n <td *matCellDef=\"let element\" mat-cell>\n <button\n (click)=\"removeRelation(element)\"\n color=\"warn\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Dissocier\"\n >\n <natural-icon name=\"link_off\"></natural-icon>\n </button>\n </td>\n </ng-container>\n </table>\n\n <mat-paginator\n (page)=\"pagination($event)\"\n *ngIf=\"dataSource?.data && (dataSource?.data?.length || 0) > (dataSource?.data?.pageSize || 0)\"\n [length]=\"dataSource?.data?.length || 0\"\n [pageIndex]=\"dataSource?.data?.pageIndex || 0\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [pageSize]=\"dataSource?.data?.pageSize || 0\"\n ></mat-paginator>\n\n <div *ngIf=\"!loading && dataSource?.data?.length === 0\" class=\"margin-v mat-body\">\n <span i18n>Aucun r\u00E9sultat</span>\n </div>\n\n <mat-progress-spinner *ngIf=\"loading\" [diameter]=\"40\" class=\"loading\" mode=\"indeterminate\"></mat-progress-spinner>\n</div>\n\n<natural-select\n #select\n (selectionChange)=\"addRelations([$any($event)])\"\n *ngIf=\"!hierarchicSelectorConfig && service && !disabled\"\n [displayWith]=\"getDisplayFn()\"\n [filter]=\"autocompleteSelectorFilter\"\n [placeholder]=\"placeholder\"\n [service]=\"service\"\n [showIcon]=\"false\"\n></natural-select>\n\n<div *ngIf=\"hierarchicSelectorConfig && !disabled\">\n <button (click)=\"openNaturalHierarchicSelector()\" color=\"primary\" mat-flat-button>{{ placeholder }}</button>\n</div>\n",
9029
- styles: [":host{display:flex;flex-direction:column}:host>:not(:last-child){margin-bottom:20px}:host .body{display:flex;flex-direction:column}:host .loading{margin:20px auto}:host .mat-column-unlink{width:2.5em}"]
9077
+ styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host .body{display:flex;flex-direction:column}:host .loading{margin:20px auto}:host .mat-column-unlink{width:2.5em}\n"]
9030
9078
  },] }
9031
9079
  ];
9032
9080
  NaturalRelationsComponent.ctorParameters = () => [
@@ -9375,7 +9423,7 @@ class NaturalSidenavContainerComponent {
9375
9423
  this.sidenavService = sidenavService;
9376
9424
  this.element = element;
9377
9425
  /**
9378
- * Unique identifier used for the local storage
9426
+ * The side that the drawer is attached to
9379
9427
  */
9380
9428
  this.position = 'start';
9381
9429
  /**
@@ -9429,7 +9477,7 @@ NaturalSidenavContainerComponent.decorators = [
9429
9477
  selector: 'natural-sidenav-container',
9430
9478
  template: "<mat-sidenav-container>\n <mat-sidenav\n (openedChange)=\"sidenavService.setOpened($event)\"\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\"></ng-content>\n </mat-sidenav>\n\n <mat-sidenav-content>\n <div>\n <ng-content select=\"natural-sidenav-content\"></ng-content>\n </div>\n </mat-sidenav-content>\n</mat-sidenav-container>\n",
9431
9479
  providers: [NaturalSidenavService],
9432
- styles: [":host{display:flex;flex-direction:column}:host mat-sidenav-container{display:flex;flex-direction:column;flex:1}:host mat-sidenav-content>div{overflow:auto}:host .menuMinimized{overflow-x:hidden}:host .buttons{display:flex;flex-direction:row;justify-content:flex-end}"]
9480
+ styles: [":host{display:flex;flex-direction:column}:host mat-sidenav-container{display:flex;flex-direction:column;flex:1}:host mat-sidenav-content>div{overflow:auto}:host .menuMinimized{overflow-x:hidden}:host .buttons{display:flex;flex-direction:row;justify-content:flex-end}\n"]
9433
9481
  },] }
9434
9482
  ];
9435
9483
  NaturalSidenavContainerComponent.ctorParameters = () => [
@@ -9453,7 +9501,7 @@ NaturalSidenavContentComponent.decorators = [
9453
9501
  { type: Component, args: [{
9454
9502
  selector: 'natural-sidenav-content',
9455
9503
  template: '<ng-content></ng-content>',
9456
- styles: [":host{flex:1;display:flex;flex-direction:column;overflow:auto}"]
9504
+ styles: [":host{flex:1;display:flex;flex-direction:column;overflow:auto}\n"]
9457
9505
  },] }
9458
9506
  ];
9459
9507
  NaturalSidenavContentComponent.ctorParameters = () => [];
@@ -9530,7 +9578,7 @@ NaturalTableButtonComponent.decorators = [
9530
9578
  selector: 'natural-table-button',
9531
9579
  template: "<!-- Because directives can't be applied conditionally (routerLink, mat-button and mat-icon-button), we have to use different elements -->\n\n<ng-container *ngIf=\"!raised\">\n <!-- App routed link with label... -->\n <a\n *ngIf=\"!href && label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [routerLink]=\"navigate\"\n [fragment]=\"fragment\"\n [preserveFragment]=\"preserveFragment\"\n mat-button\n >\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a\n *ngIf=\"!href && !label\"\n [color]=\"color\"\n [queryParamsHandling]=\"queryParamsHandling\"\n [queryParams]=\"queryParams\"\n [routerLink]=\"navigate\"\n [fragment]=\"fragment\"\n [preserveFragment]=\"preserveFragment\"\n mat-icon-button\n >\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n\n <!-- External link with label... -->\n <a *ngIf=\"href && label\" [attr.href]=\"href\" [color]=\"color\" mat-button target=\"_blank\">\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a *ngIf=\"href && !label\" [attr.href]=\"href\" [color]=\"color\" mat-icon-button target=\"_blank\">\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n</ng-container>\n\n<ng-container *ngIf=\"raised\">\n <!-- App routed link with label... -->\n <a\n *ngIf=\"!href && label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [routerLink]=\"navigate\"\n [fragment]=\"fragment\"\n [preserveFragment]=\"preserveFragment\"\n mat-raised-button\n >\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a\n *ngIf=\"!href && !label\"\n [color]=\"color\"\n [queryParamsHandling]=\"queryParamsHandling\"\n [queryParams]=\"queryParams\"\n [routerLink]=\"navigate\"\n [fragment]=\"fragment\"\n [preserveFragment]=\"preserveFragment\"\n mat-icon-button\n mat-raised-button\n >\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n\n <!-- External link with label... -->\n <a *ngIf=\"href && label\" [attr.href]=\"href\" [color]=\"color\" mat-raised-button target=\"_blank\">\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a *ngIf=\"href && !label\" [attr.href]=\"href\" [color]=\"color\" mat-icon-button mat-raised-button target=\"_blank\">\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n</ng-container>\n",
9532
9580
  encapsulation: ViewEncapsulation.None,
9533
- styles: ["natural-table-button,natural-table-button a.mat-button{flex:1;display:flex;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button a.mat-button .mat-button-wrapper,natural-table-button a.mat-button .mat-button-wrapper>*{display:flex;flex-direction:row;align-items:center}natural-table-button a.mat-button .mat-button-wrapper>:not(:last-child){margin-right:5px}"]
9581
+ styles: ["natural-table-button{flex:1;display:flex;flex-direction:row;justify-content:flex-start;align-items:center}natural-table-button a.mat-button{flex:1;display:flex;flex-direction:row;align-items:center;justify-content:flex-start}natural-table-button a.mat-button .mat-button-wrapper{display:flex;flex-direction:row;align-items:center}natural-table-button a.mat-button .mat-button-wrapper>*{display:flex;flex-direction:row;align-items:center}natural-table-button a.mat-button .mat-button-wrapper>:not(:last-child){margin-right:5px}\n"]
9534
9582
  },] }
9535
9583
  ];
9536
9584
  NaturalTableButtonComponent.ctorParameters = () => [];
@@ -10068,5 +10116,5 @@ NaturalMatomoService.ctorParameters = () => [
10068
10116
  * Generated bundle index. Do not edit.
10069
10117
  */
10070
10118
 
10071
- export { AvatarComponent, AvatarService, FileComponent, IconsConfigService, LOCAL_STORAGE, NATURAL_DROPDOWN_DATA, NATURAL_SEO_CONFIG, NaturalAbstractController, NaturalAbstractDetail, NaturalAbstractEditableList, NaturalAbstractList, NaturalAbstractModelService, NaturalAbstractNavigableList, NaturalAbstractPanel, NaturalAlertModule, NaturalAlertService, NaturalAvatarModule, NaturalCapitalizePipe, NaturalColumnsPickerColumnDirective, NaturalColumnsPickerComponent, NaturalColumnsPickerModule, NaturalCommonModule, NaturalConfirmComponent, NaturalDataSource, NaturalDetailHeaderComponent, NaturalDetailHeaderModule, NaturalDialogTriggerComponent, NaturalDialogTriggerModule, NaturalDropdownComponentsModule, NaturalDropdownRef, NaturalEllipsisPipe, NaturalEnumPipe, NaturalEnumService, NaturalFileDropDirective, NaturalFileModule, NaturalFileSelectDirective, NaturalFileService, NaturalFixedButtonComponent, NaturalFixedButtonDetailComponent, NaturalFixedButtonDetailModule, NaturalFixedButtonModule, NaturalHierarchicSelectorComponent, NaturalHierarchicSelectorDialogComponent, NaturalHierarchicSelectorDialogService, NaturalHierarchicSelectorModule, NaturalHierarchicSelectorService, NaturalHttpPrefixDirective, NaturalIconComponent, NaturalIconModule, NaturalLinkMutationService, NaturalLinkableTabDirective, NaturalMatomoModule, NaturalMatomoService, NaturalMemoryStorage, NaturalPanelsComponent, NaturalPanelsModule, NaturalPanelsService, NaturalPersistenceService, NaturalQueryVariablesManager, NaturalRelationsComponent, NaturalRelationsModule, NaturalSearchComponent, NaturalSearchModule, NaturalSelectComponent, NaturalSelectEnumComponent, NaturalSelectHierarchicComponent, NaturalSelectModule, NaturalSeoService, NaturalSidenavComponent, NaturalSidenavContainerComponent, NaturalSidenavContentComponent, NaturalSidenavModule, NaturalSidenavService, NaturalSidenavStackService, NaturalSrcDensityDirective, NaturalStampComponent, NaturalStampModule, NaturalSwissDatePipe, NaturalSwissParsingDateAdapter, NaturalTableButtonComponent, NaturalTableButtonModule, PanelsHooksConfig, ReactiveAsteriskDirective, SESSION_STORAGE, SortingOrder, TypeDateComponent, TypeDateRangeComponent, TypeHierarchicSelectorComponent, TypeNaturalSelectComponent, TypeNumberComponent, TypeSelectComponent, TypeTextComponent, cancellableTimeout, cleanSameValues, collectErrors, decimal, deliverableEmail, ensureHttpPrefix, fallbackIfNoOpenedPanels, formatIsoDate, formatIsoDateTime, fromUrl, getForegroundColor, hasFilesAndProcessDate, ifValid, integer, localStorageFactory, localStorageProvider, lowerCaseFirstLetter, makePlural, memoryLocalStorageProvider, memorySessionStorageProvider, mergeOverrideArray, money, naturalPanelsUrlMatcher, relationsToIds, replaceObjectKeepingReference, replaceOperatorByField, replaceOperatorByName, sessionStorageFactory, sessionStorageProvider, toGraphQLDoctrineFilter, toNavigationParameters, toUrl, unique, upperCaseFirstLetter, urlValidator, validTlds, validateAllFormControls, wrapLike, NaturalAbstractFile as ɵa, NaturalDropdownService as ɵb, AbstractAssociationSelectComponent as ɵc, NATURAL_DROPDOWN_CONTAINER_DATA as ɵd, NaturalDropdownContainerComponent as ɵe, naturalDropdownAnimations as ɵf, AbstractSelect as ɵg, NaturalGroupComponent as ɵh, NaturalInputComponent as ɵi, FacetSelectorComponent as ɵj };
10119
+ export { AvatarComponent, AvatarService, FileComponent, IconsConfigService, LOCAL_STORAGE, NATURAL_DROPDOWN_DATA, NATURAL_SEO_CONFIG, NaturalAbstractController, NaturalAbstractDetail, NaturalAbstractEditableList, NaturalAbstractList, NaturalAbstractModelService, NaturalAbstractNavigableList, NaturalAbstractPanel, NaturalAlertModule, NaturalAlertService, NaturalAvatarModule, NaturalCapitalizePipe, NaturalColumnsPickerColumnDirective, NaturalColumnsPickerComponent, NaturalColumnsPickerModule, NaturalCommonModule, NaturalConfirmComponent, NaturalDataSource, NaturalDetailHeaderComponent, NaturalDetailHeaderModule, NaturalDialogTriggerComponent, NaturalDialogTriggerModule, NaturalDropdownComponentsModule, NaturalDropdownRef, NaturalEllipsisPipe, NaturalEnumPipe, NaturalEnumService, NaturalFileDropDirective, NaturalFileModule, NaturalFileSelectDirective, NaturalFileService, NaturalFixedButtonComponent, NaturalFixedButtonDetailComponent, NaturalFixedButtonDetailModule, NaturalFixedButtonModule, NaturalHierarchicSelectorComponent, NaturalHierarchicSelectorDialogComponent, NaturalHierarchicSelectorDialogService, NaturalHierarchicSelectorModule, NaturalHierarchicSelectorService, NaturalHttpPrefixDirective, NaturalIconComponent, NaturalIconModule, NaturalLinkMutationService, NaturalLinkableTabDirective, NaturalMatomoModule, NaturalMatomoService, NaturalMemoryStorage, NaturalPanelsComponent, NaturalPanelsModule, NaturalPanelsService, NaturalPersistenceService, NaturalQueryVariablesManager, NaturalRelationsComponent, NaturalRelationsModule, NaturalSearchComponent, NaturalSearchModule, NaturalSelectComponent, NaturalSelectEnumComponent, NaturalSelectHierarchicComponent, NaturalSelectModule, NaturalSeoService, NaturalSidenavComponent, NaturalSidenavContainerComponent, NaturalSidenavContentComponent, NaturalSidenavModule, NaturalSidenavService, NaturalSidenavStackService, NaturalSrcDensityDirective, NaturalStampComponent, NaturalStampModule, NaturalSwissDatePipe, NaturalSwissParsingDateAdapter, NaturalTableButtonComponent, NaturalTableButtonModule, PanelsHooksConfig, ReactiveAsteriskDirective, SESSION_STORAGE, SortingOrder, TypeDateComponent, TypeDateRangeComponent, TypeHierarchicSelectorComponent, TypeNaturalSelectComponent, TypeNumberComponent, TypeSelectComponent, TypeTextComponent, available, cancellableTimeout, cleanSameValues, collectErrors, debug, decimal, deliverableEmail, ensureHttpPrefix, fallbackIfNoOpenedPanels, formatIsoDate, formatIsoDateTime, fromUrl, getForegroundColor, hasFilesAndProcessDate, ifValid, integer, localStorageFactory, localStorageProvider, lowerCaseFirstLetter, makePlural, memoryLocalStorageProvider, memorySessionStorageProvider, mergeOverrideArray, money, naturalPanelsUrlMatcher, relationsToIds, replaceObjectKeepingReference, replaceOperatorByField, replaceOperatorByName, sessionStorageFactory, sessionStorageProvider, toGraphQLDoctrineFilter, toNavigationParameters, toUrl, unique, upperCaseFirstLetter, urlValidator, validTlds, validateAllFormControls, wrapLike, NaturalAbstractFile as ɵa, NaturalDropdownService as ɵb, AbstractAssociationSelectComponent as ɵc, NATURAL_DROPDOWN_CONTAINER_DATA as ɵd, NaturalDropdownContainerComponent as ɵe, naturalDropdownAnimations as ɵf, AbstractSelect as ɵg, NaturalGroupComponent as ɵh, NaturalInputComponent as ɵi, FacetSelectorComponent as ɵj };
10072
10120
  //# sourceMappingURL=ecodev-natural.js.map