@cityway/bo-ui 1.1.0-beta007 → 1.1.0-beta009

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.
Binary file
@@ -35,7 +35,7 @@ vers une URL connue (`cw-file-to-download` de `basic-ui`).
35
35
  | Input | Type | Défaut | Description |
36
36
  |-------|------|--------|-------------|
37
37
  | `options` | `ExportOptions` | — (**requis**) | Options proposées, dans l'ordre d'affichage. **Tuple non vide.** |
38
- | `label` | `I18nKey` | `_COMMON._ACTION.EXPORT` | Clé i18n du libellé du bouton (ou du menu). |
38
+ | `label` | `I18nKey` | `_COMMON._ACTION.EXPORT` | Clé i18n du libellé du **déclencheur de menu** (deux options ou plus). Avec une **seule** option, c'est le `label` de cette option qui nomme le bouton — cet input est alors sans effet. |
39
39
  | `errorKey` | `I18nKey` | `_COMMON._EXPORT.ERROR` | Clé i18n du message du toast d'échec. |
40
40
  | `successKey` | `I18nKey \| null` | `null` | Clé i18n d'un toast de succès. `null` → **aucun toast**. |
41
41
 
@@ -53,7 +53,7 @@ interface ExportPayload {
53
53
  }
54
54
 
55
55
  interface ExportOption {
56
- label: I18nKey; // clé i18n, traduite par le composant
56
+ label: I18nKey; // clé i18n ; nomme l'entrée de menu, ou LE BOUTON si option unique
57
57
  fn: () => Observable<ExportPayload>; // produit le fichier
58
58
  disabled?: boolean; // [Option] désactive CETTE option seule
59
59
  }
@@ -341,7 +341,7 @@ class DragNDropNestedListComponent {
341
341
  }));
342
342
  }
343
343
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: DragNDropNestedListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
344
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: DragNDropNestedListComponent, isStandalone: true, selector: "cw-drag-n-drop-nested-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: false, transformFunction: null }, reorderOnDrop: { classPropertyName: "reorderOnDrop", publicName: "reorderOnDrop", isSignal: true, isRequired: false, transformFunction: null }, maxDepth: { classPropertyName: "maxDepth", publicName: "maxDepth", isSignal: true, isRequired: false, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemsChange: "itemsChange", view: "view", edit: "edit", delete: "delete", restore: "restore", add: "add" }, ngImport: i0, template: "<div class=\"ddn-list d-flex-v gap-md\">\n <div class=\"d-flex-h justify-between\">\n @if (column()?.title) {\n <h2>{{ column()!.title | translate }} ({{ columnCountLabel() }})</h2>\n }\n\n @if (column()?.showAddRoot) {\n <cw-button cssClass=\"ddn-list-add\" [type]=\"buttonType.link\" [withIcon]=\"spriteIcon.add\"\n [iconPosition]=\"buttonPosition.left\" [label]=\"column()?.addRootLabel ?? column()?.addLabel ?? '_COMMON._ACTION.ADD'\"\n [isDisabled]=\"isLevelFull(_items, 0)\" (btnAction)=\"onAdd(undefined, 0)\" />\n }\n </div>\n\n <ng-container *ngTemplateOutlet=\"nodeTpl; context: { $implicit: _items, depth: 0, parent: undefined }\" />\n</div>\n\n<!--\n Template r\u00E9cursif : \u00E0 chaque niveau, on rend un cdkDropList isol\u00E9\n (pas de cdkDropListConnectedTo => transfert inter-listes impossible),\n puis on r\u00E9-instancie le m\u00EAme template pour la sous-liste de chaque enfant.\n-->\n<ng-template #nodeTpl let-nodes let-depth=\"depth\" let-parent=\"parent\">\n @if (isLevelFull(nodes, depth)) {\n <cw-alert [type]=\"alertType.warning\" cssClass=\"ddn-list-max-alert\">\n {{ (column()?.maxReachedLabel ?? '_COMMON.MAX_ITEMS_REACHED') | translate:{ max: levelMax(depth) } }}\n </cw-alert>\n }\n\n <ul class=\"list-unstyled d-flex-v gap-md ms-none\" [ngClass]=\"column()?.cssClass\" [attr.data-depth]=\"depth\"\n cdkDropList [cdkDropListData]=\"nodes\" (cdkDropListDropped)=\"drop($event)\">\n\n @for (item of nodes; track item.id) {\n <li cdkDrag [cdkDragDisabled]=\"(item.disabled ?? false) || (item.pendingDelete ?? false)\" cdkDragPreviewClass=\"ddn-list-card-preview\">\n <cw-card [cssClass]=\"cardCssClass(item)\" [title]=\"(item.title ?? item.label) || ''\"\n [subtitle]=\"item.subtitle ?? ''\" [type]=\"cardType(depth)\" [collapsible]=\"isCollapsible(item, depth)\"\n [collapsed]=\"isCollapsible(item, depth)\" [collapseStretched]=\"false\">\n\n <!-- Poign\u00E9e de drag (\u00E0 gauche du titre) : le glisser ne d\u00E9marre que d'ici -->\n <button header-start type=\"button\" class=\"ddn-list-handle\" cdkDragHandle\n [disabled]=\"(item.disabled ?? false) || (item.pendingDelete ?? false)\" [attr.aria-label]=\"'_COMMON._ACTION.MOVE' | translate\">\n <cw-icon [icon]=\"spriteIcon.grip\" [iconSize]=\"iconSize['md']\" />\n </button>\n\n <!-- En-t\u00EAte : compteur d'enfants + badge + actions -->\n <div header-custom-area class=\"d-flex-h gap-2xs justify-end align-start\">\n @if (childrenCountLabel(item, depth); as count) {\n <span class=\"ddn-list-count fs fs-xs\">{{ count }}</span>\n }\n\n @if (item.badge) {\n <cw-badge [type]=\"item.badge.type\" [label]=\"item.badge.label\" [withIcon]=\"item.badge.icon\" />\n }\n\n <!-- Sur une carte pendingDelete, seul \u00AB Restaurer \u00BB est propos\u00E9 (view/edit masqu\u00E9s). -->\n @if (!item.pendingDelete && showAction(item, 'view')) {\n <cw-button label=\"_COMMON._ACTION.VIEW\" [withIcon]=\"spriteIcon.search\" [withOnlyIcon]=\"true\"\n [type]=\"buttonType.secondary\" [iconSize]=\"buttonIconSize.xsmall\" (btnAction)=\"view.emit(item)\" />\n }\n @if (!item.pendingDelete && showAction(item, 'edit')) {\n <cw-button label=\"_COMMON._ACTION.EDIT\" [withIcon]=\"spriteIcon.edit\" [withOnlyIcon]=\"true\"\n [type]=\"buttonType.secondary\" [iconSize]=\"buttonIconSize.xsmall\" (btnAction)=\"edit.emit(item)\" />\n }\n @if (showAction(item, 'delete')) {\n @if (item.pendingDelete) {\n <!-- Soft-delete : la corbeille bascule en \u00AB Restaurer \u00BB (d\u00E9sactiv\u00E9 si le niveau est plein). -->\n <cw-button label=\"_COMMON._ACTION.RESTORE\" [withIcon]=\"spriteIcon.toolbarRefresh\" [withOnlyIcon]=\"true\"\n [type]=\"buttonType.secondary\" cssClass=\"ddn-list-action-restore\"\n [isDisabled]=\"isRestoreBlocked(nodes, depth)\"\n [iconSize]=\"buttonIconSize.xsmall\" (btnAction)=\"restore.emit(item)\" />\n } @else {\n <cw-button label=\"_COMMON._ACTION.DELETE\" [withIcon]=\"spriteIcon.trash\" [withOnlyIcon]=\"true\"\n [type]=\"buttonType.secondary\" cssClass=\"ddn-list-action-delete\"\n [iconSize]=\"buttonIconSize.xsmall\" (btnAction)=\"delete.emit(item)\" />\n }\n }\n </div>\n\n <!-- Restauration impossible : niveau plein (mode excludePendingDeleteFromMax). -->\n @if (item.pendingDelete && isRestoreBlocked(nodes, depth)) {\n <cw-alert [type]=\"alertType.warning\" cssClass=\"ddn-list-restore-blocked-alert\">\n {{ (column()?.restoreBlockedLabel ?? '_COMMON.MAX_RESTORE_BLOCKED') | translate:{ max: levelMax(depth) } }}\n </cw-alert>\n }\n\n <!-- Corps masqu\u00E9 sur une carte pendingDelete : on n'affiche que l'en-t\u00EAte (carte compacte,\n non pliable, non d\u00E9pla\u00E7able). L'encart \u00AB restauration impossible \u00BB ci-dessus reste, lui, visible. -->\n @if (!item.pendingDelete) {\n <!-- Corps : template custom (slot) ou fallback -->\n <ng-container\n *ngTemplateOutlet=\"itemTemplate() || defaultTemplate; context: { $implicit: item, depth: depth }\" />\n\n @if (item.children?.length) {\n <ng-container\n *ngTemplateOutlet=\"nodeTpl; context: { $implicit: item.children, depth: depth + 1, parent: item }\" />\n }\n\n @if (canAdd(item, depth)) {\n <div class=\"d-flex-h justify-end\">\n <cw-button class=\"ddn-list-add\" [type]=\"buttonType.link\" [withIcon]=\"spriteIcon.add\"\n [iconPosition]=\"buttonPosition.left\" [label]=\"column()?.addLabel ?? '_COMMON._ACTION.ADD'\"\n [isDisabled]=\"isLevelFull(item.children ?? [], depth + 1)\" (btnAction)=\"onAdd(item, depth + 1)\" />\n </div>\n }\n }\n </cw-card>\n </li>\n }\n\n </ul>\n</ng-template>\n\n<ng-template #defaultTemplate let-item>\n <div class=\"default-item d-flex justify-content-between\">\n <span>\n {{ item.label }}\n @if (item.code) { <span class=\"text-muted\">({{ item.code }})</span> }\n </span>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1$1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: CardComponent, selector: "cw-card", inputs: ["title", "subtitle", "type", "titleRank", "cssClass", "collapsible", "collapsed", "disabled", "collapseLocked", "collapseStretched", "collapseId", "destroyOnHide"], outputs: ["collapsibleChange", "destroyOnHideChange", "collapseClicked"] }, { kind: "component", type: BadgeComponent, selector: "cw-badge", inputs: ["type", "label", "withIcon", "iconPosition", "cssClass", "skeletonMode", "dataTest"] }, { kind: "component", type: IconComponent, selector: "cw-icon", inputs: ["icon", "label", "type", "iconSize", "iconCssClass", "iconUiType", "iconColorCustom", "spritePath"] }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "component", type: AlertComponent, selector: "cw-alert", inputs: ["type", "title", "isDismissible", "cssClass", "dataTest"], outputs: ["close"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
344
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: DragNDropNestedListComponent, isStandalone: true, selector: "cw-drag-n-drop-nested-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: false, transformFunction: null }, reorderOnDrop: { classPropertyName: "reorderOnDrop", publicName: "reorderOnDrop", isSignal: true, isRequired: false, transformFunction: null }, maxDepth: { classPropertyName: "maxDepth", publicName: "maxDepth", isSignal: true, isRequired: false, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemsChange: "itemsChange", view: "view", edit: "edit", delete: "delete", restore: "restore", add: "add" }, ngImport: i0, template: "<div class=\"ddn-list d-flex-v gap-md\">\n <div class=\"d-flex-h justify-between\">\n @if (column()?.title) {\n <h2>{{ column()!.title | translate }} ({{ columnCountLabel() }})</h2>\n }\n\n @if (column()?.showAddRoot) {\n <cw-button cssClass=\"ddn-list-add\" [type]=\"buttonType.link\" [withIcon]=\"spriteIcon.add\"\n [iconPosition]=\"buttonPosition.left\" [label]=\"column()?.addRootLabel ?? column()?.addLabel ?? '_COMMON._ACTION.ADD'\"\n [isDisabled]=\"isLevelFull(_items, 0)\" (btnAction)=\"onAdd(undefined, 0)\" />\n }\n </div>\n\n <ng-container *ngTemplateOutlet=\"nodeTpl; context: { $implicit: _items, depth: 0, parent: undefined }\" />\n</div>\n\n<!--\n Template r\u00E9cursif : \u00E0 chaque niveau, on rend un cdkDropList isol\u00E9\n (pas de cdkDropListConnectedTo => transfert inter-listes impossible),\n puis on r\u00E9-instancie le m\u00EAme template pour la sous-liste de chaque enfant.\n-->\n<ng-template #nodeTpl let-nodes let-depth=\"depth\" let-parent=\"parent\">\n @if (isLevelFull(nodes, depth)) {\n <cw-alert [type]=\"alertType.warning\" cssClass=\"ddn-list-max-alert\">\n {{ (column()?.maxReachedLabel ?? '_COMMON.MAX_ITEMS_REACHED') | translate:{ max: levelMax(depth) } }}\n </cw-alert>\n }\n\n <ul class=\"list-unstyled d-flex-v gap-md ms-none\" [ngClass]=\"column()?.cssClass\" [attr.data-depth]=\"depth\"\n cdkDropList [cdkDropListData]=\"nodes\" (cdkDropListDropped)=\"drop($event)\">\n\n @for (item of nodes; track item.id) {\n <li cdkDrag [cdkDragDisabled]=\"(item.disabled ?? false) || (item.pendingDelete ?? false)\" cdkDragPreviewClass=\"ddn-list-card-preview\">\n <cw-card [cssClass]=\"cardCssClass(item)\" [title]=\"(item.title ?? item.label) || ''\"\n [subtitle]=\"item.subtitle ?? ''\" [type]=\"cardType(depth)\" [collapsible]=\"isCollapsible(item, depth)\"\n [collapsed]=\"isCollapsible(item, depth)\" [collapseStretched]=\"false\">\n\n <!-- Poign\u00E9e de drag (\u00E0 gauche du titre) : le glisser ne d\u00E9marre que d'ici -->\n <button header-start type=\"button\" class=\"ddn-list-handle\" cdkDragHandle\n [disabled]=\"(item.disabled ?? false) || (item.pendingDelete ?? false)\" [attr.aria-label]=\"'_COMMON._ACTION.MOVE' | translate\">\n <cw-icon [icon]=\"spriteIcon.grip\" [iconSize]=\"iconSize['md']\" />\n </button>\n\n <!-- En-t\u00EAte : compteur d'enfants + badge + actions -->\n <div header-custom-area class=\"d-flex-h gap-2xs justify-end align-start\">\n @if (childrenCountLabel(item, depth); as count) {\n <span class=\"ddn-list-count fs fs-xs\">{{ count }}</span>\n }\n\n @if (item.badge) {\n <cw-badge [type]=\"item.badge.type\" [label]=\"item.badge.label\" [withIcon]=\"item.badge.icon\" />\n }\n\n <!-- Sur une carte pendingDelete, seul \u00AB Restaurer \u00BB est propos\u00E9 (view/edit masqu\u00E9s). -->\n @if (!item.pendingDelete && showAction(item, 'view')) {\n <cw-button label=\"_COMMON._ACTION.VIEW\" [withIcon]=\"spriteIcon.search\" [withOnlyIcon]=\"true\"\n [type]=\"buttonType.secondary\" [iconSize]=\"buttonIconSize.xsmall\" (btnAction)=\"view.emit(item)\" />\n }\n @if (!item.pendingDelete && showAction(item, 'edit')) {\n <cw-button label=\"_COMMON._ACTION.EDIT\" [withIcon]=\"spriteIcon.edit\" [withOnlyIcon]=\"true\"\n [type]=\"buttonType.secondary\" [iconSize]=\"buttonIconSize.xsmall\" (btnAction)=\"edit.emit(item)\" />\n }\n @if (showAction(item, 'delete')) {\n @if (item.pendingDelete) {\n <!-- Soft-delete : la corbeille bascule en \u00AB Restaurer \u00BB (d\u00E9sactiv\u00E9 si le niveau est plein). -->\n <cw-button label=\"_COMMON._ACTION.RESTORE\" [withIcon]=\"spriteIcon.toolbarRefresh\" [withOnlyIcon]=\"true\"\n [type]=\"buttonType.secondary\" cssClass=\"ddn-list-action-restore\"\n [isDisabled]=\"isRestoreBlocked(nodes, depth)\"\n [iconSize]=\"buttonIconSize.xsmall\" (btnAction)=\"restore.emit(item)\" />\n } @else {\n <cw-button label=\"_COMMON._ACTION.DELETE\" [withIcon]=\"spriteIcon.trash\" [withOnlyIcon]=\"true\"\n [type]=\"buttonType.secondary\" cssClass=\"ddn-list-action-delete\"\n [iconSize]=\"buttonIconSize.xsmall\" (btnAction)=\"delete.emit(item)\" />\n }\n }\n </div>\n\n <!-- Restauration impossible : niveau plein (mode excludePendingDeleteFromMax). -->\n @if (item.pendingDelete && isRestoreBlocked(nodes, depth)) {\n <cw-alert [type]=\"alertType.warning\" cssClass=\"ddn-list-restore-blocked-alert\">\n {{ (column()?.restoreBlockedLabel ?? '_COMMON.MAX_RESTORE_BLOCKED') | translate:{ max: levelMax(depth) } }}\n </cw-alert>\n }\n\n <!-- Corps masqu\u00E9 sur une carte pendingDelete : on n'affiche que l'en-t\u00EAte (carte compacte,\n non pliable, non d\u00E9pla\u00E7able). L'encart \u00AB restauration impossible \u00BB ci-dessus reste, lui, visible. -->\n @if (!item.pendingDelete) {\n <!-- Corps : template custom (slot) ou fallback -->\n <ng-container\n *ngTemplateOutlet=\"itemTemplate() || defaultTemplate; context: { $implicit: item, depth: depth }\" />\n\n @if (item.children?.length) {\n <ng-container\n *ngTemplateOutlet=\"nodeTpl; context: { $implicit: item.children, depth: depth + 1, parent: item }\" />\n }\n\n @if (canAdd(item, depth)) {\n <div class=\"d-flex-h justify-end\">\n <cw-button class=\"ddn-list-add\" [type]=\"buttonType.link\" [withIcon]=\"spriteIcon.add\"\n [iconPosition]=\"buttonPosition.left\" [label]=\"column()?.addLabel ?? '_COMMON._ACTION.ADD'\"\n [isDisabled]=\"isLevelFull(item.children ?? [], depth + 1)\" (btnAction)=\"onAdd(item, depth + 1)\" />\n </div>\n }\n }\n </cw-card>\n </li>\n }\n\n </ul>\n</ng-template>\n\n<ng-template #defaultTemplate let-item>\n <div class=\"default-item d-flex justify-content-between\">\n <span>\n {{ item.label }}\n @if (item.code) { <span class=\"text-muted\">({{ item.code }})</span> }\n </span>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1$1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: CardComponent, selector: "cw-card", inputs: ["title", "subtitle", "type", "titleRank", "cssClass", "collapsible", "collapsed", "disabled", "collapseLocked", "collapseStretched", "collapseId", "destroyOnHide"], outputs: ["collapsibleChange", "destroyOnHideChange", "collapseClicked"] }, { kind: "component", type: BadgeComponent, selector: "cw-badge", inputs: ["type", "label", "withIcon", "iconPosition", "cssClass", "skeletonMode", "dataTest"] }, { kind: "component", type: IconComponent, selector: "cw-icon", inputs: ["icon", "label", "type", "iconSize", "iconCssClass", "iconUiType", "iconColorCustom", "spritePath"] }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "loadingAnnounce", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "component", type: AlertComponent, selector: "cw-alert", inputs: ["type", "title", "isDismissible", "cssClass", "dataTest"], outputs: ["close"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
345
345
  }
346
346
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: DragNDropNestedListComponent, decorators: [{
347
347
  type: Component,
@@ -433,7 +433,7 @@ class PaginationComponent {
433
433
  });
434
434
  }
435
435
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
436
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: PaginationComponent, isStandalone: true, selector: "cw-pagination", inputs: { pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { paginationChange: "paginationChange" }, ngImport: i0, template: "@if (pagination().totalPages > 0) {\r\n<div class=\"pagination d-flex-h gap-md justify-between fs fs-sm\">\r\n\r\n <!-- LEFT PART -->\r\n <div class=\"d-flex-h gap-sm\">\r\n {{ '_COMMON._PAGINATION.RESULT_P' | translate: {total: pagination().totalItems } }}\r\n -\r\n {{ '_COMMON._PAGINATION.DISPLAY' | translate }}\r\n\r\n <cw-form-field\r\n [label]=\"'_COMMON._PAGINATION.ITEMS_PER_PAGE'\"\r\n [type]=\"typeField.select\"\r\n [control]=\"itemsPerPageControl\"\r\n [options]=\"pageSizesOptions\"\r\n [displayLabel]=\"false\"\r\n [clearable]=\"false\">\r\n </cw-form-field>\r\n\r\n {{ '_COMMON._PAGINATION.ITEMS_PER_PAGE' | translate }}\r\n </div>\r\n\r\n <!-- PAGINATION -->\r\n <ul class=\"list-unstyled d-flex-h gap-3xs\">\r\n\r\n <!-- PREVIOUS -->\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n [withOnlyIcon]=\"true\"\r\n [withIcon]=\"spriteIcon.nextLeft\"\r\n [isDisabled]=\"pagination().currentPage <= 1\"\r\n [iconSize]=\"buttonIconSize.small\"\r\n cssClass=\"btn-pagination\"\r\n (btnAction)=\"emit(pagination().currentPage - 1)\">\r\n </cw-button>\r\n </li>\r\n\r\n <!-- PAGES -->\r\n @for (item of visiblePages(); track item) {\r\n\r\n <!-- NUMBER -->\r\n @if (typeof item === 'number') {\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n [label]=\"item.toString()\"\r\n [cssClass]=\"item === pagination().currentPage ? 'btn-pagination btn-pagination-active' : 'btn-pagination'\"\r\n (btnAction)=\"emit(item)\">\r\n </cw-button>\r\n </li>\r\n }\r\n\r\n <!-- JUMP PREV -->\r\n @else if (item.type === 'jump-prev') {\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n label=\"...\"\r\n cssClass=\"btn-pagination\"\r\n (btnAction)=\"emit(item.page)\">\r\n </cw-button>\r\n </li>\r\n }\r\n\r\n <!-- JUMP NEXT -->\r\n @else if (item.type === 'jump-next') {\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n label=\"...\"\r\n cssClass=\"btn-pagination\"\r\n (btnAction)=\"emit(item.page)\">\r\n </cw-button>\r\n </li>\r\n }\r\n }\r\n\r\n <!-- NEXT -->\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n [withOnlyIcon]=\"true\"\r\n [withIcon]=\"spriteIcon.nextRight\"\r\n [isDisabled]=\"pagination().currentPage >= pagination().totalPages\"\r\n [iconSize]=\"buttonIconSize.small\"\r\n cssClass=\"btn-pagination\"\r\n (btnAction)=\"emit(pagination().currentPage + 1)\">\r\n </cw-button>\r\n </li>\r\n\r\n </ul>\r\n</div>\r\n}\r\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "component", type: FormFieldComponent, selector: "cw-form-field", inputs: ["control", "formGroup", "type", "label", "displayLabel", "name", "placeholder", "autocomplete", "options", "rangeOptions", "validationOptions", "autocompleteOptions", "richTextOptions", "errorMessages", "isRequired", "help", "tooltip", "addonLeft", "addonRight", "isInAddon", "isReadonly", "isDisabled", "sliderValue", "sliderOptions", "cssClass", "skeletonMode", "clearable", "appendTo", "initialCountry", "indeterminate"], outputs: ["refreshEvent", "textChanged", "valueChange", "phoneRegionChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
436
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: PaginationComponent, isStandalone: true, selector: "cw-pagination", inputs: { pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { paginationChange: "paginationChange" }, ngImport: i0, template: "@if (pagination().totalPages > 0) {\r\n<div class=\"pagination d-flex-h gap-md justify-between fs fs-sm\">\r\n\r\n <!-- LEFT PART -->\r\n <div class=\"d-flex-h gap-sm\">\r\n {{ '_COMMON._PAGINATION.RESULT_P' | translate: {total: pagination().totalItems } }}\r\n -\r\n {{ '_COMMON._PAGINATION.DISPLAY' | translate }}\r\n\r\n <cw-form-field\r\n [label]=\"'_COMMON._PAGINATION.ITEMS_PER_PAGE'\"\r\n [type]=\"typeField.select\"\r\n [control]=\"itemsPerPageControl\"\r\n [options]=\"pageSizesOptions\"\r\n [displayLabel]=\"false\"\r\n [clearable]=\"false\">\r\n </cw-form-field>\r\n\r\n {{ '_COMMON._PAGINATION.ITEMS_PER_PAGE' | translate }}\r\n </div>\r\n\r\n <!-- PAGINATION -->\r\n <ul class=\"list-unstyled d-flex-h gap-3xs\">\r\n\r\n <!-- PREVIOUS -->\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n [withOnlyIcon]=\"true\"\r\n [withIcon]=\"spriteIcon.nextLeft\"\r\n [isDisabled]=\"pagination().currentPage <= 1\"\r\n [iconSize]=\"buttonIconSize.small\"\r\n cssClass=\"btn-pagination\"\r\n (btnAction)=\"emit(pagination().currentPage - 1)\">\r\n </cw-button>\r\n </li>\r\n\r\n <!-- PAGES -->\r\n @for (item of visiblePages(); track item) {\r\n\r\n <!-- NUMBER -->\r\n @if (typeof item === 'number') {\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n [label]=\"item.toString()\"\r\n [cssClass]=\"item === pagination().currentPage ? 'btn-pagination btn-pagination-active' : 'btn-pagination'\"\r\n (btnAction)=\"emit(item)\">\r\n </cw-button>\r\n </li>\r\n }\r\n\r\n <!-- JUMP PREV -->\r\n @else if (item.type === 'jump-prev') {\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n label=\"...\"\r\n cssClass=\"btn-pagination\"\r\n (btnAction)=\"emit(item.page)\">\r\n </cw-button>\r\n </li>\r\n }\r\n\r\n <!-- JUMP NEXT -->\r\n @else if (item.type === 'jump-next') {\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n label=\"...\"\r\n cssClass=\"btn-pagination\"\r\n (btnAction)=\"emit(item.page)\">\r\n </cw-button>\r\n </li>\r\n }\r\n }\r\n\r\n <!-- NEXT -->\r\n <li>\r\n <cw-button\r\n [type]=\"typeButton.ghost\"\r\n [withOnlyIcon]=\"true\"\r\n [withIcon]=\"spriteIcon.nextRight\"\r\n [isDisabled]=\"pagination().currentPage >= pagination().totalPages\"\r\n [iconSize]=\"buttonIconSize.small\"\r\n cssClass=\"btn-pagination\"\r\n (btnAction)=\"emit(pagination().currentPage + 1)\">\r\n </cw-button>\r\n </li>\r\n\r\n </ul>\r\n</div>\r\n}\r\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "loadingAnnounce", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "component", type: FormFieldComponent, selector: "cw-form-field", inputs: ["control", "formGroup", "type", "label", "displayLabel", "name", "placeholder", "autocomplete", "options", "rangeOptions", "validationOptions", "autocompleteOptions", "richTextOptions", "errorMessages", "isRequired", "help", "tooltip", "addonLeft", "addonRight", "isInAddon", "isReadonly", "isDisabled", "sliderValue", "sliderOptions", "cssClass", "skeletonMode", "clearable", "appendTo", "initialCountry", "indeterminate"], outputs: ["refreshEvent", "textChanged", "valueChange", "phoneRegionChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
437
437
  }
438
438
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: PaginationComponent, decorators: [{
439
439
  type: Component,
@@ -771,7 +771,7 @@ class TableComponent {
771
771
  return typeof descriptor.link === 'function' ? descriptor.link(row) : descriptor.link;
772
772
  }
773
773
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
774
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: TableComponent, isStandalone: true, selector: "cw-table", inputs: { checkbox: { classPropertyName: "checkbox", publicName: "checkbox", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, rowClassFn: { classPropertyName: "rowClassFn", publicName: "rowClassFn", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, bulkActions: { classPropertyName: "bulkActions", publicName: "bulkActions", isSignal: true, isRequired: false, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, emptyStateNoData: { classPropertyName: "emptyStateNoData", publicName: "emptyStateNoData", isSignal: true, isRequired: false, transformFunction: null }, emptyStateNoResult: { classPropertyName: "emptyStateNoResult", publicName: "emptyStateNoResult", isSignal: true, isRequired: false, transformFunction: null }, isFiltered: { classPropertyName: "isFiltered", publicName: "isFiltered", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", sortChange: "sortChange", selectionChange: "selectionChange", paginationChange: "paginationChange", bulkDelete: "bulkDelete", bulkAction: "bulkAction" }, host: { classAttribute: "cw-table" }, queries: [{ propertyName: "actionsTemplate", first: true, predicate: ["actionsTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (checkbox() && selectedRows().size > 0) {\n <div class=\"table-selection-info mb-2 d-flex align-items-center gap-2 flex-wrap\">\n <span>\n {{ selectedRows().size }} {{ '_COMMON._TABLE._BULK_ACTION.SELECTED_ITEMS_CURRENT_PAGE' | translate }}\n </span>\n @for (action of bulkActions(); track $index) {\n <cw-button\n [type]=\"resolveVariant(action)\"\n [label]=\"action.label\"\n [withIcon]=\"action.icon\"\n [isDisabled]=\"resolveDisabled(action)\"\n (btnAction)=\"onBulkActionClick(action)\">\n </cw-button>\n }\n </div>\n}\n\n<div class=\"table-responsive\">\n <table class=\"table\">\n <caption class=\"visually-hidden\" [innerHTML]=\"'_COMMON._TABLE.CAPTION' | translate: { label: title() } \"></caption>\n <thead>\n <tr>\n @if(checkbox()) {\n <th scope=\"col\" width=\"10\">\n <div class=\"field-check\">\n <input class=\"field-check-input\" type=\"checkbox\" [id]=\"uid + '-all'\" [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\" (change)=\"toggleAll()\">\n <label class=\"field-check-label\" [for]=\"uid + '-all'\">\n <span class=\"visually-hidden\">{{ '_COMMON._TABLE._THEAD.CHECK_LINE' | translate }}</span>\n </label>\n </div>\n </th>\n }\n\n @for (column of columns(); track column.key) {\n @if (!column.hidden) {\n <th scope=\"col\" [class.p-0]=\"column.sort\" [attr.aria-sort]=\"column.sort ? getAriaSort(column.key) : null\">\n @if (column.sort) {\n <button class=\"d-flex-h gap-2xs\" [class]=\"getSortClass(column.key)\" (click)=\"setSortProperty(column.key)\">\n {{ column.label | translate}}\n <cw-icon\n [icon]=\"getSortIcon(column.key)\"\n [label]=\"'_COMMON._TABLE._SORT.LABEL' | translate\"\n [type]=\"iconType.default\"\n [iconSize]=\"iconSize['xs']\"></cw-icon>\n </button>\n }\n @else {\n {{ column.label | translate }}\n }\n </th>\n }\n }\n </tr>\n </thead>\n <tbody>\n @if (loading()) {\n <tr>\n <td [attr.colspan]=\"visibleColumnCount()\">\n <cw-loader></cw-loader>\n </td>\n </tr>\n }\n @else if (!data() || data().length === 0) {\n <tr>\n <td class=\"table-info no-result\" [attr.colspan]=\"visibleColumnCount()\">\n @if (currentEmptyState(); as empty) {\n <cw-empty-state\n [illustration]=\"empty.illustration ?? (isFiltered() ? illustrationEnum.noResult : illustrationEnum.noData)\"\n [imageSource]=\"empty.imageSource\"\n [title]=\"empty.title\"\n [description]=\"empty.description\"\n [primaryButton]=\"empty.primaryButton\"\n [secondaryButton]=\"empty.secondaryButton\"\n (primaryClick)=\"empty.primaryButton?.click?.()\"\n (secondaryClick)=\"empty.secondaryButton?.click?.()\">\n </cw-empty-state>\n } @else {\n {{ '_COMMON._TABLE.NO_RESULT' | translate }}\n }\n </td>\n </tr>\n }\n @else {\n @for (row of data(); track row) {\n <tr [class.tr-selected]=\"isSelected(row)\" [class]=\"getRowClass(row)\">\n @if (checkbox()) {\n <td>\n <input class=\"field-check-input\" type=\"checkbox\" [checked]=\"isSelected(row)\" (change)=\"toggleRow(row)\" [id]=\"uid + '-check-' + row.id\"\n [attr.aria-label]=\"('_COMMON._TABLE._THEAD.CHECK_LINE' | translate) + ' ' + row.id\">\n <label class=\"visually-hidden\" [for]=\"uid + '-check-' + row.id\">{{ '_COMMON._TABLE._THEAD.CHECK_LINE' | translate }} {{ row.id }}</label>\n </td>\n }\n @for (column of columns(); track column.key) {\n @if (!column.hidden) {\n <td [class.text-end]=\"column.align === 'right'\" [class.text-center]=\"column.align === 'center'\"\n [class.td-actions]=\"column.type === 'actions'\">\n @switch (column.type) {\n @case ('link') {\n <a href=\"javascript:void(0)\" (click)=\"onCellClick(row, column)\">\n {{ column.translate ? (row[column.key] | translate) : row[column.key] }}\n </a>\n }\n @case ('badge') {\n <cw-badge\n [type]=\"getBadge(column, row[column.key]).type\"\n [label]=\"getBadge(column, row[column.key]).label ?? row[column.key]\"\n [withIcon]=\"getBadge(column, row[column.key]).withIcon\"\n [iconPosition]=\"getBadge(column, row[column.key]).iconPosition\"></cw-badge>\n }\n @case ('icon') {\n @if (isClickable(column)) {\n <a href=\"javascript:void(0)\" (click)=\"onCellClick(row, column)\" [attr.aria-label]=\"row[column.key].label\">\n <cw-icon\n [icon]=\"row[column.key].icon\"\n [label]=\"row[column.key].label\"\n [type]=\"iconType.default\"\n [iconSize]=\"iconSize['md']\"\n [iconCssClass]=\"row[column.key].iconCssClass\"\n ></cw-icon>\n </a>\n } @else {\n <cw-icon\n [icon]=\"row[column.key].icon\"\n [label]=\"row[column.key].label\"\n [type]=\"iconType.default\"\n [iconSize]=\"iconSize['md']\"\n [iconCssClass]=\"row[column.key].iconCssClass\"\n ></cw-icon>\n }\n }\n @case ('image') {\n @if (isClickable(column)) {\n <a href=\"javascript:void(0)\" (click)=\"onCellClick(row, column)\" [attr.aria-label]=\"row[column.key].label\">\n <cw-image\n [source]=\"row[column.key].source\"\n [alt]=\"row[column.key].label\"\n [isAriaHidden]=\"true\"\n [cssClass]=\"row[column.key].iconCssClass\"\n width=\"32\"\n height=\"32\"\n ></cw-image>\n </a>\n } @else {\n <cw-image\n [source]=\"row[column.key].source\"\n [alt]=\"row[column.key].label\"\n [isAriaHidden]=\"true\"\n [cssClass]=\"row[column.key].iconCssClass\"\n width=\"32\"\n height=\"32\"\n ></cw-image>\n }\n }\n @case ('check') {\n @if (isTruthy(row[column.key])) {\n <cw-icon\n [icon]=\"spriteIcon.checkCircle\"\n [label]=\"'_COMMON._PRO_SENTENCE.YES' | translate\"\n [type]=\"iconType.default\"\n iconCssClass=\"text-success\"\n [iconSize]=\"iconSize['md']\"></cw-icon>\n } @else {\n <cw-icon\n [icon]=\"spriteIcon.closeCircle\"\n [label]=\"'_COMMON._PRO_SENTENCE.NO' | translate\"\n [type]=\"iconType.default\"\n iconCssClass=\"text-danger\"\n [iconSize]=\"iconSize['md']\"></cw-icon>\n }\n }\n @case ('progressbar') {\n <div class=\"td-progressbar\">\n <cw-progress-bar\n [value]=\"row[column.key]\"\n [size]=\"progressBarSize.sm\"\n [type]=\"progressBarType.information\"></cw-progress-bar>\n <span class=\"td-progressbar-value\">{{ row[column.key] }}%</span>\n </div>\n }\n @case ('actions') {\n @if (usingRowActions) {\n @let actions = getResolvedActions(row);\n @if (actions.length > 0) {\n @if (!useDropdownActions()) {\n @for (action of actions; track $index) {\n <cw-button\n [type]=\"buttonType.ghost\"\n [label]=\"action.label\"\n [withIcon]=\"action.icon\"\n [link]=\"action.link\"\n [isDisabled]=\"action.disabled\"\n [cssClass]=\"actionCssClass(action)\"\n (btnAction)=\"onRowActionClick(action, row)\">\n </cw-button>\n }\n } @else {\n <cw-button\n [label]=\"'_COMMON._TABLE.ACTIONS_MENU'\"\n [withIcon]=\"spriteIcon.menuVertical\"\n [withOnlyIcon]=\"true\"\n [type]=\"buttonType.ghost\"\n [isDropdown]=\"true\"\n [hideCaret]=\"true\">\n <ul class=\"p-0 m-0\">\n @for (action of actions; track $index) {\n <li>\n @if (action.link) {\n <cw-button\n [type]=\"buttonType.ghost\"\n [label]=\"action.label\"\n [withIcon]=\"action.icon\"\n [link]=\"action.link\"\n [isDisabled]=\"action.disabled\"\n [cssClass]=\"'dropdown-item ' + actionCssClass(action)\">\n </cw-button>\n } @else {\n <cw-button\n [type]=\"buttonType.ghost\"\n [label]=\"action.label\"\n [withIcon]=\"action.icon\"\n [isDisabled]=\"action.disabled\"\n [cssClass]=\"'dropdown-item ' + actionCssClass(action)\"\n (btnAction)=\"onRowActionClick(action, row)\">\n </cw-button>\n }\n </li>\n }\n </ul>\n </cw-button>\n }\n }\n } @else {\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate(); context: { $implicit: row }\">\n </ng-container>\n }\n }\n @default {\n {{ column.translate ? (row[column.key] | translate) : row[column.key] }}\n }\n }\n </td>\n }\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (pagination()) {\n <cw-pagination\n [pagination]=\"pagination()!\"\n (paginationChange)=\"paginationChange.emit($event)\">\n </cw-pagination>\n}\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "component", type: LoaderComponent, selector: "cw-loader", inputs: ["size", "displayText"] }, { kind: "component", type: BadgeComponent, selector: "cw-badge", inputs: ["type", "label", "withIcon", "iconPosition", "cssClass", "skeletonMode", "dataTest"] }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PaginationComponent, selector: "cw-pagination", inputs: ["pagination"], outputs: ["paginationChange"] }, { kind: "component", type: IconComponent, selector: "cw-icon", inputs: ["icon", "label", "type", "iconSize", "iconCssClass", "iconUiType", "iconColorCustom", "spritePath"] }, { kind: "component", type: ImageComponent, selector: "cw-image", inputs: ["source", "alt", "isAriaHidden", "cssClass", "width", "height"] }, { kind: "component", type: EmptyStateComponent, selector: "cw-empty-state", inputs: ["illustration", "illustrationBasePath", "imageSource", "imageAlt", "title", "description", "primaryButton", "secondaryButton", "dataTest"], outputs: ["primaryClick", "secondaryClick"] }, { kind: "component", type: ProgressBarComponent, selector: "cw-progress-bar", inputs: ["value", "max", "size", "type", "showValue", "label", "dataTest"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
774
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: TableComponent, isStandalone: true, selector: "cw-table", inputs: { checkbox: { classPropertyName: "checkbox", publicName: "checkbox", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, rowClassFn: { classPropertyName: "rowClassFn", publicName: "rowClassFn", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, bulkActions: { classPropertyName: "bulkActions", publicName: "bulkActions", isSignal: true, isRequired: false, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, emptyStateNoData: { classPropertyName: "emptyStateNoData", publicName: "emptyStateNoData", isSignal: true, isRequired: false, transformFunction: null }, emptyStateNoResult: { classPropertyName: "emptyStateNoResult", publicName: "emptyStateNoResult", isSignal: true, isRequired: false, transformFunction: null }, isFiltered: { classPropertyName: "isFiltered", publicName: "isFiltered", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", sortChange: "sortChange", selectionChange: "selectionChange", paginationChange: "paginationChange", bulkDelete: "bulkDelete", bulkAction: "bulkAction" }, host: { classAttribute: "cw-table" }, queries: [{ propertyName: "actionsTemplate", first: true, predicate: ["actionsTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (checkbox() && selectedRows().size > 0) {\n <div class=\"table-selection-info mb-2 d-flex align-items-center gap-2 flex-wrap\">\n <span>\n {{ selectedRows().size }} {{ '_COMMON._TABLE._BULK_ACTION.SELECTED_ITEMS_CURRENT_PAGE' | translate }}\n </span>\n @for (action of bulkActions(); track $index) {\n <cw-button\n [type]=\"resolveVariant(action)\"\n [label]=\"action.label\"\n [withIcon]=\"action.icon\"\n [isDisabled]=\"resolveDisabled(action)\"\n (btnAction)=\"onBulkActionClick(action)\">\n </cw-button>\n }\n </div>\n}\n\n<div class=\"table-responsive\">\n <table class=\"table\">\n <caption class=\"visually-hidden\" [innerHTML]=\"'_COMMON._TABLE.CAPTION' | translate: { label: title() } \"></caption>\n <thead>\n <tr>\n @if(checkbox()) {\n <th scope=\"col\" width=\"10\">\n <div class=\"field-check\">\n <input class=\"field-check-input\" type=\"checkbox\" [id]=\"uid + '-all'\" [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\" (change)=\"toggleAll()\">\n <label class=\"field-check-label\" [for]=\"uid + '-all'\">\n <span class=\"visually-hidden\">{{ '_COMMON._TABLE._THEAD.CHECK_LINE' | translate }}</span>\n </label>\n </div>\n </th>\n }\n\n @for (column of columns(); track column.key) {\n @if (!column.hidden) {\n <th scope=\"col\" [class.p-0]=\"column.sort\" [attr.aria-sort]=\"column.sort ? getAriaSort(column.key) : null\">\n @if (column.sort) {\n <button class=\"d-flex-h gap-2xs\" [class]=\"getSortClass(column.key)\" (click)=\"setSortProperty(column.key)\">\n {{ column.label | translate}}\n <cw-icon\n [icon]=\"getSortIcon(column.key)\"\n [label]=\"'_COMMON._TABLE._SORT.LABEL' | translate\"\n [type]=\"iconType.default\"\n [iconSize]=\"iconSize['xs']\"></cw-icon>\n </button>\n }\n @else {\n {{ column.label | translate }}\n }\n </th>\n }\n }\n </tr>\n </thead>\n <tbody>\n @if (loading()) {\n <tr>\n <td [attr.colspan]=\"visibleColumnCount()\">\n <cw-loader></cw-loader>\n </td>\n </tr>\n }\n @else if (!data() || data().length === 0) {\n <tr>\n <td class=\"table-info no-result\" [attr.colspan]=\"visibleColumnCount()\">\n @if (currentEmptyState(); as empty) {\n <cw-empty-state\n [illustration]=\"empty.illustration ?? (isFiltered() ? illustrationEnum.noResult : illustrationEnum.noData)\"\n [imageSource]=\"empty.imageSource\"\n [title]=\"empty.title\"\n [description]=\"empty.description\"\n [primaryButton]=\"empty.primaryButton\"\n [secondaryButton]=\"empty.secondaryButton\"\n (primaryClick)=\"empty.primaryButton?.click?.()\"\n (secondaryClick)=\"empty.secondaryButton?.click?.()\">\n </cw-empty-state>\n } @else {\n {{ '_COMMON._TABLE.NO_RESULT' | translate }}\n }\n </td>\n </tr>\n }\n @else {\n @for (row of data(); track row) {\n <tr [class.tr-selected]=\"isSelected(row)\" [class]=\"getRowClass(row)\">\n @if (checkbox()) {\n <td>\n <input class=\"field-check-input\" type=\"checkbox\" [checked]=\"isSelected(row)\" (change)=\"toggleRow(row)\" [id]=\"uid + '-check-' + row.id\"\n [attr.aria-label]=\"('_COMMON._TABLE._THEAD.CHECK_LINE' | translate) + ' ' + row.id\">\n <label class=\"visually-hidden\" [for]=\"uid + '-check-' + row.id\">{{ '_COMMON._TABLE._THEAD.CHECK_LINE' | translate }} {{ row.id }}</label>\n </td>\n }\n @for (column of columns(); track column.key) {\n @if (!column.hidden) {\n <td [class.text-end]=\"column.align === 'right'\" [class.text-center]=\"column.align === 'center'\"\n [class.td-actions]=\"column.type === 'actions'\">\n @switch (column.type) {\n @case ('link') {\n <a href=\"javascript:void(0)\" (click)=\"onCellClick(row, column)\">\n {{ column.translate ? (row[column.key] | translate) : row[column.key] }}\n </a>\n }\n @case ('badge') {\n <cw-badge\n [type]=\"getBadge(column, row[column.key]).type\"\n [label]=\"getBadge(column, row[column.key]).label ?? row[column.key]\"\n [withIcon]=\"getBadge(column, row[column.key]).withIcon\"\n [iconPosition]=\"getBadge(column, row[column.key]).iconPosition\"></cw-badge>\n }\n @case ('icon') {\n @if (isClickable(column)) {\n <a href=\"javascript:void(0)\" (click)=\"onCellClick(row, column)\" [attr.aria-label]=\"row[column.key].label\">\n <cw-icon\n [icon]=\"row[column.key].icon\"\n [label]=\"row[column.key].label\"\n [type]=\"iconType.default\"\n [iconSize]=\"iconSize['md']\"\n [iconCssClass]=\"row[column.key].iconCssClass\"\n ></cw-icon>\n </a>\n } @else {\n <cw-icon\n [icon]=\"row[column.key].icon\"\n [label]=\"row[column.key].label\"\n [type]=\"iconType.default\"\n [iconSize]=\"iconSize['md']\"\n [iconCssClass]=\"row[column.key].iconCssClass\"\n ></cw-icon>\n }\n }\n @case ('image') {\n @if (isClickable(column)) {\n <a href=\"javascript:void(0)\" (click)=\"onCellClick(row, column)\" [attr.aria-label]=\"row[column.key].label\">\n <cw-image\n [source]=\"row[column.key].source\"\n [alt]=\"row[column.key].label\"\n [isAriaHidden]=\"true\"\n [cssClass]=\"row[column.key].iconCssClass\"\n width=\"32\"\n height=\"32\"\n ></cw-image>\n </a>\n } @else {\n <cw-image\n [source]=\"row[column.key].source\"\n [alt]=\"row[column.key].label\"\n [isAriaHidden]=\"true\"\n [cssClass]=\"row[column.key].iconCssClass\"\n width=\"32\"\n height=\"32\"\n ></cw-image>\n }\n }\n @case ('check') {\n @if (isTruthy(row[column.key])) {\n <cw-icon\n [icon]=\"spriteIcon.checkCircle\"\n [label]=\"'_COMMON._PRO_SENTENCE.YES' | translate\"\n [type]=\"iconType.default\"\n iconCssClass=\"text-success\"\n [iconSize]=\"iconSize['md']\"></cw-icon>\n } @else {\n <cw-icon\n [icon]=\"spriteIcon.closeCircle\"\n [label]=\"'_COMMON._PRO_SENTENCE.NO' | translate\"\n [type]=\"iconType.default\"\n iconCssClass=\"text-danger\"\n [iconSize]=\"iconSize['md']\"></cw-icon>\n }\n }\n @case ('progressbar') {\n <div class=\"td-progressbar\">\n <cw-progress-bar\n [value]=\"row[column.key]\"\n [size]=\"progressBarSize.sm\"\n [type]=\"progressBarType.information\"></cw-progress-bar>\n <span class=\"td-progressbar-value\">{{ row[column.key] }}%</span>\n </div>\n }\n @case ('actions') {\n @if (usingRowActions) {\n @let actions = getResolvedActions(row);\n @if (actions.length > 0) {\n @if (!useDropdownActions()) {\n @for (action of actions; track $index) {\n <cw-button\n [type]=\"buttonType.ghost\"\n [label]=\"action.label\"\n [withIcon]=\"action.icon\"\n [link]=\"action.link\"\n [isDisabled]=\"action.disabled\"\n [cssClass]=\"actionCssClass(action)\"\n (btnAction)=\"onRowActionClick(action, row)\">\n </cw-button>\n }\n } @else {\n <cw-button\n [label]=\"'_COMMON._TABLE.ACTIONS_MENU'\"\n [withIcon]=\"spriteIcon.menuVertical\"\n [withOnlyIcon]=\"true\"\n [type]=\"buttonType.ghost\"\n [isDropdown]=\"true\"\n [hideCaret]=\"true\">\n <ul class=\"p-0 m-0\">\n @for (action of actions; track $index) {\n <li>\n @if (action.link) {\n <cw-button\n [type]=\"buttonType.ghost\"\n [label]=\"action.label\"\n [withIcon]=\"action.icon\"\n [link]=\"action.link\"\n [isDisabled]=\"action.disabled\"\n [cssClass]=\"'dropdown-item ' + actionCssClass(action)\">\n </cw-button>\n } @else {\n <cw-button\n [type]=\"buttonType.ghost\"\n [label]=\"action.label\"\n [withIcon]=\"action.icon\"\n [isDisabled]=\"action.disabled\"\n [cssClass]=\"'dropdown-item ' + actionCssClass(action)\"\n (btnAction)=\"onRowActionClick(action, row)\">\n </cw-button>\n }\n </li>\n }\n </ul>\n </cw-button>\n }\n }\n } @else {\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate(); context: { $implicit: row }\">\n </ng-container>\n }\n }\n @default {\n {{ column.translate ? (row[column.key] | translate) : row[column.key] }}\n }\n }\n </td>\n }\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (pagination()) {\n <cw-pagination\n [pagination]=\"pagination()!\"\n (paginationChange)=\"paginationChange.emit($event)\">\n </cw-pagination>\n}\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "component", type: LoaderComponent, selector: "cw-loader", inputs: ["size", "displayText"] }, { kind: "component", type: BadgeComponent, selector: "cw-badge", inputs: ["type", "label", "withIcon", "iconPosition", "cssClass", "skeletonMode", "dataTest"] }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "loadingAnnounce", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PaginationComponent, selector: "cw-pagination", inputs: ["pagination"], outputs: ["paginationChange"] }, { kind: "component", type: IconComponent, selector: "cw-icon", inputs: ["icon", "label", "type", "iconSize", "iconCssClass", "iconUiType", "iconColorCustom", "spritePath"] }, { kind: "component", type: ImageComponent, selector: "cw-image", inputs: ["source", "alt", "isAriaHidden", "cssClass", "width", "height"] }, { kind: "component", type: EmptyStateComponent, selector: "cw-empty-state", inputs: ["illustration", "illustrationBasePath", "imageSource", "imageAlt", "title", "description", "primaryButton", "secondaryButton", "dataTest"], outputs: ["primaryClick", "secondaryClick"] }, { kind: "component", type: ProgressBarComponent, selector: "cw-progress-bar", inputs: ["value", "max", "size", "type", "showValue", "label", "dataTest"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
775
775
  }
776
776
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: TableComponent, decorators: [{
777
777
  type: Component,
@@ -927,7 +927,7 @@ class FilterBarComponent {
927
927
  }
928
928
  }
929
929
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: FilterBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
930
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: FilterBarComponent, isStandalone: true, selector: "cw-filter-bar", inputs: { filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: true, transformFunction: null }, manual: { classPropertyName: "manual", publicName: "manual", isSignal: true, isRequired: false, transformFunction: null }, syncUrl: { classPropertyName: "syncUrl", publicName: "syncUrl", isSignal: true, isRequired: false, transformFunction: null }, applyLabel: { classPropertyName: "applyLabel", publicName: "applyLabel", isSignal: true, isRequired: false, transformFunction: null }, resetLabel: { classPropertyName: "resetLabel", publicName: "resetLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filtersApplied: "filtersApplied", filtersReset: "filtersReset" }, ngImport: i0, template: "<form [formGroup]=\"filterForm\" (ngSubmit)=\"apply()\" class=\"filter-bar\">\r\n <div class=\"d-flex-h flex-wrap gap-md\">\r\n @for (field of filters(); track field.key) {\r\n <div class=\"filter-field\" [class]=\"field.colClass ?? ''\">\r\n <cw-form-field\r\n [label]=\"field.label | translate\"\r\n [displayLabel]=\"false\"\r\n [type]=\"field.type\"\r\n [placeholder]=\"(field.placeholder ?? '') | translate\"\r\n [options]=\"resolveOptions(field)\"\r\n [control]=\"getControl(field.key)\"\r\n [clearable]=\"false\">\r\n </cw-form-field>\r\n </div>\r\n }\r\n <div class=\"d-flex-h gap-md\">\r\n @if (manual()) {\r\n <cw-button\r\n [label]=\"applyLabel() | translate\"\r\n [type]=\"uiType.link\"\r\n (btnAction)=\"apply()\">\r\n </cw-button>\r\n }\r\n <cw-button\r\n [label]=\"resetLabel() | translate\"\r\n [type]=\"uiType.link\"\r\n (btnAction)=\"reset()\">\r\n </cw-button>\r\n </div>\r\n </div>\r\n</form>\r\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FormFieldComponent, selector: "cw-form-field", inputs: ["control", "formGroup", "type", "label", "displayLabel", "name", "placeholder", "autocomplete", "options", "rangeOptions", "validationOptions", "autocompleteOptions", "richTextOptions", "errorMessages", "isRequired", "help", "tooltip", "addonLeft", "addonRight", "isInAddon", "isReadonly", "isDisabled", "sliderValue", "sliderOptions", "cssClass", "skeletonMode", "clearable", "appendTo", "initialCountry", "indeterminate"], outputs: ["refreshEvent", "textChanged", "valueChange", "phoneRegionChange"] }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
930
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: FilterBarComponent, isStandalone: true, selector: "cw-filter-bar", inputs: { filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: true, transformFunction: null }, manual: { classPropertyName: "manual", publicName: "manual", isSignal: true, isRequired: false, transformFunction: null }, syncUrl: { classPropertyName: "syncUrl", publicName: "syncUrl", isSignal: true, isRequired: false, transformFunction: null }, applyLabel: { classPropertyName: "applyLabel", publicName: "applyLabel", isSignal: true, isRequired: false, transformFunction: null }, resetLabel: { classPropertyName: "resetLabel", publicName: "resetLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filtersApplied: "filtersApplied", filtersReset: "filtersReset" }, ngImport: i0, template: "<form [formGroup]=\"filterForm\" (ngSubmit)=\"apply()\" class=\"filter-bar\">\r\n <div class=\"d-flex-h flex-wrap gap-md\">\r\n @for (field of filters(); track field.key) {\r\n <div class=\"filter-field\" [class]=\"field.colClass ?? ''\">\r\n <cw-form-field\r\n [label]=\"field.label | translate\"\r\n [displayLabel]=\"false\"\r\n [type]=\"field.type\"\r\n [placeholder]=\"(field.placeholder ?? '') | translate\"\r\n [options]=\"resolveOptions(field)\"\r\n [control]=\"getControl(field.key)\"\r\n [clearable]=\"false\">\r\n </cw-form-field>\r\n </div>\r\n }\r\n <div class=\"d-flex-h gap-md\">\r\n @if (manual()) {\r\n <cw-button\r\n [label]=\"applyLabel() | translate\"\r\n [type]=\"uiType.link\"\r\n (btnAction)=\"apply()\">\r\n </cw-button>\r\n }\r\n <cw-button\r\n [label]=\"resetLabel() | translate\"\r\n [type]=\"uiType.link\"\r\n (btnAction)=\"reset()\">\r\n </cw-button>\r\n </div>\r\n </div>\r\n</form>\r\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FormFieldComponent, selector: "cw-form-field", inputs: ["control", "formGroup", "type", "label", "displayLabel", "name", "placeholder", "autocomplete", "options", "rangeOptions", "validationOptions", "autocompleteOptions", "richTextOptions", "errorMessages", "isRequired", "help", "tooltip", "addonLeft", "addonRight", "isInAddon", "isReadonly", "isDisabled", "sliderValue", "sliderOptions", "cssClass", "skeletonMode", "clearable", "appendTo", "initialCountry", "indeterminate"], outputs: ["refreshEvent", "textChanged", "valueChange", "phoneRegionChange"] }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "loadingAnnounce", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
931
931
  }
932
932
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: FilterBarComponent, decorators: [{
933
933
  type: Component,
@@ -1120,11 +1120,11 @@ class ExportButtonComponent {
1120
1120
  });
1121
1121
  }
1122
1122
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: ExportButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1123
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: ExportButtonComponent, isStandalone: true, selector: "cw-export-button", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, errorKey: { classPropertyName: "errorKey", publicName: "errorKey", isSignal: true, isRequired: false, transformFunction: null }, successKey: { classPropertyName: "successKey", publicName: "successKey", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "cw-export-button" }, ngImport: i0, template: "@if (isMenu()) {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"label()\" [isDropdown]=\"true\" [isDisabled]=\"allDisabled()\">\n <!-- Motif documente de basic-ui : `<button cwDropdownItem>` en direct, et non un\n `cw-button` imbrique. La directive pose la classe `dropdown-item` sur la CIBLE du\n clic, seule condition pour que `cw-button` referme son menu apres la selection. -->\n <ul>\n @for (option of options(); track $index) {\n <li>\n <button type=\"button\" class=\"btn btn-ghost\" cwDropdownItem [disabled]=\"option.disabled\" (click)=\"run(option)\">\n {{ option.label | translate }}\n </button>\n </li>\n }\n </ul>\n </cw-button>\n} @else {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"label()\" [isDisabled]=\"!!options()[0].disabled\"\n (btnAction)=\"run(options()[0])\">\n </cw-button>\n}\n\n<!-- Region live PERMANENTE : seul son contenu change. La creer et la detruire avec le\n message ferait manquer l'annonce aux technologies d'assistance, qui doivent avoir\n observe la region AVANT sa mise a jour. -->\n<span class=\"visually-hidden\" role=\"status\">\n @if (liveMessage(); as message) {\n {{ message.key | translate: message.params }}\n }\n</span>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "directive", type: DropdownItemDirective, selector: "[cwDropdownItem]" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1123
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: ExportButtonComponent, isStandalone: true, selector: "cw-export-button", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, errorKey: { classPropertyName: "errorKey", publicName: "errorKey", isSignal: true, isRequired: false, transformFunction: null }, successKey: { classPropertyName: "successKey", publicName: "successKey", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "cw-export-button" }, ngImport: i0, template: "@if (isMenu()) {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"label()\" [isDropdown]=\"true\" [isDisabled]=\"allDisabled()\"\n [isLoading]=\"running()\" [loadingAnnounce]=\"false\">\n <!-- Motif documente de basic-ui : `<button cwDropdownItem>` en direct, et non un\n `cw-button` imbrique. La directive pose la classe `dropdown-item` sur la CIBLE du\n clic, seule condition pour que `cw-button` referme son menu apres la selection. -->\n <ul>\n @for (option of options(); track $index) {\n <li>\n <button type=\"button\" class=\"btn btn-ghost\" cwDropdownItem [disabled]=\"option.disabled\" (click)=\"run(option)\">\n {{ option.label | translate }}\n </button>\n </li>\n }\n </ul>\n </cw-button>\n} @else {\n <!-- Option unique : c'est le libelle de L'OPTION qui nomme le bouton, pas `label()`.\n L'inverse rendait `ExportOption.label` obligatoire mais mort dans ce mode \u2014 l'hote\n ecrivait un libelle qui n'apparaissait nulle part. `label()` reste le libelle du\n declencheur de MENU, ou les options sont nommees une a une. -->\n <cw-button [type]=\"buttonType.secondary\" [label]=\"options()[0].label\" [isDisabled]=\"!!options()[0].disabled\"\n [isLoading]=\"running()\" [loadingAnnounce]=\"false\" (btnAction)=\"run(options()[0])\">\n </cw-button>\n}\n\n<!-- Region live PERMANENTE : seul son contenu change. La creer et la detruire avec le\n message ferait manquer l'annonce aux technologies d'assistance, qui doivent avoir\n observe la region AVANT sa mise a jour. -->\n<span class=\"visually-hidden\" role=\"status\">\n @if (liveMessage(); as message) {\n {{ message.key | translate: message.params }}\n }\n</span>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "loadingAnnounce", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "directive", type: DropdownItemDirective, selector: "[cwDropdownItem]" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1124
1124
  }
1125
1125
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: ExportButtonComponent, decorators: [{
1126
1126
  type: Component,
1127
- args: [{ selector: 'cw-export-button', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'cw-export-button' }, imports: [ButtonComponent, DropdownItemDirective, TranslateModule], template: "@if (isMenu()) {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"label()\" [isDropdown]=\"true\" [isDisabled]=\"allDisabled()\">\n <!-- Motif documente de basic-ui : `<button cwDropdownItem>` en direct, et non un\n `cw-button` imbrique. La directive pose la classe `dropdown-item` sur la CIBLE du\n clic, seule condition pour que `cw-button` referme son menu apres la selection. -->\n <ul>\n @for (option of options(); track $index) {\n <li>\n <button type=\"button\" class=\"btn btn-ghost\" cwDropdownItem [disabled]=\"option.disabled\" (click)=\"run(option)\">\n {{ option.label | translate }}\n </button>\n </li>\n }\n </ul>\n </cw-button>\n} @else {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"label()\" [isDisabled]=\"!!options()[0].disabled\"\n (btnAction)=\"run(options()[0])\">\n </cw-button>\n}\n\n<!-- Region live PERMANENTE : seul son contenu change. La creer et la detruire avec le\n message ferait manquer l'annonce aux technologies d'assistance, qui doivent avoir\n observe la region AVANT sa mise a jour. -->\n<span class=\"visually-hidden\" role=\"status\">\n @if (liveMessage(); as message) {\n {{ message.key | translate: message.params }}\n }\n</span>\n" }]
1127
+ args: [{ selector: 'cw-export-button', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'cw-export-button' }, imports: [ButtonComponent, DropdownItemDirective, TranslateModule], template: "@if (isMenu()) {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"label()\" [isDropdown]=\"true\" [isDisabled]=\"allDisabled()\"\n [isLoading]=\"running()\" [loadingAnnounce]=\"false\">\n <!-- Motif documente de basic-ui : `<button cwDropdownItem>` en direct, et non un\n `cw-button` imbrique. La directive pose la classe `dropdown-item` sur la CIBLE du\n clic, seule condition pour que `cw-button` referme son menu apres la selection. -->\n <ul>\n @for (option of options(); track $index) {\n <li>\n <button type=\"button\" class=\"btn btn-ghost\" cwDropdownItem [disabled]=\"option.disabled\" (click)=\"run(option)\">\n {{ option.label | translate }}\n </button>\n </li>\n }\n </ul>\n </cw-button>\n} @else {\n <!-- Option unique : c'est le libelle de L'OPTION qui nomme le bouton, pas `label()`.\n L'inverse rendait `ExportOption.label` obligatoire mais mort dans ce mode \u2014 l'hote\n ecrivait un libelle qui n'apparaissait nulle part. `label()` reste le libelle du\n declencheur de MENU, ou les options sont nommees une a une. -->\n <cw-button [type]=\"buttonType.secondary\" [label]=\"options()[0].label\" [isDisabled]=\"!!options()[0].disabled\"\n [isLoading]=\"running()\" [loadingAnnounce]=\"false\" (btnAction)=\"run(options()[0])\">\n </cw-button>\n}\n\n<!-- Region live PERMANENTE : seul son contenu change. La creer et la detruire avec le\n message ferait manquer l'annonce aux technologies d'assistance, qui doivent avoir\n observe la region AVANT sa mise a jour. -->\n<span class=\"visually-hidden\" role=\"status\">\n @if (liveMessage(); as message) {\n {{ message.key | translate: message.params }}\n }\n</span>\n" }]
1128
1128
  }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], errorKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorKey", required: false }] }], successKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "successKey", required: false }] }] } });
1129
1129
 
1130
1130
  // Modele du composant `cw-import-wizard` — assistant d'import de donnees.
@@ -1310,7 +1310,12 @@ class ImportWizardComponent {
1310
1310
  * Langue active, en signal : la categorie de pluriel et le format des nombres doivent
1311
1311
  * suivre un changement de langue a chaud.
1312
1312
  */
1313
- this.lang = toSignal(this.translate.onLangChange.pipe(map((event) => event.lang)), { initialValue: this.translate.currentLang || this.translate.getDefaultLang() });
1313
+ this.lang = toSignal(this.translate.onLangChange.pipe(map((event) => event.lang)),
1314
+ // `currentLang` et `getDefaultLang()` sont types `string` en @ngx-translate/core 16,
1315
+ // mais nullables dans des majeures plus recentes : le repli garde le contrat local a
1316
+ // `string` quelle que soit la version installee chez le consommateur, et evite un
1317
+ // `Intl.PluralRules('')` qui leverait. Meme forme que form-field (lang intl-tel-input).
1318
+ { initialValue: this.translate.currentLang || this.translate.getDefaultLang() || 'fr' });
1314
1319
  /** Pont signal du control : un `computed` lisant `mode.value` resterait fige. */
1315
1320
  this.modeValue = toSignal(this.mode.valueChanges, { initialValue: null });
1316
1321
  /** Idem pour le fichier : meme piege de `computed` fige. */
@@ -1705,7 +1710,7 @@ class ImportWizardComponent {
1705
1710
  }));
1706
1711
  }
1707
1712
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: ImportWizardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1708
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: ImportWizardComponent, isStandalone: true, selector: "cw-import-wizard", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { completed: "completed" }, host: { classAttribute: "cw-import-wizard" }, viewQueries: [{ propertyName: "panels", predicate: ["stepPanel"], descendants: true, read: CardComponent, isSignal: true }, { propertyName: "selectionTarget", first: true, predicate: ["selectionTarget"], descendants: true, isSignal: true }, { propertyName: "analysisStatus", first: true, predicate: ["analysisStatus"], descendants: true, isSignal: true }, { propertyName: "analysisOutcome", first: true, predicate: ["analysisOutcome"], descendants: true, isSignal: true }, { propertyName: "executionStatus", first: true, predicate: ["executionStatus"], descendants: true, isSignal: true }, { propertyName: "cancellingStatus", first: true, predicate: ["cancellingStatus"], descendants: true, isSignal: true }, { propertyName: "reportOutcome", first: true, predicate: ["reportOutcome"], descendants: true, isSignal: true }, { propertyName: "interruptedOutcome", first: true, predicate: ["interruptedOutcome"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Pastille d'etape : icone ronde verte (terminee) / rouge (echec), sinon le numero.\n Rendue dans [header-start] pour etre AVANT le titre, comme sur les maquettes.\n Le numero seul n'etant pas parlant a l'oreille, le statut est double en visually-hidden --\n et c'est LUI qui distingue \u00AB en cours \u00BB de \u00AB a venir \u00BB pour qui ne voit pas la couleur. -->\n<ng-template #badge let-stepKey=\"stepKey\" let-number=\"number\">\n @if (stateOf(stepKey) === stepState.done) {\n <cw-icon [icon]=\"spriteIcon.check\" [type]=\"iconType.circular\" [iconSize]=\"iconSize['sm']\"\n [iconUiType]=\"iconUiType.success\" [label]=\"stepStatusLabel(stepKey) | translate\"></cw-icon>\n }\n @else if (stateOf(stepKey) === stepState.error) {\n <cw-icon [icon]=\"spriteIcon.close\" [type]=\"iconType.circular\" [iconSize]=\"iconSize['sm']\"\n [iconUiType]=\"iconUiType.danger\" [label]=\"stepStatusLabel(stepKey) | translate\"></cw-icon>\n }\n @else {\n <div class=\"icon-circular icon-circular-sm\" [class]=\"'icon-circular-' + badgeVariant(stepKey)\">\n <span aria-hidden=\"true\">{{ number }}</span>\n <span class=\"visually-hidden\">{{ stepStatusLabel(stepKey) | translate }}</span>\n </div>\n }\n</ng-template>\n\n<ng-template #counts let-rows=\"rows\">\n <ul class=\"list-unstyled d-flex-h gap-md\">\n @for (row of rows; track row.key) {\n <li>\n <span class=\"fs-lg fw-bold\" [class]=\"'text-' + row.tone\">{{ row.count }}</span> {{ row.key | translate }}\n </li>\n }\n </ul>\n</ng-template>\n\n<cw-accordion [closeOthers]=\"true\" [destroyOnHide]=\"false\">\n\n <!-- Etape 1 : fichier + type d'import -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.SELECT'\"\n [collapseId]=\"'import-step-select'\"\n [collapsed]=\"!isPanelOpen(step.select)\"\n [collapseLocked]=\"stateOf(step.select) === stepState.done\"\n [disabled]=\"stateOf(step.select) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.select, number: 1 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n <div class=\"row\">\n <div class=\"col-lg-6\">\n <!-- Retour depuis une analyse non conforme : cible de focus. Le bouton qui declenche\n ce retour disparait avec le repli du panneau 2, le focus retomberait sur <body>. -->\n @if (selectionReopened()) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #selectionTarget>\n {{ '_COMMON._IMPORT._A11Y.SELECTION' | translate }}\n </h3>\n }\n\n <cw-file-drop\n [formControl]=\"file\"\n [accept]=\"config().accept\"\n [acceptLabel]=\"config().acceptLabel\"\n [maxSizeMb]=\"maxSizeMb()\"\n [label]=\"'_COMMON._IMPORT.FILE_TO_IMPORT' | translate\">\n </cw-file-drop>\n </div>\n\n @if (config().templateFile) {\n <div class=\"col-lg-6\">\n <cw-card [type]=\"cardType.light\">\n <strong>{{ '_COMMON._IMPORT._TEMPLATE.TITLE' | translate }}</strong>\n <span>{{ '_COMMON._IMPORT._TEMPLATE.TEXT' | translate }}</span>\n <cw-file-to-download [attachments]=\"templateAttachments()\"></cw-file-to-download>\n </cw-card>\n </div>\n }\n </div>\n\n <!-- Choix impose : on informe sans champ de saisie. Choix libre : groupe radio,\n dont la selection est REQUISE (pas de preselection, cf. `selectedMode`). -->\n @if (isModeImposed()) {\n <div class=\"d-flex-v gap-2xs\">\n <p class=\"mb-none\">\n <strong>{{ '_COMMON._IMPORT._MODE.LABEL' | translate }}</strong>\n {{ imposedModeLabel() | translate }}\n </p>\n <!-- Champ cle affiche ici AUSSI : c'est le cas le plus courant, et le seul ou\n l'utilisateur ne voyait pas sur quoi portait le rapprochement. -->\n @if (selectedKeyFieldHint(); as keyFieldHint) {\n <span class=\"fs fs-xs text-light\">{{ keyFieldHint | translate }}</span>\n }\n </div>\n }\n @else {\n <cw-form-field\n [type]=\"fieldType.radio\"\n [control]=\"mode\"\n [name]=\"'importMode'\"\n [label]=\"'_COMMON._IMPORT._MODE.LABEL'\"\n [options]=\"modeOptions()\"\n [isRequired]=\"true\"\n [help]=\"selectedKeyFieldHint()\">\n </cw-form-field>\n }\n\n <!-- Portee du mode retenu (destructif ou non) : exigence SFD \u00AB l'utilisateur est\n informe du type d'import selectionne ou impose \u00BB. Rien tant qu'aucun mode n'est\n retenu : l'alerte ne decrit jamais un mode que l'utilisateur n'a pas choisi. -->\n @if (modeNoticeKey(); as noticeKey) {\n <cw-alert [type]=\"modeNoticeType()\">\n {{ noticeKey | translate }}\n </cw-alert>\n }\n\n <!-- Un bouton desactive muet est un cul-de-sac : ce texte dit ce qui manque, et il est\n place AVANT le bouton, seul chemin possible puisqu'un bouton desactive n'est pas\n focusable (donc pas d'aria-describedby exploitable). Pas de classe de couleur\n atenuee : c'est une information necessaire, elle garde le contraste du corps. -->\n <div class=\"d-flex-h justify-end gap-md\">\n @if (missingRequirementKey(); as missing) {\n <p class=\"mb-none fs-xs\">{{ missing | translate }}</p>\n }\n\n <cw-button\n [type]=\"buttonType.primary\"\n [label]=\"'_COMMON._IMPORT.CONTINUE'\"\n [dataTest]=\"'btn-import-continue'\"\n [isDisabled]=\"!canContinue()\"\n (btnAction)=\"continueToAnalysis()\">\n </cw-button>\n </div>\n </div>\n </cw-card>\n\n <!-- Etape 2 : analyse a blanc -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.ANALYSIS'\"\n [collapseId]=\"'import-step-analysis'\"\n [collapsed]=\"!isPanelOpen(step.analysis)\"\n [collapseLocked]=\"stateOf(step.analysis) === stepState.done\"\n [disabled]=\"stateOf(step.analysis) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.analysis, number: 2 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n @if (analyzing()) {\n <!-- Cible de focus : ce texte EST le message d'etat, il est donc lu une fois et une\n seule (aucune region live en doublon). -->\n <span tabindex=\"-1\" #analysisStatus>{{ '_COMMON._IMPORT.ANALYSIS_IN_PROGRESS' | translate }}</span>\n }\n @else if (analysis(); as result) {\n <!-- Cible de focus a l'arrivee du resultat : libelle de section, pas une reprise du\n message, pour que la lecture enchaine sur l'alerte puis les compteurs. -->\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #analysisOutcome>\n {{ '_COMMON._IMPORT._A11Y.ANALYSIS_RESULT' | translate }}\n </h3>\n\n @if (result.valid) {\n <cw-alert [type]=\"alertType.success\">\n {{ '_COMMON._IMPORT.ANALYSIS_OK' | translate }}\n </cw-alert>\n\n <!-- scope=list : previsualisation chiffree. scope=singleConfig : le message ci-dessus suffit. -->\n @if (isList() && previewRows().length) {\n <ng-container *ngTemplateOutlet=\"counts; context: { rows: previewRows() }\"></ng-container>\n }\n\n <div class=\"list-unstyled d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.primary\"\n [label]=\"'_COMMON._IMPORT.START'\"\n [dataTest]=\"'btn-import-start'\"\n (btnAction)=\"startImport()\">\n </cw-button>\n </div>\n }\n @else {\n <cw-alert [type]=\"alertType.danger\">\n {{ '_COMMON._IMPORT.ANALYSIS_KO' | translate }}\n </cw-alert>\n\n @if (errors()?.length) {\n <ul class=\"mb-none\">\n @for (issue of errors(); track $index) {\n <li>\n @if (issue.line !== undefined) {\n <strong>{{ '_COMMON._IMPORT.ERROR_LINE' | translate: { line: issue.line } }}</strong>\n }\n {{ issue.messageKey ? (issue.messageKey | translate: issue.messageParams) : issue.message }}\n </li>\n }\n </ul>\n }\n\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.secondary\"\n [label]=\"'_COMMON._IMPORT.BACK_TO_SELECTION'\"\n [dataTest]=\"'btn-import-back'\"\n (btnAction)=\"backToSelection()\">\n </cw-button>\n </div>\n }\n }\n </div>\n </cw-card>\n\n <!-- Etape 3 : import -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.EXECUTION'\"\n [collapseId]=\"'import-step-execution'\"\n [collapsed]=\"!isPanelOpen(step.execution)\"\n [disabled]=\"stateOf(step.execution) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.execution, number: 3 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n @if (isImporting) {\n <div class=\"d-flex-v gap-2xs\">\n <!-- Cible de focus. Le bouton \u00AB Arreter l'import \u00BB est le focusable suivant. -->\n <span tabindex=\"-1\" #executionStatus>{{ '_COMMON._IMPORT.IN_PROGRESS' | translate }}</span>\n @if (progress()?.remainingLabel; as remaining) {\n <span>{{ '_COMMON._IMPORT.REMAINING' | translate: { value: remaining } }}</span>\n }\n </div>\n\n <!-- Avancement connu => barre deterministe. Aucune progression recue => spinner\n indetermine, plutot qu'une barre figee a 0 %. La bascule se fait a la premiere\n emission `ImportProgress` : une source qui n'en emet jamais reste sur le spinner.\n `displayText` a false : le libelle \u00AB Import en cours \u00BB est deja au-dessus. -->\n @if (progress(); as current) {\n <cw-progress-bar\n [value]=\"current.percent\"\n [type]=\"progressType.information\"\n [label]=\"'_COMMON._IMPORT.IN_PROGRESS' | translate\">\n </cw-progress-bar>\n }\n @else {\n <cw-loader [size]=\"loaderSize.sm\" [displayText]=\"false\"></cw-loader>\n }\n\n <!-- Pas de bouton d'arret quand l'objet declare l'import non interruptible : un\n bouton qui ne peut rien arreter serait pire que son absence. -->\n @if (canInterrupt()) {\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.dangerOutline\"\n [label]=\"'_COMMON._IMPORT.STOP'\"\n [dataTest]=\"'btn-import-stop'\"\n (btnAction)=\"stopImport()\">\n </cw-button>\n </div>\n }\n }\n @else if (cancelling()) {\n <!-- Annulation demandee au serveur, reponse en attente. Cible de focus. -->\n <span tabindex=\"-1\" #cancellingStatus>{{ '_COMMON._IMPORT.CANCELLING' | translate }}</span>\n\n <cw-loader [size]=\"loaderSize.sm\" [displayText]=\"false\"></cw-loader>\n\n <!-- Sortie de secours : aucun delai n'etant defendable depuis la lib, c'est\n l'utilisateur qui decide d'arreter d'attendre. Conclut en \u00AB etat incertain \u00BB. -->\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.secondary\"\n [label]=\"'_COMMON._IMPORT.STOP_WAITING'\"\n [dataTest]=\"'btn-import-stop-waiting'\"\n (btnAction)=\"stopWaiting()\">\n </cw-button>\n </div>\n }\n @else if (interruptionMessageKey(); as interruptionMessage) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #interruptedOutcome>\n {{ '_COMMON._IMPORT._A11Y.IMPORT_RESULT' | translate }}\n </h3>\n\n <cw-alert [type]=\"interruptionAlertType()\">\n {{ interruptionMessage | translate }}\n </cw-alert>\n }\n @else if (report(); as result) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #reportOutcome>\n {{ '_COMMON._IMPORT._A11Y.IMPORT_RESULT' | translate }}\n </h3>\n\n @if (result.success) {\n <cw-alert [type]=\"alertType.success\">\n {{ '_COMMON._IMPORT.SUCCESS' | translate }}\n </cw-alert>\n\n @if (isList() && reportRows().length) {\n <ng-container *ngTemplateOutlet=\"counts; context: { rows: reportRows() }\"></ng-container>\n }\n }\n @else {\n <!-- Le message generique ne promet l'absence d'ecriture que si l'atomicite est\n declaree (cf. `failureMessageKey`). -->\n <cw-alert [type]=\"alertType.danger\">\n {{ result.errorMessage ?? (failureMessageKey() | translate) }}\n </cw-alert>\n }\n }\n </div>\n </cw-card>\n\n</cw-accordion>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: AccordionComponent, selector: "cw-accordion", inputs: ["closeOthers", "allowMultiple", "destroyOnHide"], outputs: ["panelOpened", "panelClosed"] }, { kind: "component", type: AlertComponent, selector: "cw-alert", inputs: ["type", "title", "isDismissible", "cssClass", "dataTest"], outputs: ["close"] }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "component", type: CardComponent, selector: "cw-card", inputs: ["title", "subtitle", "type", "titleRank", "cssClass", "collapsible", "collapsed", "disabled", "collapseLocked", "collapseStretched", "collapseId", "destroyOnHide"], outputs: ["collapsibleChange", "destroyOnHideChange", "collapseClicked"] }, { kind: "component", type: FileDropComponent, selector: "cw-file-drop", inputs: ["mode", "multiple", "maxFiles", "accept", "acceptLabel", "maxSizeMb", "recommendedDimensions", "label", "isDisabled", "errorMessage", "dataTest"], outputs: ["filesChange", "rejected", "retry"] }, { kind: "component", type: FileToDownloadComponent, selector: "cw-file-to-download", inputs: ["attachments"] }, { kind: "component", type: FormFieldComponent, selector: "cw-form-field", inputs: ["control", "formGroup", "type", "label", "displayLabel", "name", "placeholder", "autocomplete", "options", "rangeOptions", "validationOptions", "autocompleteOptions", "richTextOptions", "errorMessages", "isRequired", "help", "tooltip", "addonLeft", "addonRight", "isInAddon", "isReadonly", "isDisabled", "sliderValue", "sliderOptions", "cssClass", "skeletonMode", "clearable", "appendTo", "initialCountry", "indeterminate"], outputs: ["refreshEvent", "textChanged", "valueChange", "phoneRegionChange"] }, { kind: "component", type: IconComponent, selector: "cw-icon", inputs: ["icon", "label", "type", "iconSize", "iconCssClass", "iconUiType", "iconColorCustom", "spritePath"] }, { kind: "component", type: LoaderComponent, selector: "cw-loader", inputs: ["size", "displayText"] }, { kind: "component", type: ProgressBarComponent, selector: "cw-progress-bar", inputs: ["value", "max", "size", "type", "showValue", "label", "dataTest"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1713
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: ImportWizardComponent, isStandalone: true, selector: "cw-import-wizard", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { completed: "completed" }, host: { classAttribute: "cw-import-wizard" }, viewQueries: [{ propertyName: "panels", predicate: ["stepPanel"], descendants: true, read: CardComponent, isSignal: true }, { propertyName: "selectionTarget", first: true, predicate: ["selectionTarget"], descendants: true, isSignal: true }, { propertyName: "analysisStatus", first: true, predicate: ["analysisStatus"], descendants: true, isSignal: true }, { propertyName: "analysisOutcome", first: true, predicate: ["analysisOutcome"], descendants: true, isSignal: true }, { propertyName: "executionStatus", first: true, predicate: ["executionStatus"], descendants: true, isSignal: true }, { propertyName: "cancellingStatus", first: true, predicate: ["cancellingStatus"], descendants: true, isSignal: true }, { propertyName: "reportOutcome", first: true, predicate: ["reportOutcome"], descendants: true, isSignal: true }, { propertyName: "interruptedOutcome", first: true, predicate: ["interruptedOutcome"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Pastille d'etape : icone ronde verte (terminee) / rouge (echec), sinon le numero.\n Rendue dans [header-start] pour etre AVANT le titre, comme sur les maquettes.\n Le numero seul n'etant pas parlant a l'oreille, le statut est double en visually-hidden --\n et c'est LUI qui distingue \u00AB en cours \u00BB de \u00AB a venir \u00BB pour qui ne voit pas la couleur. -->\n<ng-template #badge let-stepKey=\"stepKey\" let-number=\"number\">\n @if (stateOf(stepKey) === stepState.done) {\n <cw-icon [icon]=\"spriteIcon.check\" [type]=\"iconType.circular\" [iconSize]=\"iconSize['sm']\"\n [iconUiType]=\"iconUiType.success\" [label]=\"stepStatusLabel(stepKey) | translate\"></cw-icon>\n }\n @else if (stateOf(stepKey) === stepState.error) {\n <cw-icon [icon]=\"spriteIcon.close\" [type]=\"iconType.circular\" [iconSize]=\"iconSize['sm']\"\n [iconUiType]=\"iconUiType.danger\" [label]=\"stepStatusLabel(stepKey) | translate\"></cw-icon>\n }\n @else {\n <div class=\"icon-circular icon-circular-sm\" [class]=\"'icon-circular-' + badgeVariant(stepKey)\">\n <span aria-hidden=\"true\">{{ number }}</span>\n <span class=\"visually-hidden\">{{ stepStatusLabel(stepKey) | translate }}</span>\n </div>\n }\n</ng-template>\n\n<ng-template #counts let-rows=\"rows\">\n <ul class=\"list-unstyled d-flex-h gap-md\">\n @for (row of rows; track row.key) {\n <li>\n <span class=\"fs-lg fw-bold\" [class]=\"'text-' + row.tone\">{{ row.count }}</span> {{ row.key | translate }}\n </li>\n }\n </ul>\n</ng-template>\n\n<cw-accordion [closeOthers]=\"true\" [destroyOnHide]=\"false\">\n\n <!-- Etape 1 : fichier + type d'import -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.SELECT'\"\n [collapseId]=\"'import-step-select'\"\n [collapsed]=\"!isPanelOpen(step.select)\"\n [collapseLocked]=\"stateOf(step.select) === stepState.done\"\n [disabled]=\"stateOf(step.select) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.select, number: 1 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n <div class=\"row\">\n <div class=\"col-lg-6\">\n <!-- Retour depuis une analyse non conforme : cible de focus. Le bouton qui declenche\n ce retour disparait avec le repli du panneau 2, le focus retomberait sur <body>. -->\n @if (selectionReopened()) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #selectionTarget>\n {{ '_COMMON._IMPORT._A11Y.SELECTION' | translate }}\n </h3>\n }\n\n <cw-file-drop\n [formControl]=\"file\"\n [accept]=\"config().accept\"\n [acceptLabel]=\"config().acceptLabel\"\n [maxSizeMb]=\"maxSizeMb()\"\n [label]=\"'_COMMON._IMPORT.FILE_TO_IMPORT' | translate\">\n </cw-file-drop>\n </div>\n\n @if (config().templateFile) {\n <div class=\"col-lg-6\">\n <cw-card [type]=\"cardType.light\">\n <strong>{{ '_COMMON._IMPORT._TEMPLATE.TITLE' | translate }}</strong>\n <span>{{ '_COMMON._IMPORT._TEMPLATE.TEXT' | translate }}</span>\n <cw-file-to-download [attachments]=\"templateAttachments()\"></cw-file-to-download>\n </cw-card>\n </div>\n }\n </div>\n\n <!-- Choix impose : on informe sans champ de saisie. Choix libre : groupe radio,\n dont la selection est REQUISE (pas de preselection, cf. `selectedMode`). -->\n @if (isModeImposed()) {\n <div class=\"d-flex-v gap-2xs\">\n <p class=\"mb-none\">\n <strong>{{ '_COMMON._IMPORT._MODE.LABEL' | translate }}</strong>\n {{ imposedModeLabel() | translate }}\n </p>\n <!-- Champ cle affiche ici AUSSI : c'est le cas le plus courant, et le seul ou\n l'utilisateur ne voyait pas sur quoi portait le rapprochement. -->\n @if (selectedKeyFieldHint(); as keyFieldHint) {\n <span class=\"fs fs-xs text-light\">{{ keyFieldHint | translate }}</span>\n }\n </div>\n }\n @else {\n <cw-form-field\n [type]=\"fieldType.radio\"\n [control]=\"mode\"\n [name]=\"'importMode'\"\n [label]=\"'_COMMON._IMPORT._MODE.LABEL'\"\n [options]=\"modeOptions()\"\n [isRequired]=\"true\"\n [help]=\"selectedKeyFieldHint()\">\n </cw-form-field>\n }\n\n <!-- Portee du mode retenu (destructif ou non) : exigence SFD \u00AB l'utilisateur est\n informe du type d'import selectionne ou impose \u00BB. Rien tant qu'aucun mode n'est\n retenu : l'alerte ne decrit jamais un mode que l'utilisateur n'a pas choisi. -->\n @if (modeNoticeKey(); as noticeKey) {\n <cw-alert [type]=\"modeNoticeType()\">\n {{ noticeKey | translate }}\n </cw-alert>\n }\n\n <!-- Un bouton desactive muet est un cul-de-sac : ce texte dit ce qui manque, et il est\n place AVANT le bouton, seul chemin possible puisqu'un bouton desactive n'est pas\n focusable (donc pas d'aria-describedby exploitable). Pas de classe de couleur\n atenuee : c'est une information necessaire, elle garde le contraste du corps. -->\n <div class=\"d-flex-h justify-end gap-md\">\n @if (missingRequirementKey(); as missing) {\n <p class=\"mb-none fs-xs\">{{ missing | translate }}</p>\n }\n\n <cw-button\n [type]=\"buttonType.primary\"\n [label]=\"'_COMMON._IMPORT.CONTINUE'\"\n [dataTest]=\"'btn-import-continue'\"\n [isDisabled]=\"!canContinue()\"\n (btnAction)=\"continueToAnalysis()\">\n </cw-button>\n </div>\n </div>\n </cw-card>\n\n <!-- Etape 2 : analyse a blanc -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.ANALYSIS'\"\n [collapseId]=\"'import-step-analysis'\"\n [collapsed]=\"!isPanelOpen(step.analysis)\"\n [collapseLocked]=\"stateOf(step.analysis) === stepState.done\"\n [disabled]=\"stateOf(step.analysis) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.analysis, number: 2 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n @if (analyzing()) {\n <!-- Cible de focus : ce texte EST le message d'etat, il est donc lu une fois et une\n seule (aucune region live en doublon). -->\n <span tabindex=\"-1\" #analysisStatus>{{ '_COMMON._IMPORT.ANALYSIS_IN_PROGRESS' | translate }}</span>\n }\n @else if (analysis(); as result) {\n <!-- Cible de focus a l'arrivee du resultat : libelle de section, pas une reprise du\n message, pour que la lecture enchaine sur l'alerte puis les compteurs. -->\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #analysisOutcome>\n {{ '_COMMON._IMPORT._A11Y.ANALYSIS_RESULT' | translate }}\n </h3>\n\n @if (result.valid) {\n <cw-alert [type]=\"alertType.success\">\n {{ '_COMMON._IMPORT.ANALYSIS_OK' | translate }}\n </cw-alert>\n\n <!-- scope=list : previsualisation chiffree. scope=singleConfig : le message ci-dessus suffit. -->\n @if (isList() && previewRows().length) {\n <ng-container *ngTemplateOutlet=\"counts; context: { rows: previewRows() }\"></ng-container>\n }\n\n <div class=\"list-unstyled d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.primary\"\n [label]=\"'_COMMON._IMPORT.START'\"\n [dataTest]=\"'btn-import-start'\"\n (btnAction)=\"startImport()\">\n </cw-button>\n </div>\n }\n @else {\n <cw-alert [type]=\"alertType.danger\">\n {{ '_COMMON._IMPORT.ANALYSIS_KO' | translate }}\n </cw-alert>\n\n @if (errors().length) {\n <ul class=\"mb-none\">\n @for (issue of errors(); track $index) {\n <li>\n @if (issue.line !== undefined) {\n <strong>{{ '_COMMON._IMPORT.ERROR_LINE' | translate: { line: issue.line } }}</strong>\n }\n {{ issue.messageKey ? (issue.messageKey | translate: issue.messageParams) : issue.message }}\n </li>\n }\n </ul>\n }\n\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.secondary\"\n [label]=\"'_COMMON._IMPORT.BACK_TO_SELECTION'\"\n [dataTest]=\"'btn-import-back'\"\n (btnAction)=\"backToSelection()\">\n </cw-button>\n </div>\n }\n }\n </div>\n </cw-card>\n\n <!-- Etape 3 : import -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.EXECUTION'\"\n [collapseId]=\"'import-step-execution'\"\n [collapsed]=\"!isPanelOpen(step.execution)\"\n [disabled]=\"stateOf(step.execution) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.execution, number: 3 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n @if (isImporting) {\n <div class=\"d-flex-v gap-2xs\">\n <!-- Cible de focus. Le bouton \u00AB Arreter l'import \u00BB est le focusable suivant. -->\n <span tabindex=\"-1\" #executionStatus>{{ '_COMMON._IMPORT.IN_PROGRESS' | translate }}</span>\n @if (progress()?.remainingLabel; as remaining) {\n <span>{{ '_COMMON._IMPORT.REMAINING' | translate: { value: remaining } }}</span>\n }\n </div>\n\n <!-- Avancement connu => barre deterministe. Aucune progression recue => spinner\n indetermine, plutot qu'une barre figee a 0 %. La bascule se fait a la premiere\n emission `ImportProgress` : une source qui n'en emet jamais reste sur le spinner.\n `displayText` a false : le libelle \u00AB Import en cours \u00BB est deja au-dessus. -->\n @if (progress(); as current) {\n <cw-progress-bar\n [value]=\"current.percent\"\n [type]=\"progressType.information\"\n [label]=\"'_COMMON._IMPORT.IN_PROGRESS' | translate\">\n </cw-progress-bar>\n }\n @else {\n <cw-loader [size]=\"loaderSize.sm\" [displayText]=\"false\"></cw-loader>\n }\n\n <!-- Pas de bouton d'arret quand l'objet declare l'import non interruptible : un\n bouton qui ne peut rien arreter serait pire que son absence. -->\n @if (canInterrupt()) {\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.dangerOutline\"\n [label]=\"'_COMMON._IMPORT.STOP'\"\n [dataTest]=\"'btn-import-stop'\"\n (btnAction)=\"stopImport()\">\n </cw-button>\n </div>\n }\n }\n @else if (cancelling()) {\n <!-- Annulation demandee au serveur, reponse en attente. Cible de focus. -->\n <span tabindex=\"-1\" #cancellingStatus>{{ '_COMMON._IMPORT.CANCELLING' | translate }}</span>\n\n <cw-loader [size]=\"loaderSize.sm\" [displayText]=\"false\"></cw-loader>\n\n <!-- Sortie de secours : aucun delai n'etant defendable depuis la lib, c'est\n l'utilisateur qui decide d'arreter d'attendre. Conclut en \u00AB etat incertain \u00BB. -->\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.secondary\"\n [label]=\"'_COMMON._IMPORT.STOP_WAITING'\"\n [dataTest]=\"'btn-import-stop-waiting'\"\n (btnAction)=\"stopWaiting()\">\n </cw-button>\n </div>\n }\n @else if (interruptionMessageKey(); as interruptionMessage) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #interruptedOutcome>\n {{ '_COMMON._IMPORT._A11Y.IMPORT_RESULT' | translate }}\n </h3>\n\n <cw-alert [type]=\"interruptionAlertType()\">\n {{ interruptionMessage | translate }}\n </cw-alert>\n }\n @else if (report(); as result) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #reportOutcome>\n {{ '_COMMON._IMPORT._A11Y.IMPORT_RESULT' | translate }}\n </h3>\n\n @if (result.success) {\n <cw-alert [type]=\"alertType.success\">\n {{ '_COMMON._IMPORT.SUCCESS' | translate }}\n </cw-alert>\n\n @if (isList() && reportRows().length) {\n <ng-container *ngTemplateOutlet=\"counts; context: { rows: reportRows() }\"></ng-container>\n }\n }\n @else {\n <!-- Le message generique ne promet l'absence d'ecriture que si l'atomicite est\n declaree (cf. `failureMessageKey`). -->\n <cw-alert [type]=\"alertType.danger\">\n {{ result.errorMessage ?? (failureMessageKey() | translate) }}\n </cw-alert>\n }\n }\n </div>\n </cw-card>\n\n</cw-accordion>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: AccordionComponent, selector: "cw-accordion", inputs: ["closeOthers", "allowMultiple", "destroyOnHide"], outputs: ["panelOpened", "panelClosed"] }, { kind: "component", type: AlertComponent, selector: "cw-alert", inputs: ["type", "title", "isDismissible", "cssClass", "dataTest"], outputs: ["close"] }, { kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "loadingAnnounce", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "component", type: CardComponent, selector: "cw-card", inputs: ["title", "subtitle", "type", "titleRank", "cssClass", "collapsible", "collapsed", "disabled", "collapseLocked", "collapseStretched", "collapseId", "destroyOnHide"], outputs: ["collapsibleChange", "destroyOnHideChange", "collapseClicked"] }, { kind: "component", type: FileDropComponent, selector: "cw-file-drop", inputs: ["mode", "multiple", "maxFiles", "accept", "acceptLabel", "maxSizeMb", "recommendedDimensions", "label", "isDisabled", "errorMessage", "dataTest"], outputs: ["filesChange", "rejected", "retry"] }, { kind: "component", type: FileToDownloadComponent, selector: "cw-file-to-download", inputs: ["attachments"] }, { kind: "component", type: FormFieldComponent, selector: "cw-form-field", inputs: ["control", "formGroup", "type", "label", "displayLabel", "name", "placeholder", "autocomplete", "options", "rangeOptions", "validationOptions", "autocompleteOptions", "richTextOptions", "errorMessages", "isRequired", "help", "tooltip", "addonLeft", "addonRight", "isInAddon", "isReadonly", "isDisabled", "sliderValue", "sliderOptions", "cssClass", "skeletonMode", "clearable", "appendTo", "initialCountry", "indeterminate"], outputs: ["refreshEvent", "textChanged", "valueChange", "phoneRegionChange"] }, { kind: "component", type: IconComponent, selector: "cw-icon", inputs: ["icon", "label", "type", "iconSize", "iconCssClass", "iconUiType", "iconColorCustom", "spritePath"] }, { kind: "component", type: LoaderComponent, selector: "cw-loader", inputs: ["size", "displayText"] }, { kind: "component", type: ProgressBarComponent, selector: "cw-progress-bar", inputs: ["value", "max", "size", "type", "showValue", "label", "dataTest"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1709
1714
  }
1710
1715
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: ImportWizardComponent, decorators: [{
1711
1716
  type: Component,
@@ -1723,7 +1728,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.20", ngImpo
1723
1728
  IconComponent,
1724
1729
  LoaderComponent,
1725
1730
  ProgressBarComponent
1726
- ], template: "<!-- Pastille d'etape : icone ronde verte (terminee) / rouge (echec), sinon le numero.\n Rendue dans [header-start] pour etre AVANT le titre, comme sur les maquettes.\n Le numero seul n'etant pas parlant a l'oreille, le statut est double en visually-hidden --\n et c'est LUI qui distingue \u00AB en cours \u00BB de \u00AB a venir \u00BB pour qui ne voit pas la couleur. -->\n<ng-template #badge let-stepKey=\"stepKey\" let-number=\"number\">\n @if (stateOf(stepKey) === stepState.done) {\n <cw-icon [icon]=\"spriteIcon.check\" [type]=\"iconType.circular\" [iconSize]=\"iconSize['sm']\"\n [iconUiType]=\"iconUiType.success\" [label]=\"stepStatusLabel(stepKey) | translate\"></cw-icon>\n }\n @else if (stateOf(stepKey) === stepState.error) {\n <cw-icon [icon]=\"spriteIcon.close\" [type]=\"iconType.circular\" [iconSize]=\"iconSize['sm']\"\n [iconUiType]=\"iconUiType.danger\" [label]=\"stepStatusLabel(stepKey) | translate\"></cw-icon>\n }\n @else {\n <div class=\"icon-circular icon-circular-sm\" [class]=\"'icon-circular-' + badgeVariant(stepKey)\">\n <span aria-hidden=\"true\">{{ number }}</span>\n <span class=\"visually-hidden\">{{ stepStatusLabel(stepKey) | translate }}</span>\n </div>\n }\n</ng-template>\n\n<ng-template #counts let-rows=\"rows\">\n <ul class=\"list-unstyled d-flex-h gap-md\">\n @for (row of rows; track row.key) {\n <li>\n <span class=\"fs-lg fw-bold\" [class]=\"'text-' + row.tone\">{{ row.count }}</span> {{ row.key | translate }}\n </li>\n }\n </ul>\n</ng-template>\n\n<cw-accordion [closeOthers]=\"true\" [destroyOnHide]=\"false\">\n\n <!-- Etape 1 : fichier + type d'import -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.SELECT'\"\n [collapseId]=\"'import-step-select'\"\n [collapsed]=\"!isPanelOpen(step.select)\"\n [collapseLocked]=\"stateOf(step.select) === stepState.done\"\n [disabled]=\"stateOf(step.select) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.select, number: 1 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n <div class=\"row\">\n <div class=\"col-lg-6\">\n <!-- Retour depuis une analyse non conforme : cible de focus. Le bouton qui declenche\n ce retour disparait avec le repli du panneau 2, le focus retomberait sur <body>. -->\n @if (selectionReopened()) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #selectionTarget>\n {{ '_COMMON._IMPORT._A11Y.SELECTION' | translate }}\n </h3>\n }\n\n <cw-file-drop\n [formControl]=\"file\"\n [accept]=\"config().accept\"\n [acceptLabel]=\"config().acceptLabel\"\n [maxSizeMb]=\"maxSizeMb()\"\n [label]=\"'_COMMON._IMPORT.FILE_TO_IMPORT' | translate\">\n </cw-file-drop>\n </div>\n\n @if (config().templateFile) {\n <div class=\"col-lg-6\">\n <cw-card [type]=\"cardType.light\">\n <strong>{{ '_COMMON._IMPORT._TEMPLATE.TITLE' | translate }}</strong>\n <span>{{ '_COMMON._IMPORT._TEMPLATE.TEXT' | translate }}</span>\n <cw-file-to-download [attachments]=\"templateAttachments()\"></cw-file-to-download>\n </cw-card>\n </div>\n }\n </div>\n\n <!-- Choix impose : on informe sans champ de saisie. Choix libre : groupe radio,\n dont la selection est REQUISE (pas de preselection, cf. `selectedMode`). -->\n @if (isModeImposed()) {\n <div class=\"d-flex-v gap-2xs\">\n <p class=\"mb-none\">\n <strong>{{ '_COMMON._IMPORT._MODE.LABEL' | translate }}</strong>\n {{ imposedModeLabel() | translate }}\n </p>\n <!-- Champ cle affiche ici AUSSI : c'est le cas le plus courant, et le seul ou\n l'utilisateur ne voyait pas sur quoi portait le rapprochement. -->\n @if (selectedKeyFieldHint(); as keyFieldHint) {\n <span class=\"fs fs-xs text-light\">{{ keyFieldHint | translate }}</span>\n }\n </div>\n }\n @else {\n <cw-form-field\n [type]=\"fieldType.radio\"\n [control]=\"mode\"\n [name]=\"'importMode'\"\n [label]=\"'_COMMON._IMPORT._MODE.LABEL'\"\n [options]=\"modeOptions()\"\n [isRequired]=\"true\"\n [help]=\"selectedKeyFieldHint()\">\n </cw-form-field>\n }\n\n <!-- Portee du mode retenu (destructif ou non) : exigence SFD \u00AB l'utilisateur est\n informe du type d'import selectionne ou impose \u00BB. Rien tant qu'aucun mode n'est\n retenu : l'alerte ne decrit jamais un mode que l'utilisateur n'a pas choisi. -->\n @if (modeNoticeKey(); as noticeKey) {\n <cw-alert [type]=\"modeNoticeType()\">\n {{ noticeKey | translate }}\n </cw-alert>\n }\n\n <!-- Un bouton desactive muet est un cul-de-sac : ce texte dit ce qui manque, et il est\n place AVANT le bouton, seul chemin possible puisqu'un bouton desactive n'est pas\n focusable (donc pas d'aria-describedby exploitable). Pas de classe de couleur\n atenuee : c'est une information necessaire, elle garde le contraste du corps. -->\n <div class=\"d-flex-h justify-end gap-md\">\n @if (missingRequirementKey(); as missing) {\n <p class=\"mb-none fs-xs\">{{ missing | translate }}</p>\n }\n\n <cw-button\n [type]=\"buttonType.primary\"\n [label]=\"'_COMMON._IMPORT.CONTINUE'\"\n [dataTest]=\"'btn-import-continue'\"\n [isDisabled]=\"!canContinue()\"\n (btnAction)=\"continueToAnalysis()\">\n </cw-button>\n </div>\n </div>\n </cw-card>\n\n <!-- Etape 2 : analyse a blanc -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.ANALYSIS'\"\n [collapseId]=\"'import-step-analysis'\"\n [collapsed]=\"!isPanelOpen(step.analysis)\"\n [collapseLocked]=\"stateOf(step.analysis) === stepState.done\"\n [disabled]=\"stateOf(step.analysis) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.analysis, number: 2 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n @if (analyzing()) {\n <!-- Cible de focus : ce texte EST le message d'etat, il est donc lu une fois et une\n seule (aucune region live en doublon). -->\n <span tabindex=\"-1\" #analysisStatus>{{ '_COMMON._IMPORT.ANALYSIS_IN_PROGRESS' | translate }}</span>\n }\n @else if (analysis(); as result) {\n <!-- Cible de focus a l'arrivee du resultat : libelle de section, pas une reprise du\n message, pour que la lecture enchaine sur l'alerte puis les compteurs. -->\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #analysisOutcome>\n {{ '_COMMON._IMPORT._A11Y.ANALYSIS_RESULT' | translate }}\n </h3>\n\n @if (result.valid) {\n <cw-alert [type]=\"alertType.success\">\n {{ '_COMMON._IMPORT.ANALYSIS_OK' | translate }}\n </cw-alert>\n\n <!-- scope=list : previsualisation chiffree. scope=singleConfig : le message ci-dessus suffit. -->\n @if (isList() && previewRows().length) {\n <ng-container *ngTemplateOutlet=\"counts; context: { rows: previewRows() }\"></ng-container>\n }\n\n <div class=\"list-unstyled d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.primary\"\n [label]=\"'_COMMON._IMPORT.START'\"\n [dataTest]=\"'btn-import-start'\"\n (btnAction)=\"startImport()\">\n </cw-button>\n </div>\n }\n @else {\n <cw-alert [type]=\"alertType.danger\">\n {{ '_COMMON._IMPORT.ANALYSIS_KO' | translate }}\n </cw-alert>\n\n @if (errors()?.length) {\n <ul class=\"mb-none\">\n @for (issue of errors(); track $index) {\n <li>\n @if (issue.line !== undefined) {\n <strong>{{ '_COMMON._IMPORT.ERROR_LINE' | translate: { line: issue.line } }}</strong>\n }\n {{ issue.messageKey ? (issue.messageKey | translate: issue.messageParams) : issue.message }}\n </li>\n }\n </ul>\n }\n\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.secondary\"\n [label]=\"'_COMMON._IMPORT.BACK_TO_SELECTION'\"\n [dataTest]=\"'btn-import-back'\"\n (btnAction)=\"backToSelection()\">\n </cw-button>\n </div>\n }\n }\n </div>\n </cw-card>\n\n <!-- Etape 3 : import -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.EXECUTION'\"\n [collapseId]=\"'import-step-execution'\"\n [collapsed]=\"!isPanelOpen(step.execution)\"\n [disabled]=\"stateOf(step.execution) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.execution, number: 3 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n @if (isImporting) {\n <div class=\"d-flex-v gap-2xs\">\n <!-- Cible de focus. Le bouton \u00AB Arreter l'import \u00BB est le focusable suivant. -->\n <span tabindex=\"-1\" #executionStatus>{{ '_COMMON._IMPORT.IN_PROGRESS' | translate }}</span>\n @if (progress()?.remainingLabel; as remaining) {\n <span>{{ '_COMMON._IMPORT.REMAINING' | translate: { value: remaining } }}</span>\n }\n </div>\n\n <!-- Avancement connu => barre deterministe. Aucune progression recue => spinner\n indetermine, plutot qu'une barre figee a 0 %. La bascule se fait a la premiere\n emission `ImportProgress` : une source qui n'en emet jamais reste sur le spinner.\n `displayText` a false : le libelle \u00AB Import en cours \u00BB est deja au-dessus. -->\n @if (progress(); as current) {\n <cw-progress-bar\n [value]=\"current.percent\"\n [type]=\"progressType.information\"\n [label]=\"'_COMMON._IMPORT.IN_PROGRESS' | translate\">\n </cw-progress-bar>\n }\n @else {\n <cw-loader [size]=\"loaderSize.sm\" [displayText]=\"false\"></cw-loader>\n }\n\n <!-- Pas de bouton d'arret quand l'objet declare l'import non interruptible : un\n bouton qui ne peut rien arreter serait pire que son absence. -->\n @if (canInterrupt()) {\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.dangerOutline\"\n [label]=\"'_COMMON._IMPORT.STOP'\"\n [dataTest]=\"'btn-import-stop'\"\n (btnAction)=\"stopImport()\">\n </cw-button>\n </div>\n }\n }\n @else if (cancelling()) {\n <!-- Annulation demandee au serveur, reponse en attente. Cible de focus. -->\n <span tabindex=\"-1\" #cancellingStatus>{{ '_COMMON._IMPORT.CANCELLING' | translate }}</span>\n\n <cw-loader [size]=\"loaderSize.sm\" [displayText]=\"false\"></cw-loader>\n\n <!-- Sortie de secours : aucun delai n'etant defendable depuis la lib, c'est\n l'utilisateur qui decide d'arreter d'attendre. Conclut en \u00AB etat incertain \u00BB. -->\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.secondary\"\n [label]=\"'_COMMON._IMPORT.STOP_WAITING'\"\n [dataTest]=\"'btn-import-stop-waiting'\"\n (btnAction)=\"stopWaiting()\">\n </cw-button>\n </div>\n }\n @else if (interruptionMessageKey(); as interruptionMessage) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #interruptedOutcome>\n {{ '_COMMON._IMPORT._A11Y.IMPORT_RESULT' | translate }}\n </h3>\n\n <cw-alert [type]=\"interruptionAlertType()\">\n {{ interruptionMessage | translate }}\n </cw-alert>\n }\n @else if (report(); as result) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #reportOutcome>\n {{ '_COMMON._IMPORT._A11Y.IMPORT_RESULT' | translate }}\n </h3>\n\n @if (result.success) {\n <cw-alert [type]=\"alertType.success\">\n {{ '_COMMON._IMPORT.SUCCESS' | translate }}\n </cw-alert>\n\n @if (isList() && reportRows().length) {\n <ng-container *ngTemplateOutlet=\"counts; context: { rows: reportRows() }\"></ng-container>\n }\n }\n @else {\n <!-- Le message generique ne promet l'absence d'ecriture que si l'atomicite est\n declaree (cf. `failureMessageKey`). -->\n <cw-alert [type]=\"alertType.danger\">\n {{ result.errorMessage ?? (failureMessageKey() | translate) }}\n </cw-alert>\n }\n }\n </div>\n </cw-card>\n\n</cw-accordion>\n" }]
1731
+ ], template: "<!-- Pastille d'etape : icone ronde verte (terminee) / rouge (echec), sinon le numero.\n Rendue dans [header-start] pour etre AVANT le titre, comme sur les maquettes.\n Le numero seul n'etant pas parlant a l'oreille, le statut est double en visually-hidden --\n et c'est LUI qui distingue \u00AB en cours \u00BB de \u00AB a venir \u00BB pour qui ne voit pas la couleur. -->\n<ng-template #badge let-stepKey=\"stepKey\" let-number=\"number\">\n @if (stateOf(stepKey) === stepState.done) {\n <cw-icon [icon]=\"spriteIcon.check\" [type]=\"iconType.circular\" [iconSize]=\"iconSize['sm']\"\n [iconUiType]=\"iconUiType.success\" [label]=\"stepStatusLabel(stepKey) | translate\"></cw-icon>\n }\n @else if (stateOf(stepKey) === stepState.error) {\n <cw-icon [icon]=\"spriteIcon.close\" [type]=\"iconType.circular\" [iconSize]=\"iconSize['sm']\"\n [iconUiType]=\"iconUiType.danger\" [label]=\"stepStatusLabel(stepKey) | translate\"></cw-icon>\n }\n @else {\n <div class=\"icon-circular icon-circular-sm\" [class]=\"'icon-circular-' + badgeVariant(stepKey)\">\n <span aria-hidden=\"true\">{{ number }}</span>\n <span class=\"visually-hidden\">{{ stepStatusLabel(stepKey) | translate }}</span>\n </div>\n }\n</ng-template>\n\n<ng-template #counts let-rows=\"rows\">\n <ul class=\"list-unstyled d-flex-h gap-md\">\n @for (row of rows; track row.key) {\n <li>\n <span class=\"fs-lg fw-bold\" [class]=\"'text-' + row.tone\">{{ row.count }}</span> {{ row.key | translate }}\n </li>\n }\n </ul>\n</ng-template>\n\n<cw-accordion [closeOthers]=\"true\" [destroyOnHide]=\"false\">\n\n <!-- Etape 1 : fichier + type d'import -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.SELECT'\"\n [collapseId]=\"'import-step-select'\"\n [collapsed]=\"!isPanelOpen(step.select)\"\n [collapseLocked]=\"stateOf(step.select) === stepState.done\"\n [disabled]=\"stateOf(step.select) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.select, number: 1 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n <div class=\"row\">\n <div class=\"col-lg-6\">\n <!-- Retour depuis une analyse non conforme : cible de focus. Le bouton qui declenche\n ce retour disparait avec le repli du panneau 2, le focus retomberait sur <body>. -->\n @if (selectionReopened()) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #selectionTarget>\n {{ '_COMMON._IMPORT._A11Y.SELECTION' | translate }}\n </h3>\n }\n\n <cw-file-drop\n [formControl]=\"file\"\n [accept]=\"config().accept\"\n [acceptLabel]=\"config().acceptLabel\"\n [maxSizeMb]=\"maxSizeMb()\"\n [label]=\"'_COMMON._IMPORT.FILE_TO_IMPORT' | translate\">\n </cw-file-drop>\n </div>\n\n @if (config().templateFile) {\n <div class=\"col-lg-6\">\n <cw-card [type]=\"cardType.light\">\n <strong>{{ '_COMMON._IMPORT._TEMPLATE.TITLE' | translate }}</strong>\n <span>{{ '_COMMON._IMPORT._TEMPLATE.TEXT' | translate }}</span>\n <cw-file-to-download [attachments]=\"templateAttachments()\"></cw-file-to-download>\n </cw-card>\n </div>\n }\n </div>\n\n <!-- Choix impose : on informe sans champ de saisie. Choix libre : groupe radio,\n dont la selection est REQUISE (pas de preselection, cf. `selectedMode`). -->\n @if (isModeImposed()) {\n <div class=\"d-flex-v gap-2xs\">\n <p class=\"mb-none\">\n <strong>{{ '_COMMON._IMPORT._MODE.LABEL' | translate }}</strong>\n {{ imposedModeLabel() | translate }}\n </p>\n <!-- Champ cle affiche ici AUSSI : c'est le cas le plus courant, et le seul ou\n l'utilisateur ne voyait pas sur quoi portait le rapprochement. -->\n @if (selectedKeyFieldHint(); as keyFieldHint) {\n <span class=\"fs fs-xs text-light\">{{ keyFieldHint | translate }}</span>\n }\n </div>\n }\n @else {\n <cw-form-field\n [type]=\"fieldType.radio\"\n [control]=\"mode\"\n [name]=\"'importMode'\"\n [label]=\"'_COMMON._IMPORT._MODE.LABEL'\"\n [options]=\"modeOptions()\"\n [isRequired]=\"true\"\n [help]=\"selectedKeyFieldHint()\">\n </cw-form-field>\n }\n\n <!-- Portee du mode retenu (destructif ou non) : exigence SFD \u00AB l'utilisateur est\n informe du type d'import selectionne ou impose \u00BB. Rien tant qu'aucun mode n'est\n retenu : l'alerte ne decrit jamais un mode que l'utilisateur n'a pas choisi. -->\n @if (modeNoticeKey(); as noticeKey) {\n <cw-alert [type]=\"modeNoticeType()\">\n {{ noticeKey | translate }}\n </cw-alert>\n }\n\n <!-- Un bouton desactive muet est un cul-de-sac : ce texte dit ce qui manque, et il est\n place AVANT le bouton, seul chemin possible puisqu'un bouton desactive n'est pas\n focusable (donc pas d'aria-describedby exploitable). Pas de classe de couleur\n atenuee : c'est une information necessaire, elle garde le contraste du corps. -->\n <div class=\"d-flex-h justify-end gap-md\">\n @if (missingRequirementKey(); as missing) {\n <p class=\"mb-none fs-xs\">{{ missing | translate }}</p>\n }\n\n <cw-button\n [type]=\"buttonType.primary\"\n [label]=\"'_COMMON._IMPORT.CONTINUE'\"\n [dataTest]=\"'btn-import-continue'\"\n [isDisabled]=\"!canContinue()\"\n (btnAction)=\"continueToAnalysis()\">\n </cw-button>\n </div>\n </div>\n </cw-card>\n\n <!-- Etape 2 : analyse a blanc -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.ANALYSIS'\"\n [collapseId]=\"'import-step-analysis'\"\n [collapsed]=\"!isPanelOpen(step.analysis)\"\n [collapseLocked]=\"stateOf(step.analysis) === stepState.done\"\n [disabled]=\"stateOf(step.analysis) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.analysis, number: 2 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n @if (analyzing()) {\n <!-- Cible de focus : ce texte EST le message d'etat, il est donc lu une fois et une\n seule (aucune region live en doublon). -->\n <span tabindex=\"-1\" #analysisStatus>{{ '_COMMON._IMPORT.ANALYSIS_IN_PROGRESS' | translate }}</span>\n }\n @else if (analysis(); as result) {\n <!-- Cible de focus a l'arrivee du resultat : libelle de section, pas une reprise du\n message, pour que la lecture enchaine sur l'alerte puis les compteurs. -->\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #analysisOutcome>\n {{ '_COMMON._IMPORT._A11Y.ANALYSIS_RESULT' | translate }}\n </h3>\n\n @if (result.valid) {\n <cw-alert [type]=\"alertType.success\">\n {{ '_COMMON._IMPORT.ANALYSIS_OK' | translate }}\n </cw-alert>\n\n <!-- scope=list : previsualisation chiffree. scope=singleConfig : le message ci-dessus suffit. -->\n @if (isList() && previewRows().length) {\n <ng-container *ngTemplateOutlet=\"counts; context: { rows: previewRows() }\"></ng-container>\n }\n\n <div class=\"list-unstyled d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.primary\"\n [label]=\"'_COMMON._IMPORT.START'\"\n [dataTest]=\"'btn-import-start'\"\n (btnAction)=\"startImport()\">\n </cw-button>\n </div>\n }\n @else {\n <cw-alert [type]=\"alertType.danger\">\n {{ '_COMMON._IMPORT.ANALYSIS_KO' | translate }}\n </cw-alert>\n\n @if (errors().length) {\n <ul class=\"mb-none\">\n @for (issue of errors(); track $index) {\n <li>\n @if (issue.line !== undefined) {\n <strong>{{ '_COMMON._IMPORT.ERROR_LINE' | translate: { line: issue.line } }}</strong>\n }\n {{ issue.messageKey ? (issue.messageKey | translate: issue.messageParams) : issue.message }}\n </li>\n }\n </ul>\n }\n\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.secondary\"\n [label]=\"'_COMMON._IMPORT.BACK_TO_SELECTION'\"\n [dataTest]=\"'btn-import-back'\"\n (btnAction)=\"backToSelection()\">\n </cw-button>\n </div>\n }\n }\n </div>\n </cw-card>\n\n <!-- Etape 3 : import -->\n <cw-card\n #stepPanel\n [title]=\"'_COMMON._IMPORT._STEP.EXECUTION'\"\n [collapseId]=\"'import-step-execution'\"\n [collapsed]=\"!isPanelOpen(step.execution)\"\n [disabled]=\"stateOf(step.execution) === stepState.todo\"\n [collapseStretched]=\"false\">\n\n <ng-container ngProjectAs=\"[header-start]\">\n <ng-container *ngTemplateOutlet=\"badge; context: { stepKey: step.execution, number: 3 }\"></ng-container>\n </ng-container>\n\n <div class=\"d-flex-v gap-md\">\n @if (isImporting) {\n <div class=\"d-flex-v gap-2xs\">\n <!-- Cible de focus. Le bouton \u00AB Arreter l'import \u00BB est le focusable suivant. -->\n <span tabindex=\"-1\" #executionStatus>{{ '_COMMON._IMPORT.IN_PROGRESS' | translate }}</span>\n @if (progress()?.remainingLabel; as remaining) {\n <span>{{ '_COMMON._IMPORT.REMAINING' | translate: { value: remaining } }}</span>\n }\n </div>\n\n <!-- Avancement connu => barre deterministe. Aucune progression recue => spinner\n indetermine, plutot qu'une barre figee a 0 %. La bascule se fait a la premiere\n emission `ImportProgress` : une source qui n'en emet jamais reste sur le spinner.\n `displayText` a false : le libelle \u00AB Import en cours \u00BB est deja au-dessus. -->\n @if (progress(); as current) {\n <cw-progress-bar\n [value]=\"current.percent\"\n [type]=\"progressType.information\"\n [label]=\"'_COMMON._IMPORT.IN_PROGRESS' | translate\">\n </cw-progress-bar>\n }\n @else {\n <cw-loader [size]=\"loaderSize.sm\" [displayText]=\"false\"></cw-loader>\n }\n\n <!-- Pas de bouton d'arret quand l'objet declare l'import non interruptible : un\n bouton qui ne peut rien arreter serait pire que son absence. -->\n @if (canInterrupt()) {\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.dangerOutline\"\n [label]=\"'_COMMON._IMPORT.STOP'\"\n [dataTest]=\"'btn-import-stop'\"\n (btnAction)=\"stopImport()\">\n </cw-button>\n </div>\n }\n }\n @else if (cancelling()) {\n <!-- Annulation demandee au serveur, reponse en attente. Cible de focus. -->\n <span tabindex=\"-1\" #cancellingStatus>{{ '_COMMON._IMPORT.CANCELLING' | translate }}</span>\n\n <cw-loader [size]=\"loaderSize.sm\" [displayText]=\"false\"></cw-loader>\n\n <!-- Sortie de secours : aucun delai n'etant defendable depuis la lib, c'est\n l'utilisateur qui decide d'arreter d'attendre. Conclut en \u00AB etat incertain \u00BB. -->\n <div class=\"d-flex-h justify-end\">\n <cw-button\n [type]=\"buttonType.secondary\"\n [label]=\"'_COMMON._IMPORT.STOP_WAITING'\"\n [dataTest]=\"'btn-import-stop-waiting'\"\n (btnAction)=\"stopWaiting()\">\n </cw-button>\n </div>\n }\n @else if (interruptionMessageKey(); as interruptionMessage) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #interruptedOutcome>\n {{ '_COMMON._IMPORT._A11Y.IMPORT_RESULT' | translate }}\n </h3>\n\n <cw-alert [type]=\"interruptionAlertType()\">\n {{ interruptionMessage | translate }}\n </cw-alert>\n }\n @else if (report(); as result) {\n <h3 class=\"visually-hidden\" tabindex=\"-1\" #reportOutcome>\n {{ '_COMMON._IMPORT._A11Y.IMPORT_RESULT' | translate }}\n </h3>\n\n @if (result.success) {\n <cw-alert [type]=\"alertType.success\">\n {{ '_COMMON._IMPORT.SUCCESS' | translate }}\n </cw-alert>\n\n @if (isList() && reportRows().length) {\n <ng-container *ngTemplateOutlet=\"counts; context: { rows: reportRows() }\"></ng-container>\n }\n }\n @else {\n <!-- Le message generique ne promet l'absence d'ecriture que si l'atomicite est\n declaree (cf. `failureMessageKey`). -->\n <cw-alert [type]=\"alertType.danger\">\n {{ result.errorMessage ?? (failureMessageKey() | translate) }}\n </cw-alert>\n }\n }\n </div>\n </cw-card>\n\n</cw-accordion>\n" }]
1727
1732
  }], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], completed: [{ type: i0.Output, args: ["completed"] }], panels: [{ type: i0.ViewChildren, args: ['stepPanel', { ...{ read: CardComponent }, isSignal: true }] }], selectionTarget: [{ type: i0.ViewChild, args: ['selectionTarget', { isSignal: true }] }], analysisStatus: [{ type: i0.ViewChild, args: ['analysisStatus', { isSignal: true }] }], analysisOutcome: [{ type: i0.ViewChild, args: ['analysisOutcome', { isSignal: true }] }], executionStatus: [{ type: i0.ViewChild, args: ['executionStatus', { isSignal: true }] }], cancellingStatus: [{ type: i0.ViewChild, args: ['cancellingStatus', { isSignal: true }] }], reportOutcome: [{ type: i0.ViewChild, args: ['reportOutcome', { isSignal: true }] }], interruptedOutcome: [{ type: i0.ViewChild, args: ['interruptedOutcome', { isSignal: true }] }] } });
1728
1733
 
1729
1734
  /**
@@ -1779,7 +1784,7 @@ class ImportButtonComponent {
1779
1784
  ref.result.then(emitClosed, emitClosed);
1780
1785
  }
1781
1786
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: ImportButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1782
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.20", type: ImportButtonComponent, isStandalone: true, selector: "cw-import-button", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, modalTitle: { classPropertyName: "modalTitle", publicName: "modalTitle", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", completed: "completed" }, host: { classAttribute: "cw-import-button" }, viewQueries: [{ propertyName: "bodyTemplate", first: true, predicate: ["bodyTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<cw-button [type]=\"buttonType.secondary\" [label]=\"label()\" [isDisabled]=\"disabled()\" (btnAction)=\"open()\">\n</cw-button>\n\n<!-- L'assistant n'est que le CORPS de la modale : titre, croix et bouton \u00AB Fermer \u00BB du\n pied viennent de `ModalsService`. Le composant ne ferme jamais la modale lui-meme. -->\n<ng-template #bodyTemplate>\n <cw-import-wizard [config]=\"config()\" (completed)=\"completed.emit($event)\"></cw-import-wizard>\n</ng-template>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "component", type: ImportWizardComponent, selector: "cw-import-wizard", inputs: ["config"], outputs: ["completed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1787
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.20", type: ImportButtonComponent, isStandalone: true, selector: "cw-import-button", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, modalTitle: { classPropertyName: "modalTitle", publicName: "modalTitle", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", completed: "completed" }, host: { classAttribute: "cw-import-button" }, viewQueries: [{ propertyName: "bodyTemplate", first: true, predicate: ["bodyTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<cw-button [type]=\"buttonType.secondary\" [label]=\"label()\" [isDisabled]=\"disabled()\" (btnAction)=\"open()\">\n</cw-button>\n\n<!-- L'assistant n'est que le CORPS de la modale : titre, croix et bouton \u00AB Fermer \u00BB du\n pied viennent de `ModalsService`. Le composant ne ferme jamais la modale lui-meme. -->\n<ng-template #bodyTemplate>\n <cw-import-wizard [config]=\"config()\" (completed)=\"completed.emit($event)\"></cw-import-wizard>\n</ng-template>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "loadingAnnounce", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "component", type: ImportWizardComponent, selector: "cw-import-wizard", inputs: ["config"], outputs: ["completed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1783
1788
  }
1784
1789
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: ImportButtonComponent, decorators: [{
1785
1790
  type: Component,
@@ -1941,7 +1946,7 @@ class PageHeaderComponent {
1941
1946
  return !!this.isDisabled()[action];
1942
1947
  }
1943
1948
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: PageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1944
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: PageHeaderComponent, isStandalone: true, selector: "cw-page-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, showBack: { classPropertyName: "showBack", publicName: "showBack", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, storageKey: { classPropertyName: "storageKey", publicName: "storageKey", isSignal: true, isRequired: false, transformFunction: null }, columnsLabel: { classPropertyName: "columnsLabel", publicName: "columnsLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action", columnsChange: "columnsChange" }, ngImport: i0, template: "<div class=\"page-header d-flex-v gap-2xs\">\n @if (showBack()) {\n <cw-button [type]=\"buttonType.ghost\" [label]=\"'_COMMON._FORM.BACK'\" [withIcon]=\"spriteIcon.left1\"\n (btnAction)=\"goBack()\" />\n }\n <div class=\"d-flex-h gap-md items-start justify-between flex-wrap\">\n <div class=\"d-flex-v\">\n <h1 class=\"page-header-title\">{{ title() | translate}}</h1>\n @if (description(); as desc) {\n <p class=\"fs-md page-header-description\" [innerHTML]=\"desc | translate\"></p>\n }\n </div>\n\n <div class=\"page-header-actions d-flex-h gap-md flex-wrap items-center\">\n @if (showColumns()) {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"columnsLabel()\" [withIcon]=\"spriteIcon.miscNews\"\n [isDropdown]=\"true\">\n <ul class=\"d-flex-v gap-2xs p-md\">\n @for (col of toggleableColumns(); track col.key) {\n <li class=\"field-check\">\n <input class=\"field-check-input\" type=\"checkbox\" [id]=\"'col-toggle-' + col.key\"\n [checked]=\"!col.hidden\" [disabled]=\"isLastVisible(col)\" (change)=\"toggleColumn(col)\">\n <label class=\"field-check-label\" [for]=\"'col-toggle-' + col.key\">{{ col.label | translate }}</label>\n </li>\n }\n </ul>\n </cw-button>\n }\n\n <!-- Slot de l'import : `<cw-import-button cwPageHeaderImport \u2026>`. Projete plutot que\n rendu, pour que `cw-page-header` ne reference pas `cw-import-wizard`. -->\n <ng-content select=\"[cwPageHeaderImport]\"></ng-content>\n\n @if (showReset()) {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"'_COMMON._ACTION.RESET'\"\n [isDisabled]=\"disabled(actionEnum.reset)\" [isLoading]=\"loading(actionEnum.reset)\"\n (btnAction)=\"emit(actionEnum.reset)\">\n </cw-button>\n }\n\n <!-- Slot de l'export : `<cw-export-button cwPageHeaderExport \u2026>`. -->\n <ng-content select=\"[cwPageHeaderExport]\"></ng-content>\n\n <!-- Slot libre, inchange : tout ce qui n'est marque ni import ni export atterrit ici.\n C'est l'echappatoire d'un hote qui veut piloter son propre bouton. -->\n <ng-content></ng-content>\n\n @if (showAdd()) {\n <cw-button [type]=\"buttonType.primary\" [label]=\"'_COMMON._ACTION.ADD'\" [withIcon]=\"spriteIcon.add\"\n [isDisabled]=\"disabled(actionEnum.add)\" [isLoading]=\"loading(actionEnum.add)\"\n (btnAction)=\"emit(actionEnum.add)\">\n </cw-button>\n }\n\n @if (showSave()) {\n <cw-button [type]=\"buttonType.primary\" [label]=\"'_COMMON._ACTION.SAVE'\" [isDisabled]=\"disabled(actionEnum.save)\"\n [isLoading]=\"loading(actionEnum.save)\" (btnAction)=\"emit(actionEnum.save)\">\n </cw-button>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1949
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.20", type: PageHeaderComponent, isStandalone: true, selector: "cw-page-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, showBack: { classPropertyName: "showBack", publicName: "showBack", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, storageKey: { classPropertyName: "storageKey", publicName: "storageKey", isSignal: true, isRequired: false, transformFunction: null }, columnsLabel: { classPropertyName: "columnsLabel", publicName: "columnsLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action", columnsChange: "columnsChange" }, ngImport: i0, template: "<div class=\"page-header d-flex-v gap-2xs\">\n @if (showBack()) {\n <cw-button [type]=\"buttonType.ghost\" [label]=\"'_COMMON._FORM.BACK'\" [withIcon]=\"spriteIcon.left1\"\n (btnAction)=\"goBack()\" />\n }\n <div class=\"d-flex-h gap-md items-start justify-between flex-wrap\">\n <div class=\"d-flex-v\">\n <h1 class=\"page-header-title\">{{ title() | translate}}</h1>\n @if (description(); as desc) {\n <p class=\"fs-md page-header-description\" [innerHTML]=\"desc | translate\"></p>\n }\n </div>\n\n <div class=\"page-header-actions d-flex-h gap-md flex-wrap items-center\">\n @if (showColumns()) {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"columnsLabel()\" [withIcon]=\"spriteIcon.miscNews\"\n [isDropdown]=\"true\">\n <ul class=\"d-flex-v gap-2xs p-md\">\n @for (col of toggleableColumns(); track col.key) {\n <li class=\"field-check\">\n <input class=\"field-check-input\" type=\"checkbox\" [id]=\"'col-toggle-' + col.key\"\n [checked]=\"!col.hidden\" [disabled]=\"isLastVisible(col)\" (change)=\"toggleColumn(col)\">\n <label class=\"field-check-label\" [for]=\"'col-toggle-' + col.key\">{{ col.label | translate }}</label>\n </li>\n }\n </ul>\n </cw-button>\n }\n\n <!-- Slot de l'import : `<cw-import-button cwPageHeaderImport \u2026>`. Projete plutot que\n rendu, pour que `cw-page-header` ne reference pas `cw-import-wizard`. -->\n <ng-content select=\"[cwPageHeaderImport]\"></ng-content>\n\n @if (showReset()) {\n <cw-button [type]=\"buttonType.secondary\" [label]=\"'_COMMON._ACTION.RESET'\"\n [isDisabled]=\"disabled(actionEnum.reset)\" [isLoading]=\"loading(actionEnum.reset)\"\n (btnAction)=\"emit(actionEnum.reset)\">\n </cw-button>\n }\n\n <!-- Slot de l'export : `<cw-export-button cwPageHeaderExport \u2026>`. -->\n <ng-content select=\"[cwPageHeaderExport]\"></ng-content>\n\n <!-- Slot libre, inchange : tout ce qui n'est marque ni import ni export atterrit ici.\n C'est l'echappatoire d'un hote qui veut piloter son propre bouton. -->\n <ng-content></ng-content>\n\n @if (showAdd()) {\n <cw-button [type]=\"buttonType.primary\" [label]=\"'_COMMON._ACTION.ADD'\" [withIcon]=\"spriteIcon.add\"\n [isDisabled]=\"disabled(actionEnum.add)\" [isLoading]=\"loading(actionEnum.add)\"\n (btnAction)=\"emit(actionEnum.add)\">\n </cw-button>\n }\n\n @if (showSave()) {\n <cw-button [type]=\"buttonType.primary\" [label]=\"'_COMMON._ACTION.SAVE'\" [isDisabled]=\"disabled(actionEnum.save)\"\n [isLoading]=\"loading(actionEnum.save)\" (btnAction)=\"emit(actionEnum.save)\">\n </cw-button>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "cw-button", inputs: ["type", "label", "id", "link", "isDropdown", "hideCaret", "withIcon", "withOnlyIcon", "iconSize", "iconPosition", "dropdownPosition", "isMinWidth", "isDisabled", "isLoading", "loadingAnnounce", "cssClass", "dataTest", "skeletonMode", "withTooltip", "tooltipText", "tooltipTitle", "tooltipTrigger", "tooltipPosition", "tooltipType"], outputs: ["btnAction", "dropDownClicked"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1945
1950
  }
1946
1951
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.20", ngImport: i0, type: PageHeaderComponent, decorators: [{
1947
1952
  type: Component,