@ecodev/natural 63.1.0 → 63.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8048,12 +8048,16 @@ class NaturalSearchComponent {
8048
8048
  /**
8049
8049
  * Cleaned inputted selections. Allow valid selections to be manipulated inside component
8050
8050
  */
8051
- innerSelections = [[]];
8051
+ #innerSelections = signal([[]]);
8052
+ /**
8053
+ * Cleaned inputted selections. This public API is useful because `selectionChange` does not emit changes made via `[selections]`
8054
+ */
8055
+ innerSelections = this.#innerSelections.asReadonly();
8052
8056
  /**
8053
8057
  * Input to display at component initialisation
8054
8058
  */
8055
8059
  set selections(selections) {
8056
- this.innerSelections = selections?.[0] ? deepClone(selections) : [[]];
8060
+ this.#innerSelections.set(selections?.[0] ? deepClone(selections) : [[]]);
8057
8061
  }
8058
8062
  isMobile = this.breakpointObserver.observe(Breakpoints.XSmall).pipe(map$1(result => result.matches));
8059
8063
  ngOnChanges() {
@@ -8062,26 +8066,32 @@ class NaturalSearchComponent {
8062
8066
  }
8063
8067
  }
8064
8068
  updateGroup(groupSelections, groupIndex) {
8069
+ const selections = [...this.#innerSelections()];
8065
8070
  for (let i = 0; i < groupSelections.length; i++) {
8066
- this.innerSelections[groupIndex][i] = groupSelections[i];
8071
+ selections[groupIndex][i] = groupSelections[i];
8067
8072
  }
8068
- this.innerSelections[groupIndex].length = groupSelections.length;
8069
- this.selectionChange.emit(this.innerSelections);
8073
+ selections[groupIndex].length = groupSelections.length;
8074
+ this.#notify(selections);
8070
8075
  }
8071
8076
  addGroup() {
8072
- this.innerSelections.push([]);
8073
- this.selectionChange.emit(this.innerSelections);
8077
+ const selections = [...this.#innerSelections()];
8078
+ selections.push([]);
8079
+ this.#notify(selections);
8074
8080
  }
8075
8081
  removeGroup(index) {
8076
- this.innerSelections.splice(index, 1);
8077
- this.selectionChange.emit(this.innerSelections);
8082
+ const selections = [...this.#innerSelections()];
8083
+ selections.splice(index, 1);
8084
+ this.#notify(selections);
8078
8085
  }
8079
8086
  clear() {
8080
- this.innerSelections = [[]];
8081
- this.selectionChange.emit([[]]);
8087
+ this.#notify([[]]);
8088
+ }
8089
+ #notify(selections) {
8090
+ this.#innerSelections.set(selections);
8091
+ this.selectionChange.emit(selections);
8082
8092
  }
8083
8093
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NaturalSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8084
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.6", type: NaturalSearchComponent, isStandalone: true, selector: "natural-search", inputs: { placeholder: "placeholder", facets: "facets", multipleGroups: "multipleGroups", dropdownTitle: "dropdownTitle", selections: "selections" }, outputs: { selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"natural-search\" [ngClass]=\"{mobile: isMobile | async, hasMultipleGroups: innerSelections.length > 1}\">\n <div class=\"groupsWrapper\">\n @for (groupSelections of innerSelections; track $index) {\n <div class=\"groupWrapper\">\n <natural-group\n [facets]=\"facets\"\n [placeholder]=\"placeholder\"\n [selections]=\"groupSelections\"\n [dropdownTitle]=\"dropdownTitle\"\n (selectionChange)=\"updateGroup($event, $index)\"\n />\n <div class=\"endOfRowButton\">\n @if ($count > 1) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Supprimer ce groupe\"\n (click)=\"removeGroup($index)\"\n >\n <mat-icon naturalIcon=\"remove\" />\n </button>\n }\n </div>\n </div>\n @if (!$last) {\n <mat-divider />\n }\n }\n </div>\n\n <div class=\"endOfRowButton\">\n @if (multipleGroups) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"Ajouter un groupe logique OU\" (click)=\"addGroup()\">\n <mat-icon naturalIcon=\"add\" />\n </button>\n }\n\n <button\n mat-icon-button\n class=\"clear-button\"\n i18n-matTooltip\n matTooltip=\"Annuler la recherche\"\n (click)=\"clear()\"\n >\n <mat-icon naturalIcon=\"close\" />\n </button>\n </div>\n</div>\n", styles: [".natural-search{display:flex;flex-direction:row;align-items:flex-end}.natural-search .groupsWrapper{display:flex;flex:1;flex-direction:column;min-width:0}.natural-search .groupWrapper{display:flex;flex-direction:row;margin-bottom:10px;min-width:0}.natural-search .groupWrapper natural-group{flex:1;max-width:100%}.natural-search .groupWrapper:last-of-type{margin-bottom:0}.natural-search .endOfRowButton{display:flex;flex-direction:row;align-items:center;margin-bottom:15px;height:53px}.natural-search mat-divider{margin:-10px 0 10px}.natural-search.mobile .clear-button{display:none}.natural-search.mobile.hasMultipleGroups{flex-direction:column;align-items:stretch}.natural-search.mobile.hasMultipleGroups .endOfRowButton{flex-direction:row-reverse;margin-bottom:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "component", type: NaturalGroupComponent, selector: "natural-group", inputs: ["dropdownTitle", "placeholder", "facets", "selections"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i4$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
8094
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.6", type: NaturalSearchComponent, isStandalone: true, selector: "natural-search", inputs: { placeholder: "placeholder", facets: "facets", multipleGroups: "multipleGroups", dropdownTitle: "dropdownTitle", selections: "selections" }, outputs: { selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"natural-search\" [ngClass]=\"{mobile: isMobile | async, hasMultipleGroups: innerSelections().length > 1}\">\n <div class=\"groupsWrapper\">\n @for (groupSelections of innerSelections(); track $index) {\n <div class=\"groupWrapper\">\n <natural-group\n [facets]=\"facets\"\n [placeholder]=\"placeholder\"\n [selections]=\"groupSelections\"\n [dropdownTitle]=\"dropdownTitle\"\n (selectionChange)=\"updateGroup($event, $index)\"\n />\n <div class=\"endOfRowButton\">\n @if ($count > 1) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Supprimer ce groupe\"\n (click)=\"removeGroup($index)\"\n >\n <mat-icon naturalIcon=\"remove\" />\n </button>\n }\n </div>\n </div>\n @if (!$last) {\n <mat-divider />\n }\n }\n </div>\n\n <div class=\"endOfRowButton\">\n @if (multipleGroups) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"Ajouter un groupe logique OU\" (click)=\"addGroup()\">\n <mat-icon naturalIcon=\"add\" />\n </button>\n }\n\n <button\n mat-icon-button\n class=\"clear-button\"\n i18n-matTooltip\n matTooltip=\"Annuler la recherche\"\n (click)=\"clear()\"\n >\n <mat-icon naturalIcon=\"close\" />\n </button>\n </div>\n</div>\n", styles: [".natural-search{display:flex;flex-direction:row;align-items:flex-end}.natural-search .groupsWrapper{display:flex;flex:1;flex-direction:column;min-width:0}.natural-search .groupWrapper{display:flex;flex-direction:row;margin-bottom:10px;min-width:0}.natural-search .groupWrapper natural-group{flex:1;max-width:100%}.natural-search .groupWrapper:last-of-type{margin-bottom:0}.natural-search .endOfRowButton{display:flex;flex-direction:row;align-items:center;margin-bottom:15px;height:53px}.natural-search mat-divider{margin:-10px 0 10px}.natural-search.mobile .clear-button{display:none}.natural-search.mobile.hasMultipleGroups{flex-direction:column;align-items:stretch}.natural-search.mobile.hasMultipleGroups .endOfRowButton{flex-direction:row-reverse;margin-bottom:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "component", type: NaturalGroupComponent, selector: "natural-group", inputs: ["dropdownTitle", "placeholder", "facets", "selections"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i4$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
8085
8095
  }
8086
8096
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NaturalSearchComponent, decorators: [{
8087
8097
  type: Component,
@@ -8093,7 +8103,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImpor
8093
8103
  MatIconModule,
8094
8104
  NaturalIconDirective,
8095
8105
  MatDividerModule,
8096
- ], template: "<div class=\"natural-search\" [ngClass]=\"{mobile: isMobile | async, hasMultipleGroups: innerSelections.length > 1}\">\n <div class=\"groupsWrapper\">\n @for (groupSelections of innerSelections; track $index) {\n <div class=\"groupWrapper\">\n <natural-group\n [facets]=\"facets\"\n [placeholder]=\"placeholder\"\n [selections]=\"groupSelections\"\n [dropdownTitle]=\"dropdownTitle\"\n (selectionChange)=\"updateGroup($event, $index)\"\n />\n <div class=\"endOfRowButton\">\n @if ($count > 1) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Supprimer ce groupe\"\n (click)=\"removeGroup($index)\"\n >\n <mat-icon naturalIcon=\"remove\" />\n </button>\n }\n </div>\n </div>\n @if (!$last) {\n <mat-divider />\n }\n }\n </div>\n\n <div class=\"endOfRowButton\">\n @if (multipleGroups) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"Ajouter un groupe logique OU\" (click)=\"addGroup()\">\n <mat-icon naturalIcon=\"add\" />\n </button>\n }\n\n <button\n mat-icon-button\n class=\"clear-button\"\n i18n-matTooltip\n matTooltip=\"Annuler la recherche\"\n (click)=\"clear()\"\n >\n <mat-icon naturalIcon=\"close\" />\n </button>\n </div>\n</div>\n", styles: [".natural-search{display:flex;flex-direction:row;align-items:flex-end}.natural-search .groupsWrapper{display:flex;flex:1;flex-direction:column;min-width:0}.natural-search .groupWrapper{display:flex;flex-direction:row;margin-bottom:10px;min-width:0}.natural-search .groupWrapper natural-group{flex:1;max-width:100%}.natural-search .groupWrapper:last-of-type{margin-bottom:0}.natural-search .endOfRowButton{display:flex;flex-direction:row;align-items:center;margin-bottom:15px;height:53px}.natural-search mat-divider{margin:-10px 0 10px}.natural-search.mobile .clear-button{display:none}.natural-search.mobile.hasMultipleGroups{flex-direction:column;align-items:stretch}.natural-search.mobile.hasMultipleGroups .endOfRowButton{flex-direction:row-reverse;margin-bottom:0}\n"] }]
8106
+ ], template: "<div class=\"natural-search\" [ngClass]=\"{mobile: isMobile | async, hasMultipleGroups: innerSelections().length > 1}\">\n <div class=\"groupsWrapper\">\n @for (groupSelections of innerSelections(); track $index) {\n <div class=\"groupWrapper\">\n <natural-group\n [facets]=\"facets\"\n [placeholder]=\"placeholder\"\n [selections]=\"groupSelections\"\n [dropdownTitle]=\"dropdownTitle\"\n (selectionChange)=\"updateGroup($event, $index)\"\n />\n <div class=\"endOfRowButton\">\n @if ($count > 1) {\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Supprimer ce groupe\"\n (click)=\"removeGroup($index)\"\n >\n <mat-icon naturalIcon=\"remove\" />\n </button>\n }\n </div>\n </div>\n @if (!$last) {\n <mat-divider />\n }\n }\n </div>\n\n <div class=\"endOfRowButton\">\n @if (multipleGroups) {\n <button mat-icon-button i18n-matTooltip matTooltip=\"Ajouter un groupe logique OU\" (click)=\"addGroup()\">\n <mat-icon naturalIcon=\"add\" />\n </button>\n }\n\n <button\n mat-icon-button\n class=\"clear-button\"\n i18n-matTooltip\n matTooltip=\"Annuler la recherche\"\n (click)=\"clear()\"\n >\n <mat-icon naturalIcon=\"close\" />\n </button>\n </div>\n</div>\n", styles: [".natural-search{display:flex;flex-direction:row;align-items:flex-end}.natural-search .groupsWrapper{display:flex;flex:1;flex-direction:column;min-width:0}.natural-search .groupWrapper{display:flex;flex-direction:row;margin-bottom:10px;min-width:0}.natural-search .groupWrapper natural-group{flex:1;max-width:100%}.natural-search .groupWrapper:last-of-type{margin-bottom:0}.natural-search .endOfRowButton{display:flex;flex-direction:row;align-items:center;margin-bottom:15px;height:53px}.natural-search mat-divider{margin:-10px 0 10px}.natural-search.mobile .clear-button{display:none}.natural-search.mobile.hasMultipleGroups{flex-direction:column;align-items:stretch}.natural-search.mobile.hasMultipleGroups .endOfRowButton{flex-direction:row-reverse;margin-bottom:0}\n"] }]
8097
8107
  }], propDecorators: { placeholder: [{
8098
8108
  type: Input
8099
8109
  }], facets: [{
@@ -8940,7 +8950,7 @@ class NaturalAbstractFile {
8940
8950
  */
8941
8951
  multiple = false;
8942
8952
  /**
8943
- * Comma-separated list of unique file type specifiers. Like the native element
8953
+ * Comma-separated list of unique file type specifiers. Like the native element,
8944
8954
  * it can be a mix of mime-type and file extensions.
8945
8955
  *
8946
8956
  * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept
@@ -8964,7 +8974,7 @@ class NaturalAbstractFile {
8964
8974
  /**
8965
8975
  * If true, the file selection will be broadcast through `NaturalFileService.filesChanged`.
8966
8976
  *
8967
- * It is useful to set this to false if there is two upload on a page with different purpose
8977
+ * It is useful to set this to false if there are two uploads on a page with different purposes,
8968
8978
  * and the second upload should not be confused with the first one.
8969
8979
  */
8970
8980
  broadcast = true;
@@ -9742,6 +9752,11 @@ class NaturalPanelsService {
9742
9752
  this.updateComponentsPosition();
9743
9753
  });
9744
9754
  }
9755
+ /**
9756
+ * Notify the service to start listening to route changes to open panels
9757
+ *
9758
+ * @internal
9759
+ */
9745
9760
  start(route) {
9746
9761
  NaturalPanelsService._opened = true;
9747
9762
  this.routeSub = route.url.subscribe(segments => {
@@ -9786,6 +9801,11 @@ class NaturalPanelsService {
9786
9801
  const newUrl = config.map(conf => segmentsToString(conf.route.segments)).join('/');
9787
9802
  this.router.navigateByUrl(this.router.url + '/' + newUrl);
9788
9803
  }
9804
+ /**
9805
+ * Notify the service that all panels were closed
9806
+ *
9807
+ * @internal
9808
+ */
9789
9809
  stop() {
9790
9810
  NaturalPanelsService._opened = false;
9791
9811
  this.routeSub?.unsubscribe();
@@ -9796,6 +9816,8 @@ class NaturalPanelsService {
9796
9816
  }
9797
9817
  /**
9798
9818
  * Go to panel matching given component. Causes an url change.
9819
+ *
9820
+ * @internal
9799
9821
  */
9800
9822
  goToPanelByComponent(component) {
9801
9823
  this.goToPanelByIndex(this.getPanelIndex(component));
@@ -9939,6 +9961,13 @@ class NaturalPanelsService {
9939
9961
  }
9940
9962
  return this.dialog.openDialogs.findIndex(dialog => dialog.componentInstance === component);
9941
9963
  }
9964
+ /**
9965
+ * Whether the given panel is currently the top, visible, panel. If there are no panels opened at all, then any panel given is considered top, visible, panel.
9966
+ */
9967
+ isTopPanel(component) {
9968
+ const length = this.dialog.openDialogs.length;
9969
+ return !length || this.dialog.openDialogs[length - 1]?.componentInstance === component;
9970
+ }
9942
9971
  /**
9943
9972
  * Repositions panels from start until given index
9944
9973
  */