import * as _angular_core from '@angular/core'; import { TemplateRef, Signal } from '@angular/core'; import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { FormArray, AbstractControl, FormGroup, FormControl } from '@angular/forms'; import { BadgeTypeEnum, SpriteIconEnum, IconSizeEnum, BoButtonTypeEnum, ButtonPositionEnum, ButtonIconSizeEnum, AlertTypeEnum, CardTypeEnum, BadgePositionEnum, IconTypeEnum, IconUiTypeEnum, FormFieldTypeEnum, FormFieldOption } from '@cityway/basic-ui'; import { HttpParams } from '@angular/common/http'; interface DataCustomList { label: string; value: any; type?: 'date' | 'boolean' | 'text' | 'html'; translateValue?: boolean; context?: any; hideIfEmpty?: boolean; } interface DataCustomListGroup { title?: string; fields: DataCustomList[]; } declare class CustomListComponent { readonly customListData: _angular_core.InputSignal; hasValue(value: any): boolean; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } interface DragItem { id: number | string; label: string; code?: string; order?: number; disabled?: boolean; children?: DragItem[]; /** Titre affiché dans l'en-tête de la carte (fallback sur `label` si absent). */ title?: string; /** Sous-titre affiché sous le titre. */ subtitle?: string; /** Badge « à part » paramétrable par carte. */ badge?: DragItemBadge; /** * Nom des enfants, affiché en compteur « [N] childrenLabel » uniquement * quand la carte a des enfants (ex. « rubriques » → « 5 rubriques »). * Forme plurielle. */ childrenLabel?: string; /** Forme singulière du compteur d'enfants (ex. « rubrique » → « 1 rubrique »). */ childrenLabelSingular?: string; /** Override par item de la visibilité des actions (sinon défauts de la colonne). */ actions?: DragItemActions; /** * État : carte « sélectionnée » (typiquement en cours d'édition) → surbrillance. * Flag legacy : autorise plusieurs sélections, à TOI de garantir l'exclusivité. * Pour une sélection exclusive sans risque, préférer l'input `selectedId` du composant * (la lib pose la classe sur la seule carte dont l'`id` correspond). */ selected?: boolean; /** * État : carte marquée pour suppression (soft-delete différé). La lib applique la * classe DS dédiée (barré/atténué) et bascule l'action « Supprimer » en « Restaurer » * (émet alors `(restore)` au lieu de `(delete)`). Piloté par le consommateur. */ pendingDelete?: boolean; [key: string]: any; } interface DragItemBadge { label: string; type: BadgeTypeEnum; icon?: SpriteIconEnum; } interface DragItemActions { /** Loupe — consulter. */ view?: boolean; /** Crayon — éditer. */ edit?: boolean; /** Corbeille — supprimer (bascule en « Restaurer » quand `pendingDelete`). */ delete?: boolean; /** Lien « Ajouter » en pied de carte. */ add?: boolean; } interface DragListColumn { title: string; description?: string; descriptionRwd?: string; cssClass?: string; /** Cartes pliables/dépliables (défaut : true). */ collapsible?: boolean; /** Visibilité par défaut des actions, surchargeable par item via `DragItem.actions`. */ showView?: boolean; showEdit?: boolean; showDelete?: boolean; showAdd?: boolean; /** Libellé du lien d'ajout dans les cartes (défaut : « Ajouter »). */ addLabel?: string; /** Affiche un bouton d'ajout d'item de premier niveau en tête de liste. */ showAddRoot?: boolean; /** Libellé du bouton d'ajout racine (défaut : `addLabel`, sinon « Ajouter »). */ addRootLabel?: string; /** * Nombre maximum d'items par niveau, indexé par profondeur (0 = racine). * Objet creux : ne renseigner que les niveaux limités (ex. `{ 1: 3 }` = enfants niveau 1 * plafonnés à 3, racine illimitée). Niveau absent => pas de limite. * - Le titre de colonne affiche le compteur racine `(count)`, et `(count/max)` si `maxItemsByDepth[0]`. * - Le compteur d'enfants d'une carte affiche `count label / max` si une limite existe pour ses enfants. * - Quand un niveau atteint son max : le bouton « Ajouter » correspondant est désactivé * et un encart d'alerte s'affiche en tête de ce niveau. */ maxItemsByDepth?: { [depth: number]: number; }; /** Clé i18n du message d'alerte « max atteint » (param `{{max}}`). Défaut : `_COMMON.MAX_ITEMS_REACHED`. */ maxReachedLabel?: string; /** * Si `true`, les cartes `pendingDelete` ne comptent PAS dans le plafond `maxItemsByDepth` * (ni compteur, ni alerte, ni désactivation du bouton « Ajouter »). Permet de remplacer * une carte marquée sans attendre le Save. Défaut `false` (comptage brut). * * Effet de bord assumé : en mode exclude, restaurer un marqué ré-incrémente le décompte. * Si le niveau est déjà plein (des remplaçants ont comblé le plafond), le bouton * « Restaurer » est automatiquement désactivé et un encart explicatif s'affiche dans la carte. */ excludePendingDeleteFromMax?: boolean; /** Clé i18n de l'encart « restauration impossible (max atteint) » (param `{{max}}`). Défaut : `_COMMON.MAX_RESTORE_BLOCKED`. */ restoreBlockedLabel?: string; } /** Contexte émis avec l'event `add` : la carte parent (undefined si racine). */ interface DragAddEvent { parent?: DragItem; depth: number; } interface DragDropAdapter { toDragItems(source: T): DragItem[]; fromDragItems(items: DragItem[], source: T, peers?: T[]): void; } declare class ArrayAdapter implements DragDropAdapter { toDragItems(source: DragItem[]): DragItem[]; fromDragItems(items: DragItem[], source: DragItem[], _peers?: DragItem[][]): void; } declare class FormArrayAdapter implements DragDropAdapter { private readonly mapper; private readonly reorderFn?; constructor(mapper: (ctrl: AbstractControl, index: number) => DragItem, reorderFn?: (ctrl: AbstractControl, newOrder: number) => void); toDragItems(source: FormArray): DragItem[]; fromDragItems(items: DragItem[], source: FormArray, peers?: FormArray[]): void; } declare class DragNDropListComponent { readonly availableItems: _angular_core.InputSignal; readonly activeItems: _angular_core.InputSignal; readonly adapter: _angular_core.InputSignal>; readonly itemTemplate: _angular_core.InputSignal>; readonly availableColumn: _angular_core.InputSignal; readonly activeColumn: _angular_core.InputSignal; readonly reorderOnDrop: _angular_core.InputSignal; readonly availableItemsChange: _angular_core.OutputEmitterRef; readonly activeItemsChange: _angular_core.OutputEmitterRef; _available: DragItem[]; _active: DragItem[]; constructor(); drop(event: CdkDragDrop): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } declare class DragNDropNestedListComponent { readonly items: _angular_core.InputSignal; readonly itemTemplate: _angular_core.InputSignal>; readonly column: _angular_core.InputSignal; /** * Renumérote la propriété `order` (1..n par niveau) à chaque drop. `true` par défaut : * réordonner + renuméroter est le comportement attendu d'une liste triable. * Passer `false` pour ne déplacer que visuellement sans toucher à `order`. */ readonly reorderOnDrop: _angular_core.InputSignal; /** * Profondeur maximale autorisée (index 0-based, racine = 0). Une carte à `depth < maxDepth` * peut recevoir des enfants (même vide) ; une carte à `depth >= maxDepth` est terminale. * `undefined` => imbrication infinie (ajout possible partout). Ex. `maxDepth = 1` => 2 niveaux. */ readonly maxDepth: _angular_core.InputSignal; /** * Sélection EXCLUSIVE gérée par la lib : la carte dont l'`id` vaut `selectedId` reçoit * la classe `ddn-list-card-selected`. Une seule carte à la fois, à n'importe quel niveau, * sans avoir à manipuler `DragItem.selected` (qui reste supporté en parallèle). * Piloté par le consommateur (ex. l'id de la carte en cours d'édition ; `undefined` = aucune). */ readonly selectedId: _angular_core.InputSignal; readonly itemsChange: _angular_core.OutputEmitterRef; readonly view: _angular_core.OutputEmitterRef; readonly edit: _angular_core.OutputEmitterRef; readonly delete: _angular_core.OutputEmitterRef; /** Émis quand on clique « Restaurer » sur une carte `pendingDelete` (au lieu de `delete`). */ readonly restore: _angular_core.OutputEmitterRef; readonly add: _angular_core.OutputEmitterRef; readonly spriteIcon: typeof SpriteIconEnum; readonly iconSize: typeof IconSizeEnum; readonly buttonType: typeof BoButtonTypeEnum; readonly buttonPosition: typeof ButtonPositionEnum; readonly buttonIconSize: typeof ButtonIconSizeEnum; readonly alertType: typeof AlertTypeEnum; _items: DragItem[]; constructor(); drop(event: CdkDragDrop): void; /** * Une carte n'est pliable que si elle a des enfants OU qu'on peut lui en ajouter. * `column.collapsible === false` désactive globalement. */ isCollapsible(item: DragItem, depth: number): boolean; /** * Peut-on ajouter des enfants à cette carte ? Résolution : * override item (`actions.add`) → override colonne (`showAdd`) → plafond `maxDepth` * (`depth < maxDepth`) → sinon `true` (imbrication infinie). Indépendant du fait * d'avoir déjà des enfants : une carte vide reste addable. */ canAdd(item: DragItem, depth: number): boolean; /** Nombre max d'items autorisé à un niveau (`undefined` => pas de limite). */ levelMax(depth: number): number | undefined; /** * Nombre d'items pris en compte pour le plafond/compteur à un niveau. * Exclut les cartes `pendingDelete` si `column.excludePendingDeleteFromMax`. */ countForMax(nodes: DragItem[] | undefined): number; /** Vrai si le niveau `depth` a atteint son max (et qu'un max est défini). */ isLevelFull(nodes: DragItem[], depth: number): boolean; /** * Vrai si une carte `pendingDelete` ne peut PAS être restaurée car le niveau est plein. * Ne s'applique qu'en mode `excludePendingDeleteFromMax` : restaurer ré-active la carte * (+1 au décompte effectif), ce qui dépasserait le plafond déjà atteint par les autres items. */ isRestoreBlocked(nodes: DragItem[], depth: number): boolean; /** Compteur affiché dans le titre de colonne (racine) : `6` ou `6/10` si limite racine. */ columnCountLabel(): string; /** Visibilité d'une action (view/edit/delete) : override item → défaut colonne → true. */ showAction(item: DragItem, action: 'view' | 'edit' | 'delete'): boolean; /** * Classe(s) de la carte selon son état (posées par la lib, stylées dans le SCSS DS). * Sélection → `ddn-list-card-selected` si `item.id === selectedId` (exclusif, géré par la lib) * OU `item.selected === true` (flag legacy). `pendingDelete` → `ddn-list-card-deleting`. */ cardCssClass(item: DragItem): string; /** * Libellé du compteur d'enfants, en gérant singulier/pluriel. * Affiché aussi à `0` quand la carte est vide mais peut recevoir des enfants * (ex. « 0 rubrique »). Masqué sur une carte terminale sans enfant. */ childrenCountLabel(item: DragItem, depth: number): string | null; onAdd(parent: DragItem | undefined, depth: number): void; /** Alterne le type de carte selon la profondeur : pair => default, impair => light. */ cardType(depth: number): CardTypeEnum; private applyOrderRecursive; private cloneTree; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } type ColumnType = 'text' | 'badge' | 'link' | 'actions' | 'icon' | 'image' | 'check'; interface BadgeConfig { value: string; label?: string; type: BadgeTypeEnum; withIcon?: SpriteIconEnum; iconPosition?: BadgePositionEnum; } type SortDirection = 'asc' | 'desc'; interface SortEvent { key: string; direction: SortDirection; } interface TableColumn { key: string; label: string; type?: ColumnType; align?: 'left' | 'right' | 'center'; badges?: BadgeConfig[]; icon?: SpriteIconEnum; iconCssClass?: string; image?: string; sort?: boolean; defaultSort?: SortDirection; hidden?: boolean; clickable?: boolean; } interface CellClickEvent { row: any; column: TableColumn; } interface TableConfig { rowClassFn?: (row: any) => string; } type BulkActionType = 'delete' | 'custom'; interface BulkAction { /** 'delete' déclenche le flow modale intégré ; 'custom' (défaut) émet (bulkAction). */ type?: BulkActionType; /** Identifiant — requis pour 'custom', utilisé dans l'event (bulkAction). */ id?: string; /** Clé i18n du libellé du bouton — la lib applique le pipe translate (cf. cw-button). */ label: string; icon?: SpriteIconEnum; /** Style visuel du bouton ; défaut: 'danger' si type='delete', 'primary' sinon. */ variant?: BoButtonTypeEnum; /** Désactive le bouton (peut être un signal pour réactivité). */ isDisabled?: boolean | Signal; /** Extracteur du libellé d'un item pour la modale de confirmation. Défaut : row.name ?? row.label ?? row.title ?? row.id. */ itemLabel?: (row: T) => string; /** Clé i18n du nom singulier de l'entité (ex: '_DOMAIN.LBL_DOMAIN'), passée à itemsToDeleteTitle. */ itemTitle?: string; } interface BulkActionEvent { id: string; rows: T[]; } type RowActionVariant = 'default' | 'primary' | 'danger'; interface RowActionDescriptor { /** * Clé i18n (traduite en interne). Peut dépendre du row (ex. Publish/Unpublish). * Optionnel pour les slots `edit` / `delete` (défauts `_COMMON._ACTION.EDIT` / `DELETE`). * Requis en pratique pour les `customActions`. */ label?: string | ((row: T) => string); /** Affichage. Défaut: true. */ show?: boolean | ((row: T) => boolean); /** Désactivation. Défaut: false. */ disabled?: boolean | ((row: T) => boolean); /** Handler de clic. Exclusif avec `link`. */ click?: (row: T) => void; /** Rendu en ``. Exclusif avec `click`. */ link?: string | unknown[] | ((row: T) => string | unknown[]); /** Variante visuelle. 'danger' applique le styling rouge utilisé pour Delete. */ variant?: RowActionVariant; /** Icône optionnelle (sprite). */ icon?: SpriteIconEnum; } interface RowActionsConfig { /** Slot fixe gauche. Libellé par défaut: `_COMMON._ACTION.EDIT`. */ edit?: RowActionDescriptor; /** Slot fixe droit. Libellé par défaut: `_COMMON._ACTION.DELETE`. Variant `danger` appliqué automatiquement. */ delete?: RowActionDescriptor; /** Actions custom, rendues entre edit et delete dans l'ordre du tableau. */ customActions?: RowActionDescriptor[]; /** Seuil au-dessus duquel on bascule en dropdown. Défaut: 2. */ overflowThreshold?: number; /** * Si false (défaut), les actions `disabled` sont MASQUÉES et ne comptent pas dans le décompte. * Si true, elles sont rendues grisées et comptent dans le décompte. */ showDisabled?: boolean; } /** Forme résolue par cw-table pour le rendu d'une action sur un row donné. */ interface ResolvedRowAction { label: string; disabled: boolean; variant: RowActionVariant; icon?: SpriteIconEnum; link?: string | unknown[]; click?: (row: T) => void; } interface Pagination { currentPage: number; totalPages: number; totalItems: number; itemsPerPage: number; } interface PaginationChangeEvent { page: number; itemsPerPage: number; } declare class TableComponent { private readonly modalsService; readonly checkbox: _angular_core.InputSignal; readonly title: _angular_core.InputSignal; readonly columns: _angular_core.InputSignal; readonly data: _angular_core.InputSignal; readonly loading: _angular_core.InputSignal; readonly rowClassFn: _angular_core.InputSignal<(row: any) => string>; readonly pagination: _angular_core.InputSignal; readonly bulkActions: _angular_core.InputSignal[]>; readonly rowActions: _angular_core.InputSignal>; readonly cellClick: _angular_core.OutputEmitterRef; readonly sortChange: _angular_core.OutputEmitterRef; readonly selectionChange: _angular_core.OutputEmitterRef; readonly paginationChange: _angular_core.OutputEmitterRef; /** Émis quand l'utilisateur confirme la modale d'une action type='delete'. */ readonly bulkDelete: _angular_core.OutputEmitterRef; /** Émis pour les actions type='custom' au clic, et pour les 'delete' après confirmation. */ readonly bulkAction: _angular_core.OutputEmitterRef>; readonly actionsTemplate: Signal>; readonly iconType: typeof IconTypeEnum; readonly iconUiType: typeof IconUiTypeEnum; readonly iconSize: typeof IconSizeEnum; readonly spriteIcon: typeof SpriteIconEnum; readonly buttonType: typeof BoButtonTypeEnum; readonly currentSortKey: _angular_core.WritableSignal; readonly currentSortDirection: _angular_core.WritableSignal; readonly selectedRows: _angular_core.WritableSignal>; readonly allSelected: Signal; readonly someSelected: Signal; constructor(); ngOnInit(): void; getRowClass(row: any): string; setSortProperty(key: string): void; getSortClass(key: string): string; getSortIcon(key: string): SpriteIconEnum; getBadge(column: TableColumn, value: string): BadgeConfig; onCellClick(row: any, column: TableColumn): void; isClickable(column: TableColumn): boolean; isTruthy(value: unknown): boolean; toggleAll(): void; toggleRow(row: any): void; isSelected(row: any): boolean; resolveVariant(action: BulkAction): BoButtonTypeEnum; resolveDisabled(action: BulkAction): boolean; onBulkActionClick(action: BulkAction): Promise; private readonly defaultLabelFn; /** Booléen indiquant si l'API déclarative `rowActions` est utilisée. */ get usingRowActions(): boolean; /** Résout la liste d'actions visibles pour un row donné, en appliquant show/disabled/showDisabled. */ getResolvedActions(row: any): ResolvedRowAction[]; getOverflowThreshold(): number; /** * Nombre maximum d'actions visibles parmi toutes les lignes. * Sert à décider d'un affichage UNIFORME : la bascule inline/dropdown * est globale au tableau, pas calculée ligne par ligne. */ readonly maxVisibleActions: Signal; /** * Vrai si le tableau doit afficher les actions en dropdown. * Dès qu'une seule ligne dépasse le seuil, TOUTES les lignes * basculent en dropdown pour un rendu uniforme. */ readonly useDropdownActions: Signal; onRowActionClick(action: ResolvedRowAction, row: any): void; actionCssClass(action: ResolvedRowAction): string; private evalShow; private evalDisabled; private evalLabel; private evalLink; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } interface FilterFieldConfig { key: string; label: string; placeholder?: string; type: FormFieldTypeEnum; options?: FormFieldOption[] | Signal; defaultValue?: any; colClass?: string; } type FilterValues = Record; declare class FilterBarComponent { private readonly destroyRef; private readonly router; private readonly route; readonly filters: _angular_core.InputSignal; readonly manual: _angular_core.InputSignal; /** Synchronise l'état appliqué des filtres avec les query params de l'URL (mémorisation / partage). */ readonly syncUrl: _angular_core.InputSignal; readonly applyLabel: _angular_core.InputSignal; readonly resetLabel: _angular_core.InputSignal; readonly filtersApplied: _angular_core.OutputEmitterRef; readonly filtersReset: _angular_core.OutputEmitterRef; readonly uiType: typeof BoButtonTypeEnum; filterForm: FormGroup<{}>; private defaults; constructor(); private buildForm; /** Lit les valeurs de filtre présentes dans les query params de l'URL. */ private readUrlValues; /** Reporte l'état appliqué des filtres dans les query params (replaceUrl, sans polluer l'historique). */ private syncFiltersToUrl; /** Normalise une valeur en param d'URL ; les valeurs vides sont retirées (null). */ private toParam; getControl(key: string): FormControl | FormGroup; resolveOptions(field: FilterFieldConfig): FormFieldOption[]; apply(): void; reset(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } declare enum PageHeaderActionEnum { add = "add", save = "save", reset = "reset", exportCurrent = "exportCurrent", exportAll = "exportAll", import = "import" } type PageHeaderActionState = Partial>; declare class PageHeaderComponent { private readonly location; readonly title: _angular_core.InputSignal; readonly description: _angular_core.InputSignal; readonly showBack: _angular_core.InputSignal; readonly actions: _angular_core.InputSignal; readonly isLoading: _angular_core.InputSignal>>; readonly isDisabled: _angular_core.InputSignal>>; readonly action: _angular_core.OutputEmitterRef; readonly buttonType: typeof BoButtonTypeEnum; readonly iconSize: typeof ButtonIconSizeEnum; readonly spriteIcon: typeof SpriteIconEnum; readonly actionEnum: typeof PageHeaderActionEnum; readonly hasExport: _angular_core.Signal; readonly showExportCurrent: _angular_core.Signal; readonly showExportAll: _angular_core.Signal; readonly showImport: _angular_core.Signal; readonly showReset: _angular_core.Signal; readonly showAdd: _angular_core.Signal; readonly showSave: _angular_core.Signal; goBack(): void; emit(action: PageHeaderActionEnum): void; loading(action: PageHeaderActionEnum): boolean; disabled(action: PageHeaderActionEnum): boolean; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } type PageItem = number | { type: 'jump-prev' | 'jump-next'; page: number; }; declare class PaginationComponent { pagination: _angular_core.InputSignal; paginationChange: _angular_core.OutputEmitterRef; readonly spriteIcon: typeof SpriteIconEnum; readonly typeField: typeof FormFieldTypeEnum; readonly typeButton: typeof BoButtonTypeEnum; readonly buttonIconSize: typeof ButtonIconSizeEnum; readonly pageSizes: number[]; readonly pageSizesOptions: FormFieldOption[]; itemsPerPageControl: FormControl; constructor(); readonly visiblePages: _angular_core.Signal; emit(page: number): void; onItemsPerPageChange(value: number): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } declare function buildFilterParams(filters: FilterValues, keyMap?: Record): HttpParams; export { ArrayAdapter, CustomListComponent, DragNDropListComponent, DragNDropNestedListComponent, FilterBarComponent, FormArrayAdapter, PageHeaderActionEnum, PageHeaderComponent, PaginationComponent, TableComponent, buildFilterParams }; export type { BadgeConfig, BulkAction, BulkActionEvent, BulkActionType, CellClickEvent, ColumnType, DataCustomList, DataCustomListGroup, DragAddEvent, DragDropAdapter, DragItem, DragItemActions, DragItemBadge, DragListColumn, FilterFieldConfig, FilterValues, PageHeaderActionState, Pagination, PaginationChangeEvent, ResolvedRowAction, RowActionDescriptor, RowActionVariant, RowActionsConfig, SortDirection, SortEvent, TableColumn, TableConfig };