@dsivd/prestations-ng 19.2.0-beta.7 → 19.2.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, InjectionToken, model, input, viewChildren, viewChild, forwardRef, output, computed, linkedSignal, DestroyRef, signal, effect, untracked, PendingTasks, Directive, ChangeDetectorRef, Pipe, Component, contentChildren, EnvironmentInjector, runInInjectionContext, afterNextRender, ElementRef, Injector, makeEnvironmentProviders, ErrorHandler, provideBrowserGlobalErrorListeners, provideAppInitializer, importProvidersFrom, NgZone, contentChild, TemplateRef } from '@angular/core';
2
+ import { Injectable, inject, InjectionToken, model, input, viewChildren, viewChild, forwardRef, output, computed, linkedSignal, DestroyRef, signal, effect, untracked, PendingTasks, Directive, ChangeDetectorRef, Pipe, Component, contentChildren, EnvironmentInjector, runInInjectionContext, afterNextRender, ElementRef, Injector, makeEnvironmentProviders, ErrorHandler, provideBrowserGlobalErrorListeners, provideAppInitializer, importProvidersFrom, NgZone, afterRenderEffect, contentChild, TemplateRef } from '@angular/core';
3
3
  import { takeUntilDestroyed, toSignal, toObservable, outputToObservable } from '@angular/core/rxjs-interop';
4
4
  import { Router, ActivatedRoute, RouterLink, NavigationStart, NavigationEnd } from '@angular/router';
5
5
  import { Subject, BehaviorSubject, combineLatest, of, filter as filter$1, tap as tap$1, throwError, switchMap as switchMap$1, forkJoin, from, concatMap, toArray, EMPTY, startWith, merge, noop, interval, withLatestFrom, map as map$1, concat } from 'rxjs';
@@ -1340,6 +1340,7 @@ const DEFAULT_DICTIONARY = {
1340
1340
  'foehn-uploader.delete-error-message': 'Une erreur est survenue lors de la suppression de votre document',
1341
1341
  'foehn-uploader.delete-readonly-error-message': 'Un document en lecture seule ne peut pas être supprimé',
1342
1342
  'foehn-uploader.unknown-error-message': 'Impossible de transmettre le fichier',
1343
+ 'foehn-uploader.pending-label': "en attente d'envoi",
1343
1344
  'foehn-picture-upload.choose-button-label': 'Choisissez une photo',
1344
1345
  'foehn-picture-upload.loading-label': 'Chargement...',
1345
1346
  'foehn-picture-upload.invalid-file-type': 'Le type de votre pièce jointe {filename} ne figure pas parmi ceux qui sont autorisés : "{acceptFormats}"',
@@ -9716,12 +9717,35 @@ class FoehnMultiselectAutocompleteComponent extends FoehnAutocompleteComponent {
9716
9717
  return [...defaultValues, defaultValue];
9717
9718
  }, ...(ngDevMode ? [{ debugName: "defaultElementValuesComputed" }] : /* istanbul ignore next */ []));
9718
9719
  autocompleteInputValue = signal(null, ...(ngDevMode ? [{ debugName: "autocompleteInputValue" }] : /* istanbul ignore next */ []));
9719
- showEmptyListMessage = signal(false, ...(ngDevMode ? [{ debugName: "showEmptyListMessage" }] : /* istanbul ignore next */ []));
9720
+ /**
9721
+ * Every element is selected: a message replaces the autocomplete (not for an empty list of elements).
9722
+ */
9723
+ showEmptyListMessage = computed(() => !this.disabled() &&
9724
+ !!this.elements()?.length &&
9725
+ !this.suggestions().length, ...(ngDevMode ? [{ debugName: "showEmptyListMessage" }] : /* istanbul ignore next */ []));
9720
9726
  srAnnouncements = signal('', ...(ngDevMode ? [{ debugName: "srAnnouncements" }] : /* istanbul ignore next */ []));
9727
+ // The elements which are not selected, proposed by the autocomplete
9728
+ suggestions = computed(() => this.filterAutocompleteElements(this.elements() ?? []), ...(ngDevMode ? [{ debugName: "suggestions" }] : /* istanbul ignore next */ []));
9721
9729
  dictionaryService = inject(SdkDictionaryService);
9722
9730
  srAnnouncementClearTimer = null;
9723
9731
  SR_ANNOUNCEMENT_CLEAR_TIMEOUT_INTERVAL_MS = 2000;
9724
9732
  pendingRemovedIndexForFocus = null;
9733
+ // The suggestions follow the elements and the model, whoever changes them (the user or the project)
9734
+ suggestionsEffect = effect(() => {
9735
+ this.suggestions();
9736
+ this.autocompleteComponent();
9737
+ untracked(() => this.applySuggestionsToAutocomplete());
9738
+ }, ...(ngDevMode ? [{ debugName: "suggestionsEffect" }] : /* istanbul ignore next */ []));
9739
+ // The input is hidden while the message replaces the autocomplete
9740
+ autocompleteInputVisibilityEffect = afterRenderEffect({
9741
+ write: () => {
9742
+ const isHidden = this.showEmptyListMessage();
9743
+ const inputElement = this.autocompleteComponent()?.inputElement()?.nativeElement;
9744
+ if (inputElement) {
9745
+ inputElement.hidden = isHidden;
9746
+ }
9747
+ },
9748
+ });
9725
9749
  selectedElemRefEffect = effect(() => {
9726
9750
  this.selectedElemRef();
9727
9751
  if (this.pendingRemovedIndexForFocus !== null) {
@@ -9736,12 +9760,6 @@ class FoehnMultiselectAutocompleteComponent extends FoehnAutocompleteComponent {
9736
9760
  this.hostId.set(this.buildId('ParentContainer'));
9737
9761
  this.hostName = this.hostId();
9738
9762
  }
9739
- onModelChange(value) {
9740
- super.onModelChange(value);
9741
- if (!value || ObjectHelper.isEmpty(value)) {
9742
- this.manageSuggestionListAndFocusAfterRemovingAnItem(null);
9743
- }
9744
- }
9745
9763
  hasErrorsToDisplay() {
9746
9764
  return this.autocompleteComponent()?.hasErrorsToDisplay() ?? false;
9747
9765
  }
@@ -9768,7 +9786,7 @@ class FoehnMultiselectAutocompleteComponent extends FoehnAutocompleteComponent {
9768
9786
  current.push(item);
9769
9787
  this.updateMultiselectAutocomplete(current);
9770
9788
  this.handleUserInput(current);
9771
- this.manageSuggestionListAndFocusAfterAddingAnItem();
9789
+ this.focusAfterAddingAnItem();
9772
9790
  this.manageScreenReaderAnnouncement(item, false);
9773
9791
  }
9774
9792
  }
@@ -9777,7 +9795,8 @@ class FoehnMultiselectAutocompleteComponent extends FoehnAutocompleteComponent {
9777
9795
  const current = (this.model() ?? []).filter((_item, itemIndex) => itemIndex !== index);
9778
9796
  this.updateMultiselectAutocomplete(current);
9779
9797
  this.handleUserInput(current);
9780
- this.manageSuggestionListAndFocusAfterRemovingAnItem(index);
9798
+ // When deleting a selected item, check were to set focus back when no more items to delete
9799
+ this.pendingRemovedIndexForFocus = index;
9781
9800
  this.manageScreenReaderAnnouncement(item, true);
9782
9801
  this.autocompleteComponent()?.markAsDirty();
9783
9802
  }
@@ -9788,14 +9807,14 @@ class FoehnMultiselectAutocompleteComponent extends FoehnAutocompleteComponent {
9788
9807
  return (!this.disabled() &&
9789
9808
  !this.defaultElementValuesComputed()?.includes(this.model()?.[index]));
9790
9809
  }
9791
- onAutocompleteElementsLoaded(elements) {
9792
- this.manageListWhenElementsAreLoaded(elements);
9810
+ onAutocompleteElementsLoaded() {
9811
+ // The autocomplete has (re)loaded its elements: it proposes the elements which are not selected
9812
+ this.applySuggestionsToAutocomplete();
9793
9813
  if (!this.model()?.length &&
9794
9814
  this.defaultElementValuesComputed()?.length) {
9795
9815
  // The default values are selected once the current rendering is done.
9796
9816
  afterNextRender(() => {
9797
9817
  this.updateMultiselectAutocomplete(this.defaultElementValuesComputed());
9798
- this.manageListWhenElementsAreLoaded(elements);
9799
9818
  }, { injector: this.componentInjector });
9800
9819
  }
9801
9820
  }
@@ -9816,15 +9835,6 @@ class FoehnMultiselectAutocompleteComponent extends FoehnAutocompleteComponent {
9816
9835
  }
9817
9836
  return elementBadgeLabel(element);
9818
9837
  }
9819
- manageListWhenElementsAreLoaded(elements) {
9820
- const autocompleteComponent = this.autocompleteComponent();
9821
- if (autocompleteComponent) {
9822
- autocompleteComponent.elements.set(this.filterAutocompleteElements(elements));
9823
- if (!this.disabled() && !autocompleteComponent.elements().length) {
9824
- this.showAlertMessageAndHideAutocomplete();
9825
- }
9826
- }
9827
- }
9828
9838
  findElementByModelItem(item) {
9829
9839
  const elements = this.elements();
9830
9840
  if (elements?.length) {
@@ -9879,24 +9889,14 @@ class FoehnMultiselectAutocompleteComponent extends FoehnAutocompleteComponent {
9879
9889
  }
9880
9890
  return filteredElements;
9881
9891
  }
9882
- manageSuggestionListAndFocusAfterAddingAnItem() {
9892
+ focusAfterAddingAnItem() {
9883
9893
  // Empty autocomplete input
9884
9894
  if (!this.isEmpty(this.autocompleteInputValue())) {
9885
9895
  this.autocompleteInputValue.set(null);
9886
9896
  }
9887
- const autocompleteComponent = this.autocompleteComponent();
9888
- if (!autocompleteComponent) {
9889
- return;
9890
- }
9891
9897
  // Reset autocomplete input value signal to ensure the input is empty
9892
- autocompleteComponent.inputValue.set(null);
9893
- // Remove selected item from autocomplete suggestion list
9894
- autocompleteComponent.elements.set(this.filterAutocompleteElements(this.elements()));
9895
- // Force autocomplete to filter elements again because the input value is empty and the list of elements has changed
9896
- autocompleteComponent.filterElements(true);
9897
- // Check if we still have suggestions to display
9898
- if (!autocompleteComponent.elements().length) {
9899
- this.showAlertMessageAndHideAutocomplete();
9898
+ this.autocompleteComponent()?.inputValue.set(null);
9899
+ if (this.showEmptyListMessage()) {
9900
9900
  // The alert message can be focused once it is rendered
9901
9901
  afterNextRender(() => {
9902
9902
  const alertMessage = this.alertMessageContainer()?.nativeElement.querySelector('p');
@@ -9906,37 +9906,18 @@ class FoehnMultiselectAutocompleteComponent extends FoehnAutocompleteComponent {
9906
9906
  }, { injector: this.componentInjector });
9907
9907
  }
9908
9908
  }
9909
- manageSuggestionListAndFocusAfterRemovingAnItem(removedIndex) {
9910
- // Hide message saying no more suggestions to display
9911
- this.showEmptyListMessage.set(false);
9909
+ applySuggestionsToAutocomplete() {
9912
9910
  const autocompleteComponent = this.autocompleteComponent();
9913
- if (autocompleteComponent) {
9914
- // Manually show autocomplete because there is at least one suggestions to display
9915
- const inputElement = autocompleteComponent.inputElement();
9916
- if (inputElement?.nativeElement) {
9917
- inputElement.nativeElement.hidden = false;
9918
- }
9919
- // Add back selected item to autocomplete suggestion list
9920
- autocompleteComponent.elements.set(this.filterAutocompleteElements(this.elements()));
9921
- // Force autocomplete to filter elements again because the input value is empty and the list of elements has changed
9922
- autocompleteComponent.filterElements(true);
9923
- }
9924
- if (removedIndex !== null) {
9925
- // When deleting a selected item, check were to set focus back when no more items to delete
9926
- this.pendingRemovedIndexForFocus = removedIndex;
9927
- }
9928
- }
9929
- showAlertMessageAndHideAutocomplete() {
9930
- // Show a message to user indicating there is no more suggestions to display
9931
- this.showEmptyListMessage.set(true);
9932
- // Manually reset and hide autocomplete because there is no more suggestions to display
9933
- if (!this.isEmpty(this.autocompleteInputValue())) {
9934
- this.autocompleteInputValue.set(null);
9911
+ // Before the rendering or the loading of the elements
9912
+ if (!autocompleteComponent || !this.elements()) {
9913
+ return;
9935
9914
  }
9936
- const autocompleteComponent = this.autocompleteComponent();
9937
- const inputElement = autocompleteComponent?.inputElement();
9938
- if (inputElement?.nativeElement) {
9939
- inputElement.nativeElement.hidden = true;
9915
+ autocompleteComponent.elements.set(this.suggestions());
9916
+ // Force autocomplete to filter elements again because the list of elements has changed
9917
+ autocompleteComponent.filterElements(true);
9918
+ if (this.showEmptyListMessage() &&
9919
+ !this.isEmpty(this.autocompleteInputValue())) {
9920
+ this.autocompleteInputValue.set(null);
9940
9921
  }
9941
9922
  }
9942
9923
  manageScreenReaderAnnouncement(element, isDelete) {
@@ -9961,7 +9942,7 @@ class FoehnMultiselectAutocompleteComponent extends FoehnAutocompleteComponent {
9961
9942
  provide: FoehnAutocompleteComponent,
9962
9943
  useExisting: forwardRef(() => FoehnMultiselectAutocompleteComponent),
9963
9944
  },
9964
- ], viewQueries: [{ propertyName: "autocompleteComponent", first: true, predicate: ["autocompleteComponent"], descendants: true, isSignal: true }, { propertyName: "alertMessageContainer", first: true, predicate: ["alertMessageContainer"], descendants: true, isSignal: true }, { propertyName: "selectedElemRef", predicate: ["selectedElemRef"], descendants: true, isSignal: true }, { propertyName: "defaultElemRef", predicate: ["defaultElemRef"], descendants: true, isSignal: true }, { propertyName: "defaultDeleteFocusArea", first: true, predicate: ["defaultDeleteFocusArea"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n class=\"form-group container-box\"\n [class.has-danger]=\"hasErrorsToDisplay()\"\n [class.vd-form-group-danger]=\"hasErrorsToDisplay()\"\n>\n <foehn-autocomplete\n #autocompleteComponent\n [name]=\"name()\"\n [label]=\"label()\"\n [elements]=\"elements()\"\n [elementsUrl]=\"elementsUrl()\"\n [elementValue]=\"elementValue()\"\n [elementLabel]=\"elementLabel()\"\n [elementSuggestionLabel]=\"elementSuggestionLabel()\"\n [elementValueIdentity]=\"elementValueIdentity()\"\n [elementDisabled]=\"elementDisabled()\"\n [elementGroup]=\"elementGroup()\"\n [allowCustomValue]=\"false\"\n [searchValueMinCharsCount]=\"searchValueMinCharsCount()\"\n [customValueModelGenerator]=\"customValueModelGenerator()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n (userInput)=\"addItem($event)\"\n [(model)]=\"autocompleteInputValue\"\n (elementsLoaded)=\"onAutocompleteElementsLoaded($event)\"\n [showErrorWhenDisabled]=\"showErrorWhenDisabled()\"\n [hideNotRequiredExtraLabel]=\"hideNotRequiredExtraLabel()\"\n [itemHeightInSuggestionListInPx]=\"itemHeightInSuggestionListInPx()\"\n [caseSensitiveSearch]=\"caseSensitiveSearch()\"\n [isLabelSrOnly]=\"isLabelSrOnly()\"\n [isSuggestionListDynamic]=\"isSuggestionListDynamic()\"\n >\n @if (!showEmptyListMessage()) {\n <small\n [attr.id]=\"buildChildId('Help')\"\n class=\"form-text text-secondary\"\n [innerHTML]=\"\n helpText()\n ? helpText()\n : ('foehn-multiselect-autocomplete.autocomplete.screen-reader.label'\n | fromDictionary)\n \"\n ></small>\n }\n\n <ng-content />\n\n <output\n [id]=\"buildChildId('AlertMessageContainer')\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n #alertMessageContainer\n >\n @if (showEmptyListMessage()) {\n <p class=\"alert alert-info mb-0\" tabindex=\"-1\">\n {{\n 'foehn-multiselect-autocomplete.autocomplete.empty-message'\n | fromDictionary\n }}\n </p>\n }\n </output>\n </foehn-autocomplete>\n\n <div class=\"selected-list-container pt-2\" tabindex=\"-1\">\n @if (hasDefaultDeleteFocusArea()) {\n <small\n class=\"form-text text-secondary my-0\"\n [tabindex]=\"0\"\n [innerHTML]=\"noElementsSelectedLabel() | fromDictionary\"\n #defaultDeleteFocusArea\n ></small>\n }\n\n <p\n [id]=\"buildChildId('srOnlyAnnouncements')\"\n class=\"visually-hidden\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {{ srAnnouncements() }}\n </p>\n\n @if (!!model()?.length) {\n <fieldset\n class=\"mb-0\"\n [attr.aria-describedby]=\"buildChildId('Label')\"\n >\n <legend\n [id]=\"buildChildId('Legend')\"\n class=\"form-text text-secondary small mb-0\"\n [innerHTML]=\"selectedItemsListLegend() | fromDictionary\"\n ></legend>\n <div\n class=\"selected-list d-flex align-content-stretch flex-wrap\"\n >\n @for (\n element of model();\n track trackByFn(index);\n let index = $index\n ) {\n @if (!canBeDeleted(index)) {\n <span\n class=\"badge rounded-pill bg-secondary me-1 mb-1 py-2 px-3 d-flex align-items-center\"\n [tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-describedby]=\"buildChildId('Legend')\"\n #defaultElemRef\n >\n <span\n [innerHTML]=\"getBadgeLabel(element)\"\n ></span>\n <span class=\"visually-hidden\">\n {{\n 'foehn-multiselect-autocomplete.sr-default-selected-element'\n | fromDictionary\n }}\n </span>\n </span>\n }\n @if (canBeDeleted(index)) {\n <button\n type=\"button\"\n class=\"btn btn-primary badge rounded-pill me-1 mb-1 py-2 px-3 d-flex align-items-center\"\n [tabindex]=\"0\"\n [attr.aria-label]=\"\n getDeleteButtonAriaLabel(element)\n \"\n [attr.aria-describedby]=\"buildChildId('Legend')\"\n [title]=\"getDeleteButtonAriaLabel(element)\"\n (click)=\"removeItem(element, index)\"\n #selectedElemRef\n >\n <span\n [innerHTML]=\"getBadgeLabel(element)\"\n ></span>\n <foehn-icon-times\n aria-hidden=\"true\"\n class=\"ms-2\"\n [title]=\"getDeleteButtonAriaLabel(element)\"\n />\n </button>\n }\n }\n </div>\n </fieldset>\n }\n </div>\n\n @if (hasMissingModelValue()) {\n @for (missingValue of missingModelValues(); track $index) {\n <p\n class=\"alert alert-warning\"\n role=\"alert\"\n [attr.id]=\"buildId('MissingValue' + $index)\"\n >\n {{\n 'foehn-checkable-group.missing-value.warning'\n | fromDictionary\n : { value: getMissingValueLabel(missingValue) }\n }}\n </p>\n }\n }\n</div>\n", styles: ["foehn-autocomplete p.alert:focus{outline:0;box-shadow:inset 0 1px 1px #00000013,0 0 0 .2rem var(--vd-focus)}:host ::ng-deep foehn-autocomplete .form-group{margin-bottom:0!important}.selected-list-container .btn{text-transform:none}:host ::ng-deep .btn .svg-inline--fa,:host ::ng-deep .btn a{color:#fff!important}.selected-list-container span.rounded-pill:focus{outline:0;box-shadow:inset 0 1px 1px #00000013,0 0 0 .2rem var(--vd-focus)}.container-box{border:1px solid #ededed;background-color:#fbfbfb;padding:.5rem}.container-box.vd-form-group-danger{border-left:5px solid var(--vd-danger);padding-left:1rem}:host ::ng-deep foehn-autocomplete div.vd-form-group-danger{border-left:0;padding-left:0}\n"], dependencies: [{ kind: "component", type: FoehnAutocompleteComponent, selector: "foehn-autocomplete", inputs: ["searchValueMinCharsCount", "allowCustomValue", "isSuggestionListDynamic", "customValueModelGenerator", "itemHeightInSuggestionListInPx", "elementSuggestionLabel", "caseSensitiveSearch"], outputs: ["userSearchInput"] }, { kind: "component", type: FoehnIconTimesComponent, selector: "foehn-icon-times" }, { kind: "pipe", type: SdkDictionaryPipe, name: "fromDictionary" }] });
9945
+ ], viewQueries: [{ propertyName: "autocompleteComponent", first: true, predicate: ["autocompleteComponent"], descendants: true, isSignal: true }, { propertyName: "alertMessageContainer", first: true, predicate: ["alertMessageContainer"], descendants: true, isSignal: true }, { propertyName: "selectedElemRef", predicate: ["selectedElemRef"], descendants: true, isSignal: true }, { propertyName: "defaultElemRef", predicate: ["defaultElemRef"], descendants: true, isSignal: true }, { propertyName: "defaultDeleteFocusArea", first: true, predicate: ["defaultDeleteFocusArea"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n class=\"form-group container-box\"\n [class.has-danger]=\"hasErrorsToDisplay()\"\n [class.vd-form-group-danger]=\"hasErrorsToDisplay()\"\n>\n <foehn-autocomplete\n #autocompleteComponent\n [name]=\"name()\"\n [label]=\"label()\"\n [elements]=\"elements()\"\n [elementsUrl]=\"elementsUrl()\"\n [elementValue]=\"elementValue()\"\n [elementLabel]=\"elementLabel()\"\n [elementSuggestionLabel]=\"elementSuggestionLabel()\"\n [elementValueIdentity]=\"elementValueIdentity()\"\n [elementDisabled]=\"elementDisabled()\"\n [elementGroup]=\"elementGroup()\"\n [allowCustomValue]=\"false\"\n [searchValueMinCharsCount]=\"searchValueMinCharsCount()\"\n [customValueModelGenerator]=\"customValueModelGenerator()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n (userInput)=\"addItem($event)\"\n [(model)]=\"autocompleteInputValue\"\n (elementsLoaded)=\"onAutocompleteElementsLoaded()\"\n [showErrorWhenDisabled]=\"showErrorWhenDisabled()\"\n [hideNotRequiredExtraLabel]=\"hideNotRequiredExtraLabel()\"\n [itemHeightInSuggestionListInPx]=\"itemHeightInSuggestionListInPx()\"\n [caseSensitiveSearch]=\"caseSensitiveSearch()\"\n [isLabelSrOnly]=\"isLabelSrOnly()\"\n [isSuggestionListDynamic]=\"isSuggestionListDynamic()\"\n >\n @if (!showEmptyListMessage()) {\n <small\n [attr.id]=\"buildChildId('Help')\"\n class=\"form-text text-secondary\"\n [innerHTML]=\"\n helpText()\n ? helpText()\n : ('foehn-multiselect-autocomplete.autocomplete.screen-reader.label'\n | fromDictionary)\n \"\n ></small>\n }\n\n <ng-content />\n\n <output\n [id]=\"buildChildId('AlertMessageContainer')\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n #alertMessageContainer\n >\n @if (showEmptyListMessage()) {\n <p class=\"alert alert-info mb-0\" tabindex=\"-1\">\n {{\n 'foehn-multiselect-autocomplete.autocomplete.empty-message'\n | fromDictionary\n }}\n </p>\n }\n </output>\n </foehn-autocomplete>\n\n <div class=\"selected-list-container pt-2\" tabindex=\"-1\">\n @if (hasDefaultDeleteFocusArea()) {\n <small\n class=\"form-text text-secondary my-0\"\n [tabindex]=\"0\"\n [innerHTML]=\"noElementsSelectedLabel() | fromDictionary\"\n #defaultDeleteFocusArea\n ></small>\n }\n\n <p\n [id]=\"buildChildId('srOnlyAnnouncements')\"\n class=\"visually-hidden\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {{ srAnnouncements() }}\n </p>\n\n @if (!!model()?.length) {\n <fieldset\n class=\"mb-0\"\n [attr.aria-describedby]=\"buildChildId('Label')\"\n >\n <legend\n [id]=\"buildChildId('Legend')\"\n class=\"form-text text-secondary small mb-0\"\n [innerHTML]=\"selectedItemsListLegend() | fromDictionary\"\n ></legend>\n <div\n class=\"selected-list d-flex align-content-stretch flex-wrap\"\n >\n @for (\n element of model();\n track trackByFn(index);\n let index = $index\n ) {\n @if (!canBeDeleted(index)) {\n <span\n class=\"badge rounded-pill bg-secondary me-1 mb-1 py-2 px-3 d-flex align-items-center\"\n [tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-describedby]=\"buildChildId('Legend')\"\n #defaultElemRef\n >\n <span\n [innerHTML]=\"getBadgeLabel(element)\"\n ></span>\n <span class=\"visually-hidden\">\n {{\n 'foehn-multiselect-autocomplete.sr-default-selected-element'\n | fromDictionary\n }}\n </span>\n </span>\n }\n @if (canBeDeleted(index)) {\n <button\n type=\"button\"\n class=\"btn btn-primary badge rounded-pill me-1 mb-1 py-2 px-3 d-flex align-items-center\"\n [tabindex]=\"0\"\n [attr.aria-label]=\"\n getDeleteButtonAriaLabel(element)\n \"\n [attr.aria-describedby]=\"buildChildId('Legend')\"\n [title]=\"getDeleteButtonAriaLabel(element)\"\n (click)=\"removeItem(element, index)\"\n #selectedElemRef\n >\n <span\n [innerHTML]=\"getBadgeLabel(element)\"\n ></span>\n <foehn-icon-times\n aria-hidden=\"true\"\n class=\"ms-2\"\n [title]=\"getDeleteButtonAriaLabel(element)\"\n />\n </button>\n }\n }\n </div>\n </fieldset>\n }\n </div>\n\n @if (hasMissingModelValue()) {\n @for (missingValue of missingModelValues(); track $index) {\n <p\n class=\"alert alert-warning\"\n role=\"alert\"\n [attr.id]=\"buildId('MissingValue' + $index)\"\n >\n {{\n 'foehn-checkable-group.missing-value.warning'\n | fromDictionary\n : { value: getMissingValueLabel(missingValue) }\n }}\n </p>\n }\n }\n</div>\n", styles: ["foehn-autocomplete p.alert:focus{outline:0;box-shadow:inset 0 1px 1px #00000013,0 0 0 .2rem var(--vd-focus)}:host ::ng-deep foehn-autocomplete .form-group{margin-bottom:0!important}.selected-list-container .btn{text-transform:none}:host ::ng-deep .btn .svg-inline--fa,:host ::ng-deep .btn a{color:#fff!important}.selected-list-container span.rounded-pill:focus{outline:0;box-shadow:inset 0 1px 1px #00000013,0 0 0 .2rem var(--vd-focus)}.container-box{border:1px solid #ededed;background-color:#fbfbfb;padding:.5rem}.container-box.vd-form-group-danger{border-left:5px solid var(--vd-danger);padding-left:1rem}:host ::ng-deep foehn-autocomplete div.vd-form-group-danger{border-left:0;padding-left:0}\n"], dependencies: [{ kind: "component", type: FoehnAutocompleteComponent, selector: "foehn-autocomplete", inputs: ["searchValueMinCharsCount", "allowCustomValue", "isSuggestionListDynamic", "customValueModelGenerator", "itemHeightInSuggestionListInPx", "elementSuggestionLabel", "caseSensitiveSearch"], outputs: ["userSearchInput"] }, { kind: "component", type: FoehnIconTimesComponent, selector: "foehn-icon-times" }, { kind: "pipe", type: SdkDictionaryPipe, name: "fromDictionary" }] });
9965
9946
  }
9966
9947
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: FoehnMultiselectAutocompleteComponent, decorators: [{
9967
9948
  type: Component,
@@ -9980,7 +9961,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
9980
9961
  SdkDictionaryPipe,
9981
9962
  ], host: {
9982
9963
  '[attr.name]': 'hostName',
9983
- }, template: "<div\n class=\"form-group container-box\"\n [class.has-danger]=\"hasErrorsToDisplay()\"\n [class.vd-form-group-danger]=\"hasErrorsToDisplay()\"\n>\n <foehn-autocomplete\n #autocompleteComponent\n [name]=\"name()\"\n [label]=\"label()\"\n [elements]=\"elements()\"\n [elementsUrl]=\"elementsUrl()\"\n [elementValue]=\"elementValue()\"\n [elementLabel]=\"elementLabel()\"\n [elementSuggestionLabel]=\"elementSuggestionLabel()\"\n [elementValueIdentity]=\"elementValueIdentity()\"\n [elementDisabled]=\"elementDisabled()\"\n [elementGroup]=\"elementGroup()\"\n [allowCustomValue]=\"false\"\n [searchValueMinCharsCount]=\"searchValueMinCharsCount()\"\n [customValueModelGenerator]=\"customValueModelGenerator()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n (userInput)=\"addItem($event)\"\n [(model)]=\"autocompleteInputValue\"\n (elementsLoaded)=\"onAutocompleteElementsLoaded($event)\"\n [showErrorWhenDisabled]=\"showErrorWhenDisabled()\"\n [hideNotRequiredExtraLabel]=\"hideNotRequiredExtraLabel()\"\n [itemHeightInSuggestionListInPx]=\"itemHeightInSuggestionListInPx()\"\n [caseSensitiveSearch]=\"caseSensitiveSearch()\"\n [isLabelSrOnly]=\"isLabelSrOnly()\"\n [isSuggestionListDynamic]=\"isSuggestionListDynamic()\"\n >\n @if (!showEmptyListMessage()) {\n <small\n [attr.id]=\"buildChildId('Help')\"\n class=\"form-text text-secondary\"\n [innerHTML]=\"\n helpText()\n ? helpText()\n : ('foehn-multiselect-autocomplete.autocomplete.screen-reader.label'\n | fromDictionary)\n \"\n ></small>\n }\n\n <ng-content />\n\n <output\n [id]=\"buildChildId('AlertMessageContainer')\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n #alertMessageContainer\n >\n @if (showEmptyListMessage()) {\n <p class=\"alert alert-info mb-0\" tabindex=\"-1\">\n {{\n 'foehn-multiselect-autocomplete.autocomplete.empty-message'\n | fromDictionary\n }}\n </p>\n }\n </output>\n </foehn-autocomplete>\n\n <div class=\"selected-list-container pt-2\" tabindex=\"-1\">\n @if (hasDefaultDeleteFocusArea()) {\n <small\n class=\"form-text text-secondary my-0\"\n [tabindex]=\"0\"\n [innerHTML]=\"noElementsSelectedLabel() | fromDictionary\"\n #defaultDeleteFocusArea\n ></small>\n }\n\n <p\n [id]=\"buildChildId('srOnlyAnnouncements')\"\n class=\"visually-hidden\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {{ srAnnouncements() }}\n </p>\n\n @if (!!model()?.length) {\n <fieldset\n class=\"mb-0\"\n [attr.aria-describedby]=\"buildChildId('Label')\"\n >\n <legend\n [id]=\"buildChildId('Legend')\"\n class=\"form-text text-secondary small mb-0\"\n [innerHTML]=\"selectedItemsListLegend() | fromDictionary\"\n ></legend>\n <div\n class=\"selected-list d-flex align-content-stretch flex-wrap\"\n >\n @for (\n element of model();\n track trackByFn(index);\n let index = $index\n ) {\n @if (!canBeDeleted(index)) {\n <span\n class=\"badge rounded-pill bg-secondary me-1 mb-1 py-2 px-3 d-flex align-items-center\"\n [tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-describedby]=\"buildChildId('Legend')\"\n #defaultElemRef\n >\n <span\n [innerHTML]=\"getBadgeLabel(element)\"\n ></span>\n <span class=\"visually-hidden\">\n {{\n 'foehn-multiselect-autocomplete.sr-default-selected-element'\n | fromDictionary\n }}\n </span>\n </span>\n }\n @if (canBeDeleted(index)) {\n <button\n type=\"button\"\n class=\"btn btn-primary badge rounded-pill me-1 mb-1 py-2 px-3 d-flex align-items-center\"\n [tabindex]=\"0\"\n [attr.aria-label]=\"\n getDeleteButtonAriaLabel(element)\n \"\n [attr.aria-describedby]=\"buildChildId('Legend')\"\n [title]=\"getDeleteButtonAriaLabel(element)\"\n (click)=\"removeItem(element, index)\"\n #selectedElemRef\n >\n <span\n [innerHTML]=\"getBadgeLabel(element)\"\n ></span>\n <foehn-icon-times\n aria-hidden=\"true\"\n class=\"ms-2\"\n [title]=\"getDeleteButtonAriaLabel(element)\"\n />\n </button>\n }\n }\n </div>\n </fieldset>\n }\n </div>\n\n @if (hasMissingModelValue()) {\n @for (missingValue of missingModelValues(); track $index) {\n <p\n class=\"alert alert-warning\"\n role=\"alert\"\n [attr.id]=\"buildId('MissingValue' + $index)\"\n >\n {{\n 'foehn-checkable-group.missing-value.warning'\n | fromDictionary\n : { value: getMissingValueLabel(missingValue) }\n }}\n </p>\n }\n }\n</div>\n", styles: ["foehn-autocomplete p.alert:focus{outline:0;box-shadow:inset 0 1px 1px #00000013,0 0 0 .2rem var(--vd-focus)}:host ::ng-deep foehn-autocomplete .form-group{margin-bottom:0!important}.selected-list-container .btn{text-transform:none}:host ::ng-deep .btn .svg-inline--fa,:host ::ng-deep .btn a{color:#fff!important}.selected-list-container span.rounded-pill:focus{outline:0;box-shadow:inset 0 1px 1px #00000013,0 0 0 .2rem var(--vd-focus)}.container-box{border:1px solid #ededed;background-color:#fbfbfb;padding:.5rem}.container-box.vd-form-group-danger{border-left:5px solid var(--vd-danger);padding-left:1rem}:host ::ng-deep foehn-autocomplete div.vd-form-group-danger{border-left:0;padding-left:0}\n"] }]
9964
+ }, template: "<div\n class=\"form-group container-box\"\n [class.has-danger]=\"hasErrorsToDisplay()\"\n [class.vd-form-group-danger]=\"hasErrorsToDisplay()\"\n>\n <foehn-autocomplete\n #autocompleteComponent\n [name]=\"name()\"\n [label]=\"label()\"\n [elements]=\"elements()\"\n [elementsUrl]=\"elementsUrl()\"\n [elementValue]=\"elementValue()\"\n [elementLabel]=\"elementLabel()\"\n [elementSuggestionLabel]=\"elementSuggestionLabel()\"\n [elementValueIdentity]=\"elementValueIdentity()\"\n [elementDisabled]=\"elementDisabled()\"\n [elementGroup]=\"elementGroup()\"\n [allowCustomValue]=\"false\"\n [searchValueMinCharsCount]=\"searchValueMinCharsCount()\"\n [customValueModelGenerator]=\"customValueModelGenerator()\"\n [required]=\"required()\"\n [disabled]=\"disabled()\"\n (userInput)=\"addItem($event)\"\n [(model)]=\"autocompleteInputValue\"\n (elementsLoaded)=\"onAutocompleteElementsLoaded()\"\n [showErrorWhenDisabled]=\"showErrorWhenDisabled()\"\n [hideNotRequiredExtraLabel]=\"hideNotRequiredExtraLabel()\"\n [itemHeightInSuggestionListInPx]=\"itemHeightInSuggestionListInPx()\"\n [caseSensitiveSearch]=\"caseSensitiveSearch()\"\n [isLabelSrOnly]=\"isLabelSrOnly()\"\n [isSuggestionListDynamic]=\"isSuggestionListDynamic()\"\n >\n @if (!showEmptyListMessage()) {\n <small\n [attr.id]=\"buildChildId('Help')\"\n class=\"form-text text-secondary\"\n [innerHTML]=\"\n helpText()\n ? helpText()\n : ('foehn-multiselect-autocomplete.autocomplete.screen-reader.label'\n | fromDictionary)\n \"\n ></small>\n }\n\n <ng-content />\n\n <output\n [id]=\"buildChildId('AlertMessageContainer')\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n #alertMessageContainer\n >\n @if (showEmptyListMessage()) {\n <p class=\"alert alert-info mb-0\" tabindex=\"-1\">\n {{\n 'foehn-multiselect-autocomplete.autocomplete.empty-message'\n | fromDictionary\n }}\n </p>\n }\n </output>\n </foehn-autocomplete>\n\n <div class=\"selected-list-container pt-2\" tabindex=\"-1\">\n @if (hasDefaultDeleteFocusArea()) {\n <small\n class=\"form-text text-secondary my-0\"\n [tabindex]=\"0\"\n [innerHTML]=\"noElementsSelectedLabel() | fromDictionary\"\n #defaultDeleteFocusArea\n ></small>\n }\n\n <p\n [id]=\"buildChildId('srOnlyAnnouncements')\"\n class=\"visually-hidden\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {{ srAnnouncements() }}\n </p>\n\n @if (!!model()?.length) {\n <fieldset\n class=\"mb-0\"\n [attr.aria-describedby]=\"buildChildId('Label')\"\n >\n <legend\n [id]=\"buildChildId('Legend')\"\n class=\"form-text text-secondary small mb-0\"\n [innerHTML]=\"selectedItemsListLegend() | fromDictionary\"\n ></legend>\n <div\n class=\"selected-list d-flex align-content-stretch flex-wrap\"\n >\n @for (\n element of model();\n track trackByFn(index);\n let index = $index\n ) {\n @if (!canBeDeleted(index)) {\n <span\n class=\"badge rounded-pill bg-secondary me-1 mb-1 py-2 px-3 d-flex align-items-center\"\n [tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-describedby]=\"buildChildId('Legend')\"\n #defaultElemRef\n >\n <span\n [innerHTML]=\"getBadgeLabel(element)\"\n ></span>\n <span class=\"visually-hidden\">\n {{\n 'foehn-multiselect-autocomplete.sr-default-selected-element'\n | fromDictionary\n }}\n </span>\n </span>\n }\n @if (canBeDeleted(index)) {\n <button\n type=\"button\"\n class=\"btn btn-primary badge rounded-pill me-1 mb-1 py-2 px-3 d-flex align-items-center\"\n [tabindex]=\"0\"\n [attr.aria-label]=\"\n getDeleteButtonAriaLabel(element)\n \"\n [attr.aria-describedby]=\"buildChildId('Legend')\"\n [title]=\"getDeleteButtonAriaLabel(element)\"\n (click)=\"removeItem(element, index)\"\n #selectedElemRef\n >\n <span\n [innerHTML]=\"getBadgeLabel(element)\"\n ></span>\n <foehn-icon-times\n aria-hidden=\"true\"\n class=\"ms-2\"\n [title]=\"getDeleteButtonAriaLabel(element)\"\n />\n </button>\n }\n }\n </div>\n </fieldset>\n }\n </div>\n\n @if (hasMissingModelValue()) {\n @for (missingValue of missingModelValues(); track $index) {\n <p\n class=\"alert alert-warning\"\n role=\"alert\"\n [attr.id]=\"buildId('MissingValue' + $index)\"\n >\n {{\n 'foehn-checkable-group.missing-value.warning'\n | fromDictionary\n : { value: getMissingValueLabel(missingValue) }\n }}\n </p>\n }\n }\n</div>\n", styles: ["foehn-autocomplete p.alert:focus{outline:0;box-shadow:inset 0 1px 1px #00000013,0 0 0 .2rem var(--vd-focus)}:host ::ng-deep foehn-autocomplete .form-group{margin-bottom:0!important}.selected-list-container .btn{text-transform:none}:host ::ng-deep .btn .svg-inline--fa,:host ::ng-deep .btn a{color:#fff!important}.selected-list-container span.rounded-pill:focus{outline:0;box-shadow:inset 0 1px 1px #00000013,0 0 0 .2rem var(--vd-focus)}.container-box{border:1px solid #ededed;background-color:#fbfbfb;padding:.5rem}.container-box.vd-form-group-danger{border-left:5px solid var(--vd-danger);padding-left:1rem}:host ::ng-deep foehn-autocomplete div.vd-form-group-danger{border-left:0;padding-left:0}\n"] }]
9984
9965
  }], propDecorators: { elementBadgeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "elementBadgeLabel", required: false }] }], selectedItemsListLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemsListLegend", required: false }] }], noElementsSelectedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "noElementsSelectedLabel", required: false }] }], excludeFromErrorSummary: [{ type: i0.Input, args: [{ isSignal: true, alias: "excludeFromErrorSummary", required: false }] }], defaultElementValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultElementValues", required: false }] }], autocompleteComponent: [{ type: i0.ViewChild, args: ['autocompleteComponent', { isSignal: true }] }], alertMessageContainer: [{ type: i0.ViewChild, args: ['alertMessageContainer', { isSignal: true }] }], selectedElemRef: [{ type: i0.ViewChildren, args: ['selectedElemRef', { isSignal: true }] }], defaultElemRef: [{ type: i0.ViewChildren, args: ['defaultElemRef', { isSignal: true }] }], defaultDeleteFocusArea: [{ type: i0.ViewChild, args: ['defaultDeleteFocusArea', { isSignal: true }] }] } });
9985
9966
 
9986
9967
  class FoehnInputEmailComponent extends FoehnInputStringComponent {
@@ -13120,12 +13101,23 @@ class UploaderHelper {
13120
13101
  ? this._fileMaxSizeInBytesByFormKey[keyAsRegex]
13121
13102
  : null;
13122
13103
  }
13123
- isFileTooBig(formKey, fileSizeInBytes) {
13124
- const maxFileSizeInBytesForFormKey = this.getMaxFileSizeInBytesForFormKey(formKey);
13125
- if (!maxFileSizeInBytesForFormKey) {
13104
+ /**
13105
+ * The maximum size of a file: the one of its form key (application info) and `maxFileSizeInMo` (a limit of the
13106
+ * component), the smallest of both.
13107
+ */
13108
+ getMaxFileSizeInBytes(formKey, maxFileSizeInMo) {
13109
+ const limits = [
13110
+ this.getMaxFileSizeInBytesForFormKey(formKey),
13111
+ maxFileSizeInMo ? maxFileSizeInMo * 1024 * 1024 : null,
13112
+ ].filter((limit) => !!limit);
13113
+ return limits.length ? Math.min(...limits) : null;
13114
+ }
13115
+ isFileTooBig(formKey, fileSizeInBytes, maxFileSizeInMo) {
13116
+ const maxFileSizeInBytes = this.getMaxFileSizeInBytes(formKey, maxFileSizeInMo);
13117
+ if (!maxFileSizeInBytes) {
13126
13118
  return false;
13127
13119
  }
13128
- return this.isTooBig(fileSizeInBytes, maxFileSizeInBytesForFormKey);
13120
+ return this.isTooBig(fileSizeInBytes, maxFileSizeInBytes);
13129
13121
  }
13130
13122
  isFileTooSmall(fileSizeInBytes) {
13131
13123
  if (!this.fileMinSizeInBytes) {
@@ -13162,12 +13154,12 @@ class UploaderHelper {
13162
13154
  .split(',')
13163
13155
  .includes(fileExtension.toUpperCase()));
13164
13156
  }
13165
- getUniqueErrorByCode(name, errorCode, fileName, customErrors, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters) {
13157
+ getUniqueErrorByCode(name, errorCode, fileName, customErrors, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters, maxFileSizeInMo) {
13166
13158
  const uniqSuffix = Date.now();
13167
13159
  return {
13168
13160
  name,
13169
13161
  code: `${errorCode}_${uniqSuffix}`,
13170
- message: this.replaceErrorMessageKeys(name, customErrors[errorCode], fileName, errorCode, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters),
13162
+ message: this.replaceErrorMessageKeys(name, customErrors[errorCode], fileName, errorCode, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters, maxFileSizeInMo),
13171
13163
  };
13172
13164
  }
13173
13165
  addCustomErrorOrDefault(name, destinationErrors, errorCode, fileName, customErrors, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters) {
@@ -13229,7 +13221,7 @@ class UploaderHelper {
13229
13221
  createDefaultCustomErrors(customErrors) {
13230
13222
  Object.assign(customErrors, this.getDefaultCustomErrors());
13231
13223
  }
13232
- getLocalErrors(name, files, customErrors, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters) {
13224
+ getLocalErrors(name, files, customErrors, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters, maxFileSizeInMo) {
13233
13225
  const errors = [];
13234
13226
  files.forEach((file) => {
13235
13227
  // File bad extension
@@ -13246,10 +13238,10 @@ class UploaderHelper {
13246
13238
  errors.push(this.getUniqueErrorByCode(name, 'FILENAME_SHOULD_NOT_CONTAIN', file.name, customErrors, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters));
13247
13239
  }
13248
13240
  // Files too big
13249
- if (this.isFileTooBig(name, file.size)) {
13250
- // Default custom error 413 exist (see function 'createDefaultCustomErrors')
13241
+ if (this.isFileTooBig(name, file.size, maxFileSizeInMo)) {
13242
+ // Default custom error 413 exist (see function 'getDefaultCustomErrors')
13251
13243
  // Need to create unique error to ensure ability to display multiple error messages
13252
- errors.push(this.getUniqueErrorByCode(name, '413', file.name, customErrors, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters));
13244
+ errors.push(this.getUniqueErrorByCode(name, '413', file.name, customErrors, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters, maxFileSizeInMo));
13253
13245
  }
13254
13246
  if (this.isFileTooSmall(file.size)) {
13255
13247
  // Default custom error FILE_TOO_SMALL exist (see function 'createDefaultCustomErrors')
@@ -13365,7 +13357,7 @@ class UploaderHelper {
13365
13357
  isTooBig(fileSizeInBytes, limitInBytes) {
13366
13358
  return fileSizeInBytes > limitInBytes;
13367
13359
  }
13368
- replaceErrorMessageKeys(name, errorMsg, fileName, errorCode, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters) {
13360
+ replaceErrorMessageKeys(name, errorMsg, fileName, errorCode, overrideAcceptedExtensions, overrideMaxFileNameLength, overrideIllegalCharacters, maxFileSizeInMo) {
13369
13361
  const safeFileName = fileName?.length
13370
13362
  ? getSafeFileNameForErrorMessage(fileName)
13371
13363
  : '';
@@ -13379,7 +13371,7 @@ class UploaderHelper {
13379
13371
  // getDefaultCustomErrors function: customErrors['0'] = customErrors['413'];
13380
13372
  if (errorCode.startsWith('413') || errorCode.startsWith('0')) {
13381
13373
  // REQUEST_ENTITY_TOO_LARGE_ERROR_MSG
13382
- const fileMaxSize = ((this.getMaxFileSizeInBytesForFormKey(name) ?? 0) /
13374
+ const fileMaxSize = ((this.getMaxFileSizeInBytes(name, maxFileSizeInMo) ?? 0) /
13383
13375
  (1024 * 1024)).toString();
13384
13376
  return withValue('fileMaxSize', fileMaxSize);
13385
13377
  }
@@ -13538,8 +13530,14 @@ class AbstractFoehnUploaderComponent extends FoehnInputComponent {
13538
13530
  removeFileOnConfirmation(document) {
13539
13531
  this.deleteDocumentSubject.next(document);
13540
13532
  }
13533
+ /**
13534
+ * A maximum size of each file, in addition to the one of its form key in the application info.
13535
+ */
13536
+ getMaxFileSizeInMo() {
13537
+ return undefined;
13538
+ }
13541
13539
  displayLocalErrors(files) {
13542
- const errors = this.uploaderHelper.getLocalErrors(this.name(), files, this.uploaderCustomErrors(), this.overrideAcceptedExtensions(), this.overrideMaxFileNameLength(), this.overrideIllegalCharacters());
13540
+ const errors = this.uploaderHelper.getLocalErrors(this.name(), files, this.uploaderCustomErrors(), this.overrideAcceptedExtensions(), this.overrideMaxFileNameLength(), this.overrideIllegalCharacters(), this.getMaxFileSizeInMo());
13543
13541
  this.refreshErrors([errors, true]);
13544
13542
  return errors;
13545
13543
  }
@@ -13598,6 +13596,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
13598
13596
  }]
13599
13597
  }], ctorParameters: () => [], propDecorators: { showUploadButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showUploadButton", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], hideGlobalInfos: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideGlobalInfos", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], overrideAcceptedExtensions: [{ type: i0.Input, args: [{ isSignal: true, alias: "overrideAcceptedExtensions", required: false }] }], overrideMaxFileNameLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "overrideMaxFileNameLength", required: false }] }], overrideIllegalCharacters: [{ type: i0.Input, args: [{ isSignal: true, alias: "overrideIllegalCharacters", required: false }] }], showDeleteConfirmationMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDeleteConfirmationMessage", required: false }] }], maxSimultaneousSelectedFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSimultaneousSelectedFiles", required: false }] }], maxFilesCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFilesCount", required: false }] }], maxFilesSizeInMo: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFilesSizeInMo", required: false }] }], dragAndDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragAndDrop", required: false }] }], shouldDisplayFileSavedConfirmation: [{ type: i0.Input, args: [{ isSignal: true, alias: "shouldDisplayFileSavedConfirmation", required: false }] }], chooseButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "chooseButtonLabel", required: false }] }], chooseButtonLabelMultiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "chooseButtonLabelMultiple", required: false }] }], dropZoneLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropZoneLabel", required: false }] }], dropZoneLabelMultiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropZoneLabelMultiple", required: false }] }], deleteConfirmationMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "deleteConfirmationMessage", required: false }] }] } });
13600
13598
 
13599
+ /**
13600
+ * Computes what needs to be uploaded/deleted server-side by comparing a document list
13601
+ * currently held in a "local upload" model (mixing already persisted `DocumentReference`
13602
+ * and pending `DocumentReferenceWithFile`) against the list as it was originally loaded.
13603
+ */
13604
+ function splitDocumentChanges(current, original) {
13605
+ const filesToAdd = (current ?? [])
13606
+ .filter((doc) => doc instanceof DocumentReferenceWithFile)
13607
+ .map((doc) => doc.file)
13608
+ .filter((file) => !!file);
13609
+ const currentReferences = new Set((current ?? [])
13610
+ .map((doc) => doc.reference)
13611
+ .filter((reference) => !!reference));
13612
+ const documentsToDelete = (original ?? []).filter((doc) => !!doc.reference && !currentReferences.has(doc.reference));
13613
+ return { filesToAdd, documentsToDelete };
13614
+ }
13615
+
13601
13616
  class UploadProgressService extends AbstractUploadProgressService {
13602
13617
  _analysisProgressSubject = new BehaviorSubject(false);
13603
13618
  _uploadProgressSubject = new BehaviorSubject(null);
@@ -14287,9 +14302,14 @@ class FoehnBoMultiUploadComponent extends AbstractFoehnUploaderComponent {
14287
14302
  deleteUrl = input(...(ngDevMode ? [undefined, { debugName: "deleteUrl" }] : /* istanbul ignore next */ []));
14288
14303
  downloadUrl = input(...(ngDevMode ? [undefined, { debugName: "downloadUrl" }] : /* istanbul ignore next */ []));
14289
14304
  optionalLabelKey = input('foehn-input.optional', ...(ngDevMode ? [{ debugName: "optionalLabelKey" }] : /* istanbul ignore next */ []));
14305
+ localUpload = input(false, ...(ngDevMode ? [{ debugName: "localUpload" }] : /* istanbul ignore next */ []));
14306
+ maxFileSizeInMo = input(...(ngDevMode ? [undefined, { debugName: "maxFileSizeInMo" }] : /* istanbul ignore next */ []));
14307
+ chooseButtonStyleModifier = input(...(ngDevMode ? [undefined, { debugName: "chooseButtonStyleModifier" }] : /* istanbul ignore next */ []));
14290
14308
  documentDeleted = output();
14291
14309
  boMultiUploadService = inject(BoMultiUploadService);
14292
14310
  pageUploadLimitService = inject(PageUploadLimitService);
14311
+ blobUrls = new Map();
14312
+ localSequence = 0;
14293
14313
  get addedFiles() {
14294
14314
  return this.model()?.filter((e) => !e.readonly) ?? [];
14295
14315
  }
@@ -14337,6 +14357,23 @@ class FoehnBoMultiUploadComponent extends AbstractFoehnUploaderComponent {
14337
14357
  }
14338
14358
  ngOnDestroy() {
14339
14359
  this.pageUploadLimitService.unregisterUploader(this);
14360
+ this.blobUrls.forEach((url) => URL.revokeObjectURL(url));
14361
+ this.blobUrls.clear();
14362
+ }
14363
+ isPending(document) {
14364
+ return document instanceof DocumentReferenceWithFile;
14365
+ }
14366
+ getDocumentDownloadUrl(document) {
14367
+ if (document instanceof DocumentReferenceWithFile) {
14368
+ const file = document.file;
14369
+ if (file) {
14370
+ if (!this.blobUrls.has(file)) {
14371
+ this.blobUrls.set(file, URL.createObjectURL(file));
14372
+ }
14373
+ return this.blobUrls.get(file) ?? '';
14374
+ }
14375
+ }
14376
+ return this.boMultiUploadService.getDownloadUrl(this.downloadUrl(), document);
14340
14377
  }
14341
14378
  getTotalFilesSize() {
14342
14379
  return (this.model()
@@ -14377,6 +14414,16 @@ class FoehnBoMultiUploadComponent extends AbstractFoehnUploaderComponent {
14377
14414
  }
14378
14415
  }
14379
14416
  }
14417
+ getMaxFileSizeInMo() {
14418
+ return this.maxFileSizeInMo();
14419
+ }
14420
+ removeFileOnConfirmation(document) {
14421
+ if (this.localUpload()) {
14422
+ this.removeDocumentLocally(document);
14423
+ return;
14424
+ }
14425
+ super.removeFileOnConfirmation(document);
14426
+ }
14380
14427
  populateFileItemList(fileList) {
14381
14428
  let files = Array.from(fileList);
14382
14429
  if (!files.length ||
@@ -14397,9 +14444,54 @@ class FoehnBoMultiUploadComponent extends AbstractFoehnUploaderComponent {
14397
14444
  if (!this.model()?.length) {
14398
14445
  this.model.set([]);
14399
14446
  }
14447
+ if (this.localUpload()) {
14448
+ // The files stay purely local: no HTTP call is made, the consuming project is
14449
+ // responsible for uploading them at save time (see splitDocumentChanges()).
14450
+ this.addFilesLocally(files);
14451
+ return;
14452
+ }
14400
14453
  // we send files to server
14401
14454
  this.uploadFilesSubject.next(files);
14402
14455
  }
14456
+ addFilesLocally(files) {
14457
+ const pendingDocuments = files.map((file) => this.toPendingDocument(file));
14458
+ this.model.update((current) => [
14459
+ ...(current ?? []),
14460
+ ...pendingDocuments,
14461
+ ]);
14462
+ this.markAsDirty();
14463
+ this.triggerUserInput(this.model());
14464
+ }
14465
+ toPendingDocument(file) {
14466
+ const document = new DocumentReferenceWithFile();
14467
+ document.reference = '';
14468
+ document.key = `${this.key() ?? this.name()}_local_${this.localSequence++}`;
14469
+ document.label = this.label();
14470
+ document.filename = file.name;
14471
+ document.mimeType = file.type;
14472
+ document.fileSize = file.size;
14473
+ document.file = file;
14474
+ return document;
14475
+ }
14476
+ removeDocumentLocally(document) {
14477
+ const current = this.model() ?? [];
14478
+ if (!current.includes(document)) {
14479
+ return;
14480
+ }
14481
+ this.model.set(current.filter((candidate) => candidate !== document));
14482
+ if (document instanceof DocumentReferenceWithFile && document.file) {
14483
+ this.revokeBlobUrl(document.file);
14484
+ }
14485
+ this.markAsDirty();
14486
+ this.triggerUserInput(this.model());
14487
+ }
14488
+ revokeBlobUrl(file) {
14489
+ const blobUrl = this.blobUrls.get(file);
14490
+ if (blobUrl) {
14491
+ URL.revokeObjectURL(blobUrl);
14492
+ this.blobUrls.delete(file);
14493
+ }
14494
+ }
14403
14495
  displayResultFromServer(documents, errors) {
14404
14496
  this.displayErrorsFromServer(errors);
14405
14497
  this.model.set([...(this.model() ?? []), ...(documents || [])]);
@@ -14437,7 +14529,7 @@ class FoehnBoMultiUploadComponent extends AbstractFoehnUploaderComponent {
14437
14529
  return files.slice(0, 1);
14438
14530
  }
14439
14531
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: FoehnBoMultiUploadComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
14440
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", type: FoehnBoMultiUploadComponent, isStandalone: true, selector: "foehn-bo-multi-upload", inputs: { uploadUrl: { classPropertyName: "uploadUrl", publicName: "uploadUrl", isSignal: true, isRequired: false, transformFunction: null }, deleteUrl: { classPropertyName: "deleteUrl", publicName: "deleteUrl", isSignal: true, isRequired: false, transformFunction: null }, downloadUrl: { classPropertyName: "downloadUrl", publicName: "downloadUrl", isSignal: true, isRequired: false, transformFunction: null }, optionalLabelKey: { classPropertyName: "optionalLabelKey", publicName: "optionalLabelKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { documentDeleted: "documentDeleted" }, providers: [
14532
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", type: FoehnBoMultiUploadComponent, isStandalone: true, selector: "foehn-bo-multi-upload", inputs: { uploadUrl: { classPropertyName: "uploadUrl", publicName: "uploadUrl", isSignal: true, isRequired: false, transformFunction: null }, deleteUrl: { classPropertyName: "deleteUrl", publicName: "deleteUrl", isSignal: true, isRequired: false, transformFunction: null }, downloadUrl: { classPropertyName: "downloadUrl", publicName: "downloadUrl", isSignal: true, isRequired: false, transformFunction: null }, optionalLabelKey: { classPropertyName: "optionalLabelKey", publicName: "optionalLabelKey", isSignal: true, isRequired: false, transformFunction: null }, localUpload: { classPropertyName: "localUpload", publicName: "localUpload", isSignal: true, isRequired: false, transformFunction: null }, maxFileSizeInMo: { classPropertyName: "maxFileSizeInMo", publicName: "maxFileSizeInMo", isSignal: true, isRequired: false, transformFunction: null }, chooseButtonStyleModifier: { classPropertyName: "chooseButtonStyleModifier", publicName: "chooseButtonStyleModifier", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { documentDeleted: "documentDeleted" }, providers: [
14441
14533
  {
14442
14534
  provide: FoehnInputComponent,
14443
14535
  useExisting: forwardRef(() => FoehnBoMultiUploadComponent),
@@ -14448,7 +14540,7 @@ class FoehnBoMultiUploadComponent extends AbstractFoehnUploaderComponent {
14448
14540
  provide: AbstractUploadProgressService,
14449
14541
  useExisting: UploadProgressService,
14450
14542
  },
14451
- ], usesInheritance: true, ngImport: i0, template: "<div\n class=\"form-group container-box\"\n [class.has-danger]=\"hasErrorsToDisplay()\"\n [class.vd-form-group-danger]=\"hasErrorsToDisplay()\"\n [class.drop-zone-highlight]=\"showDropZone\"\n [attr.id]=\"buildId('Container')\"\n tabindex=\"-1\"\n (drop)=\"onDrop($event)\"\n (dragenter)=\"onDragenter($event)\"\n (dragleave)=\"onDragleave($event)\"\n (dragover)=\"onDragover($event)\"\n #fallBackTrigger\n>\n @if (!!label()) {\n <label\n [class]=\"\n 'form-label ' +\n (isLabelSrOnly()\n ? 'visually-hidden'\n : (labelStyleModifier() ?? ''))\n \"\n [attr.for]=\"buildChildId()\"\n >\n <span [innerHTML]=\"label()\"></span>\n @if (!required() && !hideNotRequiredExtraLabel()) {\n <span aria-hidden=\"true\">\n {{ optionalLabelKey() | fromDictionary }}\n </span>\n }\n </label>\n }\n\n <foehn-validation-alerts\n [component]=\"this\"\n [shouldErrorsBeLive]=\"hasLiveUploadErrors()\"\n />\n\n @if (helpText()) {\n <small\n [attr.id]=\"buildChildId('Help')\"\n class=\"form-text text-secondary\"\n [innerHTML]=\"helpText()\"\n ></small>\n }\n\n <!-- PRESTAKIT-309: Fake input with NgModel to be registered into Form controls -->\n <input type=\"hidden\" [name]=\"name() || label() || ''\" [ngModel]=\"model()\" />\n\n <ng-content />\n\n @for (document of model(); track trackByDocument($index, document)) {\n <div class=\"file file-uploaded\">\n <!-- prettier-ignore -->\n <a [href]=\"boMultiUploadService.getDownloadUrl(downloadUrl(), document)\" target=\"_blank\">{{ document.filename }}</a>\n <span class=\"ms-1 me-1\">\n ({{ toMegaOctets(document.fileSize ?? 0) }}\n <abbr\n [title]=\"\n 'foehn-uploader.abbr-megaoctet-title' | fromDictionary\n \"\n >\n {{ 'foehn-uploader.abbr-megaoctet' | fromDictionary }}\n </abbr>\n )\n </span>\n @if (!readonly() && !document.readonly) {\n <button\n [disabled]=\"disabled()\"\n type=\"button\"\n class=\"btn btn-link icon-button delete-uploaded\"\n (click)=\"removeFile(document)\"\n >\n <foehn-icon-times\n [title]=\"\n 'foehn-uploader.delete-icon-title'\n | fromDictionary: { docName: document.filename }\n \"\n />\n </button>\n }\n </div>\n }\n\n @if (showGlobalInfos(model())) {\n <small\n class=\"form-text text-secondary uploaded-global-info\"\n [innerHTML]=\"getGlobalInfos(model())\"\n ></small>\n }\n\n @if (canAddMoreFiles()) {\n <input\n class=\"form-control actual-input\"\n type=\"file\"\n [name]=\"name() || label()\"\n [multiple]=\"multiple()\"\n [attr.accept]=\"\n overrideAcceptedExtensions()\n ? overrideAcceptedExtensions()\n : uploaderHelper.accept\n ? uploaderHelper.accept\n : null\n \"\n (change)=\"onFileChange($event)\"\n #inputFile\n />\n\n <button\n type=\"button\"\n class=\"btn btn-primary\"\n [disabled]=\"disabled()\"\n [class.visually-hidden]=\"!showUploadButton()\"\n [attr.id]=\"buildChildId()\"\n [attr.aria-invalid]=\"hasErrorsToDisplay() || null\"\n [attr.aria-describedby]=\"buildId('ErrorsContainer')\"\n (click)=\"inputFile.click()\"\n #entryComponent\n >\n {{\n multiple()\n ? resolvedChooseButtonLabelMultiple()\n : resolvedChooseButtonLabel()\n }}\n </button>\n\n @if (dragAndDrop() && !disabled()) {\n <div\n aria-hidden=\"true\"\n class=\"dropfile\"\n [class.dropfile-border-transparent]=\"showDropZone\"\n (click)=\"inputFile.click()\"\n >\n {{\n multiple()\n ? resolvedDropZoneLabelMultiple()\n : resolvedDropZoneLabel()\n }}\n </div>\n }\n }\n\n <foehn-upload-progress-bar\n [progressBarTriggerHtmlElement]=\"\n inputElement()?.nativeElement || fallBackTrigger\n \"\n />\n</div>\n", styles: [".dropfile{width:300px;border:3px dashed #bbb;text-align:center;margin-top:10px;cursor:pointer;padding:15px 3px}.dropfile-border-transparent{border-color:#fff}.actual-input{display:none}.file-list{margin-top:20px}.icon-button{border:0}.icon-button:hover{cursor:pointer}:host ::ng-deep .svg-inline--fa{color:#000!important}.drop-zone-highlight{outline:3px dashed #bbb}.container-box{border:1px solid #ededed;background-color:#fbfbfb;padding:.5rem}.container-box.vd-form-group-danger{border-left:5px solid var(--vd-danger);padding-left:1rem}\n"], dependencies: [{ kind: "component", type: FoehnValidationAlertsComponent, selector: "foehn-validation-alerts", inputs: ["component", "shouldErrorsBeLive"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FoehnIconTimesComponent, selector: "foehn-icon-times" }, { kind: "component", type: FoehnUploadProgressBarComponent, selector: "foehn-upload-progress-bar", inputs: ["progressBarTriggerHtmlElement"] }, { kind: "pipe", type: SdkDictionaryPipe, name: "fromDictionary" }] });
14543
+ ], usesInheritance: true, ngImport: i0, template: "<div\n class=\"form-group container-box\"\n [class.has-danger]=\"hasErrorsToDisplay()\"\n [class.vd-form-group-danger]=\"hasErrorsToDisplay()\"\n [class.drop-zone-highlight]=\"showDropZone\"\n [attr.id]=\"buildId('Container')\"\n tabindex=\"-1\"\n (drop)=\"onDrop($event)\"\n (dragenter)=\"onDragenter($event)\"\n (dragleave)=\"onDragleave($event)\"\n (dragover)=\"onDragover($event)\"\n #fallBackTrigger\n>\n @if (!!label()) {\n <label\n [class]=\"\n 'form-label ' +\n (isLabelSrOnly()\n ? 'visually-hidden'\n : (labelStyleModifier() ?? ''))\n \"\n [attr.for]=\"buildChildId()\"\n >\n <span [innerHTML]=\"label()\"></span>\n @if (!required() && !hideNotRequiredExtraLabel()) {\n <span aria-hidden=\"true\">\n {{ optionalLabelKey() | fromDictionary }}\n </span>\n }\n </label>\n }\n\n <foehn-validation-alerts\n [component]=\"this\"\n [shouldErrorsBeLive]=\"hasLiveUploadErrors()\"\n />\n\n @if (helpText()) {\n <small\n [attr.id]=\"buildChildId('Help')\"\n class=\"form-text text-secondary\"\n [innerHTML]=\"helpText()\"\n ></small>\n }\n\n <!-- PRESTAKIT-309: Fake input with NgModel to be registered into Form controls -->\n <input type=\"hidden\" [name]=\"name() || label() || ''\" [ngModel]=\"model()\" />\n\n <ng-content />\n\n @for (document of model(); track trackByDocument($index, document)) {\n <div class=\"file file-uploaded\">\n <!-- prettier-ignore -->\n <a [href]=\"getDocumentDownloadUrl(document)\" target=\"_blank\">{{ document.filename }}</a>\n <span class=\"ms-1 me-1\">\n ({{ toMegaOctets(document.fileSize ?? 0) }}\n <abbr\n [title]=\"\n 'foehn-uploader.abbr-megaoctet-title' | fromDictionary\n \"\n >\n {{ 'foehn-uploader.abbr-megaoctet' | fromDictionary }}\n </abbr>\n )\n </span>\n @if (isPending(document)) {\n <span class=\"fst-italic text-secondary\">\n ({{ 'foehn-uploader.pending-label' | fromDictionary }})\n </span>\n }\n @if (!readonly() && !document.readonly) {\n <button\n [disabled]=\"disabled()\"\n type=\"button\"\n class=\"btn btn-link icon-button delete-uploaded\"\n (click)=\"removeFile(document)\"\n >\n <foehn-icon-times\n [title]=\"\n 'foehn-uploader.delete-icon-title'\n | fromDictionary: { docName: document.filename }\n \"\n />\n </button>\n }\n </div>\n }\n\n @if (showGlobalInfos(model())) {\n <small\n class=\"form-text text-secondary uploaded-global-info\"\n [innerHTML]=\"getGlobalInfos(model())\"\n ></small>\n }\n\n @if (canAddMoreFiles()) {\n <input\n class=\"form-control actual-input\"\n type=\"file\"\n [name]=\"name() || label()\"\n [multiple]=\"multiple()\"\n [attr.accept]=\"\n overrideAcceptedExtensions()\n ? overrideAcceptedExtensions()\n : uploaderHelper.accept\n ? uploaderHelper.accept\n : null\n \"\n (change)=\"onFileChange($event)\"\n #inputFile\n />\n\n <button\n type=\"button\"\n [class]=\"'btn btn-primary ' + (chooseButtonStyleModifier() ?? '')\"\n [disabled]=\"disabled()\"\n [class.visually-hidden]=\"!showUploadButton()\"\n [attr.id]=\"buildChildId()\"\n [attr.aria-invalid]=\"hasErrorsToDisplay() || null\"\n [attr.aria-describedby]=\"buildId('ErrorsContainer')\"\n (click)=\"inputFile.click()\"\n #entryComponent\n >\n {{\n multiple()\n ? resolvedChooseButtonLabelMultiple()\n : resolvedChooseButtonLabel()\n }}\n </button>\n\n @if (dragAndDrop() && !disabled()) {\n <div\n aria-hidden=\"true\"\n class=\"dropfile\"\n [class.dropfile-border-transparent]=\"showDropZone\"\n (click)=\"inputFile.click()\"\n >\n {{\n multiple()\n ? resolvedDropZoneLabelMultiple()\n : resolvedDropZoneLabel()\n }}\n </div>\n }\n }\n\n <foehn-upload-progress-bar\n [progressBarTriggerHtmlElement]=\"\n inputElement()?.nativeElement || fallBackTrigger\n \"\n />\n</div>\n", styles: [".dropfile{width:300px;border:3px dashed #bbb;text-align:center;margin-top:10px;cursor:pointer;padding:15px 3px}.dropfile-border-transparent{border-color:#fff}.actual-input{display:none}.file-list{margin-top:20px}.icon-button{border:0}.icon-button:hover{cursor:pointer}:host ::ng-deep .svg-inline--fa{color:#000!important}.drop-zone-highlight{outline:3px dashed #bbb}.container-box{border:1px solid #ededed;background-color:#fbfbfb;padding:.5rem}.container-box.vd-form-group-danger{border-left:5px solid var(--vd-danger);padding-left:1rem}\n"], dependencies: [{ kind: "component", type: FoehnValidationAlertsComponent, selector: "foehn-validation-alerts", inputs: ["component", "shouldErrorsBeLive"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FoehnIconTimesComponent, selector: "foehn-icon-times" }, { kind: "component", type: FoehnUploadProgressBarComponent, selector: "foehn-upload-progress-bar", inputs: ["progressBarTriggerHtmlElement"] }, { kind: "pipe", type: SdkDictionaryPipe, name: "fromDictionary" }] });
14452
14544
  }
14453
14545
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: FoehnBoMultiUploadComponent, decorators: [{
14454
14546
  type: Component,
@@ -14469,8 +14561,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
14469
14561
  FoehnIconTimesComponent,
14470
14562
  FoehnUploadProgressBarComponent,
14471
14563
  SdkDictionaryPipe,
14472
- ], template: "<div\n class=\"form-group container-box\"\n [class.has-danger]=\"hasErrorsToDisplay()\"\n [class.vd-form-group-danger]=\"hasErrorsToDisplay()\"\n [class.drop-zone-highlight]=\"showDropZone\"\n [attr.id]=\"buildId('Container')\"\n tabindex=\"-1\"\n (drop)=\"onDrop($event)\"\n (dragenter)=\"onDragenter($event)\"\n (dragleave)=\"onDragleave($event)\"\n (dragover)=\"onDragover($event)\"\n #fallBackTrigger\n>\n @if (!!label()) {\n <label\n [class]=\"\n 'form-label ' +\n (isLabelSrOnly()\n ? 'visually-hidden'\n : (labelStyleModifier() ?? ''))\n \"\n [attr.for]=\"buildChildId()\"\n >\n <span [innerHTML]=\"label()\"></span>\n @if (!required() && !hideNotRequiredExtraLabel()) {\n <span aria-hidden=\"true\">\n {{ optionalLabelKey() | fromDictionary }}\n </span>\n }\n </label>\n }\n\n <foehn-validation-alerts\n [component]=\"this\"\n [shouldErrorsBeLive]=\"hasLiveUploadErrors()\"\n />\n\n @if (helpText()) {\n <small\n [attr.id]=\"buildChildId('Help')\"\n class=\"form-text text-secondary\"\n [innerHTML]=\"helpText()\"\n ></small>\n }\n\n <!-- PRESTAKIT-309: Fake input with NgModel to be registered into Form controls -->\n <input type=\"hidden\" [name]=\"name() || label() || ''\" [ngModel]=\"model()\" />\n\n <ng-content />\n\n @for (document of model(); track trackByDocument($index, document)) {\n <div class=\"file file-uploaded\">\n <!-- prettier-ignore -->\n <a [href]=\"boMultiUploadService.getDownloadUrl(downloadUrl(), document)\" target=\"_blank\">{{ document.filename }}</a>\n <span class=\"ms-1 me-1\">\n ({{ toMegaOctets(document.fileSize ?? 0) }}\n <abbr\n [title]=\"\n 'foehn-uploader.abbr-megaoctet-title' | fromDictionary\n \"\n >\n {{ 'foehn-uploader.abbr-megaoctet' | fromDictionary }}\n </abbr>\n )\n </span>\n @if (!readonly() && !document.readonly) {\n <button\n [disabled]=\"disabled()\"\n type=\"button\"\n class=\"btn btn-link icon-button delete-uploaded\"\n (click)=\"removeFile(document)\"\n >\n <foehn-icon-times\n [title]=\"\n 'foehn-uploader.delete-icon-title'\n | fromDictionary: { docName: document.filename }\n \"\n />\n </button>\n }\n </div>\n }\n\n @if (showGlobalInfos(model())) {\n <small\n class=\"form-text text-secondary uploaded-global-info\"\n [innerHTML]=\"getGlobalInfos(model())\"\n ></small>\n }\n\n @if (canAddMoreFiles()) {\n <input\n class=\"form-control actual-input\"\n type=\"file\"\n [name]=\"name() || label()\"\n [multiple]=\"multiple()\"\n [attr.accept]=\"\n overrideAcceptedExtensions()\n ? overrideAcceptedExtensions()\n : uploaderHelper.accept\n ? uploaderHelper.accept\n : null\n \"\n (change)=\"onFileChange($event)\"\n #inputFile\n />\n\n <button\n type=\"button\"\n class=\"btn btn-primary\"\n [disabled]=\"disabled()\"\n [class.visually-hidden]=\"!showUploadButton()\"\n [attr.id]=\"buildChildId()\"\n [attr.aria-invalid]=\"hasErrorsToDisplay() || null\"\n [attr.aria-describedby]=\"buildId('ErrorsContainer')\"\n (click)=\"inputFile.click()\"\n #entryComponent\n >\n {{\n multiple()\n ? resolvedChooseButtonLabelMultiple()\n : resolvedChooseButtonLabel()\n }}\n </button>\n\n @if (dragAndDrop() && !disabled()) {\n <div\n aria-hidden=\"true\"\n class=\"dropfile\"\n [class.dropfile-border-transparent]=\"showDropZone\"\n (click)=\"inputFile.click()\"\n >\n {{\n multiple()\n ? resolvedDropZoneLabelMultiple()\n : resolvedDropZoneLabel()\n }}\n </div>\n }\n }\n\n <foehn-upload-progress-bar\n [progressBarTriggerHtmlElement]=\"\n inputElement()?.nativeElement || fallBackTrigger\n \"\n />\n</div>\n", styles: [".dropfile{width:300px;border:3px dashed #bbb;text-align:center;margin-top:10px;cursor:pointer;padding:15px 3px}.dropfile-border-transparent{border-color:#fff}.actual-input{display:none}.file-list{margin-top:20px}.icon-button{border:0}.icon-button:hover{cursor:pointer}:host ::ng-deep .svg-inline--fa{color:#000!important}.drop-zone-highlight{outline:3px dashed #bbb}.container-box{border:1px solid #ededed;background-color:#fbfbfb;padding:.5rem}.container-box.vd-form-group-danger{border-left:5px solid var(--vd-danger);padding-left:1rem}\n"] }]
14473
- }], propDecorators: { uploadUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadUrl", required: false }] }], deleteUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "deleteUrl", required: false }] }], downloadUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "downloadUrl", required: false }] }], optionalLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabelKey", required: false }] }], documentDeleted: [{ type: i0.Output, args: ["documentDeleted"] }] } });
14564
+ ], template: "<div\n class=\"form-group container-box\"\n [class.has-danger]=\"hasErrorsToDisplay()\"\n [class.vd-form-group-danger]=\"hasErrorsToDisplay()\"\n [class.drop-zone-highlight]=\"showDropZone\"\n [attr.id]=\"buildId('Container')\"\n tabindex=\"-1\"\n (drop)=\"onDrop($event)\"\n (dragenter)=\"onDragenter($event)\"\n (dragleave)=\"onDragleave($event)\"\n (dragover)=\"onDragover($event)\"\n #fallBackTrigger\n>\n @if (!!label()) {\n <label\n [class]=\"\n 'form-label ' +\n (isLabelSrOnly()\n ? 'visually-hidden'\n : (labelStyleModifier() ?? ''))\n \"\n [attr.for]=\"buildChildId()\"\n >\n <span [innerHTML]=\"label()\"></span>\n @if (!required() && !hideNotRequiredExtraLabel()) {\n <span aria-hidden=\"true\">\n {{ optionalLabelKey() | fromDictionary }}\n </span>\n }\n </label>\n }\n\n <foehn-validation-alerts\n [component]=\"this\"\n [shouldErrorsBeLive]=\"hasLiveUploadErrors()\"\n />\n\n @if (helpText()) {\n <small\n [attr.id]=\"buildChildId('Help')\"\n class=\"form-text text-secondary\"\n [innerHTML]=\"helpText()\"\n ></small>\n }\n\n <!-- PRESTAKIT-309: Fake input with NgModel to be registered into Form controls -->\n <input type=\"hidden\" [name]=\"name() || label() || ''\" [ngModel]=\"model()\" />\n\n <ng-content />\n\n @for (document of model(); track trackByDocument($index, document)) {\n <div class=\"file file-uploaded\">\n <!-- prettier-ignore -->\n <a [href]=\"getDocumentDownloadUrl(document)\" target=\"_blank\">{{ document.filename }}</a>\n <span class=\"ms-1 me-1\">\n ({{ toMegaOctets(document.fileSize ?? 0) }}\n <abbr\n [title]=\"\n 'foehn-uploader.abbr-megaoctet-title' | fromDictionary\n \"\n >\n {{ 'foehn-uploader.abbr-megaoctet' | fromDictionary }}\n </abbr>\n )\n </span>\n @if (isPending(document)) {\n <span class=\"fst-italic text-secondary\">\n ({{ 'foehn-uploader.pending-label' | fromDictionary }})\n </span>\n }\n @if (!readonly() && !document.readonly) {\n <button\n [disabled]=\"disabled()\"\n type=\"button\"\n class=\"btn btn-link icon-button delete-uploaded\"\n (click)=\"removeFile(document)\"\n >\n <foehn-icon-times\n [title]=\"\n 'foehn-uploader.delete-icon-title'\n | fromDictionary: { docName: document.filename }\n \"\n />\n </button>\n }\n </div>\n }\n\n @if (showGlobalInfos(model())) {\n <small\n class=\"form-text text-secondary uploaded-global-info\"\n [innerHTML]=\"getGlobalInfos(model())\"\n ></small>\n }\n\n @if (canAddMoreFiles()) {\n <input\n class=\"form-control actual-input\"\n type=\"file\"\n [name]=\"name() || label()\"\n [multiple]=\"multiple()\"\n [attr.accept]=\"\n overrideAcceptedExtensions()\n ? overrideAcceptedExtensions()\n : uploaderHelper.accept\n ? uploaderHelper.accept\n : null\n \"\n (change)=\"onFileChange($event)\"\n #inputFile\n />\n\n <button\n type=\"button\"\n [class]=\"'btn btn-primary ' + (chooseButtonStyleModifier() ?? '')\"\n [disabled]=\"disabled()\"\n [class.visually-hidden]=\"!showUploadButton()\"\n [attr.id]=\"buildChildId()\"\n [attr.aria-invalid]=\"hasErrorsToDisplay() || null\"\n [attr.aria-describedby]=\"buildId('ErrorsContainer')\"\n (click)=\"inputFile.click()\"\n #entryComponent\n >\n {{\n multiple()\n ? resolvedChooseButtonLabelMultiple()\n : resolvedChooseButtonLabel()\n }}\n </button>\n\n @if (dragAndDrop() && !disabled()) {\n <div\n aria-hidden=\"true\"\n class=\"dropfile\"\n [class.dropfile-border-transparent]=\"showDropZone\"\n (click)=\"inputFile.click()\"\n >\n {{\n multiple()\n ? resolvedDropZoneLabelMultiple()\n : resolvedDropZoneLabel()\n }}\n </div>\n }\n }\n\n <foehn-upload-progress-bar\n [progressBarTriggerHtmlElement]=\"\n inputElement()?.nativeElement || fallBackTrigger\n \"\n />\n</div>\n", styles: [".dropfile{width:300px;border:3px dashed #bbb;text-align:center;margin-top:10px;cursor:pointer;padding:15px 3px}.dropfile-border-transparent{border-color:#fff}.actual-input{display:none}.file-list{margin-top:20px}.icon-button{border:0}.icon-button:hover{cursor:pointer}:host ::ng-deep .svg-inline--fa{color:#000!important}.drop-zone-highlight{outline:3px dashed #bbb}.container-box{border:1px solid #ededed;background-color:#fbfbfb;padding:.5rem}.container-box.vd-form-group-danger{border-left:5px solid var(--vd-danger);padding-left:1rem}\n"] }]
14565
+ }], propDecorators: { uploadUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadUrl", required: false }] }], deleteUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "deleteUrl", required: false }] }], downloadUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "downloadUrl", required: false }] }], optionalLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabelKey", required: false }] }], localUpload: [{ type: i0.Input, args: [{ isSignal: true, alias: "localUpload", required: false }] }], maxFileSizeInMo: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSizeInMo", required: false }] }], chooseButtonStyleModifier: [{ type: i0.Input, args: [{ isSignal: true, alias: "chooseButtonStyleModifier", required: false }] }], documentDeleted: [{ type: i0.Output, args: ["documentDeleted"] }] } });
14474
14566
 
14475
14567
  class FoehnPictureUploadComponent extends FoehnInputComponent {
14476
14568
  key = input(...(ngDevMode ? [undefined, { debugName: "key" }] : /* istanbul ignore next */ []));
@@ -16000,5 +16092,5 @@ class SdkLog {
16000
16092
  * Generated bundle index. Do not edit.
16001
16093
  */
16002
16094
 
16003
- export { APP_INFO_API_URL, AbstractFoehnUploaderComponent, AbstractListDetailPageComponent, AbstractMenuPageComponent, AbstractPageComponent, AbstractPageFromMenuComponent, ActionStatut, Address, AddressTypeLight, ApplicationInfo, ApplicationInfoService, BAD_PARAMS_HELP_TEXT, BoDocumentError, BoDocumentsWithErrors, BoMultiUploadService, Breadcrumb, BreadcrumbEventService, BreadcrumbItem, CAPTCHA_ERROR_NAME, CURRENCY_REGEXP, Calendar, Canton, Captcha, ChunkLoadErrorHandler, Configuration, Country, CurrencyHelper, CurrentWeek, DECIMALS_SEPARATOR, DEFAULT_INTERNATIONAL_FIX_AND_MOBILE, DEFAULT_INTERNATIONAL_FIX_ONLY, DEFAULT_INTERNATIONAL_MOBILE_ONLY, DEFAULT_PREFIX, DEFAULT_SWISS_FIX_AND_MOBILE, DEFAULT_SWISS_FIX_ONLY, DEFAULT_SWISS_MOBILE_ONLY, DICTIONARY_BASE_URL, DateHelper, DatePickerHelper, DatePickerNavigationHelper, DayMonth, DaySlots, DemandeExpirationService, DemandeHelper, DisplayCurrencyPipe, DisplayDatePipe, District, Document, DocumentError, DocumentReference, DocumentReferenceWithFile, DocumentsWithErrors, DropdownMenuGroup, DropdownMenuItem, EPaymentService, EtapeInfo, FEEDBACK_USAGERS_LOCAL_STORAGE_PREFIX, FORM_SUPPORT_CYBER_TITLE_FALLBACK, FocusedDay, FoehnAbbrComponent, FoehnAgendaComponent, FoehnAgendaNavigationComponent, FoehnAgendaTimeslotPanelComponent, FoehnAutocompleteComponent, FoehnBoMultiUploadComponent, FoehnBooleanCheckboxComponent, FoehnBooleanRadioComponent, FoehnBreadcrumbComponent, FoehnCheckableGroupComponent, FoehnCheckboxComponent, FoehnConfirmModalComponent, FoehnConfirmModalContent, FoehnConfirmModalService, FoehnDateComponent, FoehnDatePickerButtonComponent, FoehnDatePickerComponent, FoehnDateTimeComponent, FoehnDecisionElectroniqueComponent, FoehnDisplayAddressComponent, FoehnDropdownMenuComponent, FoehnErrorPillComponent, FoehnFeedbackNotificationComponent, FoehnFormComponent, FoehnGlobalUploadProgressBarComponent, FoehnHeaderComponent, FoehnHelpModalComponent, FoehnIconCalendarComponent, FoehnIconCheckComponent, FoehnIconCheckSquareOComponent, FoehnIconChevronDownComponent, FoehnIconChevronLeftComponent, FoehnIconChevronRightComponent, FoehnIconChevronUpComponent, FoehnIconClockComponent, FoehnIconCommentDotsComponent, FoehnIconEditComponent, FoehnIconExternalLinkAltComponent, FoehnIconFilePdfComponent, FoehnIconInfoCircleComponent, FoehnIconLockComponent, FoehnIconMapMarkerComponent, FoehnIconMinusCircleComponent, FoehnIconPencilComponent, FoehnIconPlusCircleComponent, FoehnIconPlusSquareComponent, FoehnIconSearchComponent, FoehnIconTimesComponent, FoehnIconTrashAltComponent, FoehnIconUnlockAltComponent, FoehnIconUserComponent, FoehnInputAddressComponent, FoehnInputComponent, FoehnInputEmailComponent, FoehnInputForeignLocalityComponent, FoehnInputForeignStreetComponent, FoehnInputHiddenComponent, FoehnInputNav13Component, FoehnInputNumberComponent, FoehnInputPasswordComponent, FoehnInputPhoneComponent, FoehnInputPrefixedTextComponent, FoehnInputStringComponent, FoehnInputTextComponent, FoehnInputTextareaComponent, FoehnListComponent, FoehnListItem, FoehnListSummaryComponent, FoehnMenuItemComponent, FoehnMenuItemTransmitComponent, FoehnModalComponent, FoehnMultiUploadComponent, FoehnMultiselectAutocompleteComponent, FoehnNavigationComponent, FoehnNavigationService, FoehnNotfoundComponent, FoehnPageComponent, FoehnPageCounterComponent, FoehnPageExpirationTimerComponent, FoehnPageModalComponent, FoehnPageService, FoehnPictureUploadComponent, FoehnRadioComponent, FoehnRecapSectionComponent, FoehnRemainingAlertsSummaryComponent, FoehnSelectComponent, FoehnSimpleNavigationComponent, FoehnSkipLinkComponent, FoehnStatusProgressBarComponent, FoehnTableColumnConfiguration, FoehnTableComponent, FoehnTablePageChangeEvent, FoehnTimeComponent, FoehnTransmitWaitingModalComponent, FoehnTransmitWaitingModalService, FoehnUploadProgressBarComponent, FoehnUserConnectedAsComponent, FoehnValidationAlertSummaryComponent, FoehnValidationAlertsComponent, FooterLink, FormMetadata, FormPostResponse, FormSelectOption, FormatAvsPipe, FormatIdePipe, GESDEM_MAX_DATA_LENGTH, GesdemActionRecoveryLoginComponent, GesdemActionRecoveryRegistrationComponent, GesdemConfirmationComponent, GesdemErrorComponent, GesdemEventService, GesdemHandlerService, GesdemStatutUtils, GlobalUploadProgressService, GrowlBrokerService, GrowlMessage, GrowlType, HTTP_LOADER_FILTERED_URL, I18nForm, IAM_ACV_OIDC_REDIRECT_LOCATION_REGEX, IAM_ACV_REDIRECT_LOCATION_REGEX, IbanFormatterDirective, IdeFormatterDirective, IntervalHelper, LineBreakAsHtmlPipe, Locality, MonthYear, MultiUploadService, Municipality, NDCFormatterDirective, NEVER_CONNECTED, NavigationDirection, NumberCurrencyFormatterDirective, OIDC_ENABLED, ObjectHelper, PORTAIL_BASE_URL_INT, PORTAIL_BASE_URL_PROD, PORTAIL_BASE_URL_VAL, PageChangeEvent, PageUploadLimitService, PaginationWeek, PendingFiles, PendingPaymentComponent, PendingUploadService, PlaceOfOrigin, Portail, PostalLocality, Preferences, RECAPTCHA_API_URL, RecaptchaService, RedirectComponent, RegisterNgModelService, RowElement, SESSION_INFO_API_URL, SWISS_ISO_ID, ScrollHelper, SdkDictionaryPipe, SdkDictionaryService, SdkEpaymentComponent, SdkEvent, SdkEventType, SdkEventsLoggerService, SdkLog, SdkLogLevel, SdkLogsService, SdkRecaptchaComponent, SdkStatisticsService, SelectedSlot, Session, SessionInfo, SessionInfoData, SessionInfoWithApplicationService, Street, StreetNumber, StringHelper, THOUSANDS_SEPARATOR, TRANSMIT_WAITING_MODAL_DELAY_IN_MILLISECONDS, TableSort, UploadProgress, UploadProgressService, UploaderHelper, ValidationHandlerService, formatDecimalCurrency, formatNonDecimalCurrency, formatNumberAsGiven, gesdemLoaderGuard, providePrestationsNgCore, replaceAll };
16095
+ export { APP_INFO_API_URL, AbstractFoehnUploaderComponent, AbstractListDetailPageComponent, AbstractMenuPageComponent, AbstractPageComponent, AbstractPageFromMenuComponent, ActionStatut, Address, AddressTypeLight, ApplicationInfo, ApplicationInfoService, BAD_PARAMS_HELP_TEXT, BoDocumentError, BoDocumentsWithErrors, BoMultiUploadService, Breadcrumb, BreadcrumbEventService, BreadcrumbItem, CAPTCHA_ERROR_NAME, CURRENCY_REGEXP, Calendar, Canton, Captcha, ChunkLoadErrorHandler, Configuration, Country, CurrencyHelper, CurrentWeek, DECIMALS_SEPARATOR, DEFAULT_INTERNATIONAL_FIX_AND_MOBILE, DEFAULT_INTERNATIONAL_FIX_ONLY, DEFAULT_INTERNATIONAL_MOBILE_ONLY, DEFAULT_PREFIX, DEFAULT_SWISS_FIX_AND_MOBILE, DEFAULT_SWISS_FIX_ONLY, DEFAULT_SWISS_MOBILE_ONLY, DICTIONARY_BASE_URL, DateHelper, DatePickerHelper, DatePickerNavigationHelper, DayMonth, DaySlots, DemandeExpirationService, DemandeHelper, DisplayCurrencyPipe, DisplayDatePipe, District, Document, DocumentError, DocumentReference, DocumentReferenceWithFile, DocumentsWithErrors, DropdownMenuGroup, DropdownMenuItem, EPaymentService, EtapeInfo, FEEDBACK_USAGERS_LOCAL_STORAGE_PREFIX, FORM_SUPPORT_CYBER_TITLE_FALLBACK, FocusedDay, FoehnAbbrComponent, FoehnAgendaComponent, FoehnAgendaNavigationComponent, FoehnAgendaTimeslotPanelComponent, FoehnAutocompleteComponent, FoehnBoMultiUploadComponent, FoehnBooleanCheckboxComponent, FoehnBooleanRadioComponent, FoehnBreadcrumbComponent, FoehnCheckableGroupComponent, FoehnCheckboxComponent, FoehnConfirmModalComponent, FoehnConfirmModalContent, FoehnConfirmModalService, FoehnDateComponent, FoehnDatePickerButtonComponent, FoehnDatePickerComponent, FoehnDateTimeComponent, FoehnDecisionElectroniqueComponent, FoehnDisplayAddressComponent, FoehnDropdownMenuComponent, FoehnErrorPillComponent, FoehnFeedbackNotificationComponent, FoehnFormComponent, FoehnGlobalUploadProgressBarComponent, FoehnHeaderComponent, FoehnHelpModalComponent, FoehnIconCalendarComponent, FoehnIconCheckComponent, FoehnIconCheckSquareOComponent, FoehnIconChevronDownComponent, FoehnIconChevronLeftComponent, FoehnIconChevronRightComponent, FoehnIconChevronUpComponent, FoehnIconClockComponent, FoehnIconCommentDotsComponent, FoehnIconEditComponent, FoehnIconExternalLinkAltComponent, FoehnIconFilePdfComponent, FoehnIconInfoCircleComponent, FoehnIconLockComponent, FoehnIconMapMarkerComponent, FoehnIconMinusCircleComponent, FoehnIconPencilComponent, FoehnIconPlusCircleComponent, FoehnIconPlusSquareComponent, FoehnIconSearchComponent, FoehnIconTimesComponent, FoehnIconTrashAltComponent, FoehnIconUnlockAltComponent, FoehnIconUserComponent, FoehnInputAddressComponent, FoehnInputComponent, FoehnInputEmailComponent, FoehnInputForeignLocalityComponent, FoehnInputForeignStreetComponent, FoehnInputHiddenComponent, FoehnInputNav13Component, FoehnInputNumberComponent, FoehnInputPasswordComponent, FoehnInputPhoneComponent, FoehnInputPrefixedTextComponent, FoehnInputStringComponent, FoehnInputTextComponent, FoehnInputTextareaComponent, FoehnListComponent, FoehnListItem, FoehnListSummaryComponent, FoehnMenuItemComponent, FoehnMenuItemTransmitComponent, FoehnModalComponent, FoehnMultiUploadComponent, FoehnMultiselectAutocompleteComponent, FoehnNavigationComponent, FoehnNavigationService, FoehnNotfoundComponent, FoehnPageComponent, FoehnPageCounterComponent, FoehnPageExpirationTimerComponent, FoehnPageModalComponent, FoehnPageService, FoehnPictureUploadComponent, FoehnRadioComponent, FoehnRecapSectionComponent, FoehnRemainingAlertsSummaryComponent, FoehnSelectComponent, FoehnSimpleNavigationComponent, FoehnSkipLinkComponent, FoehnStatusProgressBarComponent, FoehnTableColumnConfiguration, FoehnTableComponent, FoehnTablePageChangeEvent, FoehnTimeComponent, FoehnTransmitWaitingModalComponent, FoehnTransmitWaitingModalService, FoehnUploadProgressBarComponent, FoehnUserConnectedAsComponent, FoehnValidationAlertSummaryComponent, FoehnValidationAlertsComponent, FooterLink, FormMetadata, FormPostResponse, FormSelectOption, FormatAvsPipe, FormatIdePipe, GESDEM_MAX_DATA_LENGTH, GesdemActionRecoveryLoginComponent, GesdemActionRecoveryRegistrationComponent, GesdemConfirmationComponent, GesdemErrorComponent, GesdemEventService, GesdemHandlerService, GesdemStatutUtils, GlobalUploadProgressService, GrowlBrokerService, GrowlMessage, GrowlType, HTTP_LOADER_FILTERED_URL, I18nForm, IAM_ACV_OIDC_REDIRECT_LOCATION_REGEX, IAM_ACV_REDIRECT_LOCATION_REGEX, IbanFormatterDirective, IdeFormatterDirective, IntervalHelper, LineBreakAsHtmlPipe, Locality, MonthYear, MultiUploadService, Municipality, NDCFormatterDirective, NEVER_CONNECTED, NavigationDirection, NumberCurrencyFormatterDirective, OIDC_ENABLED, ObjectHelper, PORTAIL_BASE_URL_INT, PORTAIL_BASE_URL_PROD, PORTAIL_BASE_URL_VAL, PageChangeEvent, PageUploadLimitService, PaginationWeek, PendingFiles, PendingPaymentComponent, PendingUploadService, PlaceOfOrigin, Portail, PostalLocality, Preferences, RECAPTCHA_API_URL, RecaptchaService, RedirectComponent, RegisterNgModelService, RowElement, SESSION_INFO_API_URL, SWISS_ISO_ID, ScrollHelper, SdkDictionaryPipe, SdkDictionaryService, SdkEpaymentComponent, SdkEvent, SdkEventType, SdkEventsLoggerService, SdkLog, SdkLogLevel, SdkLogsService, SdkRecaptchaComponent, SdkStatisticsService, SelectedSlot, Session, SessionInfo, SessionInfoData, SessionInfoWithApplicationService, Street, StreetNumber, StringHelper, THOUSANDS_SEPARATOR, TRANSMIT_WAITING_MODAL_DELAY_IN_MILLISECONDS, TableSort, UploadProgress, UploadProgressService, UploaderHelper, ValidationHandlerService, formatDecimalCurrency, formatNonDecimalCurrency, formatNumberAsGiven, gesdemLoaderGuard, getSafeFileNameForErrorMessage, providePrestationsNgCore, replaceAll, splitDocumentChanges };
16004
16096
  //# sourceMappingURL=dsivd-prestations-ng.mjs.map