@ecodev/natural 45.4.2 → 46.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 (74) hide show
  1. package/esm2020/lib/classes/abstract-controller.mjs +2 -2
  2. package/esm2020/lib/classes/abstract-detail.mjs +10 -3
  3. package/esm2020/lib/classes/abstract-list.mjs +1 -1
  4. package/esm2020/lib/classes/abstract-navigable-list.mjs +1 -1
  5. package/esm2020/lib/classes/rxjs.mjs +1 -1
  6. package/esm2020/lib/classes/validators.mjs +2 -2
  7. package/esm2020/lib/modules/avatar/service/avatar.service.mjs +2 -2
  8. package/esm2020/lib/modules/avatar/service/md5.mjs +4 -4
  9. package/esm2020/lib/modules/columns-picker/columns-picker-column.directive.mjs +1 -1
  10. package/esm2020/lib/modules/common/pipes/swiss-date.pipe.mjs +1 -1
  11. package/esm2020/lib/modules/dropdown-components/type-date/type-date.component.mjs +67 -34
  12. package/esm2020/lib/modules/dropdown-components/type-date-range/type-date-range.component.mjs +4 -4
  13. package/esm2020/lib/modules/dropdown-components/type-hierarchic-selector/type-hierarchic-selector.component.mjs +1 -1
  14. package/esm2020/lib/modules/dropdown-components/type-text/type-text.component.mjs +2 -2
  15. package/esm2020/lib/modules/file/abstract-file.mjs +2 -2
  16. package/esm2020/lib/modules/file/component/file.component.mjs +32 -24
  17. package/esm2020/lib/modules/file/file-drop.directive.mjs +1 -1
  18. package/esm2020/lib/modules/file/file-select.directive.mjs +1 -1
  19. package/esm2020/lib/modules/fixed-button/fixed-button.component.mjs +2 -2
  20. package/esm2020/lib/modules/hierarchic-selector/classes/hierarchic-filters-configuration.mjs +1 -1
  21. package/esm2020/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.service.mjs +1 -1
  22. package/esm2020/lib/modules/logger/error-handler.mjs +1 -1
  23. package/esm2020/lib/modules/panels/fallback-if-no-opened-panels.urlmatcher.mjs +2 -2
  24. package/esm2020/lib/modules/panels/panels.service.mjs +2 -2
  25. package/esm2020/lib/modules/panels/types.mjs +1 -1
  26. package/esm2020/lib/modules/relations/relations.component.mjs +2 -2
  27. package/esm2020/lib/modules/search/classes/graphql-doctrine.mjs +11 -5
  28. package/esm2020/lib/modules/search/classes/transformers.mjs +51 -1
  29. package/esm2020/lib/modules/search/input/input.component.mjs +4 -4
  30. package/esm2020/lib/modules/search/public-api.mjs +2 -2
  31. package/esm2020/lib/modules/search/search/search.component.mjs +2 -2
  32. package/esm2020/lib/modules/search/types/facet.mjs +1 -1
  33. package/esm2020/lib/modules/search/types/values.mjs +1 -1
  34. package/esm2020/lib/modules/select/abstract-select.component.mjs +2 -2
  35. package/esm2020/lib/modules/select/select/select.component.mjs +1 -1
  36. package/esm2020/lib/modules/select/select-enum/select-enum.component.mjs +1 -2
  37. package/esm2020/lib/modules/select/select-hierarchic/select-hierarchic.component.mjs +1 -1
  38. package/esm2020/lib/modules/sidenav/sidenav/sidenav.component.mjs +2 -3
  39. package/esm2020/lib/modules/sidenav/sidenav-content/sidenav-content.component.mjs +2 -3
  40. package/esm2020/lib/modules/sidenav/sidenav.service.mjs +1 -1
  41. package/esm2020/lib/modules/table-button/table-button.component.mjs +2 -2
  42. package/esm2020/lib/services/abstract-model.service.mjs +8 -1
  43. package/esm2020/lib/services/debounce.service.mjs +1 -1
  44. package/esm2020/lib/services/persistence.service.mjs +4 -2
  45. package/esm2020/lib/services/swiss-parsing-date-adapter.service.mjs +1 -1
  46. package/fesm2015/ecodev-natural.mjs +1299 -1194
  47. package/fesm2015/ecodev-natural.mjs.map +1 -1
  48. package/fesm2020/ecodev-natural.mjs +712 -609
  49. package/fesm2020/ecodev-natural.mjs.map +1 -1
  50. package/lib/classes/abstract-controller.d.ts +0 -1
  51. package/lib/modules/avatar/service/avatar.service.d.ts +0 -1
  52. package/lib/modules/dropdown-components/type-date/type-date.component.d.ts +6 -2
  53. package/lib/modules/dropdown-components/type-date-range/type-date-range.component.d.ts +1 -1
  54. package/lib/modules/dropdown-components/type-hierarchic-selector/type-hierarchic-selector.component.d.ts +1 -2
  55. package/lib/modules/dropdown-components/type-text/type-text.component.d.ts +2 -2
  56. package/lib/modules/file/abstract-file.d.ts +1 -1
  57. package/lib/modules/file/component/file.component.d.ts +32 -9
  58. package/lib/modules/fixed-button/fixed-button.component.d.ts +0 -1
  59. package/lib/modules/hierarchic-selector/classes/hierarchic-filters-configuration.d.ts +1 -2
  60. package/lib/modules/panels/types.d.ts +1 -2
  61. package/lib/modules/relations/relations.component.d.ts +2 -2
  62. package/lib/modules/search/classes/transformers.d.ts +15 -0
  63. package/lib/modules/search/input/input.component.d.ts +6 -5
  64. package/lib/modules/search/public-api.d.ts +1 -1
  65. package/lib/modules/search/search/search.component.d.ts +2 -2
  66. package/lib/modules/search/types/facet.d.ts +1 -2
  67. package/lib/modules/search/types/values.d.ts +2 -4
  68. package/lib/modules/select/abstract-select.component.d.ts +2 -2
  69. package/lib/modules/select/select-enum/select-enum.component.d.ts +0 -1
  70. package/lib/modules/sidenav/sidenav/sidenav.component.d.ts +0 -1
  71. package/lib/modules/sidenav/sidenav-content/sidenav-content.component.d.ts +0 -1
  72. package/lib/modules/table-button/table-button.component.d.ts +2 -2
  73. package/lib/services/debounce.service.d.ts +1 -1
  74. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
1
  import '@angular/localize/init';
2
2
  import * as i0 from '@angular/core';
3
- import { Directive, Component, Inject, Injectable, HostBinding, HostListener, InjectionToken, Optional, Input, NgModule, EventEmitter, ChangeDetectionStrategy, Output, ContentChildren, Pipe, TemplateRef, ViewEncapsulation, ViewChild, Injector, Self, ContentChild, createEnvironmentInjector, createComponent, PLATFORM_ID, ErrorHandler } from '@angular/core';
4
- import { Subject, BehaviorSubject, of, timer, switchMap as switchMap$1, endWith, last, EMPTY, Observable, first as first$1, combineLatest, catchError, ReplaySubject, debounceTime as debounceTime$1, raceWith, take as take$1, mergeMap, shareReplay as shareReplay$1, forkJoin, map as map$1, merge as merge$1, tap as tap$1, asyncScheduler, takeUntil as takeUntil$1 } from 'rxjs';
3
+ import { Directive, Component, Inject, Injectable, HostBinding, HostListener, InjectionToken, TemplateRef, ViewEncapsulation, ViewChild, Injector, Optional, Input, NgModule, EventEmitter, ChangeDetectionStrategy, Output, ContentChildren, Pipe, Self, ContentChild, createEnvironmentInjector, createComponent, PLATFORM_ID, ErrorHandler } from '@angular/core';
4
+ import { Subject, BehaviorSubject, of, timer, switchMap as switchMap$1, endWith, last, EMPTY, merge as merge$1, Observable, first as first$1, combineLatest, catchError, ReplaySubject, debounceTime as debounceTime$1, raceWith, take as take$1, mergeMap, shareReplay as shareReplay$1, forkJoin, map as map$1, tap as tap$1, asyncScheduler, takeUntil as takeUntil$1 } from 'rxjs';
5
5
  import * as i3 from '@angular/forms';
6
- import { FormGroup, FormArray, Validators, UntypedFormGroup, UntypedFormArray, UntypedFormControl, FormsModule, FormControl, FormControlDirective, FormControlName, ReactiveFormsModule } from '@angular/forms';
6
+ import { FormGroup, FormArray, Validators, UntypedFormGroup, UntypedFormArray, FormControl, UntypedFormControl, FormsModule, FormControlDirective, FormControlName, ReactiveFormsModule } from '@angular/forms';
7
7
  import * as i2$1 from '@angular/router';
8
8
  import { Router, ActivatedRoute, NavigationStart, NavigationEnd, RouterModule, NavigationError, DefaultUrlSerializer } from '@angular/router';
9
9
  import { merge, isObject, isArray, pickBy, isEmpty, cloneDeep, uniq, groupBy, mergeWith, defaultsDeep, omit, kebabCase, clone, pick, isEqual, defaults, intersection, flatten, differenceWith } from 'lodash-es';
@@ -14,53 +14,53 @@ import { MatButtonModule } from '@angular/material/button';
14
14
  import * as i2 from '@angular/material/snack-bar';
15
15
  import { MatSnackBarModule } from '@angular/material/snack-bar';
16
16
  import { switchMap, first, map, filter, finalize, takeUntil, take, tap, takeWhile, debounceTime, shareReplay, startWith, distinctUntilChanged, throttleTime } from 'rxjs/operators';
17
- import * as i7$2 from '@angular/material/table';
17
+ import * as i7$3 from '@angular/material/table';
18
18
  import { MatTableDataSource, MatTableModule } from '@angular/material/table';
19
19
  import { DataSource, SelectionModel } from '@angular/cdk/collections';
20
- import * as i1$1 from 'apollo-angular';
20
+ import * as i1$4 from '@angular/material/core';
21
+ import { MAT_DATE_FORMATS, NativeDateAdapter, ErrorStateMatcher, MatRipple, MatRippleModule } from '@angular/material/core';
22
+ import * as i1$3 from '@angular/cdk/overlay';
23
+ import { OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
24
+ import * as i4$1 from '@angular/cdk/portal';
25
+ import { BasePortalOutlet, CdkPortalOutlet, ComponentPortal, PortalModule } from '@angular/cdk/portal';
26
+ import { trigger, state, style, transition, sequence, query, animate, group } from '@angular/animations';
27
+ import * as i1$1 from '@angular/cdk/a11y';
28
+ import * as i1$2 from '@angular/common';
29
+ import { CommonModule, DatePipe, DOCUMENT, isPlatformBrowser } from '@angular/common';
30
+ import * as i4$2 from '@angular/material/form-field';
31
+ import { MatFormFieldModule, MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
32
+ import * as i5 from '@angular/material/input';
33
+ import { MatInputModule } from '@angular/material/input';
34
+ import * as i6 from '@angular/material/checkbox';
35
+ import { MatCheckboxModule } from '@angular/material/checkbox';
36
+ import * as i7 from '@angular/material/datepicker';
37
+ import { MatDatepickerModule } from '@angular/material/datepicker';
38
+ import * as i4$3 from '@angular/material/select';
39
+ import { MatSelectModule } from '@angular/material/select';
40
+ import * as i1$5 from 'apollo-angular';
21
41
  import { gql } from 'apollo-angular';
22
42
  import { NetworkStatus } from '@apollo/client/core';
23
- import * as i1$7 from '@angular/material/core';
24
- import { NativeDateAdapter, ErrorStateMatcher, MatRipple, MAT_DATE_FORMATS, MatRippleModule } from '@angular/material/core';
25
- import * as i1$3 from '@angular/common';
26
- import { CommonModule, DatePipe, DOCUMENT, isPlatformBrowser } from '@angular/common';
27
43
  import * as i3$1 from '@angular/material/menu';
28
44
  import { MatMenuModule } from '@angular/material/menu';
29
- import * as i5 from '@angular/material/checkbox';
30
- import { MatCheckboxModule } from '@angular/material/checkbox';
31
- import * as i1$2 from '@angular/material/icon';
45
+ import * as i1$6 from '@angular/material/icon';
32
46
  import { MatIconModule } from '@angular/material/icon';
33
47
  import * as i2$2 from '@angular/platform-browser';
34
- import * as i7 from '@angular/material/tooltip';
48
+ import * as i7$1 from '@angular/material/tooltip';
35
49
  import { MatTooltipModule } from '@angular/material/tooltip';
36
- import * as i1$4 from '@angular/material/tabs';
37
- import * as i4$2 from '@angular/material/form-field';
38
- import { MatFormFieldModule, MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
39
- import * as i5$1 from '@angular/material/input';
40
- import { MatInputModule } from '@angular/material/input';
41
- import * as i4$4 from '@angular/material/select';
42
- import { MatSelectModule } from '@angular/material/select';
43
- import * as i4$3 from '@angular/material/list';
50
+ import * as i1$7 from '@angular/material/tabs';
51
+ import * as i4$4 from '@angular/material/list';
44
52
  import { MatSelectionList, MatListModule } from '@angular/material/list';
45
- import * as i1$6 from '@angular/cdk/overlay';
46
- import { OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
47
- import * as i4$1 from '@angular/cdk/portal';
48
- import { BasePortalOutlet, CdkPortalOutlet, ComponentPortal, PortalModule } from '@angular/cdk/portal';
49
- import { trigger, state, style, transition, sequence, query, animate, group } from '@angular/animations';
50
- import * as i1$5 from '@angular/cdk/a11y';
51
53
  import * as i2$3 from '@angular/material/autocomplete';
52
54
  import { MatAutocompleteTrigger, MatAutocompleteModule } from '@angular/material/autocomplete';
53
55
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
54
- import * as i7$1 from '@angular/material/progress-spinner';
56
+ import * as i7$2 from '@angular/material/progress-spinner';
55
57
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
56
58
  import { FlatTreeControl, CdkTreeModule } from '@angular/cdk/tree';
57
- import * as i5$2 from '@angular/material/tree';
59
+ import * as i5$1 from '@angular/material/tree';
58
60
  import { MatTreeFlattener, MatTreeFlatDataSource, MatTreeModule } from '@angular/material/tree';
59
61
  import * as i8 from '@angular/material/chips';
60
62
  import { MatChipsModule } from '@angular/material/chips';
61
63
  import * as i3$2 from '@angular/material/divider';
62
- import * as i6 from '@angular/material/datepicker';
63
- import { MatDatepickerModule } from '@angular/material/datepicker';
64
64
  import * as i3$3 from '@angular/flex-layout';
65
65
  import * as i9 from '@angular/material/paginator';
66
66
  import { MatPaginatorModule } from '@angular/material/paginator';
@@ -95,7 +95,7 @@ NaturalAbstractController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0"
95
95
  NaturalAbstractController.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.1", type: NaturalAbstractController, ngImport: i0 });
96
96
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalAbstractController, decorators: [{
97
97
  type: Directive
98
- }], ctorParameters: function () { return []; } });
98
+ }] });
99
99
 
100
100
  class NaturalConfirmComponent {
101
101
  constructor(data) {
@@ -2191,7 +2191,7 @@ function ifValid(control) {
2191
2191
  // - is too lax because it accepts pretty much anything else
2192
2192
  //
2193
2193
  // but the TLD will be validated against a whitelist so that should make the whole thing acceptable
2194
- const RFC_5322 = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[^@ ]+\.[^@]+$/u;
2194
+ const RFC_5322 = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[^@ ]+\.[^@]+$/u;
2195
2195
  /**
2196
2196
  * Validate an email address according to RFC, and also that it is publicly deliverable (not "root@localhost" or "root@127.0.0.1")
2197
2197
  *
@@ -2391,15 +2391,22 @@ class NaturalAbstractDetail extends NaturalAbstractPanel {
2391
2391
  }), finalize(() => this.form.enable()))
2392
2392
  .subscribe();
2393
2393
  }
2394
- postUpdate(model) { }
2394
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2395
+ postUpdate(model) {
2396
+ // noop
2397
+ }
2395
2398
  /**
2396
2399
  * Returns an observable that will be subscribed to immediately and the
2397
2400
  * redirect navigation will only happen after the observable completes.
2398
2401
  */
2402
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2399
2403
  postCreate(model) {
2400
2404
  return EMPTY;
2401
2405
  }
2402
- preDelete(model) { }
2406
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2407
+ preDelete(model) {
2408
+ // noop
2409
+ }
2403
2410
  initForm() {
2404
2411
  this.form = this.service.getFormGroup(this.data.model);
2405
2412
  }
@@ -2529,578 +2536,1146 @@ function deepClone(obj) {
2529
2536
  return JSON.parse(JSON.stringify(obj));
2530
2537
  }
2531
2538
 
2532
- function toGraphQLDoctrineFilter(facets, selections) {
2533
- selections = deepClone(selections);
2534
- const filter = {};
2535
- if (!selections || selections.length === 0) {
2536
- selections = [[]];
2537
- }
2538
- for (const groupSelections of selections) {
2539
- const group = {};
2540
- const neededInversedFlags = facets ? facets.filter(isInvertedFlag) : [];
2541
- for (const selection of groupSelections) {
2542
- const facet = getFacetFromSelection(facets, selection);
2543
- const transformedSelection = transformSelection(facet, selection);
2544
- // Skip inverted flag and remove it from needed inverted flags
2545
- if (facet && isInvertedFlag(facet)) {
2546
- neededInversedFlags.splice(neededInversedFlags.indexOf(facet), 1);
2547
- }
2548
- else {
2549
- applyJoinAndCondition(group, transformedSelection);
2550
- }
2551
- }
2552
- for (const facet of neededInversedFlags) {
2553
- const transformedSelection = transformSelection(facet, {
2554
- field: facet.field,
2555
- name: facet.name,
2556
- condition: deepClone(facet.condition),
2557
- });
2558
- applyJoinAndCondition(group, transformedSelection);
2559
- }
2560
- addGroupToFilter(filter, group);
2561
- }
2562
- return filter;
2563
- }
2564
- function applyJoinAndCondition(group, selection) {
2565
- // Apply join, then apply operator on that join, if field name has a '.'
2566
- const [joinedRelation, joinedField] = selection.field.split('.');
2567
- let container;
2568
- let wrappedCondition;
2569
- if (joinedField) {
2570
- container = addJoinToGroup(group, joinedRelation);
2571
- wrappedCondition = wrapWithFieldName(joinedField, selection.condition);
2572
- }
2573
- else {
2574
- container = group;
2575
- wrappedCondition = wrapWithFieldName(selection.field, selection.condition);
2576
- }
2577
- addConditionToContainer(container, wrappedCondition);
2578
- }
2579
2539
  /**
2580
- * Only add join if it does not already exists
2540
+ * Wrap the searched value by `%` SQL wildcard
2541
+ *
2542
+ * So:
2543
+ *
2544
+ * {field: 'myFieldName', condition: {like: {value: 'foo'}}}
2545
+ *
2546
+ * will become
2547
+ *
2548
+ * {field: 'myFieldName', condition: {like: {value: '%foo%'}}}
2581
2549
  */
2582
- function addJoinToGroup(group, joinedRelation) {
2583
- if (!group.joins) {
2584
- group.joins = {};
2585
- }
2586
- if (!group.joins[joinedRelation]) {
2587
- group.joins[joinedRelation] = {};
2550
+ function wrapLike(selection) {
2551
+ if (selection.condition.like) {
2552
+ selection.condition.like.value = '%' + selection.condition.like.value + '%';
2588
2553
  }
2589
- return group.joins[joinedRelation];
2554
+ return selection;
2590
2555
  }
2591
2556
  /**
2592
- * Only add condition to group or join if it's valid
2557
+ * Replace the operator name (usually "like", "in" or "between") with the
2558
+ * attribute "field" or "name" defined in the configuration
2559
+ *
2560
+ * So:
2561
+ *
2562
+ * {field: 'myFieldName', condition: {in: {values: [1, 2, 3]}}}
2563
+ *
2564
+ * will become
2565
+ *
2566
+ * {field: 'myFieldName', condition: {myFieldName: {values: [1, 2, 3]}}}
2593
2567
  */
2594
- function addConditionToContainer(container, condition) {
2595
- if (!condition) {
2596
- return;
2597
- }
2598
- if (!container.conditions) {
2599
- container.conditions = [];
2600
- }
2601
- container.conditions.push(condition);
2568
+ function replaceOperatorByField(selection) {
2569
+ return replaceOperatorByAttribute(selection, 'field');
2602
2570
  }
2603
2571
  /**
2604
- * Only add the group if there is something meaningful
2572
+ * Replace the operator name (usually "like", "in" or "between") with the
2573
+ * field "name" defined in the configuration
2574
+ *
2575
+ * So:
2576
+ *
2577
+ * {field: 'myFieldName', name:'myConfigName', condition: {in: {values: [1, 2, 3]}}}
2578
+ *
2579
+ * will become
2580
+ *
2581
+ * {field: 'myFieldName', name:'myConfigName', condition: {myConfigName: {values: [1, 2, 3]}}}
2605
2582
  */
2606
- function addGroupToFilter(filter, group) {
2607
- if (group.conditions || group.joins) {
2608
- if (!filter.groups) {
2609
- filter.groups = [];
2610
- }
2611
- filter.groups.push(group);
2612
- if (filter.groups.length > 1) {
2613
- group.groupLogic = LogicalOperator.OR;
2614
- }
2615
- }
2583
+ function replaceOperatorByName(selection) {
2584
+ return replaceOperatorByAttribute(selection, 'name');
2616
2585
  }
2617
- function wrapWithFieldName(field, condition) {
2618
- const result = {};
2619
- // We assume a custom operator "search"
2620
- if (field === 'search' && condition.like) {
2621
- return { custom: { search: { value: condition.like.value } } };
2622
- }
2623
- else {
2624
- result[field] = condition;
2586
+ function replaceOperatorByAttribute(selection, attribute) {
2587
+ const oldOperator = Object.keys(selection.condition)[0];
2588
+ const attributeValue = selection[attribute];
2589
+ if (!attributeValue) {
2590
+ throw new Error('Attribute cannot be empty. Most likely the configuration was wrong');
2625
2591
  }
2626
- return result;
2627
- }
2628
- function transformSelection(facet, selection) {
2629
- return facet && facet.transform ? facet.transform(selection) : selection;
2630
- }
2631
- function isInvertedFlag(f) {
2632
- return ('inversed' in f && f.inversed) || false;
2592
+ selection.condition[attributeValue] = selection.condition[oldOperator];
2593
+ delete selection.condition[oldOperator];
2594
+ return selection;
2633
2595
  }
2634
-
2635
2596
  /**
2636
- * Returns a string representation of the selection that can be used in URL.
2597
+ * Replace `"today"` and `"tomorrow"` by their real value right now.
2637
2598
  *
2638
- * The string can be parsed back with `fromUrl()`
2599
+ * This transformer is applied automatically and should **not** be part
2600
+ * of Natural public API.
2601
+ *
2602
+ * So:
2603
+ *
2604
+ * {field: 'myFieldName', condition: {greater: {value: 'today'}}}
2605
+ *
2606
+ * will become
2607
+ *
2608
+ * {field: 'myFieldName', condition: {greater: {value: '2023-01-03'}}}
2639
2609
  */
2640
- function toUrl(selections) {
2641
- if (!selections || !selections.length) {
2642
- return null;
2643
- }
2644
- const s = deepClone(selections);
2645
- for (const a of s) {
2646
- for (const b of a) {
2647
- b['f'] = b.field;
2648
- b['c'] = b.condition;
2649
- delete b.field;
2650
- delete b.condition;
2610
+ function replaceToday(selection) {
2611
+ var _a, _b;
2612
+ const date = new Date();
2613
+ const today = formatIsoDate(date);
2614
+ date.setDate(date.getDate() + 1);
2615
+ const tomorrow = formatIsoDate(date);
2616
+ // Transparently adapt exclusive/inclusive ranges for special "today" value.
2617
+ // Ideally this should be done in `TypeDateComponent`, like it is done for real date values. But unfortunately I
2618
+ // could not find a reasonable way to do that while still being able to reload a coherent GUI without showing
2619
+ // "Demain" somewhere in the GUI. And that is something we want to avoid, we only want to show either "Aujourd'hui"
2620
+ // or a real date. Otherwise, the human would start thinking with "Demain", and it would then need to be properly
2621
+ // supported which over/complexify the code, the GUI and the workflow.
2622
+ const condition = selection.condition;
2623
+ if (Object.keys(condition).length === 1) {
2624
+ if (((_a = condition.lessOrEqual) === null || _a === void 0 ? void 0 : _a.value) === 'today') {
2625
+ delete condition.lessOrEqual;
2626
+ condition.less = { value: 'tomorrow' };
2627
+ }
2628
+ else if (((_b = condition.greater) === null || _b === void 0 ? void 0 : _b.value) === 'today') {
2629
+ delete condition.greater;
2630
+ condition.greaterOrEqual = { value: 'tomorrow' };
2631
+ }
2632
+ }
2633
+ for (const key in condition) {
2634
+ const operator = condition[key];
2635
+ if (operator && 'value' in operator) {
2636
+ if (operator.value === 'today') {
2637
+ operator.value = today;
2638
+ }
2639
+ else if (operator.value === 'tomorrow') {
2640
+ operator.value = tomorrow;
2641
+ }
2651
2642
  }
2652
2643
  }
2653
- const result = JSON.stringify(s);
2654
- return result === '[[]]' ? null : result;
2644
+ return selection;
2655
2645
  }
2646
+
2656
2647
  /**
2657
- * Parse a string, probably coming from URL, into a selection
2648
+ * Animations used by the mat-menu component.
2649
+ * Animation duration and timing values are based on:
2650
+ * https://material.io/guidelines/components/menus.html#menus-usage
2658
2651
  */
2659
- function fromUrl(selections) {
2660
- if (!selections || !selections.length) {
2661
- return [[]];
2652
+ const naturalDropdownAnimations = {
2653
+ /**
2654
+ * This animation controls the menu panel's entry and exit from the page.
2655
+ *
2656
+ * When the menu panel is added to the DOM, it scales in and fades in its border.
2657
+ *
2658
+ * When the menu panel is removed from the DOM, it simply fades out after a brief
2659
+ * delay to display the ripple.
2660
+ */
2661
+ transformMenu: trigger('transformMenu', [
2662
+ state('void', style({
2663
+ opacity: 0,
2664
+ // This starts off from 0.01, instead of 0, because there's an issue in the Angular animations
2665
+ // as of 4.2, which causes the animation to be skipped if it starts from 0.
2666
+ transform: 'scale(0.01, 0.01)',
2667
+ })),
2668
+ transition('void => enter', sequence([
2669
+ query('.natural-dropdown-container-content', style({ opacity: 0 })),
2670
+ animate('100ms linear', style({ opacity: 1, transform: 'scale(1, 0.5)' })),
2671
+ group([
2672
+ query('.natural-dropdown-container-content', animate('400ms cubic-bezier(0.55, 0, 0.55, 0.2)', style({ opacity: 1 }))),
2673
+ animate('300ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ transform: 'scale(1, 1)' })),
2674
+ ]),
2675
+ ])),
2676
+ transition('* => void', animate('150ms 50ms linear', style({ opacity: 0 }))),
2677
+ ]),
2678
+ /**
2679
+ * This animation fades in the background color and content of the menu panel
2680
+ * after its containing element is scaled in.
2681
+ */
2682
+ fadeInItems: trigger('fadeInItems', [
2683
+ // TODO(crisbeto): this is inside the `transformMenu`
2684
+ // now. Remove next time we do breaking changes.
2685
+ state('showing', style({ opacity: 1 })),
2686
+ transition('void => *', [style({ opacity: 0 }), animate('400ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)')]),
2687
+ ]),
2688
+ };
2689
+
2690
+ function throwMatDialogContentAlreadyAttachedError() {
2691
+ throw Error('Attempting to attach dialog content after content is already attached');
2692
+ }
2693
+ const NATURAL_DROPDOWN_CONTAINER_DATA = new InjectionToken('NaturalDropdownContainerData');
2694
+ class NaturalDropdownContainerComponent extends BasePortalOutlet {
2695
+ constructor(elementRef, focusTrapFactory, data) {
2696
+ super();
2697
+ this.elementRef = elementRef;
2698
+ this.focusTrapFactory = focusTrapFactory;
2699
+ this.data = data;
2700
+ this.closed = new Subject();
2701
+ /** Current state of the panel animation. */
2702
+ this.panelAnimationState = 'void';
2703
+ /** Emits whenever an animation on the menu completes. */
2704
+ this.animationDone = new Subject();
2705
+ this.focusTrap = null;
2706
+ this.elementFocusedBeforeDialogWasOpened = null;
2662
2707
  }
2663
- const result = JSON.parse(selections);
2664
- for (const a of result) {
2665
- for (const b of a) {
2666
- b.field = b['f'];
2667
- b.condition = b['c'];
2668
- delete b['f'];
2669
- delete b['c'];
2670
- }
2708
+ ngOnDestroy() {
2709
+ this.closed.complete();
2671
2710
  }
2672
- if (result.length === 0) {
2673
- result.push([]);
2711
+ close() {
2712
+ this.closed.next();
2713
+ }
2714
+ attachTemplatePortal(portal) {
2715
+ return this.portalOutlet.attachTemplatePortal(portal);
2716
+ }
2717
+ attachComponentPortal(portal) {
2718
+ if (this.portalOutlet.hasAttached()) {
2719
+ throwMatDialogContentAlreadyAttachedError();
2720
+ }
2721
+ return this.portalOutlet.attachComponentPortal(portal);
2722
+ }
2723
+ startAnimation() {
2724
+ this.panelAnimationState = 'enter';
2725
+ }
2726
+ onAnimationDone(event) {
2727
+ if (event.toState === 'enter') {
2728
+ this.trapFocus();
2729
+ }
2730
+ else if (event.toState === 'exit') {
2731
+ this.restoreFocus();
2732
+ }
2733
+ this.animationDone.next();
2734
+ }
2735
+ trapFocus() {
2736
+ if (!this.focusTrap) {
2737
+ this.focusTrap = this.focusTrapFactory.create(this.elementRef.nativeElement);
2738
+ }
2739
+ this.focusTrap.focusInitialElementWhenReady();
2740
+ }
2741
+ /** Restores focus to the element that was focused before the dialog opened. */
2742
+ restoreFocus() {
2743
+ const toFocus = this.elementFocusedBeforeDialogWasOpened;
2744
+ // We need the extra check, because IE can set the `activeElement` to null in some cases.
2745
+ if (toFocus && typeof toFocus.focus === 'function') {
2746
+ toFocus.focus();
2747
+ }
2748
+ if (this.focusTrap) {
2749
+ this.focusTrap.destroy();
2750
+ }
2674
2751
  }
2675
- return result;
2676
- }
2677
- /**
2678
- * Transform a search selection to navigation parameters to be used in URL.
2679
- *
2680
- * This is typically useful to craft URL to pre-filtered lists.
2681
- */
2682
- function toNavigationParameters(selections) {
2683
- const value = toUrl(selections);
2684
- return value ? { ns: JSON.stringify(value) } : {};
2685
2752
  }
2753
+ NaturalDropdownContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownContainerComponent, deps: [{ token: i0.ElementRef }, { token: i1$1.ConfigurableFocusTrapFactory }, { token: NATURAL_DROPDOWN_CONTAINER_DATA }], target: i0.ɵɵFactoryTarget.Component });
2754
+ NaturalDropdownContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalDropdownContainerComponent, selector: "ng-component", viewQueries: [{ propertyName: "portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, static: true }, { propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div\n (@transformMenu.done)=\"onAnimationDone($event)\"\n [@transformMenu]=\"panelAnimationState\"\n class=\"natural-dropdown-container mat-elevation-z2\"\n role=\"menu\"\n tabindex=\"-1\"\n>\n <div class=\"natural-dropdown-container-content\">\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n\n <div *ngIf=\"data.showValidateButton\" class=\"natural-dropdown-validate-button\">\n <button (click)=\"close()\" color=\"primary\" mat-raised-button i18n>Valider</button>\n </div>\n</div>\n", 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"], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], animations: [naturalDropdownAnimations.transformMenu, naturalDropdownAnimations.fadeInItems], encapsulation: i0.ViewEncapsulation.None });
2755
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownContainerComponent, decorators: [{
2756
+ type: Component,
2757
+ args: [{ encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, animations: [naturalDropdownAnimations.transformMenu, naturalDropdownAnimations.fadeInItems], template: "<div\n (@transformMenu.done)=\"onAnimationDone($event)\"\n [@transformMenu]=\"panelAnimationState\"\n class=\"natural-dropdown-container mat-elevation-z2\"\n role=\"menu\"\n tabindex=\"-1\"\n>\n <div class=\"natural-dropdown-container-content\">\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n\n <div *ngIf=\"data.showValidateButton\" class=\"natural-dropdown-validate-button\">\n <button (click)=\"close()\" color=\"primary\" mat-raised-button i18n>Valider</button>\n </div>\n</div>\n", 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"] }]
2758
+ }], ctorParameters: function () {
2759
+ return [{ type: i0.ElementRef }, { type: i1$1.ConfigurableFocusTrapFactory }, { type: undefined, decorators: [{
2760
+ type: Inject,
2761
+ args: [NATURAL_DROPDOWN_CONTAINER_DATA]
2762
+ }] }];
2763
+ }, propDecorators: { portalOutlet: [{
2764
+ type: ViewChild,
2765
+ args: [CdkPortalOutlet, { static: true }]
2766
+ }], templateRef: [{
2767
+ type: ViewChild,
2768
+ args: [TemplateRef, { static: true }]
2769
+ }] } });
2686
2770
 
2687
- const SESSION_STORAGE = new InjectionToken('Session storage that can be shimed when running on server or in tests');
2688
- const LOCAL_STORAGE = new InjectionToken('Local storage that can be shimed when running on server or in tests');
2689
- /**
2690
- * Memory storage to keep store volatile things in memory
2691
- *
2692
- * Should be used to shim sessionStorage when running on server or in our tests
2693
- */
2694
- class NaturalMemoryStorage {
2695
- constructor() {
2696
- this.data = new Map();
2697
- }
2698
- get length() {
2699
- return this.data.size;
2771
+ class NaturalDropdownRef {
2772
+ constructor(dropdownContainer, component, customProviders, parentInjector, containerRef) {
2773
+ this.dropdownContainer = dropdownContainer;
2774
+ this.closed = new Subject();
2775
+ // Customize injector to allow data and dropdown reference injection in component
2776
+ customProviders.push({ provide: NaturalDropdownRef, useValue: this });
2777
+ const customInjector = Injector.create({ providers: customProviders, parent: parentInjector });
2778
+ // Content (type component given in configuration)
2779
+ const componentPortal = new ComponentPortal(component, undefined, customInjector);
2780
+ const contentRef = containerRef.instance.attachComponentPortal(componentPortal);
2781
+ this.componentInstance = contentRef.instance;
2700
2782
  }
2701
- clear() {
2702
- this.data.clear();
2783
+ close(result) {
2784
+ this.closed.next(result);
2785
+ this.closed.complete();
2786
+ this.dropdownContainer.close();
2703
2787
  }
2704
- getItem(key) {
2705
- const value = this.data.get(key);
2706
- return value === undefined ? null : value;
2788
+ }
2789
+
2790
+ const NATURAL_DROPDOWN_DATA = new InjectionToken('NaturalDropdownData');
2791
+ class NaturalDropdownService {
2792
+ constructor(overlay, injector) {
2793
+ this.overlay = overlay;
2794
+ this.injector = injector;
2707
2795
  }
2708
- key(index) {
2709
- let i = 0;
2710
- for (const key of this.data.keys()) {
2711
- if (i++ === index) {
2712
- return key;
2796
+ open(component, connectedElement, customProviders, showValidateButton) {
2797
+ // Container data
2798
+ const containerData = {
2799
+ showValidateButton: showValidateButton,
2800
+ };
2801
+ const injectionTokens = [
2802
+ {
2803
+ provide: NATURAL_DROPDOWN_CONTAINER_DATA,
2804
+ useValue: containerData,
2805
+ },
2806
+ ];
2807
+ const containerInjector = Injector.create({ providers: injectionTokens, parent: this.injector });
2808
+ // Container
2809
+ const overlayRef = this.overlay.create(this.getOverlayConfig(connectedElement));
2810
+ const containerPortal = new ComponentPortal(NaturalDropdownContainerComponent, undefined, containerInjector);
2811
+ const containerRef = overlayRef.attach(containerPortal);
2812
+ const dropdownContainer = containerRef.instance;
2813
+ const dropdownRef = new NaturalDropdownRef(dropdownContainer, component, customProviders, this.injector, containerRef);
2814
+ // Start animation that shows menu
2815
+ dropdownContainer.startAnimation();
2816
+ const close = () => {
2817
+ if (dropdownRef.componentInstance.isValid() && dropdownRef.componentInstance.isDirty()) {
2818
+ dropdownRef.close({
2819
+ condition: dropdownRef.componentInstance.getCondition(),
2820
+ });
2713
2821
  }
2714
- }
2715
- return null;
2822
+ else {
2823
+ dropdownRef.close();
2824
+ }
2825
+ };
2826
+ // When parent closes, remove overlay from dom and update "return" valu
2827
+ dropdownContainer.closed.subscribe(() => {
2828
+ overlayRef.dispose();
2829
+ close();
2830
+ });
2831
+ // When click on backdrop, validate result.. ?
2832
+ overlayRef
2833
+ .backdropClick()
2834
+ .pipe(takeUntil(dropdownContainer.closed))
2835
+ .subscribe(() => dropdownContainer.close());
2836
+ return dropdownRef;
2716
2837
  }
2717
- removeItem(key) {
2718
- this.data.delete(key);
2838
+ /**
2839
+ * This method builds the configuration object needed to create the overlay, the OverlayState.
2840
+ */
2841
+ getOverlayConfig(element) {
2842
+ return new OverlayConfig({
2843
+ positionStrategy: this.getPosition(element),
2844
+ hasBackdrop: true,
2845
+ backdropClass: 'cdk-overlay-transparent-backdrop',
2846
+ });
2719
2847
  }
2720
- setItem(key, value) {
2721
- this.data.set(key, value);
2848
+ getPosition(element) {
2849
+ return this.overlay
2850
+ .position()
2851
+ .flexibleConnectedTo(element)
2852
+ .withFlexibleDimensions(true)
2853
+ .withViewportMargin(30)
2854
+ .withPush(false)
2855
+ .withPositions([
2856
+ {
2857
+ originX: 'start',
2858
+ originY: 'bottom',
2859
+ overlayX: 'start',
2860
+ overlayY: 'top',
2861
+ offsetY: 10,
2862
+ },
2863
+ ]);
2722
2864
  }
2723
2865
  }
2724
- NaturalMemoryStorage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalMemoryStorage, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2725
- NaturalMemoryStorage.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalMemoryStorage, providedIn: 'root' });
2726
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalMemoryStorage, decorators: [{
2866
+ NaturalDropdownService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownService, deps: [{ token: i1$3.Overlay }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
2867
+ NaturalDropdownService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownService, providedIn: 'root' });
2868
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownService, decorators: [{
2727
2869
  type: Injectable,
2728
2870
  args: [{
2729
2871
  providedIn: 'root',
2730
2872
  }]
2731
- }] });
2732
- function sessionStorageFactory() {
2733
- try {
2734
- // eslint-disable-next-line no-restricted-globals
2735
- if (typeof sessionStorage !== 'undefined') {
2736
- // eslint-disable-next-line no-restricted-globals
2737
- return sessionStorage;
2738
- }
2739
- }
2740
- catch (e) {
2741
- // nothing do to
2873
+ }], ctorParameters: function () { return [{ type: i1$3.Overlay }, { type: i0.Injector }]; } });
2874
+
2875
+ const possibleComparableOperators = [
2876
+ {
2877
+ key: 'less',
2878
+ label: '<',
2879
+ },
2880
+ {
2881
+ key: 'lessOrEqual',
2882
+ label: '≤',
2883
+ },
2884
+ {
2885
+ key: 'equal',
2886
+ label: '=',
2887
+ },
2888
+ {
2889
+ key: 'greaterOrEqual',
2890
+ label: '≥',
2891
+ },
2892
+ {
2893
+ key: 'greater',
2894
+ label: '>',
2895
+ },
2896
+ ];
2897
+ const possibleDiscreteOperators = [
2898
+ {
2899
+ key: 'is',
2900
+ label: $localize `est`,
2901
+ },
2902
+ {
2903
+ key: 'isnot',
2904
+ label: $localize `n'est pas`,
2905
+ },
2906
+ {
2907
+ key: 'any',
2908
+ label: $localize `tous`,
2909
+ },
2910
+ {
2911
+ key: 'none',
2912
+ label: $localize `aucun`,
2913
+ },
2914
+ ];
2915
+
2916
+ /**
2917
+ * Get only date, without time and ignoring entirely the timezone
2918
+ */
2919
+ function serialize(dateAdapter, value) {
2920
+ if (!value) {
2921
+ return '';
2742
2922
  }
2743
- return new NaturalMemoryStorage();
2923
+ const y = dateAdapter.getYear(value);
2924
+ const m = dateAdapter.getMonth(value) + 1;
2925
+ const d = dateAdapter.getDate(value);
2926
+ return y + '-' + (m < 10 ? '0' : '') + m + '-' + (d < 10 ? '0' : '') + d;
2744
2927
  }
2745
2928
  /**
2746
- * Standard `sessionStorage` provider that is compatible with SSR.
2747
- *
2748
- * In SSR environment, or when `sessionStorage` is not available, will return a `NaturalMemoryStorage`
2929
+ * Min date validator
2749
2930
  */
2750
- const sessionStorageProvider = {
2751
- // Here we must use a factory that return directly the value, otherwise it will
2752
- // crash when running on server because the value does not exist (but the factory will
2753
- // never actually be called on server, so the server will not see the missing value)
2754
- provide: SESSION_STORAGE,
2755
- useFactory: sessionStorageFactory,
2756
- };
2757
- /**
2758
- * Provide in-memory session storage to be used only in tests or SSR
2759
- */
2760
- const memorySessionStorageProvider = {
2761
- provide: SESSION_STORAGE,
2762
- useClass: NaturalMemoryStorage,
2763
- };
2764
- function localStorageFactory() {
2765
- try {
2766
- // eslint-disable-next-line no-restricted-globals
2767
- if (typeof localStorage !== 'undefined') {
2768
- // eslint-disable-next-line no-restricted-globals
2769
- return localStorage;
2931
+ function dateMin(dateAdapter, min) {
2932
+ return (control) => {
2933
+ if (control.value && dateAdapter.compareDate(control.value, min) < 0) {
2934
+ return { min: true };
2770
2935
  }
2771
- }
2772
- catch (e) {
2773
- // Do nothing
2774
- }
2775
- return new NaturalMemoryStorage();
2936
+ return null;
2937
+ };
2776
2938
  }
2777
2939
  /**
2778
- * Standard `localStorage` provider that is compatible with SSR.
2779
- *
2780
- * In SSR environment, or when `localStorage` is not available, will return a `NaturalMemoryStorage`
2781
- */
2782
- const localStorageProvider = {
2783
- // Here we must use a factory that return directly the value, otherwise it will
2784
- // crash when running on server because the value does not exist (but the factory will
2785
- // never actually be called on server, so the server will not see the missing value)
2786
- provide: LOCAL_STORAGE,
2787
- useFactory: localStorageFactory,
2788
- };
2789
- /**
2790
- * Provide in-memory local storage to be used only in tests or SSR
2940
+ * Max date validator
2791
2941
  */
2792
- const memoryLocalStorageProvider = {
2793
- provide: LOCAL_STORAGE,
2794
- useClass: NaturalMemoryStorage,
2795
- };
2942
+ function dateMax(dateAdapter, max) {
2943
+ return (control) => {
2944
+ if (control.value && dateAdapter.compareDate(control.value, max) > 0) {
2945
+ return { max: true };
2946
+ }
2947
+ return null;
2948
+ };
2949
+ }
2796
2950
 
2797
- const NATURAL_PERSISTENCE_VALIDATOR = new InjectionToken('Validator for persisted value retrieved from NaturalPersistenceService. If returns false, the persisted value will never be returned.');
2798
- class NaturalPersistenceService {
2799
- constructor(router, sessionStorage, isValid) {
2800
- var _a;
2801
- this.router = router;
2802
- this.sessionStorage = sessionStorage;
2803
- this.isValid = isValid;
2804
- // By default, anything is valid
2805
- this.isValid = (_a = this.isValid) !== null && _a !== void 0 ? _a : (() => true);
2806
- }
2807
- /**
2808
- * Persist in url and local storage the given value with the given key.
2809
- * When stored in storage, we need more "key" to identify the controller.
2810
- */
2811
- persist(key, value, route, storageKey, navigationExtras) {
2812
- this.persistInStorage(key, value, storageKey);
2813
- return this.persistInUrl(key, value, route, navigationExtras);
2951
+ class TypeDateComponent extends NaturalAbstractController {
2952
+ constructor(data, dateAdapter, dateFormats) {
2953
+ super();
2954
+ this.dateAdapter = dateAdapter;
2955
+ this.dateFormats = dateFormats;
2956
+ this.renderedValue = new BehaviorSubject('');
2957
+ this.operatorCtrl = new FormControl('equal', { nonNullable: true });
2958
+ this.valueCtrl = new FormControl(null);
2959
+ this.todayCtrl = new FormControl(false);
2960
+ this.operators = possibleComparableOperators;
2961
+ this.form = new FormGroup({
2962
+ operator: this.operatorCtrl,
2963
+ value: this.valueCtrl,
2964
+ today: this.todayCtrl,
2965
+ });
2966
+ this.defaults = {
2967
+ min: null,
2968
+ max: null,
2969
+ };
2970
+ this.configuration = Object.assign(Object.assign({}, this.defaults), data.configuration);
2971
+ this.todayCtrl.valueChanges.pipe(takeUntil(this.ngUnsubscribe)).subscribe(isToday => {
2972
+ if (isToday) {
2973
+ this.valueCtrl.setValue(this.dateAdapter.today());
2974
+ this.valueCtrl.disable();
2975
+ }
2976
+ else {
2977
+ this.valueCtrl.enable();
2978
+ }
2979
+ });
2980
+ merge$1(this.operatorCtrl.valueChanges, this.valueCtrl.valueChanges, this.todayCtrl.valueChanges)
2981
+ .pipe(takeUntil(this.ngUnsubscribe))
2982
+ .subscribe(() => this.renderedValue.next(this.getRenderedValue()));
2983
+ this.initValidators();
2984
+ this.reloadCondition(data.condition);
2814
2985
  }
2815
- /**
2816
- * Return object with persisted data in url or in session storage
2817
- * Url has priority over session storage because of url sharing. When url is provided, session storage is ignored.
2818
- * Url and storage are synced when arriving in a component :
2819
- * - When loading with url parameters, storage is updated to stay synced
2820
- * - When loading without url, but with storage data, the url is updated
2821
- */
2822
- get(key, route, storageKey) {
2823
- // From url
2824
- let params = this.getFromUrl(key, route);
2825
- if (!this.isFalseyValue(params)) {
2826
- this.persistInStorage(key, params, storageKey);
2827
- return params;
2986
+ getCondition() {
2987
+ if (!this.valueCtrl.value) {
2988
+ return {};
2828
2989
  }
2829
- // From storage
2830
- params = this.getFromStorage(key, storageKey);
2831
- if (!this.isFalseyValue(params)) {
2832
- this.persistInUrl(key, params, route);
2833
- return params;
2990
+ const condition = {};
2991
+ let operator = this.operatorCtrl.value;
2992
+ let date;
2993
+ let dayAfter;
2994
+ if (this.todayCtrl.value) {
2995
+ date = 'today';
2996
+ dayAfter = 'tomorrow';
2834
2997
  }
2835
- return null;
2836
- }
2837
- /**
2838
- * Get given key from the url parameters
2839
- */
2840
- getFromUrl(key, route) {
2841
- const value = route.snapshot.paramMap.get(key);
2842
- return this.deserialize(key, null, value);
2843
- }
2844
- /**
2845
- * Add/override given pair key-value in the url
2846
- * Always JSON.stringify() the given value
2847
- * If the value is falsey, the pair key-value is removed from the url.
2848
- */
2849
- persistInUrl(key, value, route, navigationExtras) {
2850
- const params = clone(route.snapshot.url[route.snapshot.url.length - 1].parameters);
2851
- if (this.isFalseyValue(value)) {
2852
- delete params[key];
2998
+ else {
2999
+ date = serialize(this.dateAdapter, this.valueCtrl.value);
3000
+ dayAfter = serialize(this.dateAdapter, this.getDayAfter(this.valueCtrl.value));
3001
+ }
3002
+ if (operator === 'equal') {
3003
+ condition.greaterOrEqual = { value: date };
3004
+ condition.less = { value: dayAfter };
2853
3005
  }
2854
3006
  else {
2855
- params[key] = JSON.stringify(value);
3007
+ // Transparently adapt exclusive/inclusive ranges
3008
+ if (date !== 'today') {
3009
+ if (operator === 'greater') {
3010
+ operator = 'greaterOrEqual';
3011
+ date = dayAfter;
3012
+ }
3013
+ else if (operator === 'lessOrEqual') {
3014
+ operator = 'less';
3015
+ date = dayAfter;
3016
+ }
3017
+ }
3018
+ condition[operator] = { value: date };
2856
3019
  }
2857
- navigationExtras = Object.assign(navigationExtras || {}, { relativeTo: route });
2858
- return this.router.navigate(['.', params], navigationExtras);
3020
+ return condition;
2859
3021
  }
2860
- getFromStorage(key, storageKey) {
2861
- const value = this.sessionStorage.getItem(this.getStorageKey(key, storageKey));
2862
- return this.deserialize(key, storageKey, value);
3022
+ isValid() {
3023
+ return this.form.valid;
2863
3024
  }
2864
- /**
2865
- * Store value in session storage.
2866
- * If value is falsy, the entry is removed
2867
- */
2868
- persistInStorage(key, value, storageKey) {
2869
- if (this.isFalseyValue(value)) {
2870
- this.sessionStorage.removeItem(this.getStorageKey(key, storageKey));
3025
+ isDirty() {
3026
+ return this.form.dirty;
3027
+ }
3028
+ reloadCondition(condition) {
3029
+ if (!condition) {
3030
+ return;
3031
+ }
3032
+ // Special case for '='
3033
+ if (condition.greaterOrEqual && condition.less) {
3034
+ this.operatorCtrl.setValue('equal');
3035
+ this.setTodayOrDate(condition.greaterOrEqual.value);
3036
+ return;
3037
+ }
3038
+ for (const operator of this.operators) {
3039
+ const reloadedOperator = condition[operator.key];
3040
+ if (reloadedOperator) {
3041
+ this.operatorCtrl.setValue(operator.key);
3042
+ this.setTodayOrDate(reloadedOperator.value);
3043
+ }
3044
+ }
3045
+ }
3046
+ setTodayOrDate(value) {
3047
+ if (value === 'today') {
3048
+ this.valueCtrl.setValue(this.dateAdapter.today());
3049
+ this.todayCtrl.setValue(true);
2871
3050
  }
2872
3051
  else {
2873
- this.sessionStorage.setItem(this.getStorageKey(key, storageKey), JSON.stringify(value));
3052
+ this.valueCtrl.setValue(this.dateAdapter.deserialize(value));
3053
+ this.todayCtrl.setValue(false);
2874
3054
  }
2875
3055
  }
2876
- getStorageKey(key, storageKey) {
2877
- return storageKey + '-' + key;
3056
+ initValidators() {
3057
+ const validators = [Validators.required];
3058
+ if (this.configuration.min) {
3059
+ validators.push(dateMin(this.dateAdapter, this.configuration.min));
3060
+ }
3061
+ if (this.configuration.max) {
3062
+ validators.push(dateMax(this.dateAdapter, this.configuration.max));
3063
+ }
3064
+ this.valueCtrl.setValidators(validators);
2878
3065
  }
2879
- // Returns if the given value is falsey
2880
- // Falsey values are : null, undefined and empty string.
2881
- // This cause usually the parameter to be removed from url/storage instead of being stored with no value. Url would be polluted.
2882
- isFalseyValue(value) {
2883
- return value == null || value === ''; // == means null or undefined;
3066
+ getDayAfter(date) {
3067
+ return this.dateAdapter.addCalendarDays(this.dateAdapter.clone(date), 1);
2884
3068
  }
2885
- deserialize(key, storageKey, value) {
2886
- if (!value) {
2887
- return null;
3069
+ getRenderedValue() {
3070
+ const operator = this.operators.find(v => v.key === this.operatorCtrl.value);
3071
+ let value = '';
3072
+ if (this.todayCtrl.value) {
3073
+ value = $localize `Aujourd'hui`;
2888
3074
  }
2889
- let result = null;
2890
- try {
2891
- result = JSON.parse(value);
3075
+ else if (this.valueCtrl.value) {
3076
+ value = this.dateAdapter.format(this.valueCtrl.value, this.dateFormats.display.dateInput);
3077
+ }
3078
+ if (operator && value) {
3079
+ return operator.label + ' ' + value;
3080
+ }
3081
+ else {
3082
+ return '';
2892
3083
  }
2893
- catch (e) { }
2894
- return this.isValid(key, storageKey, result) ? result : null;
2895
3084
  }
2896
3085
  }
2897
- NaturalPersistenceService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalPersistenceService, deps: [{ token: i2$1.Router }, { token: SESSION_STORAGE }, { token: NATURAL_PERSISTENCE_VALIDATOR, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
2898
- NaturalPersistenceServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalPersistenceService, providedIn: 'root' });
2899
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalPersistenceService, decorators: [{
2900
- type: Injectable,
2901
- args: [{
2902
- providedIn: 'root',
2903
- }]
3086
+ TypeDateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeDateComponent, deps: [{ token: NATURAL_DROPDOWN_DATA }, { token: i1$4.DateAdapter }, { token: MAT_DATE_FORMATS }], target: i0.ɵɵFactoryTarget.Component });
3087
+ TypeDateComponentcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeDateComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field>\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>Date</mat-label>\n <input\n [formControl]=\"valueCtrl\"\n [matDatepicker]=\"value\"\n [max]=\"configuration.max\"\n [min]=\"configuration.min\"\n [required]=\"true\"\n matInput\n />\n <mat-datepicker-toggle [for]=\"value\" matSuffix></mat-datepicker-toggle>\n <mat-datepicker #value></mat-datepicker>\n <mat-error *ngIf=\"valueCtrl.hasError('min')\">< {{ configuration.min }}</mat-error>\n <mat-error *ngIf=\"valueCtrl.hasError('max')\">> {{ configuration.max }}</mat-error>\n <mat-error *ngIf=\"valueCtrl.hasError('required')\">*</mat-error>\n </mat-form-field>\n\n <mat-checkbox [formControl]=\"todayCtrl\" i18n>Aujourd'hui</mat-checkbox>\n</form>\n", styles: ["form{display:grid;grid:auto auto/4em auto;grid-gap:0 1em}form>*{align-self:end}form>mat-checkbox{grid-column-start:2;margin-bottom:.3em}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i7.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i7.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i7.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$4.MatOption, selector: "mat-option", exportAs: ["matOption"] }] });
3088
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeDateComponent, decorators: [{
3089
+ type: Component,
3090
+ args: [{ template: "<form [formGroup]=\"form\">\n <mat-form-field>\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>Date</mat-label>\n <input\n [formControl]=\"valueCtrl\"\n [matDatepicker]=\"value\"\n [max]=\"configuration.max\"\n [min]=\"configuration.min\"\n [required]=\"true\"\n matInput\n />\n <mat-datepicker-toggle [for]=\"value\" matSuffix></mat-datepicker-toggle>\n <mat-datepicker #value></mat-datepicker>\n <mat-error *ngIf=\"valueCtrl.hasError('min')\">< {{ configuration.min }}</mat-error>\n <mat-error *ngIf=\"valueCtrl.hasError('max')\">> {{ configuration.max }}</mat-error>\n <mat-error *ngIf=\"valueCtrl.hasError('required')\">*</mat-error>\n </mat-form-field>\n\n <mat-checkbox [formControl]=\"todayCtrl\" i18n>Aujourd'hui</mat-checkbox>\n</form>\n", styles: ["form{display:grid;grid:auto auto/4em auto;grid-gap:0 1em}form>*{align-self:end}form>mat-checkbox{grid-column-start:2;margin-bottom:.3em}\n"] }]
2904
3091
  }], ctorParameters: function () {
2905
- return [{ type: i2$1.Router }, { type: undefined, decorators: [{
3092
+ return [{ type: undefined, decorators: [{
2906
3093
  type: Inject,
2907
- args: [SESSION_STORAGE]
2908
- }] }, { type: undefined, decorators: [{
2909
- type: Optional
2910
- }, {
3094
+ args: [NATURAL_DROPDOWN_DATA]
3095
+ }] }, { type: i1$4.DateAdapter }, { type: undefined, decorators: [{
2911
3096
  type: Inject,
2912
- args: [NATURAL_PERSISTENCE_VALIDATOR]
3097
+ args: [MAT_DATE_FORMATS]
2913
3098
  }] }];
2914
3099
  } });
2915
3100
 
2916
- /**
2917
- * A NaturalDataSource will connect immediately, in order to know as soon as possible if
2918
- * we need to show a template at all (as seen in my-ichtus)
2919
- *
2920
- * It also allow some extra data manipulation
2921
- */
2922
- class NaturalDataSource extends DataSource {
2923
- constructor(value) {
2924
- super();
2925
- this.ngUnsubscribe = new Subject();
2926
- if (value instanceof Observable) {
2927
- this.internalData = new BehaviorSubject(null);
2928
- value.pipe(takeUntil(this.ngUnsubscribe)).subscribe(res => (this.data = res));
2929
- }
2930
- else {
2931
- this.internalData = new BehaviorSubject(value);
2932
- }
2933
- }
2934
- get internalDataObservable() {
2935
- return this.internalData;
3101
+ function toGraphQLDoctrineFilter(facets, selections) {
3102
+ selections = deepClone(selections);
3103
+ const filter = {};
3104
+ if (!selections || selections.length === 0) {
3105
+ selections = [[]];
2936
3106
  }
2937
- /**
2938
- * Array of data that should be rendered by the table, where each object represents one row.
2939
- */
2940
- get data() {
2941
- return this.internalData.value;
3107
+ for (const groupSelections of selections) {
3108
+ const group = {};
3109
+ const neededInversedFlags = facets ? facets.filter(isInvertedFlag) : [];
3110
+ for (const selection of groupSelections) {
3111
+ const facet = getFacetFromSelection(facets, selection);
3112
+ const transformedSelection = transformSelection(facet, selection);
3113
+ // Skip inverted flag and remove it from needed inverted flags
3114
+ if (isInvertedFlag(facet)) {
3115
+ neededInversedFlags.splice(neededInversedFlags.indexOf(facet), 1);
3116
+ }
3117
+ else {
3118
+ applyJoinAndCondition(group, transformedSelection);
3119
+ }
3120
+ }
3121
+ for (const facet of neededInversedFlags) {
3122
+ const transformedSelection = transformSelection(facet, {
3123
+ field: facet.field,
3124
+ name: facet.name,
3125
+ condition: deepClone(facet.condition),
3126
+ });
3127
+ applyJoinAndCondition(group, transformedSelection);
3128
+ }
3129
+ addGroupToFilter(filter, group);
2942
3130
  }
2943
- set data(data) {
2944
- this.internalData.next(data);
3131
+ return filter;
3132
+ }
3133
+ function applyJoinAndCondition(group, selection) {
3134
+ // Apply join, then apply operator on that join, if field name has a '.'
3135
+ const [joinedRelation, joinedField] = selection.field.split('.');
3136
+ let container;
3137
+ let wrappedCondition;
3138
+ if (joinedField) {
3139
+ container = addJoinToGroup(group, joinedRelation);
3140
+ wrappedCondition = wrapWithFieldName(joinedField, selection.condition);
2945
3141
  }
2946
- connect() {
2947
- return this.internalData.pipe(takeUntil(this.ngUnsubscribe), map(data => (data ? data.items : [])));
3142
+ else {
3143
+ container = group;
3144
+ wrappedCondition = wrapWithFieldName(selection.field, selection.condition);
2948
3145
  }
2949
- disconnect() {
2950
- this.ngUnsubscribe.next(); // unsubscribe everybody
2951
- this.ngUnsubscribe.complete(); // complete the stream, because we will never emit again
3146
+ addConditionToContainer(container, wrappedCondition);
3147
+ }
3148
+ /**
3149
+ * Only add join if it does not already exists
3150
+ */
3151
+ function addJoinToGroup(group, joinedRelation) {
3152
+ if (!group.joins) {
3153
+ group.joins = {};
2952
3154
  }
2953
- push(item) {
2954
- if (!this.data) {
2955
- return;
2956
- }
2957
- const fullList = [...this.data.items];
2958
- fullList.push(item);
2959
- this.data = Object.assign(Object.assign({}, this.data), { items: fullList, length: fullList.length });
3155
+ if (!group.joins[joinedRelation]) {
3156
+ group.joins[joinedRelation] = {};
2960
3157
  }
2961
- pop() {
2962
- if (!this.data) {
2963
- return;
2964
- }
2965
- const fullList = [...this.data.items];
2966
- const removedElement = fullList.pop();
2967
- this.data = Object.assign(Object.assign({}, this.data), { items: fullList, length: fullList.length });
2968
- return removedElement;
3158
+ return group.joins[joinedRelation];
3159
+ }
3160
+ /**
3161
+ * Only add condition to group or join if it's valid
3162
+ */
3163
+ function addConditionToContainer(container, condition) {
3164
+ if (!condition) {
3165
+ return;
2969
3166
  }
2970
- remove(item) {
2971
- if (!this.data) {
2972
- return;
3167
+ if (!container.conditions) {
3168
+ container.conditions = [];
3169
+ }
3170
+ container.conditions.push(condition);
3171
+ }
3172
+ /**
3173
+ * Only add the group if there is something meaningful
3174
+ */
3175
+ function addGroupToFilter(filter, group) {
3176
+ if (group.conditions || group.joins) {
3177
+ if (!filter.groups) {
3178
+ filter.groups = [];
2973
3179
  }
2974
- const index = this.data.items.indexOf(item);
2975
- if (index > -1) {
2976
- const fullList = [...this.data.items];
2977
- fullList.splice(index, 1);
2978
- this.data = Object.assign(Object.assign({}, this.data), { items: fullList, length: fullList.length });
3180
+ filter.groups.push(group);
3181
+ if (filter.groups.length > 1) {
3182
+ group.groupLogic = LogicalOperator.OR;
2979
3183
  }
2980
3184
  }
2981
3185
  }
2982
-
2983
- function unwrapNavigable(item) {
2984
- if ('item' in item && 'hasNavigation' in item) {
2985
- return item.item;
3186
+ function wrapWithFieldName(field, condition) {
3187
+ const result = {};
3188
+ // We assume a custom operator "search"
3189
+ if (field === 'search' && condition.like) {
3190
+ return { custom: { search: { value: condition.like.value } } };
2986
3191
  }
2987
- return item;
3192
+ else {
3193
+ result[field] = condition;
3194
+ }
3195
+ return result;
3196
+ }
3197
+ function transformSelection(facet, selection) {
3198
+ const newSelection = facet && facet.transform ? facet.transform(selection) : selection;
3199
+ return isDateFacet(facet) ? replaceToday(newSelection) : selection;
3200
+ }
3201
+ function isInvertedFlag(facet) {
3202
+ return (!!facet && 'inversed' in facet && facet.inversed) || false;
3203
+ }
3204
+ function isDateFacet(facet) {
3205
+ return !!facet && 'component' in facet && facet.component === TypeDateComponent;
2988
3206
  }
3207
+
2989
3208
  /**
2990
- * This class helps managing a list of paginated items that can be filtered,
2991
- * selected, and then bulk actions can be performed on selection.
2992
- *
2993
- * Components inheriting from this class can be used as standalone with input attributes.
3209
+ * Returns a string representation of the selection that can be used in URL.
2994
3210
  *
2995
- * Usage :
2996
- * <natural-my-listing [forcedVariables]="{filter:...}" [selectedColumns]="['col1']" [persistSearch]="false">
3211
+ * The string can be parsed back with `fromUrl()`
2997
3212
  */
2998
- // @dynamic
2999
- class NaturalAbstractList extends NaturalAbstractPanel {
3000
- constructor(service, injector) {
3001
- super();
3002
- this.service = service;
3003
- this.injector = injector;
3004
- /**
3005
- * Wherever search should be loaded from url/storage and persisted in it too.
3006
- */
3007
- this.persistSearch = true;
3008
- /**
3009
- * Columns list after interaction with <natural-columns-picker>
3010
- */
3011
- this.columnsForTable = [];
3012
- /**
3013
- * The default column selection that automatically happened after <natural-columns-picker> initialization
3014
- */
3015
- this.defaultSelectedColumns = null;
3016
- /**
3017
- * Selection for bulk actions
3018
- */
3019
- this.selection = new SelectionModel(true, []);
3020
- /**
3021
- * Next executed action from bulk menu
3022
- */
3023
- this.bulkActionSelected = null;
3024
- /**
3025
- * Centralisation of query variables
3026
- */
3027
- this.variablesManager = new NaturalQueryVariablesManager();
3028
- /**
3029
- * Configuration for natural-search facets
3030
- */
3031
- this.naturalSearchFacets = [];
3032
- /**
3033
- * Result of a search (can be provided as input for initialisation)
3034
- */
3035
- this.naturalSearchSelections = [[]];
3036
- /**
3037
- * List of page sizes
3038
- */
3039
- this.pageSizeOptions = [5, 10, 25, 50, 100, 200];
3040
- /**
3041
- * Initial pagination setup
3042
- */
3043
- this.defaultPagination = {
3044
- offset: null,
3045
- pageIndex: 0,
3046
- pageSize: 25,
3047
- };
3048
- this.router = injector.get(Router);
3049
- this.route = injector.get(ActivatedRoute);
3050
- this.alertService = injector.get(NaturalAlertService);
3051
- this.persistenceService = injector.get(NaturalPersistenceService);
3213
+ function toUrl(selections) {
3214
+ if (!selections || !selections.length) {
3215
+ return null;
3052
3216
  }
3053
- /**
3054
- * Variables that are always forced on a list, in addition to whatever the end-user might select
3055
- */
3056
- set forcedVariables(variables) {
3057
- if (variables) {
3058
- this.applyForcedVariables(variables);
3217
+ const s = deepClone(selections);
3218
+ for (const a of s) {
3219
+ for (const b of a) {
3220
+ b['f'] = b.field;
3221
+ b['c'] = b.condition;
3222
+ delete b.field;
3223
+ delete b.condition;
3059
3224
  }
3060
3225
  }
3061
- /**
3062
- * If change, check DocumentsComponent that overrides this function without calling super.ngOnInit().
3063
- */
3064
- ngOnInit() {
3065
- this.routeData = this.route.snapshot.data;
3066
- this.initFromRoute();
3067
- this.initFromPersisted();
3068
- this.variablesManager.defaults('pagination', { pagination: this.defaultPagination });
3069
- this.variablesManager.defaults('sorting', { sorting: this.defaultSorting });
3070
- this.dataSource = new NaturalDataSource(this.getDataObservable());
3071
- this.selection.clear();
3072
- // Update natural search when history changes (back/forward buttons)
3073
- // History state is detectable only on NavigationStart (popstate trigger)
3074
- // But we need parameters from url after NavigationEnd. So proceed in two steps with a flag.
3075
- let isPopState = false;
3076
- this.router.events
3077
- .pipe(takeUntil(this.ngUnsubscribe), filter(event => event instanceof NavigationStart && event.navigationTrigger === 'popstate'))
3078
- .subscribe(() => {
3079
- isPopState = true;
3080
- });
3081
- this.router.events
3082
- .pipe(takeUntil(this.ngUnsubscribe), filter(event => event instanceof NavigationEnd && isPopState))
3083
- .subscribe(() => {
3084
- isPopState = false; // reset flag
3085
- this.naturalSearchSelections = fromUrl(this.persistenceService.getFromUrl('ns', this.route));
3086
- });
3226
+ const result = JSON.stringify(s);
3227
+ return result === '[[]]' ? null : result;
3228
+ }
3229
+ /**
3230
+ * Parse a string, probably coming from URL, into a selection
3231
+ */
3232
+ function fromUrl(selections) {
3233
+ if (!selections || !selections.length) {
3234
+ return [[]];
3087
3235
  }
3088
- /**
3089
- * Persist search and then launch whatever is required to refresh the list
3090
- */
3091
- search(naturalSearchSelections, navigationExtras, resetPagination = true) {
3092
- // Reset page index to restart the pagination (preserve pageSize)
3093
- if (resetPagination) {
3094
- this.variablesManager.merge('pagination', {
3095
- pagination: pick(this.defaultPagination, ['offset', 'pageIndex']),
3096
- });
3236
+ const result = JSON.parse(selections);
3237
+ for (const a of result) {
3238
+ for (const b of a) {
3239
+ b.field = b['f'];
3240
+ b.condition = b['c'];
3241
+ delete b['f'];
3242
+ delete b['c'];
3097
3243
  }
3098
- // Persist if activated
3099
- // Two parallel navigations conflict. We first persist the search, then the pagination
3100
- if (this.persistSearch && !this.isPanel) {
3101
- const promise = this.persistenceService.persist('ns', toUrl(naturalSearchSelections), this.route, this.getStorageKey());
3102
- const pagination = this.getPagination();
3103
- this.pagination(pagination, promise, navigationExtras);
3244
+ }
3245
+ if (result.length === 0) {
3246
+ result.push([]);
3247
+ }
3248
+ return result;
3249
+ }
3250
+ /**
3251
+ * Transform a search selection to navigation parameters to be used in URL.
3252
+ *
3253
+ * This is typically useful to craft URL to pre-filtered lists.
3254
+ */
3255
+ function toNavigationParameters(selections) {
3256
+ const value = toUrl(selections);
3257
+ return value ? { ns: JSON.stringify(value) } : {};
3258
+ }
3259
+
3260
+ const SESSION_STORAGE = new InjectionToken('Session storage that can be shimed when running on server or in tests');
3261
+ const LOCAL_STORAGE = new InjectionToken('Local storage that can be shimed when running on server or in tests');
3262
+ /**
3263
+ * Memory storage to keep store volatile things in memory
3264
+ *
3265
+ * Should be used to shim sessionStorage when running on server or in our tests
3266
+ */
3267
+ class NaturalMemoryStorage {
3268
+ constructor() {
3269
+ this.data = new Map();
3270
+ }
3271
+ get length() {
3272
+ return this.data.size;
3273
+ }
3274
+ clear() {
3275
+ this.data.clear();
3276
+ }
3277
+ getItem(key) {
3278
+ const value = this.data.get(key);
3279
+ return value === undefined ? null : value;
3280
+ }
3281
+ key(index) {
3282
+ let i = 0;
3283
+ for (const key of this.data.keys()) {
3284
+ if (i++ === index) {
3285
+ return key;
3286
+ }
3287
+ }
3288
+ return null;
3289
+ }
3290
+ removeItem(key) {
3291
+ this.data.delete(key);
3292
+ }
3293
+ setItem(key, value) {
3294
+ this.data.set(key, value);
3295
+ }
3296
+ }
3297
+ NaturalMemoryStorage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalMemoryStorage, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3298
+ NaturalMemoryStorage.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalMemoryStorage, providedIn: 'root' });
3299
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalMemoryStorage, decorators: [{
3300
+ type: Injectable,
3301
+ args: [{
3302
+ providedIn: 'root',
3303
+ }]
3304
+ }] });
3305
+ function sessionStorageFactory() {
3306
+ try {
3307
+ // eslint-disable-next-line no-restricted-globals
3308
+ if (typeof sessionStorage !== 'undefined') {
3309
+ // eslint-disable-next-line no-restricted-globals
3310
+ return sessionStorage;
3311
+ }
3312
+ }
3313
+ catch (e) {
3314
+ // nothing do to
3315
+ }
3316
+ return new NaturalMemoryStorage();
3317
+ }
3318
+ /**
3319
+ * Standard `sessionStorage` provider that is compatible with SSR.
3320
+ *
3321
+ * In SSR environment, or when `sessionStorage` is not available, will return a `NaturalMemoryStorage`
3322
+ */
3323
+ const sessionStorageProvider = {
3324
+ // Here we must use a factory that return directly the value, otherwise it will
3325
+ // crash when running on server because the value does not exist (but the factory will
3326
+ // never actually be called on server, so the server will not see the missing value)
3327
+ provide: SESSION_STORAGE,
3328
+ useFactory: sessionStorageFactory,
3329
+ };
3330
+ /**
3331
+ * Provide in-memory session storage to be used only in tests or SSR
3332
+ */
3333
+ const memorySessionStorageProvider = {
3334
+ provide: SESSION_STORAGE,
3335
+ useClass: NaturalMemoryStorage,
3336
+ };
3337
+ function localStorageFactory() {
3338
+ try {
3339
+ // eslint-disable-next-line no-restricted-globals
3340
+ if (typeof localStorage !== 'undefined') {
3341
+ // eslint-disable-next-line no-restricted-globals
3342
+ return localStorage;
3343
+ }
3344
+ }
3345
+ catch (e) {
3346
+ // Do nothing
3347
+ }
3348
+ return new NaturalMemoryStorage();
3349
+ }
3350
+ /**
3351
+ * Standard `localStorage` provider that is compatible with SSR.
3352
+ *
3353
+ * In SSR environment, or when `localStorage` is not available, will return a `NaturalMemoryStorage`
3354
+ */
3355
+ const localStorageProvider = {
3356
+ // Here we must use a factory that return directly the value, otherwise it will
3357
+ // crash when running on server because the value does not exist (but the factory will
3358
+ // never actually be called on server, so the server will not see the missing value)
3359
+ provide: LOCAL_STORAGE,
3360
+ useFactory: localStorageFactory,
3361
+ };
3362
+ /**
3363
+ * Provide in-memory local storage to be used only in tests or SSR
3364
+ */
3365
+ const memoryLocalStorageProvider = {
3366
+ provide: LOCAL_STORAGE,
3367
+ useClass: NaturalMemoryStorage,
3368
+ };
3369
+
3370
+ const NATURAL_PERSISTENCE_VALIDATOR = new InjectionToken('Validator for persisted value retrieved from NaturalPersistenceService. If returns false, the persisted value will never be returned.');
3371
+ class NaturalPersistenceService {
3372
+ constructor(router, sessionStorage, isValid) {
3373
+ var _a;
3374
+ this.router = router;
3375
+ this.sessionStorage = sessionStorage;
3376
+ this.isValid = isValid;
3377
+ // By default, anything is valid
3378
+ this.isValid = (_a = this.isValid) !== null && _a !== void 0 ? _a : (() => true);
3379
+ }
3380
+ /**
3381
+ * Persist in url and local storage the given value with the given key.
3382
+ * When stored in storage, we need more "key" to identify the controller.
3383
+ */
3384
+ persist(key, value, route, storageKey, navigationExtras) {
3385
+ this.persistInStorage(key, value, storageKey);
3386
+ return this.persistInUrl(key, value, route, navigationExtras);
3387
+ }
3388
+ /**
3389
+ * Return object with persisted data in url or in session storage
3390
+ * Url has priority over session storage because of url sharing. When url is provided, session storage is ignored.
3391
+ * Url and storage are synced when arriving in a component :
3392
+ * - When loading with url parameters, storage is updated to stay synced
3393
+ * - When loading without url, but with storage data, the url is updated
3394
+ */
3395
+ get(key, route, storageKey) {
3396
+ // From url
3397
+ let params = this.getFromUrl(key, route);
3398
+ if (!this.isFalseyValue(params)) {
3399
+ this.persistInStorage(key, params, storageKey);
3400
+ return params;
3401
+ }
3402
+ // From storage
3403
+ params = this.getFromStorage(key, storageKey);
3404
+ if (!this.isFalseyValue(params)) {
3405
+ this.persistInUrl(key, params, route);
3406
+ return params;
3407
+ }
3408
+ return null;
3409
+ }
3410
+ /**
3411
+ * Get given key from the url parameters
3412
+ */
3413
+ getFromUrl(key, route) {
3414
+ const value = route.snapshot.paramMap.get(key);
3415
+ return this.deserialize(key, null, value);
3416
+ }
3417
+ /**
3418
+ * Add/override given pair key-value in the url
3419
+ * Always JSON.stringify() the given value
3420
+ * If the value is falsey, the pair key-value is removed from the url.
3421
+ */
3422
+ persistInUrl(key, value, route, navigationExtras) {
3423
+ const params = clone(route.snapshot.url[route.snapshot.url.length - 1].parameters);
3424
+ if (this.isFalseyValue(value)) {
3425
+ delete params[key];
3426
+ }
3427
+ else {
3428
+ params[key] = JSON.stringify(value);
3429
+ }
3430
+ navigationExtras = Object.assign(navigationExtras || {}, { relativeTo: route });
3431
+ return this.router.navigate(['.', params], navigationExtras);
3432
+ }
3433
+ getFromStorage(key, storageKey) {
3434
+ const value = this.sessionStorage.getItem(this.getStorageKey(key, storageKey));
3435
+ return this.deserialize(key, storageKey, value);
3436
+ }
3437
+ /**
3438
+ * Store value in session storage.
3439
+ * If value is falsy, the entry is removed
3440
+ */
3441
+ persistInStorage(key, value, storageKey) {
3442
+ if (this.isFalseyValue(value)) {
3443
+ this.sessionStorage.removeItem(this.getStorageKey(key, storageKey));
3444
+ }
3445
+ else {
3446
+ this.sessionStorage.setItem(this.getStorageKey(key, storageKey), JSON.stringify(value));
3447
+ }
3448
+ }
3449
+ getStorageKey(key, storageKey) {
3450
+ return storageKey + '-' + key;
3451
+ }
3452
+ // Returns if the given value is falsey
3453
+ // Falsey values are : null, undefined and empty string.
3454
+ // This cause usually the parameter to be removed from url/storage instead of being stored with no value. Url would be polluted.
3455
+ isFalseyValue(value) {
3456
+ return value == null || value === ''; // == means null or undefined;
3457
+ }
3458
+ deserialize(key, storageKey, value) {
3459
+ if (!value) {
3460
+ return null;
3461
+ }
3462
+ let result = null;
3463
+ try {
3464
+ result = JSON.parse(value);
3465
+ }
3466
+ catch (e) {
3467
+ // noop
3468
+ }
3469
+ return this.isValid(key, storageKey, result) ? result : null;
3470
+ }
3471
+ }
3472
+ NaturalPersistenceService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalPersistenceService, deps: [{ token: i2$1.Router }, { token: SESSION_STORAGE }, { token: NATURAL_PERSISTENCE_VALIDATOR, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
3473
+ NaturalPersistenceService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalPersistenceService, providedIn: 'root' });
3474
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalPersistenceService, decorators: [{
3475
+ type: Injectable,
3476
+ args: [{
3477
+ providedIn: 'root',
3478
+ }]
3479
+ }], ctorParameters: function () {
3480
+ return [{ type: i2$1.Router }, { type: undefined, decorators: [{
3481
+ type: Inject,
3482
+ args: [SESSION_STORAGE]
3483
+ }] }, { type: undefined, decorators: [{
3484
+ type: Optional
3485
+ }, {
3486
+ type: Inject,
3487
+ args: [NATURAL_PERSISTENCE_VALIDATOR]
3488
+ }] }];
3489
+ } });
3490
+
3491
+ /**
3492
+ * A NaturalDataSource will connect immediately, in order to know as soon as possible if
3493
+ * we need to show a template at all (as seen in my-ichtus)
3494
+ *
3495
+ * It also allow some extra data manipulation
3496
+ */
3497
+ class NaturalDataSource extends DataSource {
3498
+ constructor(value) {
3499
+ super();
3500
+ this.ngUnsubscribe = new Subject();
3501
+ if (value instanceof Observable) {
3502
+ this.internalData = new BehaviorSubject(null);
3503
+ value.pipe(takeUntil(this.ngUnsubscribe)).subscribe(res => (this.data = res));
3504
+ }
3505
+ else {
3506
+ this.internalData = new BehaviorSubject(value);
3507
+ }
3508
+ }
3509
+ get internalDataObservable() {
3510
+ return this.internalData;
3511
+ }
3512
+ /**
3513
+ * Array of data that should be rendered by the table, where each object represents one row.
3514
+ */
3515
+ get data() {
3516
+ return this.internalData.value;
3517
+ }
3518
+ set data(data) {
3519
+ this.internalData.next(data);
3520
+ }
3521
+ connect() {
3522
+ return this.internalData.pipe(takeUntil(this.ngUnsubscribe), map(data => (data ? data.items : [])));
3523
+ }
3524
+ disconnect() {
3525
+ this.ngUnsubscribe.next(); // unsubscribe everybody
3526
+ this.ngUnsubscribe.complete(); // complete the stream, because we will never emit again
3527
+ }
3528
+ push(item) {
3529
+ if (!this.data) {
3530
+ return;
3531
+ }
3532
+ const fullList = [...this.data.items];
3533
+ fullList.push(item);
3534
+ this.data = Object.assign(Object.assign({}, this.data), { items: fullList, length: fullList.length });
3535
+ }
3536
+ pop() {
3537
+ if (!this.data) {
3538
+ return;
3539
+ }
3540
+ const fullList = [...this.data.items];
3541
+ const removedElement = fullList.pop();
3542
+ this.data = Object.assign(Object.assign({}, this.data), { items: fullList, length: fullList.length });
3543
+ return removedElement;
3544
+ }
3545
+ remove(item) {
3546
+ if (!this.data) {
3547
+ return;
3548
+ }
3549
+ const index = this.data.items.indexOf(item);
3550
+ if (index > -1) {
3551
+ const fullList = [...this.data.items];
3552
+ fullList.splice(index, 1);
3553
+ this.data = Object.assign(Object.assign({}, this.data), { items: fullList, length: fullList.length });
3554
+ }
3555
+ }
3556
+ }
3557
+
3558
+ function unwrapNavigable(item) {
3559
+ if ('item' in item && 'hasNavigation' in item) {
3560
+ return item.item;
3561
+ }
3562
+ return item;
3563
+ }
3564
+ /**
3565
+ * This class helps managing a list of paginated items that can be filtered,
3566
+ * selected, and then bulk actions can be performed on selection.
3567
+ *
3568
+ * Components inheriting from this class can be used as standalone with input attributes.
3569
+ *
3570
+ * Usage :
3571
+ * <natural-my-listing [forcedVariables]="{filter:...}" [selectedColumns]="['col1']" [persistSearch]="false">
3572
+ */
3573
+ // @dynamic
3574
+ class NaturalAbstractList extends NaturalAbstractPanel {
3575
+ constructor(service, injector) {
3576
+ super();
3577
+ this.service = service;
3578
+ this.injector = injector;
3579
+ /**
3580
+ * Wherever search should be loaded from url/storage and persisted in it too.
3581
+ */
3582
+ this.persistSearch = true;
3583
+ /**
3584
+ * Columns list after interaction with <natural-columns-picker>
3585
+ */
3586
+ this.columnsForTable = [];
3587
+ /**
3588
+ * The default column selection that automatically happened after <natural-columns-picker> initialization
3589
+ */
3590
+ this.defaultSelectedColumns = null;
3591
+ /**
3592
+ * Selection for bulk actions
3593
+ */
3594
+ this.selection = new SelectionModel(true, []);
3595
+ /**
3596
+ * Next executed action from bulk menu
3597
+ */
3598
+ this.bulkActionSelected = null;
3599
+ /**
3600
+ * Centralisation of query variables
3601
+ */
3602
+ this.variablesManager = new NaturalQueryVariablesManager();
3603
+ /**
3604
+ * Configuration for natural-search facets
3605
+ */
3606
+ this.naturalSearchFacets = [];
3607
+ /**
3608
+ * Result of a search (can be provided as input for initialisation)
3609
+ */
3610
+ this.naturalSearchSelections = [[]];
3611
+ /**
3612
+ * List of page sizes
3613
+ */
3614
+ this.pageSizeOptions = [5, 10, 25, 50, 100, 200];
3615
+ /**
3616
+ * Initial pagination setup
3617
+ */
3618
+ this.defaultPagination = {
3619
+ offset: null,
3620
+ pageIndex: 0,
3621
+ pageSize: 25,
3622
+ };
3623
+ this.router = injector.get(Router);
3624
+ this.route = injector.get(ActivatedRoute);
3625
+ this.alertService = injector.get(NaturalAlertService);
3626
+ this.persistenceService = injector.get(NaturalPersistenceService);
3627
+ }
3628
+ /**
3629
+ * Variables that are always forced on a list, in addition to whatever the end-user might select
3630
+ */
3631
+ set forcedVariables(variables) {
3632
+ if (variables) {
3633
+ this.applyForcedVariables(variables);
3634
+ }
3635
+ }
3636
+ /**
3637
+ * If change, check DocumentsComponent that overrides this function without calling super.ngOnInit().
3638
+ */
3639
+ ngOnInit() {
3640
+ this.routeData = this.route.snapshot.data;
3641
+ this.initFromRoute();
3642
+ this.initFromPersisted();
3643
+ this.variablesManager.defaults('pagination', { pagination: this.defaultPagination });
3644
+ this.variablesManager.defaults('sorting', { sorting: this.defaultSorting });
3645
+ this.dataSource = new NaturalDataSource(this.getDataObservable());
3646
+ this.selection.clear();
3647
+ // Update natural search when history changes (back/forward buttons)
3648
+ // History state is detectable only on NavigationStart (popstate trigger)
3649
+ // But we need parameters from url after NavigationEnd. So proceed in two steps with a flag.
3650
+ let isPopState = false;
3651
+ this.router.events
3652
+ .pipe(takeUntil(this.ngUnsubscribe), filter(event => event instanceof NavigationStart && event.navigationTrigger === 'popstate'))
3653
+ .subscribe(() => {
3654
+ isPopState = true;
3655
+ });
3656
+ this.router.events
3657
+ .pipe(takeUntil(this.ngUnsubscribe), filter(event => event instanceof NavigationEnd && isPopState))
3658
+ .subscribe(() => {
3659
+ isPopState = false; // reset flag
3660
+ this.naturalSearchSelections = fromUrl(this.persistenceService.getFromUrl('ns', this.route));
3661
+ });
3662
+ }
3663
+ /**
3664
+ * Persist search and then launch whatever is required to refresh the list
3665
+ */
3666
+ search(naturalSearchSelections, navigationExtras, resetPagination = true) {
3667
+ // Reset page index to restart the pagination (preserve pageSize)
3668
+ if (resetPagination) {
3669
+ this.variablesManager.merge('pagination', {
3670
+ pagination: pick(this.defaultPagination, ['offset', 'pageIndex']),
3671
+ });
3672
+ }
3673
+ // Persist if activated
3674
+ // Two parallel navigations conflict. We first persist the search, then the pagination
3675
+ if (this.persistSearch && !this.isPanel) {
3676
+ const promise = this.persistenceService.persist('ns', toUrl(naturalSearchSelections), this.route, this.getStorageKey());
3677
+ const pagination = this.getPagination();
3678
+ this.pagination(pagination, promise, navigationExtras);
3104
3679
  }
3105
3680
  this.translateSearchAndRefreshList(naturalSearchSelections);
3106
3681
  }
@@ -3608,24 +4183,28 @@ class NaturalAbstractModelService {
3608
4183
  /**
3609
4184
  * List of individual fields validators
3610
4185
  */
4186
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3611
4187
  getFormValidators(model) {
3612
4188
  return {};
3613
4189
  }
3614
4190
  /**
3615
4191
  * List of individual async fields validators
3616
4192
  */
4193
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3617
4194
  getFormAsyncValidators(model) {
3618
4195
  return {};
3619
4196
  }
3620
4197
  /**
3621
4198
  * List of grouped fields validators (like password + confirm password)
3622
4199
  */
4200
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3623
4201
  getFormGroupValidators(model) {
3624
4202
  return [];
3625
4203
  }
3626
4204
  /**
3627
4205
  * List of async group fields validators (like unique constraint on multiple columns)
3628
4206
  */
4207
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3629
4208
  getFormGroupAsyncValidators(model) {
3630
4209
  return [];
3631
4210
  }
@@ -4018,6 +4597,7 @@ class NaturalAbstractModelService {
4018
4597
  *
4019
4598
  * This is typically a site or state ID
4020
4599
  */
4600
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4021
4601
  getPartialVariablesForCreation(object) {
4022
4602
  return {};
4023
4603
  }
@@ -4026,6 +4606,7 @@ class NaturalAbstractModelService {
4026
4606
  *
4027
4607
  * This is typically a site or state ID
4028
4608
  */
4609
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4029
4610
  getPartialVariablesForUpdate(object) {
4030
4611
  return {};
4031
4612
  }
@@ -4034,6 +4615,7 @@ class NaturalAbstractModelService {
4034
4615
  *
4035
4616
  * This is typically a site or state ID
4036
4617
  */
4618
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4037
4619
  getPartialVariablesForDelete(objects) {
4038
4620
  return {};
4039
4621
  }
@@ -4240,14 +4822,14 @@ class NaturalEnumService {
4240
4822
  }));
4241
4823
  }
4242
4824
  }
4243
- NaturalEnumService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalEnumService, deps: [{ token: i1$1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
4825
+ NaturalEnumService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalEnumService, deps: [{ token: i1$5.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
4244
4826
  NaturalEnumService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalEnumService, providedIn: 'root' });
4245
4827
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalEnumService, decorators: [{
4246
4828
  type: Injectable,
4247
4829
  args: [{
4248
4830
  providedIn: 'root',
4249
4831
  }]
4250
- }], ctorParameters: function () { return [{ type: i1$1.Apollo }]; } });
4832
+ }], ctorParameters: function () { return [{ type: i1$5.Apollo }]; } });
4251
4833
 
4252
4834
  /**
4253
4835
  * Query to get list of mutations
@@ -4386,14 +4968,14 @@ class NaturalLinkMutationService {
4386
4968
  }`;
4387
4969
  }
4388
4970
  }
4389
- NaturalLinkMutationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalLinkMutationService, deps: [{ token: i1$1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
4971
+ NaturalLinkMutationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalLinkMutationService, deps: [{ token: i1$5.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
4390
4972
  NaturalLinkMutationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalLinkMutationService, providedIn: 'root' });
4391
4973
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalLinkMutationService, decorators: [{
4392
4974
  type: Injectable,
4393
4975
  args: [{
4394
4976
  providedIn: 'root',
4395
4977
  }]
4396
- }], ctorParameters: function () { return [{ type: i1$1.Apollo }]; } });
4978
+ }], ctorParameters: function () { return [{ type: i1$5.Apollo }]; } });
4397
4979
 
4398
4980
  const patterns = [
4399
4981
  /^(?<day>\d{1,2})\.(?<month>\d{1,2})\.(?<year>\d{4}|\d{2})$/,
@@ -4567,13 +5149,13 @@ class NaturalIconComponent {
4567
5149
  }
4568
5150
  }
4569
5151
  }
4570
- NaturalIconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalIconComponent, deps: [{ token: i1$2.MatIconRegistry }, { token: i2$2.DomSanitizer }, { token: IconsConfigService }], target: i0.ɵɵFactoryTarget.Component });
4571
- NaturalIconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalIconComponent, selector: "natural-icon", inputs: { label: "label", labelColor: "labelColor", labelPosition: "labelPosition", name: "name", size: "size" }, host: { properties: { "style.color": "this.fgColor", "class.material-icons": "this.isMaterialIcon", "class.mat-icon": "this.isIcon", "style.min-width.px": "this.width", "style.min-height.px": "this.height", "style.font-size.px": "this.fontSize" } }, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
5152
+ NaturalIconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalIconComponent, deps: [{ token: i1$6.MatIconRegistry }, { token: i2$2.DomSanitizer }, { token: IconsConfigService }], target: i0.ɵɵFactoryTarget.Component });
5153
+ NaturalIconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalIconComponent, selector: "natural-icon", inputs: { label: "label", labelColor: "labelColor", labelPosition: "labelPosition", name: "name", size: "size" }, host: { properties: { "style.color": "this.fgColor", "class.material-icons": "this.isMaterialIcon", "class.mat-icon": "this.isIcon", "style.min-width.px": "this.width", "style.min-height.px": "this.height", "style.font-size.px": "this.fontSize" } }, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1$6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
4572
5154
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalIconComponent, decorators: [{
4573
5155
  type: Component,
4574
5156
  args: [{ selector: 'natural-icon', 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", 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"] }]
4575
5157
  }], ctorParameters: function () {
4576
- return [{ type: i1$2.MatIconRegistry }, { type: i2$2.DomSanitizer }, { type: undefined, decorators: [{
5158
+ return [{ type: i1$6.MatIconRegistry }, { type: i2$2.DomSanitizer }, { type: undefined, decorators: [{
4577
5159
  type: Inject,
4578
5160
  args: [IconsConfigService]
4579
5161
  }] }];
@@ -4670,7 +5252,7 @@ class NaturalColumnsPickerComponent {
4670
5252
  }
4671
5253
  }
4672
5254
  NaturalColumnsPickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalColumnsPickerComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4673
- NaturalColumnsPickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalColumnsPickerComponent, selector: "natural-columns-picker", inputs: { selections: "selections" }, outputs: { selectionChange: "selectionChange" }, queries: [{ propertyName: "availableColumns", predicate: NaturalColumnsPickerColumnDirective }], ngImport: i0, template: "<div>\n <mat-menu #naturalMenu=\"matMenu\">\n <div\n (click)=\"$event.stopPropagation(); column.checked = !column.checked; updateColumns()\"\n *ngFor=\"let column of displayedColumns\"\n class=\"mat-menu-item\"\n >\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"updateColumns()\" [(ngModel)]=\"column.checked\">{{\n column.label\n }}</mat-checkbox>\n </div>\n </mat-menu>\n <button [matMenuTriggerFor]=\"naturalMenu\" mat-icon-button i18n-matTooltip matTooltip=\"S\u00E9lectionner les colonnes\">\n <natural-icon name=\"view_column\"></natural-icon>\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "directive", type: i3$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5255
+ NaturalColumnsPickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalColumnsPickerComponent, selector: "natural-columns-picker", inputs: { selections: "selections" }, outputs: { selectionChange: "selectionChange" }, queries: [{ propertyName: "availableColumns", predicate: NaturalColumnsPickerColumnDirective }], ngImport: i0, template: "<div>\n <mat-menu #naturalMenu=\"matMenu\">\n <div\n (click)=\"$event.stopPropagation(); column.checked = !column.checked; updateColumns()\"\n *ngFor=\"let column of displayedColumns\"\n class=\"mat-menu-item\"\n >\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"updateColumns()\" [(ngModel)]=\"column.checked\">{{\n column.label\n }}</mat-checkbox>\n </div>\n </mat-menu>\n <button [matMenuTriggerFor]=\"naturalMenu\" mat-icon-button i18n-matTooltip matTooltip=\"S\u00E9lectionner les colonnes\">\n <natural-icon name=\"view_column\"></natural-icon>\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "directive", type: i3$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4674
5256
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalColumnsPickerComponent, decorators: [{
4675
5257
  type: Component,
4676
5258
  args: [{ selector: 'natural-columns-picker', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div>\n <mat-menu #naturalMenu=\"matMenu\">\n <div\n (click)=\"$event.stopPropagation(); column.checked = !column.checked; updateColumns()\"\n *ngFor=\"let column of displayedColumns\"\n class=\"mat-menu-item\"\n >\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"updateColumns()\" [(ngModel)]=\"column.checked\">{{\n column.label\n }}</mat-checkbox>\n </div>\n </mat-menu>\n <button [matMenuTriggerFor]=\"naturalMenu\" mat-icon-button i18n-matTooltip matTooltip=\"S\u00E9lectionner les colonnes\">\n <natural-icon name=\"view_column\"></natural-icon>\n </button>\n</div>\n" }]
@@ -4855,14 +5437,14 @@ class NaturalLinkableTabDirective extends NaturalAbstractController {
4855
5437
  return this.component._tabs.toArray().findIndex(tab => fragment === getTabId(tab));
4856
5438
  }
4857
5439
  }
4858
- NaturalLinkableTabDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalLinkableTabDirective, deps: [{ token: i1$4.MatTabGroup }, { token: i2$1.ActivatedRoute }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Directive });
5440
+ NaturalLinkableTabDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalLinkableTabDirective, deps: [{ token: i1$7.MatTabGroup }, { token: i2$1.ActivatedRoute }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Directive });
4859
5441
  NaturalLinkableTabDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.1", type: NaturalLinkableTabDirective, selector: "mat-tab-group[naturalLinkableTab]", inputs: { naturalLinkableTab: "naturalLinkableTab" }, usesInheritance: true, ngImport: i0 });
4860
5442
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalLinkableTabDirective, decorators: [{
4861
5443
  type: Directive,
4862
5444
  args: [{
4863
5445
  selector: 'mat-tab-group[naturalLinkableTab]',
4864
5446
  }]
4865
- }], ctorParameters: function () { return [{ type: i1$4.MatTabGroup }, { type: i2$1.ActivatedRoute }, { type: i2$1.Router }]; }, propDecorators: { naturalLinkableTab: [{
5447
+ }], ctorParameters: function () { return [{ type: i1$7.MatTabGroup }, { type: i2$1.ActivatedRoute }, { type: i2$1.Router }]; }, propDecorators: { naturalLinkableTab: [{
4866
5448
  type: Input
4867
5449
  }] } });
4868
5450
 
@@ -5233,418 +5815,149 @@ class NaturalSeoService {
5233
5815
  value: stripTags(value),
5234
5816
  });
5235
5817
  }
5236
- else {
5237
- this.metaTagService.removeTag(`name="${name}"`);
5238
- }
5239
- }
5240
- /**
5241
- * Returns the data from the most deep/specific activated route
5242
- */
5243
- getRouteData(route) {
5244
- var _a;
5245
- if (route.firstChild) {
5246
- return this.getRouteData(route.firstChild);
5247
- }
5248
- else {
5249
- return (_a = route.data) !== null && _a !== void 0 ? _a : null;
5250
- }
5251
- }
5252
- toBasic(seo) {
5253
- var _a, _b, _c, _d, _e;
5254
- if (!this.routeData) {
5255
- throw new Error('Must have some route data to get basic SEO');
5256
- }
5257
- if (typeof seo === 'function') {
5258
- return seo(this.routeData);
5259
- }
5260
- else if ('resolveKey' in seo) {
5261
- const data = this.routeData[seo.resolveKey];
5262
- if (!data) {
5263
- throw new Error('Could not find resolved data for SEO service with key: ' + seo.resolveKey);
5264
- }
5265
- return {
5266
- title: (_d = (_b = (_a = data.model) === null || _a === void 0 ? void 0 : _a.fullName) !== null && _b !== void 0 ? _b : (_c = data.model) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : '',
5267
- description: (_e = data.model) === null || _e === void 0 ? void 0 : _e.description,
5268
- robots: seo.robots,
5269
- };
5270
- }
5271
- return seo;
5272
- }
5273
- }
5274
- NaturalSeoService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSeoService, deps: [{ token: NATURAL_SEO_CONFIG }, { token: i2$1.Router }, { token: i2$2.Title }, { token: i2$2.Meta }], target: i0.ɵɵFactoryTarget.Injectable });
5275
- NaturalSeoService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSeoService, providedIn: 'root' });
5276
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSeoService, decorators: [{
5277
- type: Injectable,
5278
- args: [{
5279
- providedIn: 'root',
5280
- }]
5281
- }], ctorParameters: function () {
5282
- return [{ type: undefined, decorators: [{
5283
- type: Inject,
5284
- args: [NATURAL_SEO_CONFIG]
5285
- }] }, { type: i2$1.Router }, { type: i2$2.Title }, { type: i2$2.Meta }];
5286
- } });
5287
-
5288
- /*
5289
- * Public API Surface of natural
5290
- */
5291
-
5292
- class NaturalDetailHeaderComponent {
5293
- constructor() {
5294
- /**
5295
- * Must be set to get proper links when used in panels
5296
- */
5297
- this.isPanel = false;
5298
- /**
5299
- * If given will show icon before title
5300
- */
5301
- this.icon = '';
5302
- /**
5303
- * Title shown if model has no name, or empty name.
5304
- *
5305
- * Typically should be the human name for the object type, eg: 'Product'
5306
- */
5307
- this.label = '';
5308
- /**
5309
- * Label of the root of the breadcrumb, defaults to the value of `label`.
5310
- *
5311
- * Typically should be the plural form of the object type, eg: 'Products'
5312
- */
5313
- this.rootLabel = '';
5314
- /**
5315
- * Title shown if model has no id.
5316
- *
5317
- * Typically should be similar to 'New product'.
5318
- */
5319
- this.newLabel = '';
5320
- this.breadcrumbs = [];
5321
- this.listRoute = [];
5322
- }
5323
- getRootLink() {
5324
- return [this.currentBaseUrl || '/'].concat(this.listRoute);
5325
- }
5326
- getLink(id) {
5327
- if (this.link) {
5328
- return this.getRootLink().concat(this.link(id));
5329
- }
5330
- return this.getRootLink().concat([id]);
5331
- }
5332
- }
5333
- NaturalDetailHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5334
- NaturalDetailHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalDetailHeaderComponent, selector: "natural-detail-header", inputs: { currentBaseUrl: "currentBaseUrl", isPanel: "isPanel", icon: "icon", label: "label", rootLabel: "rootLabel", newLabel: "newLabel", model: "model", breadcrumbs: "breadcrumbs", listRoute: "listRoute", listFragment: "listFragment", link: "link" }, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { kind: "component", type: i4.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }] });
5335
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderComponent, decorators: [{
5336
- type: Component,
5337
- args: [{ selector: 'natural-detail-header', 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", 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"] }]
5338
- }], propDecorators: { currentBaseUrl: [{
5339
- type: Input
5340
- }], isPanel: [{
5341
- type: Input
5342
- }], icon: [{
5343
- type: Input
5344
- }], label: [{
5345
- type: Input
5346
- }], rootLabel: [{
5347
- type: Input
5348
- }], newLabel: [{
5349
- type: Input
5350
- }], model: [{
5351
- type: Input
5352
- }], breadcrumbs: [{
5353
- type: Input
5354
- }], listRoute: [{
5355
- type: Input
5356
- }], listFragment: [{
5357
- type: Input
5358
- }], link: [{
5359
- type: Input
5360
- }] } });
5361
-
5362
- class NaturalDetailHeaderModule {
5363
- }
5364
- NaturalDetailHeaderModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
5365
- NaturalDetailHeaderModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderModule, declarations: [NaturalDetailHeaderComponent], imports: [CommonModule, RouterModule, MatButtonModule, NaturalIconModule], exports: [NaturalDetailHeaderComponent] });
5366
- NaturalDetailHeaderModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderModule, imports: [CommonModule, RouterModule, MatButtonModule, NaturalIconModule] });
5367
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderModule, decorators: [{
5368
- type: NgModule,
5369
- args: [{
5370
- declarations: [NaturalDetailHeaderComponent],
5371
- imports: [CommonModule, RouterModule, MatButtonModule, NaturalIconModule],
5372
- exports: [NaturalDetailHeaderComponent],
5373
- }]
5374
- }] });
5375
-
5376
- /*
5377
- * Public API Surface of natural
5378
- */
5379
-
5380
- /**
5381
- * Animations used by the mat-menu component.
5382
- * Animation duration and timing values are based on:
5383
- * https://material.io/guidelines/components/menus.html#menus-usage
5384
- */
5385
- const naturalDropdownAnimations = {
5386
- /**
5387
- * This animation controls the menu panel's entry and exit from the page.
5388
- *
5389
- * When the menu panel is added to the DOM, it scales in and fades in its border.
5390
- *
5391
- * When the menu panel is removed from the DOM, it simply fades out after a brief
5392
- * delay to display the ripple.
5393
- */
5394
- transformMenu: trigger('transformMenu', [
5395
- state('void', style({
5396
- opacity: 0,
5397
- // This starts off from 0.01, instead of 0, because there's an issue in the Angular animations
5398
- // as of 4.2, which causes the animation to be skipped if it starts from 0.
5399
- transform: 'scale(0.01, 0.01)',
5400
- })),
5401
- transition('void => enter', sequence([
5402
- query('.natural-dropdown-container-content', style({ opacity: 0 })),
5403
- animate('100ms linear', style({ opacity: 1, transform: 'scale(1, 0.5)' })),
5404
- group([
5405
- query('.natural-dropdown-container-content', animate('400ms cubic-bezier(0.55, 0, 0.55, 0.2)', style({ opacity: 1 }))),
5406
- animate('300ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ transform: 'scale(1, 1)' })),
5407
- ]),
5408
- ])),
5409
- transition('* => void', animate('150ms 50ms linear', style({ opacity: 0 }))),
5410
- ]),
5411
- /**
5412
- * This animation fades in the background color and content of the menu panel
5413
- * after its containing element is scaled in.
5414
- */
5415
- fadeInItems: trigger('fadeInItems', [
5416
- // TODO(crisbeto): this is inside the `transformMenu`
5417
- // now. Remove next time we do breaking changes.
5418
- state('showing', style({ opacity: 1 })),
5419
- transition('void => *', [style({ opacity: 0 }), animate('400ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)')]),
5420
- ]),
5421
- };
5422
-
5423
- function throwMatDialogContentAlreadyAttachedError() {
5424
- throw Error('Attempting to attach dialog content after content is already attached');
5425
- }
5426
- const NATURAL_DROPDOWN_CONTAINER_DATA = new InjectionToken('NaturalDropdownContainerData');
5427
- class NaturalDropdownContainerComponent extends BasePortalOutlet {
5428
- constructor(elementRef, focusTrapFactory, data) {
5429
- super();
5430
- this.elementRef = elementRef;
5431
- this.focusTrapFactory = focusTrapFactory;
5432
- this.data = data;
5433
- this.closed = new Subject();
5434
- /** Current state of the panel animation. */
5435
- this.panelAnimationState = 'void';
5436
- /** Emits whenever an animation on the menu completes. */
5437
- this.animationDone = new Subject();
5438
- this.focusTrap = null;
5439
- this.elementFocusedBeforeDialogWasOpened = null;
5440
- }
5441
- ngOnDestroy() {
5442
- this.closed.complete();
5443
- }
5444
- close() {
5445
- this.closed.next();
5446
- }
5447
- attachTemplatePortal(portal) {
5448
- return this.portalOutlet.attachTemplatePortal(portal);
5449
- }
5450
- attachComponentPortal(portal) {
5451
- if (this.portalOutlet.hasAttached()) {
5452
- throwMatDialogContentAlreadyAttachedError();
5453
- }
5454
- return this.portalOutlet.attachComponentPortal(portal);
5455
- }
5456
- startAnimation() {
5457
- this.panelAnimationState = 'enter';
5818
+ else {
5819
+ this.metaTagService.removeTag(`name="${name}"`);
5820
+ }
5458
5821
  }
5459
- onAnimationDone(event) {
5460
- if (event.toState === 'enter') {
5461
- this.trapFocus();
5822
+ /**
5823
+ * Returns the data from the most deep/specific activated route
5824
+ */
5825
+ getRouteData(route) {
5826
+ var _a;
5827
+ if (route.firstChild) {
5828
+ return this.getRouteData(route.firstChild);
5462
5829
  }
5463
- else if (event.toState === 'exit') {
5464
- this.restoreFocus();
5830
+ else {
5831
+ return (_a = route.data) !== null && _a !== void 0 ? _a : null;
5465
5832
  }
5466
- this.animationDone.next();
5467
5833
  }
5468
- trapFocus() {
5469
- if (!this.focusTrap) {
5470
- this.focusTrap = this.focusTrapFactory.create(this.elementRef.nativeElement);
5834
+ toBasic(seo) {
5835
+ var _a, _b, _c, _d, _e;
5836
+ if (!this.routeData) {
5837
+ throw new Error('Must have some route data to get basic SEO');
5471
5838
  }
5472
- this.focusTrap.focusInitialElementWhenReady();
5473
- }
5474
- /** Restores focus to the element that was focused before the dialog opened. */
5475
- restoreFocus() {
5476
- const toFocus = this.elementFocusedBeforeDialogWasOpened;
5477
- // We need the extra check, because IE can set the `activeElement` to null in some cases.
5478
- if (toFocus && typeof toFocus.focus === 'function') {
5479
- toFocus.focus();
5839
+ if (typeof seo === 'function') {
5840
+ return seo(this.routeData);
5480
5841
  }
5481
- if (this.focusTrap) {
5482
- this.focusTrap.destroy();
5842
+ else if ('resolveKey' in seo) {
5843
+ const data = this.routeData[seo.resolveKey];
5844
+ if (!data) {
5845
+ throw new Error('Could not find resolved data for SEO service with key: ' + seo.resolveKey);
5846
+ }
5847
+ return {
5848
+ title: (_d = (_b = (_a = data.model) === null || _a === void 0 ? void 0 : _a.fullName) !== null && _b !== void 0 ? _b : (_c = data.model) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : '',
5849
+ description: (_e = data.model) === null || _e === void 0 ? void 0 : _e.description,
5850
+ robots: seo.robots,
5851
+ };
5483
5852
  }
5853
+ return seo;
5484
5854
  }
5485
5855
  }
5486
- NaturalDropdownContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownContainerComponent, deps: [{ token: i0.ElementRef }, { token: i1$5.ConfigurableFocusTrapFactory }, { token: NATURAL_DROPDOWN_CONTAINER_DATA }], target: i0.ɵɵFactoryTarget.Component });
5487
- NaturalDropdownContainerComponentcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalDropdownContainerComponent, selector: "ng-component", viewQueries: [{ propertyName: "portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, static: true }, { propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div\n (@transformMenu.done)=\"onAnimationDone($event)\"\n [@transformMenu]=\"panelAnimationState\"\n class=\"natural-dropdown-container mat-elevation-z2\"\n role=\"menu\"\n tabindex=\"-1\"\n>\n <div class=\"natural-dropdown-container-content\">\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n\n <div *ngIf=\"data.showValidateButton\" class=\"natural-dropdown-validate-button\">\n <button (click)=\"close()\" color=\"primary\" mat-raised-button i18n>Valider</button>\n </div>\n</div>\n", 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"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], animations: [naturalDropdownAnimations.transformMenu, naturalDropdownAnimations.fadeInItems], encapsulation: i0.ViewEncapsulation.None });
5488
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownContainerComponent, decorators: [{
5489
- type: Component,
5490
- args: [{ encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, animations: [naturalDropdownAnimations.transformMenu, naturalDropdownAnimations.fadeInItems], template: "<div\n (@transformMenu.done)=\"onAnimationDone($event)\"\n [@transformMenu]=\"panelAnimationState\"\n class=\"natural-dropdown-container mat-elevation-z2\"\n role=\"menu\"\n tabindex=\"-1\"\n>\n <div class=\"natural-dropdown-container-content\">\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n\n <div *ngIf=\"data.showValidateButton\" class=\"natural-dropdown-validate-button\">\n <button (click)=\"close()\" color=\"primary\" mat-raised-button i18n>Valider</button>\n </div>\n</div>\n", 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"] }]
5856
+ NaturalSeoService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSeoService, deps: [{ token: NATURAL_SEO_CONFIG }, { token: i2$1.Router }, { token: i2$2.Title }, { token: i2$2.Meta }], target: i0.ɵɵFactoryTarget.Injectable });
5857
+ NaturalSeoServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSeoService, providedIn: 'root' });
5858
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSeoService, decorators: [{
5859
+ type: Injectable,
5860
+ args: [{
5861
+ providedIn: 'root',
5862
+ }]
5491
5863
  }], ctorParameters: function () {
5492
- return [{ type: i0.ElementRef }, { type: i1$5.ConfigurableFocusTrapFactory }, { type: undefined, decorators: [{
5864
+ return [{ type: undefined, decorators: [{
5493
5865
  type: Inject,
5494
- args: [NATURAL_DROPDOWN_CONTAINER_DATA]
5495
- }] }];
5496
- }, propDecorators: { portalOutlet: [{
5497
- type: ViewChild,
5498
- args: [CdkPortalOutlet, { static: true }]
5499
- }], templateRef: [{
5500
- type: ViewChild,
5501
- args: [TemplateRef, { static: true }]
5502
- }] } });
5866
+ args: [NATURAL_SEO_CONFIG]
5867
+ }] }, { type: i2$1.Router }, { type: i2$2.Title }, { type: i2$2.Meta }];
5868
+ } });
5503
5869
 
5504
- class NaturalDropdownRef {
5505
- constructor(dropdownContainer, component, customProviders, parentInjector, containerRef) {
5506
- this.dropdownContainer = dropdownContainer;
5507
- this.closed = new Subject();
5508
- // Customize injector to allow data and dropdown reference injection in component
5509
- customProviders.push({ provide: NaturalDropdownRef, useValue: this });
5510
- const customInjector = Injector.create({ providers: customProviders, parent: parentInjector });
5511
- // Content (type component given in configuration)
5512
- const componentPortal = new ComponentPortal(component, undefined, customInjector);
5513
- const contentRef = containerRef.instance.attachComponentPortal(componentPortal);
5514
- this.componentInstance = contentRef.instance;
5515
- }
5516
- close(result) {
5517
- this.closed.next(result);
5518
- this.closed.complete();
5519
- this.dropdownContainer.close();
5520
- }
5521
- }
5870
+ /*
5871
+ * Public API Surface of natural
5872
+ */
5522
5873
 
5523
- const NATURAL_DROPDOWN_DATA = new InjectionToken('NaturalDropdownData');
5524
- class NaturalDropdownService {
5525
- constructor(overlay, injector) {
5526
- this.overlay = overlay;
5527
- this.injector = injector;
5528
- }
5529
- open(component, connectedElement, customProviders, showValidateButton) {
5530
- // Container data
5531
- const containerData = {
5532
- showValidateButton: showValidateButton,
5533
- };
5534
- const injectionTokens = [
5535
- {
5536
- provide: NATURAL_DROPDOWN_CONTAINER_DATA,
5537
- useValue: containerData,
5538
- },
5539
- ];
5540
- const containerInjector = Injector.create({ providers: injectionTokens, parent: this.injector });
5541
- // Container
5542
- const overlayRef = this.overlay.create(this.getOverlayConfig(connectedElement));
5543
- const containerPortal = new ComponentPortal(NaturalDropdownContainerComponent, undefined, containerInjector);
5544
- const containerRef = overlayRef.attach(containerPortal);
5545
- const dropdownContainer = containerRef.instance;
5546
- const dropdownRef = new NaturalDropdownRef(dropdownContainer, component, customProviders, this.injector, containerRef);
5547
- // Start animation that shows menu
5548
- dropdownContainer.startAnimation();
5549
- const close = () => {
5550
- if (dropdownRef.componentInstance.isValid() && dropdownRef.componentInstance.isDirty()) {
5551
- dropdownRef.close({
5552
- condition: dropdownRef.componentInstance.getCondition(),
5553
- });
5554
- }
5555
- else {
5556
- dropdownRef.close();
5557
- }
5558
- };
5559
- // When parent closes, remove overlay from dom and update "return" valu
5560
- dropdownContainer.closed.subscribe(() => {
5561
- overlayRef.dispose();
5562
- close();
5563
- });
5564
- // When click on backdrop, validate result.. ?
5565
- overlayRef
5566
- .backdropClick()
5567
- .pipe(takeUntil(dropdownContainer.closed))
5568
- .subscribe(() => dropdownContainer.close());
5569
- return dropdownRef;
5874
+ class NaturalDetailHeaderComponent {
5875
+ constructor() {
5876
+ /**
5877
+ * Must be set to get proper links when used in panels
5878
+ */
5879
+ this.isPanel = false;
5880
+ /**
5881
+ * If given will show icon before title
5882
+ */
5883
+ this.icon = '';
5884
+ /**
5885
+ * Title shown if model has no name, or empty name.
5886
+ *
5887
+ * Typically should be the human name for the object type, eg: 'Product'
5888
+ */
5889
+ this.label = '';
5890
+ /**
5891
+ * Label of the root of the breadcrumb, defaults to the value of `label`.
5892
+ *
5893
+ * Typically should be the plural form of the object type, eg: 'Products'
5894
+ */
5895
+ this.rootLabel = '';
5896
+ /**
5897
+ * Title shown if model has no id.
5898
+ *
5899
+ * Typically should be similar to 'New product'.
5900
+ */
5901
+ this.newLabel = '';
5902
+ this.breadcrumbs = [];
5903
+ this.listRoute = [];
5570
5904
  }
5571
- /**
5572
- * This method builds the configuration object needed to create the overlay, the OverlayState.
5573
- */
5574
- getOverlayConfig(element) {
5575
- return new OverlayConfig({
5576
- positionStrategy: this.getPosition(element),
5577
- hasBackdrop: true,
5578
- backdropClass: 'cdk-overlay-transparent-backdrop',
5579
- });
5905
+ getRootLink() {
5906
+ return [this.currentBaseUrl || '/'].concat(this.listRoute);
5580
5907
  }
5581
- getPosition(element) {
5582
- return this.overlay
5583
- .position()
5584
- .flexibleConnectedTo(element)
5585
- .withFlexibleDimensions(true)
5586
- .withViewportMargin(30)
5587
- .withPush(false)
5588
- .withPositions([
5589
- {
5590
- originX: 'start',
5591
- originY: 'bottom',
5592
- overlayX: 'start',
5593
- overlayY: 'top',
5594
- offsetY: 10,
5595
- },
5596
- ]);
5908
+ getLink(id) {
5909
+ if (this.link) {
5910
+ return this.getRootLink().concat(this.link(id));
5911
+ }
5912
+ return this.getRootLink().concat([id]);
5597
5913
  }
5598
5914
  }
5599
- NaturalDropdownService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownService, deps: [{ token: i1$6.Overlay }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
5600
- NaturalDropdownServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownService, providedIn: 'root' });
5601
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDropdownService, decorators: [{
5602
- type: Injectable,
5603
- args: [{
5604
- providedIn: 'root',
5605
- }]
5606
- }], ctorParameters: function () { return [{ type: i1$6.Overlay }, { type: i0.Injector }]; } });
5607
-
5608
- const possibleComparableOperators = [
5609
- {
5610
- key: 'less',
5611
- label: '<',
5612
- },
5613
- {
5614
- key: 'lessOrEqual',
5615
- label: '≤',
5616
- },
5617
- {
5618
- key: 'equal',
5619
- label: '=',
5620
- },
5621
- {
5622
- key: 'greaterOrEqual',
5623
- label: '≥',
5624
- },
5625
- {
5626
- key: 'greater',
5627
- label: '>',
5628
- },
5629
- ];
5630
- const possibleDiscreteOperators = [
5631
- {
5632
- key: 'is',
5633
- label: $localize `est`,
5634
- },
5635
- {
5636
- key: 'isnot',
5637
- label: $localize `n'est pas`,
5638
- },
5639
- {
5640
- key: 'any',
5641
- label: $localize `tous`,
5642
- },
5643
- {
5644
- key: 'none',
5645
- label: $localize `aucun`,
5646
- },
5647
- ];
5915
+ NaturalDetailHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5916
+ NaturalDetailHeaderComponentcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalDetailHeaderComponent, selector: "natural-detail-header", inputs: { currentBaseUrl: "currentBaseUrl", isPanel: "isPanel", icon: "icon", label: "label", rootLabel: "rootLabel", newLabel: "newLabel", model: "model", breadcrumbs: "breadcrumbs", listRoute: "listRoute", listFragment: "listFragment", link: "link" }, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { kind: "component", type: i4.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }] });
5917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderComponent, decorators: [{
5918
+ type: Component,
5919
+ args: [{ selector: 'natural-detail-header', 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", 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"] }]
5920
+ }], propDecorators: { currentBaseUrl: [{
5921
+ type: Input
5922
+ }], isPanel: [{
5923
+ type: Input
5924
+ }], icon: [{
5925
+ type: Input
5926
+ }], label: [{
5927
+ type: Input
5928
+ }], rootLabel: [{
5929
+ type: Input
5930
+ }], newLabel: [{
5931
+ type: Input
5932
+ }], model: [{
5933
+ type: Input
5934
+ }], breadcrumbs: [{
5935
+ type: Input
5936
+ }], listRoute: [{
5937
+ type: Input
5938
+ }], listFragment: [{
5939
+ type: Input
5940
+ }], link: [{
5941
+ type: Input
5942
+ }] } });
5943
+
5944
+ class NaturalDetailHeaderModule {
5945
+ }
5946
+ NaturalDetailHeaderModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
5947
+ NaturalDetailHeaderModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderModule, declarations: [NaturalDetailHeaderComponent], imports: [CommonModule, RouterModule, MatButtonModule, NaturalIconModule], exports: [NaturalDetailHeaderComponent] });
5948
+ NaturalDetailHeaderModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderModule, imports: [CommonModule, RouterModule, MatButtonModule, NaturalIconModule] });
5949
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDetailHeaderModule, decorators: [{
5950
+ type: NgModule,
5951
+ args: [{
5952
+ declarations: [NaturalDetailHeaderComponent],
5953
+ imports: [CommonModule, RouterModule, MatButtonModule, NaturalIconModule],
5954
+ exports: [NaturalDetailHeaderComponent],
5955
+ }]
5956
+ }] });
5957
+
5958
+ /*
5959
+ * Public API Surface of natural
5960
+ */
5648
5961
 
5649
5962
  class TypeSelectComponent extends NaturalAbstractController {
5650
5963
  constructor(data) {
@@ -5792,7 +6105,7 @@ class TypeSelectComponent extends NaturalAbstractController {
5792
6105
  }
5793
6106
  }
5794
6107
  TypeSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeSelectComponent, deps: [{ token: NATURAL_DROPDOWN_DATA }], target: i0.ɵɵFactoryTarget.Component });
5795
- TypeSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeSelectComponent, selector: "ng-component", viewQueries: [{ propertyName: "list", first: true, predicate: MatSelectionList, descendants: true }], usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\" *ngIf=\"configuration.operators\">\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-selection-list *ngIf=\"requireValueCtrl\" [formControl]=\"valueCtrl\">\n <mat-list-option *ngFor=\"let item of items\" [value]=\"getId(item)\" checkboxPosition=\"before\">\n {{ getDisplay(item) }}\n </mat-list-option>\n </mat-selection-list>\n</form>\n", dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4$3.MatSelectionList, selector: "mat-selection-list", inputs: ["disableRipple", "color", "compareWith", "disabled", "multiple"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: i4$3.MatListOption, selector: "mat-list-option", inputs: ["disableRipple", "checkboxPosition", "color", "value", "disabled", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }, { kind: "component", type: i4$4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$7.MatOption, selector: "mat-option", exportAs: ["matOption"] }] });
6108
+ TypeSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeSelectComponent, selector: "ng-component", viewQueries: [{ propertyName: "list", first: true, predicate: MatSelectionList, descendants: true }], usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\" *ngIf=\"configuration.operators\">\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-selection-list *ngIf=\"requireValueCtrl\" [formControl]=\"valueCtrl\">\n <mat-list-option *ngFor=\"let item of items\" [value]=\"getId(item)\" checkboxPosition=\"before\">\n {{ getDisplay(item) }}\n </mat-list-option>\n </mat-selection-list>\n</form>\n", dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4$4.MatSelectionList, selector: "mat-selection-list", inputs: ["disableRipple", "color", "compareWith", "disabled", "multiple"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: i4$4.MatListOption, selector: "mat-list-option", inputs: ["disableRipple", "checkboxPosition", "color", "value", "disabled", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$4.MatOption, selector: "mat-option", exportAs: ["matOption"] }] });
5796
6109
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeSelectComponent, decorators: [{
5797
6110
  type: Component,
5798
6111
  args: [{ template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\" *ngIf=\"configuration.operators\">\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-selection-list *ngIf=\"requireValueCtrl\" [formControl]=\"valueCtrl\">\n <mat-list-option *ngFor=\"let item of items\" [value]=\"getId(item)\" checkboxPosition=\"before\">\n {{ getDisplay(item) }}\n </mat-list-option>\n </mat-selection-list>\n</form>\n" }]
@@ -5910,7 +6223,7 @@ class ExternalFormControlMatcher extends ErrorStateMatcher {
5910
6223
  super();
5911
6224
  this.component = component;
5912
6225
  }
5913
- isErrorState(control, form) {
6226
+ isErrorState() {
5914
6227
  var _a;
5915
6228
  const externalCtrl = ((_a = this.component.ngControl) === null || _a === void 0 ? void 0 : _a.control) || this.component.internalCtrl;
5916
6229
  if (externalCtrl) {
@@ -6252,7 +6565,7 @@ class NaturalSelectComponent extends AbstractSelect {
6252
6565
  }
6253
6566
  }
6254
6567
  NaturalSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
6255
- NaturalSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectComponent, selector: "natural-select", inputs: { service: "service", optionRequired: "optionRequired", searchField: "searchField", filter: "filter", disabled: "disabled" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "autoTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], usesInheritance: true, ngImport: i0, 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 (click)=\"$event.stopPropagation()\"\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", 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"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$3.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i2$3.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i1$7.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }] });
6568
+ NaturalSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectComponent, selector: "natural-select", inputs: { service: "service", optionRequired: "optionRequired", searchField: "searchField", filter: "filter", disabled: "disabled" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "autoTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], usesInheritance: true, ngImport: i0, 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 (click)=\"$event.stopPropagation()\"\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", 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"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$3.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i2$3.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i1$4.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }] });
6256
6569
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectComponent, decorators: [{
6257
6570
  type: Component,
6258
6571
  args: [{ selector: 'natural-select', 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 (click)=\"$event.stopPropagation()\"\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", 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"] }]
@@ -6297,14 +6610,14 @@ class TypeNaturalSelectComponent extends AbstractAssociationSelectComponent {
6297
6610
  }
6298
6611
  }
6299
6612
  TypeNaturalSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeNaturalSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
6300
- TypeNaturalSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeNaturalSelectComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\">\n <mat-label i18n=\"Mathematical operator < > =\">Op\u00E9rateur</mat-label>\n <mat-select [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 <natural-select\n style=\"display: inline\"\n *ngIf=\"configuration && requireValueCtrl\"\n [formControl]=\"valueCtrl\"\n [placeholder]=\"configuration.placeholder\"\n [service]=\"configuration.service\"\n [filter]=\"configuration.filter\"\n ></natural-select>\n</form>\n", dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4$4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$7.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: NaturalSelectComponent, selector: "natural-select", inputs: ["service", "optionRequired", "searchField", "filter", "disabled"] }] });
6613
+ TypeNaturalSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeNaturalSelectComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\">\n <mat-label i18n=\"Mathematical operator < > =\">Op\u00E9rateur</mat-label>\n <mat-select [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 <natural-select\n style=\"display: inline\"\n *ngIf=\"configuration && requireValueCtrl\"\n [formControl]=\"valueCtrl\"\n [placeholder]=\"configuration.placeholder\"\n [service]=\"configuration.service\"\n [filter]=\"configuration.filter\"\n ></natural-select>\n</form>\n", dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$4.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: NaturalSelectComponent, selector: "natural-select", inputs: ["service", "optionRequired", "searchField", "filter", "disabled"] }] });
6301
6614
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeNaturalSelectComponent, decorators: [{
6302
6615
  type: Component,
6303
6616
  args: [{ template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\">\n <mat-label i18n=\"Mathematical operator < > =\">Op\u00E9rateur</mat-label>\n <mat-select [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 <natural-select\n style=\"display: inline\"\n *ngIf=\"configuration && requireValueCtrl\"\n [formControl]=\"valueCtrl\"\n [placeholder]=\"configuration.placeholder\"\n [service]=\"configuration.service\"\n [filter]=\"configuration.filter\"\n ></natural-select>\n</form>\n" }]
6304
6617
  }] });
6305
6618
 
6306
6619
  class InvalidWithValueStateMatcher$1 {
6307
- isErrorState(control, form) {
6620
+ isErrorState(control) {
6308
6621
  return control && control.invalid && control.value;
6309
6622
  }
6310
6623
  }
@@ -6344,7 +6657,7 @@ class TypeTextComponent {
6344
6657
  }
6345
6658
  }
6346
6659
  TypeTextComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeTextComponent, deps: [{ token: NATURAL_DROPDOWN_DATA }, { token: NaturalDropdownRef }], target: i0.ɵɵFactoryTarget.Component });
6347
- TypeTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeTextComponent, selector: "ng-component", ngImport: i0, 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", styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] });
6660
+ TypeTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeTextComponent, selector: "ng-component", ngImport: i0, 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", styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] });
6348
6661
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeTextComponent, decorators: [{
6349
6662
  type: Component,
6350
6663
  args: [{ 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", styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"] }]
@@ -6440,7 +6753,7 @@ class TypeNumberComponent {
6440
6753
  }
6441
6754
  }
6442
6755
  TypeNumberComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeNumberComponent, deps: [{ token: NATURAL_DROPDOWN_DATA }, { token: NaturalDropdownRef }], target: i0.ɵɵFactoryTarget.Component });
6443
- TypeNumberComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeNumberComponent, selector: "ng-component", ngImport: i0, 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", styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i3.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4$4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$7.MatOption, selector: "mat-option", exportAs: ["matOption"] }] });
6756
+ TypeNumberComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeNumberComponent, selector: "ng-component", ngImport: i0, 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", styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i3.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$4.MatOption, selector: "mat-option", exportAs: ["matOption"] }] });
6444
6757
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeNumberComponent, decorators: [{
6445
6758
  type: Component,
6446
6759
  args: [{ 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", styles: [":host input::-webkit-outer-spin-button,:host input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"] }]
@@ -6752,7 +7065,7 @@ class FacetSelectorComponent {
6752
7065
  }
6753
7066
  }
6754
7067
  FacetSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: FacetSelectorComponent, deps: [{ token: NATURAL_DROPDOWN_DATA }, { token: NaturalDropdownRef }], target: i0.ɵɵFactoryTarget.Component });
6755
- FacetSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: FacetSelectorComponent, selector: "ng-component", ngImport: i0, 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", styles: [":host .mat-nav-list{padding:0}\n"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: i4$3.MatNavList, selector: "mat-nav-list", inputs: ["disableRipple", "disabled"], exportAs: ["matNavList"] }, { kind: "component", type: i4$3.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["disableRipple", "disabled"], exportAs: ["matListItem"] }, { kind: "directive", type: i1$7.MatLine, selector: "[mat-line], [matLine]" }] });
7068
+ FacetSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: FacetSelectorComponent, selector: "ng-component", ngImport: i0, 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", styles: [":host .mat-nav-list{padding:0}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: i4$4.MatNavList, selector: "mat-nav-list", inputs: ["disableRipple", "disabled"], exportAs: ["matNavList"] }, { kind: "component", type: i4$4.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["disableRipple", "disabled"], exportAs: ["matListItem"] }, { kind: "directive", type: i1$4.MatLine, selector: "[mat-line], [matLine]" }] });
6756
7069
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: FacetSelectorComponent, decorators: [{
6757
7070
  type: Component,
6758
7071
  args: [{ 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", styles: [":host .mat-nav-list{padding:0}\n"] }]
@@ -6765,7 +7078,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
6765
7078
 
6766
7079
  // Required to check invalid fields when initializing natural-search
6767
7080
  class AlwaysErrorStateMatcher {
6768
- isErrorState(control, form) {
7081
+ isErrorState(control) {
6769
7082
  return !!control && control.invalid;
6770
7083
  }
6771
7084
  }
@@ -6867,7 +7180,7 @@ class NaturalInputComponent {
6867
7180
  this.dropdownComponentRef.destroy();
6868
7181
  }
6869
7182
  }
6870
- ngOnChanges(changes) {
7183
+ ngOnChanges() {
6871
7184
  if (!this.facets && this.selection) {
6872
7185
  setTimeout(() => this.clear());
6873
7186
  }
@@ -7048,7 +7361,7 @@ class NaturalInputComponent {
7048
7361
  }
7049
7362
  }
7050
7363
  NaturalInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalInputComponent, deps: [{ token: i0.ElementRef }, { token: NaturalDropdownService }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Component });
7051
- NaturalInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalInputComponent, selector: "natural-input", inputs: { placeholder: "placeholder", searchFieldName: "searchFieldName", selection: "selection", facets: "facets" }, outputs: { selectionChange: "selectionChange", cleared: "cleared" }, host: { listeners: { "focus": "focus()" } }, viewQueries: [{ propertyName: "ripple", first: true, predicate: MatRipple, descendants: true, static: true }, { propertyName: "input", first: true, predicate: ["input"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i1$7.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }] });
7364
+ NaturalInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalInputComponent, selector: "natural-input", inputs: { placeholder: "placeholder", searchFieldName: "searchFieldName", selection: "selection", facets: "facets" }, outputs: { selectionChange: "selectionChange", cleared: "cleared" }, host: { listeners: { "focus": "focus()" } }, viewQueries: [{ propertyName: "ripple", first: true, predicate: MatRipple, descendants: true, static: true }, { propertyName: "input", first: true, predicate: ["input"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i1$4.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }] });
7052
7365
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalInputComponent, decorators: [{
7053
7366
  type: Component,
7054
7367
  args: [{ selector: 'natural-input', 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", 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"] }]
@@ -7098,7 +7411,7 @@ class NaturalGroupComponent {
7098
7411
  }
7099
7412
  }
7100
7413
  NaturalGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7101
- NaturalGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalGroupComponent, selector: "natural-group", inputs: { placeholder: "placeholder", facets: "facets", selections: "selections" }, outputs: { selectionChange: "selectionChange" }, viewQueries: [{ propertyName: "newValueInput", first: true, predicate: ["newValueInput"], descendants: true }], ngImport: i0, 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", styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap}:host natural-input{flex:auto;display:inline-flex;margin-right:10px;margin-bottom:10px}:host natural-input:last-of-type{flex:1;min-width:250px}\n"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NaturalInputComponent, selector: "natural-input", inputs: ["placeholder", "searchFieldName", "selection", "facets"], outputs: ["selectionChange", "cleared"] }] });
7414
+ NaturalGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalGroupComponent, selector: "natural-group", inputs: { placeholder: "placeholder", facets: "facets", selections: "selections" }, outputs: { selectionChange: "selectionChange" }, viewQueries: [{ propertyName: "newValueInput", first: true, predicate: ["newValueInput"], descendants: true }], ngImport: i0, 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", styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap}:host natural-input{flex:auto;display:inline-flex;margin-right:10px;margin-bottom:10px}:host natural-input:last-of-type{flex:1;min-width:250px}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NaturalInputComponent, selector: "natural-input", inputs: ["placeholder", "searchFieldName", "selection", "facets"], outputs: ["selectionChange", "cleared"] }] });
7102
7415
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalGroupComponent, decorators: [{
7103
7416
  type: Component,
7104
7417
  args: [{ selector: 'natural-group', 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", styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap}:host natural-input{flex:auto;display:inline-flex;margin-right:10px;margin-bottom:10px}:host natural-input:last-of-type{flex:1;min-width:250px}\n"] }]
@@ -7144,7 +7457,7 @@ class NaturalSearchComponent {
7144
7457
  set selections(selections) {
7145
7458
  this.innerSelections = selections && selections[0] ? deepClone(selections) : [[]];
7146
7459
  }
7147
- ngOnChanges(changes) {
7460
+ ngOnChanges() {
7148
7461
  if (!this.facets) {
7149
7462
  this.facets = [];
7150
7463
  }
@@ -7170,7 +7483,7 @@ class NaturalSearchComponent {
7170
7483
  }
7171
7484
  }
7172
7485
  NaturalSearchComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7173
- NaturalSearchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSearchComponent, selector: "natural-search", inputs: { placeholder: "placeholder", facets: "facets", multipleGroups: "multipleGroups", selections: "selections" }, outputs: { selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"natural-search\">\n <div class=\"groupsWrapper\">\n <ng-container *ngFor=\"let groupSelections of innerSelections; let i = index; let last = last\">\n <div 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 inGroup\">\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 inGroup\">\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 <mat-divider *ngIf=\"!last\"></mat-divider>\n </ng-container>\n </div>\n\n <div class=\"endOfRowButton outOfGroup\">\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", styles: [":host .natural-search{display:flex;flex-direction:row;align-items:flex-end}:host .natural-search .groupsWrapper{display:flex;flex-direction:column;flex:1;min-width:0}:host .natural-search .groupWrapper{display:flex;flex-direction:row;margin-bottom:10px;min-width:0}:host .natural-search .groupWrapper natural-group{flex:1;max-width:100%}: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;margin-bottom:10px}:host .natural-search mat-divider{margin:-10px 10px 10px 0}\n"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "component", type: NaturalGroupComponent, selector: "natural-group", inputs: ["placeholder", "facets", "selections"], outputs: ["selectionChange"] }] });
7486
+ NaturalSearchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSearchComponent, selector: "natural-search", inputs: { placeholder: "placeholder", facets: "facets", multipleGroups: "multipleGroups", selections: "selections" }, outputs: { selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"natural-search\">\n <div class=\"groupsWrapper\">\n <ng-container *ngFor=\"let groupSelections of innerSelections; let i = index; let last = last\">\n <div 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 inGroup\">\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 inGroup\">\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 <mat-divider *ngIf=\"!last\"></mat-divider>\n </ng-container>\n </div>\n\n <div class=\"endOfRowButton outOfGroup\">\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", styles: [":host .natural-search{display:flex;flex-direction:row;align-items:flex-end}:host .natural-search .groupsWrapper{display:flex;flex-direction:column;flex:1;min-width:0}:host .natural-search .groupWrapper{display:flex;flex-direction:row;margin-bottom:10px;min-width:0}:host .natural-search .groupWrapper natural-group{flex:1;max-width:100%}: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;margin-bottom:10px}:host .natural-search mat-divider{margin:-10px 10px 10px 0}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "component", type: NaturalGroupComponent, selector: "natural-group", inputs: ["placeholder", "facets", "selections"], outputs: ["selectionChange"] }] });
7174
7487
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSearchComponent, decorators: [{
7175
7488
  type: Component,
7176
7489
  args: [{ selector: 'natural-search', template: "<div class=\"natural-search\">\n <div class=\"groupsWrapper\">\n <ng-container *ngFor=\"let groupSelections of innerSelections; let i = index; let last = last\">\n <div 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 inGroup\">\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 inGroup\">\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 <mat-divider *ngIf=\"!last\"></mat-divider>\n </ng-container>\n </div>\n\n <div class=\"endOfRowButton outOfGroup\">\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", styles: [":host .natural-search{display:flex;flex-direction:row;align-items:flex-end}:host .natural-search .groupsWrapper{display:flex;flex-direction:column;flex:1;min-width:0}:host .natural-search .groupWrapper{display:flex;flex-direction:row;margin-bottom:10px;min-width:0}:host .natural-search .groupWrapper natural-group{flex:1;max-width:100%}: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;margin-bottom:10px}:host .natural-search mat-divider{margin:-10px 10px 10px 0}\n"] }]
@@ -7504,7 +7817,7 @@ class NaturalHierarchicSelectorComponent extends NaturalAbstractController {
7504
7817
  }
7505
7818
  }
7506
7819
  NaturalHierarchicSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalHierarchicSelectorComponent, deps: [{ token: NaturalHierarchicSelectorService }], target: i0.ɵɵFactoryTarget.Component });
7507
- NaturalHierarchicSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalHierarchicSelectorComponent, selector: "natural-hierarchic-selector", inputs: { displayWith: "displayWith", config: "config", multiple: "multiple", selected: "selected", allowUnselect: "allowUnselect", filters: "filters", searchFacets: "searchFacets", searchSelections: "searchSelections" }, outputs: { searchSelectionChange: "searchSelectionChange", selectionChange: "selectionChange" }, providers: [NaturalHierarchicSelectorService], usesInheritance: true, usesOnChanges: true, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i5$2.MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: i5$2.MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "directive", type: i5$2.MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "component", type: i5$2.MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: i5$2.MatTreeNode, selector: "mat-tree-node", inputs: ["role", "disabled", "tabIndex"], exportAs: ["matTreeNode"] }, { kind: "component", type: i7$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "component", type: i8.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i8.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "directive", type: i8.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: NaturalSearchComponent, selector: "natural-search", inputs: ["placeholder", "facets", "multipleGroups", "selections"], outputs: ["selectionChange"] }] });
7820
+ NaturalHierarchicSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalHierarchicSelectorComponent, selector: "natural-hierarchic-selector", inputs: { displayWith: "displayWith", config: "config", multiple: "multiple", selected: "selected", allowUnselect: "allowUnselect", filters: "filters", searchFacets: "searchFacets", searchSelections: "searchSelections" }, outputs: { searchSelectionChange: "searchSelectionChange", selectionChange: "selectionChange" }, providers: [NaturalHierarchicSelectorService], usesInheritance: true, usesOnChanges: true, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i5$1.MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: i5$1.MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "directive", type: i5$1.MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "component", type: i5$1.MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: i5$1.MatTreeNode, selector: "mat-tree-node", inputs: ["role", "disabled", "tabIndex"], exportAs: ["matTreeNode"] }, { kind: "component", type: i7$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "component", type: i8.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i8.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "directive", type: i8.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: NaturalSearchComponent, selector: "natural-search", inputs: ["placeholder", "facets", "multipleGroups", "selections"], outputs: ["selectionChange"] }] });
7508
7821
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalHierarchicSelectorComponent, decorators: [{
7509
7822
  type: Component,
7510
7823
  args: [{ selector: 'natural-hierarchic-selector', providers: [NaturalHierarchicSelectorService], 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", 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"] }]
@@ -7583,167 +7896,12 @@ class TypeHierarchicSelectorComponent extends AbstractAssociationSelectComponent
7583
7896
  }
7584
7897
  }
7585
7898
  TypeHierarchicSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeHierarchicSelectorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
7586
- TypeHierarchicSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeHierarchicSelectorComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\">\n <mat-label i18n=\"Mathematical operator < > =\">Op\u00E9rateur</mat-label>\n <mat-select [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 <natural-hierarchic-selector\n *ngIf=\"requireValueCtrl\"\n (selectionChange)=\"selectionChange($event)\"\n [config]=\"configuration.config\"\n [filters]=\"configuration.filters\"\n [multiple]=\"true\"\n [selected]=\"valueCtrl.value || {}\"\n style=\"margin-right: 20px\"\n ></natural-hierarchic-selector>\n</form>\n", dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4$4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$7.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: NaturalHierarchicSelectorComponent, selector: "natural-hierarchic-selector", inputs: ["displayWith", "config", "multiple", "selected", "allowUnselect", "filters", "searchFacets", "searchSelections"], outputs: ["searchSelectionChange", "selectionChange"] }] });
7899
+ TypeHierarchicSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeHierarchicSelectorComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\">\n <mat-label i18n=\"Mathematical operator < > =\">Op\u00E9rateur</mat-label>\n <mat-select [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 <natural-hierarchic-selector\n *ngIf=\"requireValueCtrl\"\n (selectionChange)=\"selectionChange($event)\"\n [config]=\"configuration.config\"\n [filters]=\"configuration.filters\"\n [multiple]=\"true\"\n [selected]=\"valueCtrl.value || {}\"\n style=\"margin-right: 20px\"\n ></natural-hierarchic-selector>\n</form>\n", dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$4.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: NaturalHierarchicSelectorComponent, selector: "natural-hierarchic-selector", inputs: ["displayWith", "config", "multiple", "selected", "allowUnselect", "filters", "searchFacets", "searchSelections"], outputs: ["searchSelectionChange", "selectionChange"] }] });
7587
7900
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeHierarchicSelectorComponent, decorators: [{
7588
7901
  type: Component,
7589
7902
  args: [{ template: "<form [formGroup]=\"form\">\n <mat-form-field style=\"max-width: 7em; margin-right: 1em\">\n <mat-label i18n=\"Mathematical operator < > =\">Op\u00E9rateur</mat-label>\n <mat-select [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 <natural-hierarchic-selector\n *ngIf=\"requireValueCtrl\"\n (selectionChange)=\"selectionChange($event)\"\n [config]=\"configuration.config\"\n [filters]=\"configuration.filters\"\n [multiple]=\"true\"\n [selected]=\"valueCtrl.value || {}\"\n style=\"margin-right: 20px\"\n ></natural-hierarchic-selector>\n</form>\n" }]
7590
7903
  }] });
7591
7904
 
7592
- /**
7593
- * Get only date, without time and ignoring entirely the timezone
7594
- */
7595
- function serialize(dateAdapter, value) {
7596
- if (!value) {
7597
- return '';
7598
- }
7599
- const y = dateAdapter.getYear(value);
7600
- const m = dateAdapter.getMonth(value) + 1;
7601
- const d = dateAdapter.getDate(value);
7602
- return y + '-' + (m < 10 ? '0' : '') + m + '-' + (d < 10 ? '0' : '') + d;
7603
- }
7604
- /**
7605
- * Min date validator
7606
- */
7607
- function dateMin(dateAdapter, min) {
7608
- return (control) => {
7609
- if (control.value && dateAdapter.compareDate(control.value, min) < 0) {
7610
- return { min: true };
7611
- }
7612
- return null;
7613
- };
7614
- }
7615
- /**
7616
- * Max date validator
7617
- */
7618
- function dateMax(dateAdapter, max) {
7619
- return (control) => {
7620
- if (control.value && dateAdapter.compareDate(control.value, max) > 0) {
7621
- return { max: true };
7622
- }
7623
- return null;
7624
- };
7625
- }
7626
-
7627
- class TypeDateComponent {
7628
- constructor(data, dateAdapter, dateFormats) {
7629
- this.dateAdapter = dateAdapter;
7630
- this.dateFormats = dateFormats;
7631
- this.renderedValue = new BehaviorSubject('');
7632
- this.operatorCtrl = new FormControl('equal', { nonNullable: true });
7633
- this.valueCtrl = new FormControl(null);
7634
- this.operators = possibleComparableOperators;
7635
- this.form = new FormGroup({
7636
- operator: this.operatorCtrl,
7637
- value: this.valueCtrl,
7638
- });
7639
- this.defaults = {
7640
- min: null,
7641
- max: null,
7642
- };
7643
- this.configuration = Object.assign(Object.assign({}, this.defaults), data.configuration);
7644
- merge$1(this.operatorCtrl.valueChanges, this.valueCtrl.valueChanges).subscribe(() => {
7645
- this.renderedValue.next(this.getRenderedValue());
7646
- });
7647
- this.initValidators();
7648
- this.reloadCondition(data.condition);
7649
- }
7650
- getCondition() {
7651
- if (!this.valueCtrl.value) {
7652
- return {};
7653
- }
7654
- const condition = {};
7655
- let operator = this.operatorCtrl.value;
7656
- let date = this.valueCtrl.value;
7657
- const dayAfter = this.getDayAfter(date);
7658
- if (operator === 'equal') {
7659
- condition.greaterOrEqual = {
7660
- value: serialize(this.dateAdapter, date),
7661
- };
7662
- condition.less = {
7663
- value: serialize(this.dateAdapter, dayAfter),
7664
- };
7665
- }
7666
- else {
7667
- // Transparently adapt exclusive/inclusive ranges
7668
- if (operator === 'greater') {
7669
- operator = 'greaterOrEqual';
7670
- date = dayAfter;
7671
- }
7672
- else if (operator === 'lessOrEqual') {
7673
- operator = 'less';
7674
- date = dayAfter;
7675
- }
7676
- condition[operator] = {
7677
- value: serialize(this.dateAdapter, date),
7678
- };
7679
- }
7680
- return condition;
7681
- }
7682
- isValid() {
7683
- return this.form.valid;
7684
- }
7685
- isDirty() {
7686
- return this.form.dirty;
7687
- }
7688
- reloadCondition(condition) {
7689
- if (!condition) {
7690
- return;
7691
- }
7692
- // Special case for '='
7693
- if (condition.greaterOrEqual && condition.less) {
7694
- this.operatorCtrl.setValue('equal');
7695
- const value = this.dateAdapter.deserialize(condition.greaterOrEqual.value);
7696
- this.valueCtrl.setValue(value);
7697
- return;
7698
- }
7699
- for (const operator of this.operators) {
7700
- const reloadedOperator = condition[operator.key];
7701
- if (reloadedOperator) {
7702
- this.operatorCtrl.setValue(operator.key);
7703
- const value = this.dateAdapter.deserialize(reloadedOperator.value);
7704
- this.valueCtrl.setValue(value);
7705
- }
7706
- }
7707
- }
7708
- initValidators() {
7709
- const validators = [Validators.required];
7710
- if (this.configuration.min) {
7711
- validators.push(dateMin(this.dateAdapter, this.configuration.min));
7712
- }
7713
- if (this.configuration.max) {
7714
- validators.push(dateMax(this.dateAdapter, this.configuration.max));
7715
- }
7716
- this.valueCtrl.setValidators(validators);
7717
- }
7718
- getDayAfter(date) {
7719
- return this.dateAdapter.addCalendarDays(this.dateAdapter.clone(date), 1);
7720
- }
7721
- getRenderedValue() {
7722
- const operator = this.operators.find(v => v.key === this.operatorCtrl.value);
7723
- if (this.valueCtrl.value === null || !operator) {
7724
- return '';
7725
- }
7726
- else {
7727
- const value = this.dateAdapter.format(this.valueCtrl.value, this.dateFormats.display.dateInput);
7728
- return operator.label + ' ' + value;
7729
- }
7730
- }
7731
- }
7732
- TypeDateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeDateComponent, deps: [{ token: NATURAL_DROPDOWN_DATA }, { token: i1$7.DateAdapter }, { token: MAT_DATE_FORMATS }], target: i0.ɵɵFactoryTarget.Component });
7733
- TypeDateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeDateComponent, selector: "ng-component", ngImport: i0, 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>Date</mat-label>\n <input\n [formControl]=\"valueCtrl\"\n [matDatepicker]=\"value\"\n [max]=\"configuration.max\"\n [min]=\"configuration.min\"\n [required]=\"true\"\n matInput\n />\n <mat-datepicker-toggle [for]=\"value\" matSuffix></mat-datepicker-toggle>\n <mat-datepicker #value></mat-datepicker>\n <mat-error>\n <span *ngIf=\"valueCtrl.hasError('min')\">< {{ configuration.min }}</span>\n <span *ngIf=\"valueCtrl.hasError('max')\">> {{ configuration.max }}</span>\n <span *ngIf=\"valueCtrl.hasError('required')\">*</span>\n </mat-error>\n </mat-form-field>\n</form>\n", dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i6.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i6.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i4$4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i1$7.MatOption, selector: "mat-option", exportAs: ["matOption"] }] });
7734
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeDateComponent, decorators: [{
7735
- type: Component,
7736
- args: [{ 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>Date</mat-label>\n <input\n [formControl]=\"valueCtrl\"\n [matDatepicker]=\"value\"\n [max]=\"configuration.max\"\n [min]=\"configuration.min\"\n [required]=\"true\"\n matInput\n />\n <mat-datepicker-toggle [for]=\"value\" matSuffix></mat-datepicker-toggle>\n <mat-datepicker #value></mat-datepicker>\n <mat-error>\n <span *ngIf=\"valueCtrl.hasError('min')\">< {{ configuration.min }}</span>\n <span *ngIf=\"valueCtrl.hasError('max')\">> {{ configuration.max }}</span>\n <span *ngIf=\"valueCtrl.hasError('required')\">*</span>\n </mat-error>\n </mat-form-field>\n</form>\n" }]
7737
- }], ctorParameters: function () {
7738
- return [{ type: undefined, decorators: [{
7739
- type: Inject,
7740
- args: [NATURAL_DROPDOWN_DATA]
7741
- }] }, { type: i1$7.DateAdapter }, { type: undefined, decorators: [{
7742
- type: Inject,
7743
- args: [MAT_DATE_FORMATS]
7744
- }] }];
7745
- } });
7746
-
7747
7905
  class InvalidWithValueStateMatcher {
7748
7906
  isErrorState(control, form) {
7749
7907
  return (form && form.invalid && (form.value.to || form.value.from)) || (control && control.invalid);
@@ -7772,7 +7930,7 @@ function toGreaterThanFrom(dateAdapter) {
7772
7930
  /**
7773
7931
  * Date range with mandatory bounding dates.
7774
7932
  *
7775
- * If you need ooptional bounding date, then use `TypeDateComponent` instead.
7933
+ * If you need optional bounding date, then use `TypeDateComponent` instead.
7776
7934
  */
7777
7935
  class TypeDateRangeComponent {
7778
7936
  constructor(data, dateAdapter, dateFormats) {
@@ -7855,16 +8013,16 @@ class TypeDateRangeComponent {
7855
8013
  }
7856
8014
  }
7857
8015
  }
7858
- TypeDateRangeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeDateRangeComponent, deps: [{ token: NATURAL_DROPDOWN_DATA }, { token: i1$7.DateAdapter }, { token: MAT_DATE_FORMATS }], target: i0.ɵɵFactoryTarget.Component });
7859
- TypeDateRangeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeDateRangeComponent, selector: "ng-component", ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"from\"\n placeholder=\"De\"\n [formControl]=\"fromCtrl\"\n [errorStateMatcher]=\"matcher\"\n [min]=\"configuration.min\"\n [max]=\"configuration.max\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"from\"></mat-datepicker-toggle>\n <mat-datepicker #from></mat-datepicker>\n <mat-error>\n <span *ngIf=\"form.hasError('toGreaterThanFrom')\"\n >{{ render(fromCtrl.value) }} > {{ render(toCtrl.value) }}</span\n >\n <span *ngIf=\"fromCtrl.hasError('min') && !form.hasError('toGreaterThanFrom')\"\n >< {{ configuration.min }}</span\n >\n <span *ngIf=\"fromCtrl.hasError('max') && !form.hasError('toGreaterThanFrom')\"\n >> {{ configuration.max }}</span\n >\n <span *ngIf=\"fromCtrl.hasError('required')\">*</span>\n </mat-error>\n </mat-form-field>\n\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"to\"\n placeholder=\"\u00E0\"\n [formControl]=\"toCtrl\"\n [errorStateMatcher]=\"matcher\"\n [min]=\"configuration.min\"\n [max]=\"configuration.max\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"to\"></mat-datepicker-toggle>\n <mat-datepicker #to></mat-datepicker>\n <mat-error>\n <span *ngIf=\"toCtrl.hasError('min') && !form.hasError('toGreaterThanFrom')\">< {{ configuration.min }}</span>\n <span *ngIf=\"toCtrl.hasError('max') && !form.hasError('toGreaterThanFrom')\">> {{ configuration.max }}</span>\n <span *ngIf=\"toCtrl.hasError('required')\">*</span>\n </mat-error>\n </mat-form-field>\n</form>\n", dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i6.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i6.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }] });
8016
+ TypeDateRangeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeDateRangeComponent, deps: [{ token: NATURAL_DROPDOWN_DATA }, { token: i1$4.DateAdapter }, { token: MAT_DATE_FORMATS }], target: i0.ɵɵFactoryTarget.Component });
8017
+ TypeDateRangeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: TypeDateRangeComponent, selector: "ng-component", ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"from\"\n placeholder=\"De\"\n [formControl]=\"fromCtrl\"\n [errorStateMatcher]=\"matcher\"\n [min]=\"configuration.min\"\n [max]=\"configuration.max\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"from\"></mat-datepicker-toggle>\n <mat-datepicker #from></mat-datepicker>\n <mat-error *ngIf=\"form.hasError('toGreaterThanFrom')\"\n >{{ render(fromCtrl.value) }} > {{ render(toCtrl.value) }}</mat-error\n >\n <mat-error *ngIf=\"fromCtrl.hasError('min') && !form.hasError('toGreaterThanFrom')\"\n >< {{ configuration.min }}</mat-error\n >\n <mat-error *ngIf=\"fromCtrl.hasError('max') && !form.hasError('toGreaterThanFrom')\"\n >> {{ configuration.max }}</mat-error\n >\n <mat-error *ngIf=\"fromCtrl.hasError('required')\">*</mat-error>\n </mat-form-field>\n\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"to\"\n placeholder=\"\u00E0\"\n [formControl]=\"toCtrl\"\n [errorStateMatcher]=\"matcher\"\n [min]=\"configuration.min\"\n [max]=\"configuration.max\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"to\"></mat-datepicker-toggle>\n <mat-datepicker #to></mat-datepicker>\n <mat-error *ngIf=\"toCtrl.hasError('min') && !form.hasError('toGreaterThanFrom')\">\n < {{ configuration.min }}</mat-error\n >\n <mat-error *ngIf=\"toCtrl.hasError('max') && !form.hasError('toGreaterThanFrom')\">\n > {{ configuration.max }}</mat-error\n >\n <mat-error *ngIf=\"toCtrl.hasError('required')\">*</mat-error>\n </mat-form-field>\n</form>\n", dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i7.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i7.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }] });
7860
8018
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: TypeDateRangeComponent, decorators: [{
7861
8019
  type: Component,
7862
- args: [{ template: "<form [formGroup]=\"form\">\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"from\"\n placeholder=\"De\"\n [formControl]=\"fromCtrl\"\n [errorStateMatcher]=\"matcher\"\n [min]=\"configuration.min\"\n [max]=\"configuration.max\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"from\"></mat-datepicker-toggle>\n <mat-datepicker #from></mat-datepicker>\n <mat-error>\n <span *ngIf=\"form.hasError('toGreaterThanFrom')\"\n >{{ render(fromCtrl.value) }} > {{ render(toCtrl.value) }}</span\n >\n <span *ngIf=\"fromCtrl.hasError('min') && !form.hasError('toGreaterThanFrom')\"\n >< {{ configuration.min }}</span\n >\n <span *ngIf=\"fromCtrl.hasError('max') && !form.hasError('toGreaterThanFrom')\"\n >> {{ configuration.max }}</span\n >\n <span *ngIf=\"fromCtrl.hasError('required')\">*</span>\n </mat-error>\n </mat-form-field>\n\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"to\"\n placeholder=\"\u00E0\"\n [formControl]=\"toCtrl\"\n [errorStateMatcher]=\"matcher\"\n [min]=\"configuration.min\"\n [max]=\"configuration.max\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"to\"></mat-datepicker-toggle>\n <mat-datepicker #to></mat-datepicker>\n <mat-error>\n <span *ngIf=\"toCtrl.hasError('min') && !form.hasError('toGreaterThanFrom')\">< {{ configuration.min }}</span>\n <span *ngIf=\"toCtrl.hasError('max') && !form.hasError('toGreaterThanFrom')\">> {{ configuration.max }}</span>\n <span *ngIf=\"toCtrl.hasError('required')\">*</span>\n </mat-error>\n </mat-form-field>\n</form>\n" }]
8020
+ args: [{ template: "<form [formGroup]=\"form\">\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"from\"\n placeholder=\"De\"\n [formControl]=\"fromCtrl\"\n [errorStateMatcher]=\"matcher\"\n [min]=\"configuration.min\"\n [max]=\"configuration.max\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"from\"></mat-datepicker-toggle>\n <mat-datepicker #from></mat-datepicker>\n <mat-error *ngIf=\"form.hasError('toGreaterThanFrom')\"\n >{{ render(fromCtrl.value) }} > {{ render(toCtrl.value) }}</mat-error\n >\n <mat-error *ngIf=\"fromCtrl.hasError('min') && !form.hasError('toGreaterThanFrom')\"\n >< {{ configuration.min }}</mat-error\n >\n <mat-error *ngIf=\"fromCtrl.hasError('max') && !form.hasError('toGreaterThanFrom')\"\n >> {{ configuration.max }}</mat-error\n >\n <mat-error *ngIf=\"fromCtrl.hasError('required')\">*</mat-error>\n </mat-form-field>\n\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"to\"\n placeholder=\"\u00E0\"\n [formControl]=\"toCtrl\"\n [errorStateMatcher]=\"matcher\"\n [min]=\"configuration.min\"\n [max]=\"configuration.max\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"to\"></mat-datepicker-toggle>\n <mat-datepicker #to></mat-datepicker>\n <mat-error *ngIf=\"toCtrl.hasError('min') && !form.hasError('toGreaterThanFrom')\">\n < {{ configuration.min }}</mat-error\n >\n <mat-error *ngIf=\"toCtrl.hasError('max') && !form.hasError('toGreaterThanFrom')\">\n > {{ configuration.max }}</mat-error\n >\n <mat-error *ngIf=\"toCtrl.hasError('required')\">*</mat-error>\n </mat-form-field>\n</form>\n" }]
7863
8021
  }], ctorParameters: function () {
7864
8022
  return [{ type: undefined, decorators: [{
7865
8023
  type: Inject,
7866
8024
  args: [NATURAL_DROPDOWN_DATA]
7867
- }] }, { type: i1$7.DateAdapter }, { type: undefined, decorators: [{
8025
+ }] }, { type: i1$4.DateAdapter }, { type: undefined, decorators: [{
7868
8026
  type: Inject,
7869
8027
  args: [MAT_DATE_FORMATS]
7870
8028
  }] }];
@@ -8141,7 +8299,7 @@ class NaturalSelectHierarchicComponent extends AbstractSelect {
8141
8299
  }
8142
8300
  }
8143
8301
  NaturalSelectHierarchicComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectHierarchicComponent, deps: [{ token: NaturalHierarchicSelectorDialogService }, { token: i3.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
8144
- NaturalSelectHierarchicComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectHierarchicComponent, selector: "natural-select-hierarchic", inputs: { selectLabel: "selectLabel", config: "config", filters: "filters" }, usesInheritance: true, ngImport: i0, 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 (click)=\"$event.stopPropagation()\"\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", 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"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }] });
8302
+ NaturalSelectHierarchicComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectHierarchicComponent, selector: "natural-select-hierarchic", inputs: { selectLabel: "selectLabel", config: "config", filters: "filters" }, usesInheritance: true, ngImport: i0, 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 (click)=\"$event.stopPropagation()\"\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", 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"], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }] });
8145
8303
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectHierarchicComponent, decorators: [{
8146
8304
  type: Component,
8147
8305
  args: [{ selector: 'natural-select-hierarchic', 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 (click)=\"$event.stopPropagation()\"\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", 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"] }]
@@ -8163,7 +8321,6 @@ class NaturalSelectEnumComponent extends AbstractSelect {
8163
8321
  constructor(enumService, ngControl) {
8164
8322
  super(ngControl);
8165
8323
  this.enumService = enumService;
8166
- this.ngControl = ngControl;
8167
8324
  /**
8168
8325
  * Whether the user should be allowed to select multiple options
8169
8326
  */
@@ -8178,7 +8335,7 @@ class NaturalSelectEnumComponent extends AbstractSelect {
8178
8335
  }
8179
8336
  }
8180
8337
  NaturalSelectEnumComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectEnumComponent, deps: [{ token: NaturalEnumService }, { token: i3.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
8181
- NaturalSelectEnumComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectEnumComponent, selector: "natural-select-enum", inputs: { enumName: "enumName", nullLabel: "nullLabel", optionDisabled: "optionDisabled", multiple: "multiple" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{ placeholder }}</mat-label>\n <mat-select\n (selectionChange)=\"propagateValue($event.value)\"\n [formControl]=\"internalCtrl\"\n (blur)=\"touch(); blur.emit()\"\n [errorStateMatcher]=\"matcher\"\n [multiple]=\"multiple\"\n >\n <mat-option *ngIf=\"nullLabel\" [value]=\"null\">{{ nullLabel }}</mat-option>\n <mat-option\n *ngFor=\"let item of items | async\"\n [value]=\"item.value\"\n [disabled]=\"optionDisabled ? optionDisabled(item) : false\"\n >\n {{ item.name | capitalize }}\n </mat-option>\n </mat-select>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error></mat-form-field\n>\n", styles: [":host{display:flex;flex-direction:column}\n"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1$7.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "component", type: i4$4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "pipe", type: NaturalCapitalizePipe, name: "capitalize" }] });
8338
+ NaturalSelectEnumComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectEnumComponent, selector: "natural-select-enum", inputs: { enumName: "enumName", nullLabel: "nullLabel", optionDisabled: "optionDisabled", multiple: "multiple" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{ placeholder }}</mat-label>\n <mat-select\n (selectionChange)=\"propagateValue($event.value)\"\n [formControl]=\"internalCtrl\"\n (blur)=\"touch(); blur.emit()\"\n [errorStateMatcher]=\"matcher\"\n [multiple]=\"multiple\"\n >\n <mat-option *ngIf=\"nullLabel\" [value]=\"null\">{{ nullLabel }}</mat-option>\n <mat-option\n *ngFor=\"let item of items | async\"\n [value]=\"item.value\"\n [disabled]=\"optionDisabled ? optionDisabled(item) : false\"\n >\n {{ item.name | capitalize }}\n </mat-option>\n </mat-select>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error></mat-form-field\n>\n", styles: [":host{display:flex;flex-direction:column}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1$4.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: NaturalCapitalizePipe, name: "capitalize" }] });
8182
8339
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectEnumComponent, decorators: [{
8183
8340
  type: Component,
8184
8341
  args: [{ selector: 'natural-select-enum', template: "<mat-form-field>\n <mat-label>{{ placeholder }}</mat-label>\n <mat-select\n (selectionChange)=\"propagateValue($event.value)\"\n [formControl]=\"internalCtrl\"\n (blur)=\"touch(); blur.emit()\"\n [errorStateMatcher]=\"matcher\"\n [multiple]=\"multiple\"\n >\n <mat-option *ngIf=\"nullLabel\" [value]=\"null\">{{ nullLabel }}</mat-option>\n <mat-option\n *ngFor=\"let item of items | async\"\n [value]=\"item.value\"\n [disabled]=\"optionDisabled ? optionDisabled(item) : false\"\n >\n {{ item.name | capitalize }}\n </mat-option>\n </mat-select>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error></mat-form-field\n>\n", styles: [":host{display:flex;flex-direction:column}\n"] }]
@@ -8507,7 +8664,7 @@ class NaturalAbstractFile extends NaturalAbstractController {
8507
8664
  this.multiple = false;
8508
8665
  /**
8509
8666
  * Comma-separated list of unique file type specifiers. Like the native element
8510
- * it can be a mixed of mime-type and file extensions.
8667
+ * it can be a mix of mime-type and file extensions.
8511
8668
  *
8512
8669
  * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept
8513
8670
  */
@@ -8840,23 +8997,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
8840
8997
 
8841
8998
  // @dynamic
8842
8999
  class FileComponent {
8843
- constructor(naturalFileService, sanitizer, document) {
9000
+ constructor(naturalFileService, alertService, sanitizer, document) {
8844
9001
  this.naturalFileService = naturalFileService;
9002
+ this.alertService = alertService;
8845
9003
  this.sanitizer = sanitizer;
8846
9004
  this.document = document;
8847
9005
  this.height = 250;
8848
9006
  this.action = null;
8849
9007
  this.backgroundSize = 'contain';
8850
9008
  /**
8851
- * Comma separated list of accepted mimetypes
9009
+ * Comma-separated list of unique file type specifiers. Like the native element
9010
+ * it can be a mix of mime-type and file extensions.
9011
+ *
9012
+ * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept
8852
9013
  */
8853
9014
  this.accept = 'image/bmp,image/gif,image/jpeg,image/pjpeg,image/png,image/svg+xml,image/svg,image/webp';
8854
9015
  this.model = null;
8855
9016
  /**
8856
- * If provided, get updated on change
8857
- * Is not used for reading -> use [model]
9017
+ * If provided, its value will get updated when the model changes.
9018
+ * But its value is never read, so if you want to set a value use `[model]` instead.
8858
9019
  */
8859
9020
  this.formCtrl = null;
9021
+ /**
9022
+ * This **must not** be used to mutate the server, because it is very likely it will never be called if the
9023
+ * human navigates away from the page before the upload is finished. Instead, you should use `[uploader]`.
9024
+ */
8860
9025
  this.modelChange = new EventEmitter();
8861
9026
  this.imagePreview = null;
8862
9027
  this.filePreview = null;
@@ -8870,20 +9035,20 @@ class FileComponent {
8870
9035
  }
8871
9036
  }
8872
9037
  upload(file) {
9038
+ var _a, _b;
8873
9039
  this.model = { file: file };
8874
9040
  this.updateImage();
8875
9041
  if (this.formCtrl) {
8876
9042
  this.formCtrl.setValue(this.model);
8877
9043
  }
8878
- if (this.service) {
8879
- this.service.create(this.model).subscribe(result => {
8880
- this.model = result;
8881
- this.modelChange.emit(result);
8882
- });
8883
- }
8884
- else {
9044
+ const observable = (_b = (_a = this.uploader) === null || _a === void 0 ? void 0 : _a.call(this, file).pipe(tap$1(() => this.alertService.info($localize `Mis à jour`)))) !== null && _b !== void 0 ? _b : of(this.model);
9045
+ observable.subscribe(result => {
9046
+ this.model = result;
9047
+ if (this.formCtrl) {
9048
+ this.formCtrl.setValue(this.model);
9049
+ }
8885
9050
  this.modelChange.emit(this.model);
8886
- }
9051
+ });
8887
9052
  }
8888
9053
  getDownloadLink() {
8889
9054
  if (this.action !== 'download') {
@@ -8943,13 +9108,13 @@ class FileComponent {
8943
9108
  return subject.asObservable();
8944
9109
  }
8945
9110
  }
8946
- FileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: FileComponent, deps: [{ token: NaturalFileService }, { token: i2$2.DomSanitizer }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component });
8947
- FileComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: FileComponent, selector: "natural-file", inputs: { height: "height", action: "action", backgroundSize: "backgroundSize", accept: "accept", service: "service", model: "model", formCtrl: "formCtrl" }, outputs: { modelChange: "modelChange" }, host: { properties: { "style.height.px": "this.height" } }, usesOnChanges: true, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i1$7.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "directive", type: NaturalFileDropDirective, selector: ":not([naturalFileSelect])[naturalFileDrop]", outputs: ["fileOver"] }, { kind: "pipe", type: i1$3.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: NaturalCapitalizePipe, name: "capitalize" }] });
9111
+ FileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: FileComponent, deps: [{ token: NaturalFileService }, { token: NaturalAlertService }, { token: i2$2.DomSanitizer }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component });
9112
+ FileComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: FileComponent, selector: "natural-file", inputs: { height: "height", action: "action", backgroundSize: "backgroundSize", accept: "accept", uploader: "uploader", model: "model", formCtrl: "formCtrl" }, outputs: { modelChange: "modelChange" }, host: { properties: { "style.height.px": "this.height" } }, usesOnChanges: true, ngImport: i0, 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", 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"], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i1$4.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "directive", type: NaturalFileDropDirective, selector: ":not([naturalFileSelect])[naturalFileDrop]", outputs: ["fileOver"] }, { kind: "pipe", type: i1$2.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: NaturalCapitalizePipe, name: "capitalize" }] });
8948
9113
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: FileComponent, decorators: [{
8949
9114
  type: Component,
8950
9115
  args: [{ selector: 'natural-file', 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", 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"] }]
8951
9116
  }], ctorParameters: function () {
8952
- return [{ type: NaturalFileService }, { type: i2$2.DomSanitizer }, { type: Document, decorators: [{
9117
+ return [{ type: NaturalFileService }, { type: NaturalAlertService }, { type: i2$2.DomSanitizer }, { type: Document, decorators: [{
8953
9118
  type: Inject,
8954
9119
  args: [DOCUMENT]
8955
9120
  }] }];
@@ -8964,7 +9129,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
8964
9129
  type: Input
8965
9130
  }], accept: [{
8966
9131
  type: Input
8967
- }], service: [{
9132
+ }], uploader: [{
8968
9133
  type: Input
8969
9134
  }], model: [{
8970
9135
  type: Input
@@ -9005,7 +9170,7 @@ NaturalFixedButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.
9005
9170
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalFixedButtonComponent, decorators: [{
9006
9171
  type: Component,
9007
9172
  args: [{ selector: 'natural-fixed-button', 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", styles: [":host{position:fixed!important;z-index:999;bottom:32px;right:32px}\n"] }]
9008
- }], ctorParameters: function () { return []; }, propDecorators: { icon: [{
9173
+ }], propDecorators: { icon: [{
9009
9174
  type: Input
9010
9175
  }], link: [{
9011
9176
  type: Input
@@ -9064,7 +9229,7 @@ class NaturalFixedButtonDetailComponent extends NaturalAbstractController {
9064
9229
  }
9065
9230
  }
9066
9231
  NaturalFixedButtonDetailComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalFixedButtonDetailComponent, deps: [{ token: i2$1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component });
9067
- NaturalFixedButtonDetailComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalFixedButtonDetailComponent, selector: "natural-fixed-button-detail", inputs: { model: "model", form: "form" }, outputs: { create: "create", delete: "delete" }, usesInheritance: true, ngImport: i0, template: "<natural-fixed-button\n (click)=\"clickCreate()\"\n *ngIf=\"isCreation\"\n [disabled]=\"form.disabled\"\n [color]=\"form.valid ? 'accent' : 'warn'\"\n class=\"detail-speed-dial\"\n icon=\"save\"\n></natural-fixed-button>\n\n<natural-fixed-button\n (click)=\"clickDelete()\"\n *ngIf=\"!isCreation && (!model.permissions || model.permissions.delete)\"\n [disabled]=\"form.disabled\"\n class=\"detail-speed-dial\"\n color=\"warn\"\n icon=\"delete_forever\"\n i18n-matTooltip\n matTooltip=\"Supprimer d\u00E9finitivement\"\n matTooltipPosition=\"left\"\n></natural-fixed-button>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NaturalFixedButtonComponent, selector: "natural-fixed-button", inputs: ["icon", "link", "color", "disabled"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
9232
+ NaturalFixedButtonDetailComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalFixedButtonDetailComponent, selector: "natural-fixed-button-detail", inputs: { model: "model", form: "form" }, outputs: { create: "create", delete: "delete" }, usesInheritance: true, ngImport: i0, template: "<natural-fixed-button\n (click)=\"clickCreate()\"\n *ngIf=\"isCreation\"\n [disabled]=\"form.disabled\"\n [color]=\"form.valid ? 'accent' : 'warn'\"\n class=\"detail-speed-dial\"\n icon=\"save\"\n></natural-fixed-button>\n\n<natural-fixed-button\n (click)=\"clickDelete()\"\n *ngIf=\"!isCreation && (!model.permissions || model.permissions.delete)\"\n [disabled]=\"form.disabled\"\n class=\"detail-speed-dial\"\n color=\"warn\"\n icon=\"delete_forever\"\n i18n-matTooltip\n matTooltip=\"Supprimer d\u00E9finitivement\"\n matTooltipPosition=\"left\"\n></natural-fixed-button>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NaturalFixedButtonComponent, selector: "natural-fixed-button", inputs: ["icon", "link", "color", "disabled"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
9068
9233
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalFixedButtonDetailComponent, decorators: [{
9069
9234
  type: Component,
9070
9235
  args: [{ selector: 'natural-fixed-button-detail', template: "<natural-fixed-button\n (click)=\"clickCreate()\"\n *ngIf=\"isCreation\"\n [disabled]=\"form.disabled\"\n [color]=\"form.valid ? 'accent' : 'warn'\"\n class=\"detail-speed-dial\"\n icon=\"save\"\n></natural-fixed-button>\n\n<natural-fixed-button\n (click)=\"clickDelete()\"\n *ngIf=\"!isCreation && (!model.permissions || model.permissions.delete)\"\n [disabled]=\"form.disabled\"\n class=\"detail-speed-dial\"\n color=\"warn\"\n icon=\"delete_forever\"\n i18n-matTooltip\n matTooltip=\"Supprimer d\u00E9finitivement\"\n matTooltipPosition=\"left\"\n></natural-fixed-button>\n" }]
@@ -9291,7 +9456,7 @@ class NaturalPanelsService {
9291
9456
  const originalErrorHandler = this.router.errorHandler;
9292
9457
  // Nullify error handler (will be de-neutralized after route redirection)
9293
9458
  if (config) {
9294
- this.router.errorHandler = () => { };
9459
+ this.router.errorHandler = () => undefined;
9295
9460
  }
9296
9461
  // Navigate to same url + /risk/new Result : /risk/risk/new
9297
9462
  const newUrl = config.map(conf => segmentsToString(conf.route.segments)).join('/');
@@ -9551,7 +9716,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
9551
9716
  * Url fallback matcher to be used instead of `path: '**'` when Panel system
9552
9717
  * is used in the project.
9553
9718
  */
9554
- const fallbackIfNoOpenedPanels = (segments, group, route) => {
9719
+ const fallbackIfNoOpenedPanels = (segments) => {
9555
9720
  if (!NaturalPanelsService.opened) {
9556
9721
  return { consumed: segments };
9557
9722
  }
@@ -9616,7 +9781,7 @@ class NaturalRelationsComponent extends NaturalAbstractController {
9616
9781
  this.disabled = this.disabled || !this.main.permissions.update;
9617
9782
  }
9618
9783
  }
9619
- ngOnChanges(changes) {
9784
+ ngOnChanges() {
9620
9785
  if (this.service) {
9621
9786
  this.queryItems();
9622
9787
  }
@@ -9716,7 +9881,7 @@ class NaturalRelationsComponent extends NaturalAbstractController {
9716
9881
  }
9717
9882
  }
9718
9883
  NaturalRelationsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalRelationsComponent, deps: [{ token: NaturalLinkMutationService }, { token: NaturalHierarchicSelectorDialogService }], target: i0.ɵɵFactoryTarget.Component });
9719
- NaturalRelationsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalRelationsComponent, selector: "natural-relations", inputs: { service: "service", placeholder: "placeholder", autocompleteSelectorFilter: "autocompleteSelectorFilter", displayWith: "displayWith", disabled: "disabled", main: "main", hierarchicSelectorFilters: "hierarchicSelectorFilters", hierarchicSelectorConfig: "hierarchicSelectorConfig", otherName: "otherName", filter: "filter" }, outputs: { selectionChange: "selectionChange" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "select", first: true, predicate: NaturalSelectComponent, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, 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 *ngIf=\"!disabled\"\n (click)=\"removeRelation(element)\"\n [disabled]=\"removing.has(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", 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"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "component", type: i7$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i7$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i7$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i7$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i7$2.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i7$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i7$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i7$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i7$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i7$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: NaturalSelectComponent, selector: "natural-select", inputs: ["service", "optionRequired", "searchField", "filter", "disabled"] }, { kind: "component", type: i9.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
9884
+ NaturalRelationsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalRelationsComponent, selector: "natural-relations", inputs: { service: "service", placeholder: "placeholder", autocompleteSelectorFilter: "autocompleteSelectorFilter", displayWith: "displayWith", disabled: "disabled", main: "main", hierarchicSelectorFilters: "hierarchicSelectorFilters", hierarchicSelectorConfig: "hierarchicSelectorConfig", otherName: "otherName", filter: "filter" }, outputs: { selectionChange: "selectionChange" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "select", first: true, predicate: NaturalSelectComponent, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, 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 *ngIf=\"!disabled\"\n (click)=\"removeRelation(element)\"\n [disabled]=\"removing.has(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", 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"], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "component", type: i7$3.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i7$3.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i7$3.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i7$3.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i7$3.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i7$3.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i7$3.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i7$3.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i7$3.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i7$3.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: NaturalSelectComponent, selector: "natural-select", inputs: ["service", "optionRequired", "searchField", "filter", "disabled"] }, { kind: "component", type: i9.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
9720
9885
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalRelationsComponent, decorators: [{
9721
9886
  type: Component,
9722
9887
  args: [{ selector: 'natural-relations', 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 *ngIf=\"!disabled\"\n (click)=\"removeRelation(element)\"\n [disabled]=\"removing.has(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", 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"] }]
@@ -9797,64 +9962,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
9797
9962
  * Public API Surface of natural
9798
9963
  */
9799
9964
 
9800
- /**
9801
- * Wrap the searched value by `%` SQL wildcard
9802
- *
9803
- * So:
9804
- *
9805
- * {field: 'myFieldName', condition: {like: {value: 'foo'}}}
9806
- *
9807
- * will become
9808
- *
9809
- * {field: 'myFieldName', condition: {like: {value: '%foo%'}}}
9810
- */
9811
- function wrapLike(selection) {
9812
- if (selection.condition.like) {
9813
- selection.condition.like.value = '%' + selection.condition.like.value + '%';
9814
- }
9815
- return selection;
9816
- }
9817
- /**
9818
- * Replace the operator name (usually "like", "in" or "between") with the
9819
- * attribute "field" or "name" defined in the configuration
9820
- *
9821
- * So:
9822
- *
9823
- * {field: 'myFieldName', condition: {in: {values: [1, 2, 3]}}}
9824
- *
9825
- * will become
9826
- *
9827
- * {field: 'myFieldName', condition: {myFieldName: {values: [1, 2, 3]}}}
9828
- */
9829
- function replaceOperatorByField(selection) {
9830
- return replaceOperatorByAttribute(selection, 'field');
9831
- }
9832
- /**
9833
- * Replace the operator name (usually "like", "in" or "between") with the
9834
- * field "name" defined in the configuration
9835
- *
9836
- * So:
9837
- *
9838
- * {field: 'myFieldName', name:'myConfigName', condition: {in: {values: [1, 2, 3]}}}
9839
- *
9840
- * will become
9841
- *
9842
- * {field: 'myFieldName', name:'myConfigName', condition: {myConfigName: {values: [1, 2, 3]}}}
9843
- */
9844
- function replaceOperatorByName(selection) {
9845
- return replaceOperatorByAttribute(selection, 'name');
9846
- }
9847
- function replaceOperatorByAttribute(selection, attribute) {
9848
- const oldOperator = Object.keys(selection.condition)[0];
9849
- const attributeValue = selection[attribute];
9850
- if (!attributeValue) {
9851
- throw new Error('Attribute cannot be empty. Most likely the configuration was wrong');
9852
- }
9853
- selection.condition[attributeValue] = selection.condition[oldOperator];
9854
- delete selection.condition[oldOperator];
9855
- return selection;
9856
- }
9857
-
9858
9965
  /*
9859
9966
  * Public API Surface of natural
9860
9967
  */
@@ -10150,7 +10257,7 @@ class NaturalSidenavContainerComponent {
10150
10257
  }
10151
10258
  }
10152
10259
  NaturalSidenavContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSidenavContainerComponent, deps: [{ token: NaturalSidenavService }], target: i0.ɵɵFactoryTarget.Component });
10153
- NaturalSidenavContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSidenavContainerComponent, selector: "natural-sidenav-container", inputs: { name: "name", position: "position", mobileAutoClose: "mobileAutoClose", minimizedWidth: "minimizedWidth", noScroll: "noScroll" }, host: { properties: { "attr.no-scroll": "this.noScroll" } }, providers: [NaturalSidenavService], viewQueries: [{ propertyName: "menuContainer", first: true, predicate: MatSidenavContainer, descendants: true, static: true }, { propertyName: "menuSidenav", first: true, predicate: MatSidenav, descendants: true, static: true }], ngImport: i0, template: "<mat-sidenav-container (backdropClick)=\"sidenavService.setOpened(false)\">\n <mat-sidenav\n [mode]=\"sidenavService.activeMode\"\n [ngClass]=\"sidenavService.isMinimized ? 'menuMinimized' : ''\"\n [opened]=\"sidenavService.isOpened\"\n [style.min-width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [style.width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [position]=\"position\"\n >\n <ng-content select=\"natural-sidenav\"></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", 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"], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i3$4.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i3$4.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i3$4.MatSidenavContent, selector: "mat-sidenav-content" }] });
10260
+ NaturalSidenavContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSidenavContainerComponent, selector: "natural-sidenav-container", inputs: { name: "name", position: "position", mobileAutoClose: "mobileAutoClose", minimizedWidth: "minimizedWidth", noScroll: "noScroll" }, host: { properties: { "attr.no-scroll": "this.noScroll" } }, providers: [NaturalSidenavService], viewQueries: [{ propertyName: "menuContainer", first: true, predicate: MatSidenavContainer, descendants: true, static: true }, { propertyName: "menuSidenav", first: true, predicate: MatSidenav, descendants: true, static: true }], ngImport: i0, template: "<mat-sidenav-container (backdropClick)=\"sidenavService.setOpened(false)\">\n <mat-sidenav\n [mode]=\"sidenavService.activeMode\"\n [ngClass]=\"sidenavService.isMinimized ? 'menuMinimized' : ''\"\n [opened]=\"sidenavService.isOpened\"\n [style.min-width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [style.width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [position]=\"position\"\n >\n <ng-content select=\"natural-sidenav\"></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", 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"], dependencies: [{ kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i3$4.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i3$4.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i3$4.MatSidenavContent, selector: "mat-sidenav-content" }] });
10154
10261
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSidenavContainerComponent, decorators: [{
10155
10262
  type: Component,
10156
10263
  args: [{ selector: 'natural-sidenav-container', providers: [NaturalSidenavService], template: "<mat-sidenav-container (backdropClick)=\"sidenavService.setOpened(false)\">\n <mat-sidenav\n [mode]=\"sidenavService.activeMode\"\n [ngClass]=\"sidenavService.isMinimized ? 'menuMinimized' : ''\"\n [opened]=\"sidenavService.isOpened\"\n [style.min-width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [style.width.px]=\"sidenavService.isMinimized && minimizedWidth ? minimizedWidth : null\"\n [position]=\"position\"\n >\n <ng-content select=\"natural-sidenav\"></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", 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"] }]
@@ -10176,17 +10283,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
10176
10283
  }] } });
10177
10284
 
10178
10285
  class NaturalSidenavContentComponent {
10179
- constructor() { }
10180
10286
  }
10181
10287
  NaturalSidenavContentComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSidenavContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10182
10288
  NaturalSidenavContentComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSidenavContentComponent, selector: "natural-sidenav-content", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{flex:1;display:flex;flex-direction:column;overflow:auto}\n"] });
10183
10289
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSidenavContentComponent, decorators: [{
10184
10290
  type: Component,
10185
10291
  args: [{ selector: 'natural-sidenav-content', template: '<ng-content></ng-content>', styles: [":host{flex:1;display:flex;flex-direction:column;overflow:auto}\n"] }]
10186
- }], ctorParameters: function () { return []; } });
10292
+ }] });
10187
10293
 
10188
10294
  class NaturalSidenavComponent {
10189
- constructor() { }
10190
10295
  }
10191
10296
  NaturalSidenavComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSidenavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10192
10297
  NaturalSidenavComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSidenavComponent, selector: "natural-sidenav", ngImport: i0, template: '<ng-content></ng-content>', isInline: true });
@@ -10196,7 +10301,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
10196
10301
  selector: 'natural-sidenav',
10197
10302
  template: '<ng-content></ng-content>',
10198
10303
  }]
10199
- }], ctorParameters: function () { return []; } });
10304
+ }] });
10200
10305
 
10201
10306
  class NaturalSidenavModule {
10202
10307
  }
@@ -10227,7 +10332,7 @@ class NaturalStampComponent {
10227
10332
  }
10228
10333
  }
10229
10334
  NaturalStampComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalStampComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10230
- NaturalStampComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalStampComponent, selector: "natural-stamp", inputs: { item: "item" }, ngImport: i0, template: "<ng-container *ngIf=\"item\">\n <div *ngIf=\"item.creationDate || item.creator\">\n <span class=\"mat-body-2\" i18n>Cr\u00E9ation</span>\n :\n <span *ngIf=\"item.creator\">{{ item.creator.fullName || item.creator.name }}</span>\n <span *ngIf=\"item.creator && item.creationDate\">,&nbsp;</span>\n <span *ngIf=\"item.creationDate\">{{ item.creationDate | swissDate }} ({{ item.creationDate | timeAgo }})</span>\n </div>\n\n <div *ngIf=\"showUpdate()\">\n <span class=\"mat-body-2\" i18n>Modification</span>\n :\n <span *ngIf=\"item.updater\">{{ item.updater.fullName || item.updater.name }}</span>\n <span *ngIf=\"item.updater && item.updateDate\">,&nbsp;</span>\n <span *ngIf=\"item.updateDate\">{{ item.updateDate | swissDate }} ({{ item.updateDate | timeAgo }})</span>\n </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: NaturalSwissDatePipe, name: "swissDate" }, { kind: "pipe", type: NaturalTimeAgoPipe, name: "timeAgo" }] });
10335
+ NaturalStampComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalStampComponent, selector: "natural-stamp", inputs: { item: "item" }, ngImport: i0, template: "<ng-container *ngIf=\"item\">\n <div *ngIf=\"item.creationDate || item.creator\">\n <span class=\"mat-body-2\" i18n>Cr\u00E9ation</span>\n :\n <span *ngIf=\"item.creator\">{{ item.creator.fullName || item.creator.name }}</span>\n <span *ngIf=\"item.creator && item.creationDate\">,&nbsp;</span>\n <span *ngIf=\"item.creationDate\">{{ item.creationDate | swissDate }} ({{ item.creationDate | timeAgo }})</span>\n </div>\n\n <div *ngIf=\"showUpdate()\">\n <span class=\"mat-body-2\" i18n>Modification</span>\n :\n <span *ngIf=\"item.updater\">{{ item.updater.fullName || item.updater.name }}</span>\n <span *ngIf=\"item.updater && item.updateDate\">,&nbsp;</span>\n <span *ngIf=\"item.updateDate\">{{ item.updateDate | swissDate }} ({{ item.updateDate | timeAgo }})</span>\n </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: NaturalSwissDatePipe, name: "swissDate" }, { kind: "pipe", type: NaturalTimeAgoPipe, name: "timeAgo" }] });
10231
10336
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalStampComponent, decorators: [{
10232
10337
  type: Component,
10233
10338
  args: [{ selector: 'natural-stamp', template: "<ng-container *ngIf=\"item\">\n <div *ngIf=\"item.creationDate || item.creator\">\n <span class=\"mat-body-2\" i18n>Cr\u00E9ation</span>\n :\n <span *ngIf=\"item.creator\">{{ item.creator.fullName || item.creator.name }}</span>\n <span *ngIf=\"item.creator && item.creationDate\">,&nbsp;</span>\n <span *ngIf=\"item.creationDate\">{{ item.creationDate | swissDate }} ({{ item.creationDate | timeAgo }})</span>\n </div>\n\n <div *ngIf=\"showUpdate()\">\n <span class=\"mat-body-2\" i18n>Modification</span>\n :\n <span *ngIf=\"item.updater\">{{ item.updater.fullName || item.updater.name }}</span>\n <span *ngIf=\"item.updater && item.updateDate\">,&nbsp;</span>\n <span *ngIf=\"item.updateDate\">{{ item.updateDate | swissDate }} ({{ item.updateDate | timeAgo }})</span>\n </div>\n</ng-container>\n" }]
@@ -10274,7 +10379,7 @@ class NaturalTableButtonComponent {
10274
10379
  this.buttonClick = new EventEmitter();
10275
10380
  this.type = 'none';
10276
10381
  }
10277
- ngOnChanges(changes) {
10382
+ ngOnChanges() {
10278
10383
  var _a;
10279
10384
  if (((_a = this.navigate) === null || _a === void 0 ? void 0 : _a.length) || Object.keys(this.queryParams).length) {
10280
10385
  this.type = 'routerLink';
@@ -10291,7 +10396,7 @@ class NaturalTableButtonComponent {
10291
10396
  }
10292
10397
  }
10293
10398
  NaturalTableButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalTableButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10294
- NaturalTableButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalTableButtonComponent, selector: "natural-table-button", inputs: { queryParams: "queryParams", queryParamsHandling: "queryParamsHandling", label: "label", icon: "icon", href: "href", navigate: "navigate", fragment: "fragment", preserveFragment: "preserveFragment", raised: "raised", color: "color" }, outputs: { buttonClick: "buttonClick" }, usesOnChanges: true, ngImport: i0, template: "<!-- Because directives can't be applied conditionally (routerLink, mat-button and mat-icon-button), we have to use different elements -->\n\n<!-- Edge case of a button without any kind of link at all -->\n<span *ngIf=\"type === 'none'\">\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span *ngIf=\"label\">{{ label }}</span>\n</span>\n\n<ng-container *ngIf=\"!raised\">\n <!-- App routed link with label... -->\n <a\n *ngIf=\"type === 'routerLink' && label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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=\"type === 'routerLink' && !label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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 <!-- Click with label... -->\n <a *ngIf=\"type === 'click' && label\" [color]=\"color\" (click)=\"buttonClick.emit($event)\" mat-button>\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a *ngIf=\"type === 'click' && !label\" (click)=\"buttonClick.emit($event)\" mat-icon-button>\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n\n <!-- External link with label... -->\n <a *ngIf=\"type === '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=\"type === '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=\"type === 'routerLink' && label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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=\"type === 'routerLink' && !label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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 <!-- Click with label... -->\n <a *ngIf=\"type === 'click' && label\" [color]=\"color\" (click)=\"buttonClick.emit($event)\" mat-raised-button>\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a\n *ngIf=\"type === 'click' && !label\"\n [color]=\"color\"\n (click)=\"buttonClick.emit($event)\"\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=\"type === '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\n *ngIf=\"type === 'href' && !label\"\n [attr.href]=\"href\"\n [color]=\"color\"\n mat-icon-button\n mat-raised-button\n target=\"_blank\"\n >\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n</ng-container>\n", 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}natural-table-button>span{padding:0 16px}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { kind: "component", type: i4.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }], encapsulation: i0.ViewEncapsulation.None });
10399
+ NaturalTableButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalTableButtonComponent, selector: "natural-table-button", inputs: { queryParams: "queryParams", queryParamsHandling: "queryParamsHandling", label: "label", icon: "icon", href: "href", navigate: "navigate", fragment: "fragment", preserveFragment: "preserveFragment", raised: "raised", color: "color" }, outputs: { buttonClick: "buttonClick" }, usesOnChanges: true, ngImport: i0, template: "<!-- Because directives can't be applied conditionally (routerLink, mat-button and mat-icon-button), we have to use different elements -->\n\n<!-- Edge case of a button without any kind of link at all -->\n<span *ngIf=\"type === 'none'\">\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span *ngIf=\"label\">{{ label }}</span>\n</span>\n\n<ng-container *ngIf=\"!raised\">\n <!-- App routed link with label... -->\n <a\n *ngIf=\"type === 'routerLink' && label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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=\"type === 'routerLink' && !label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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 <!-- Click with label... -->\n <a *ngIf=\"type === 'click' && label\" [color]=\"color\" (click)=\"buttonClick.emit($event)\" mat-button>\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a *ngIf=\"type === 'click' && !label\" (click)=\"buttonClick.emit($event)\" mat-icon-button>\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n\n <!-- External link with label... -->\n <a *ngIf=\"type === '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=\"type === '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=\"type === 'routerLink' && label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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=\"type === 'routerLink' && !label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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 <!-- Click with label... -->\n <a *ngIf=\"type === 'click' && label\" [color]=\"color\" (click)=\"buttonClick.emit($event)\" mat-raised-button>\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a\n *ngIf=\"type === 'click' && !label\"\n [color]=\"color\"\n (click)=\"buttonClick.emit($event)\"\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=\"type === '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\n *ngIf=\"type === 'href' && !label\"\n [attr.href]=\"href\"\n [color]=\"color\"\n mat-icon-button\n mat-raised-button\n target=\"_blank\"\n >\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n</ng-container>\n", 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}natural-table-button>span{padding:0 16px}\n"], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { kind: "component", type: i4.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }], encapsulation: i0.ViewEncapsulation.None });
10295
10400
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalTableButtonComponent, decorators: [{
10296
10401
  type: Component,
10297
10402
  args: [{ selector: 'natural-table-button', encapsulation: ViewEncapsulation.None, template: "<!-- Because directives can't be applied conditionally (routerLink, mat-button and mat-icon-button), we have to use different elements -->\n\n<!-- Edge case of a button without any kind of link at all -->\n<span *ngIf=\"type === 'none'\">\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span *ngIf=\"label\">{{ label }}</span>\n</span>\n\n<ng-container *ngIf=\"!raised\">\n <!-- App routed link with label... -->\n <a\n *ngIf=\"type === 'routerLink' && label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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=\"type === 'routerLink' && !label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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 <!-- Click with label... -->\n <a *ngIf=\"type === 'click' && label\" [color]=\"color\" (click)=\"buttonClick.emit($event)\" mat-button>\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a *ngIf=\"type === 'click' && !label\" (click)=\"buttonClick.emit($event)\" mat-icon-button>\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n\n <!-- External link with label... -->\n <a *ngIf=\"type === '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=\"type === '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=\"type === 'routerLink' && label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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=\"type === 'routerLink' && !label\"\n [color]=\"color\"\n [queryParams]=\"queryParams\"\n [queryParamsHandling]=\"queryParamsHandling\"\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 <!-- Click with label... -->\n <a *ngIf=\"type === 'click' && label\" [color]=\"color\" (click)=\"buttonClick.emit($event)\" mat-raised-button>\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n <span>{{ label }}</span>\n </a>\n\n <!-- ... and without label -->\n <a\n *ngIf=\"type === 'click' && !label\"\n [color]=\"color\"\n (click)=\"buttonClick.emit($event)\"\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=\"type === '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\n *ngIf=\"type === 'href' && !label\"\n [attr.href]=\"href\"\n [color]=\"color\"\n mat-icon-button\n mat-raised-button\n target=\"_blank\"\n >\n <natural-icon *ngIf=\"icon\" [name]=\"icon\"></natural-icon>\n </a>\n</ng-container>\n", 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}natural-table-button>span{padding:0 16px}\n"] }]
@@ -10537,11 +10642,11 @@ function addUnsigned(lX, lY) {
10537
10642
  const lX4 = lX & 0x40000000;
10538
10643
  const lY4 = lY & 0x40000000;
10539
10644
  const lResult = (lX & 0x3fffffff) + (lY & 0x3fffffff);
10540
- if (!!(lX4 & lY4)) {
10645
+ if (lX4 & lY4) {
10541
10646
  return lResult ^ 0x80000000 ^ lX8 ^ lY8;
10542
10647
  }
10543
- if (!!(lX4 | lY4)) {
10544
- if (!!(lResult & 0x40000000)) {
10648
+ if (lX4 | lY4) {
10649
+ if (lResult & 0x40000000) {
10545
10650
  return lResult ^ 0xc0000000 ^ lX8 ^ lY8;
10546
10651
  }
10547
10652
  else {
@@ -10767,7 +10872,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
10767
10872
  args: [{
10768
10873
  providedIn: 'root',
10769
10874
  }]
10770
- }], ctorParameters: function () { return []; } });
10875
+ }] });
10771
10876
 
10772
10877
  /**
10773
10878
  * Show an avatar from different sources
@@ -10905,7 +11010,7 @@ AvatarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", versio
10905
11010
  {{ avatarText }}
10906
11011
  </div>
10907
11012
  </div>
10908
- `, isInline: true, styles: [":host{border-radius:50%}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
11013
+ `, isInline: true, styles: [":host{border-radius:50%}\n"], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
10909
11014
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: AvatarComponent, decorators: [{
10910
11015
  type: Component,
10911
11016
  args: [{ selector: 'natural-avatar', template: `