@cityway/bo-ui 1.1.0-beta017 → 1.1.0-beta018
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.
- package/cityway-bo-ui-1.1.0-beta018.tgz +0 -0
- package/docs/components/drag-n-drop-nested-list.md +47 -1
- package/docs/components/page-header.md +3 -3
- package/fesm2022/cityway-bo-ui.mjs +65 -16
- package/fesm2022/cityway-bo-ui.mjs.map +1 -1
- package/index.d.ts +46 -3
- package/package.json +2 -2
- package/cityway-bo-ui-1.1.0-beta017.tgz +0 -0
|
Binary file
|
|
@@ -45,6 +45,7 @@ Liste hiérarchique réordonnable par glisser-déposer (CDK drag-drop), pilotée
|
|
|
45
45
|
| `delete` | `DragItem` | Clic sur l'action « supprimer » (corbeille) — sur une carte **non** `pendingDelete`. |
|
|
46
46
|
| `restore` | `DragItem` | Clic sur « Restaurer » — sur une carte `pendingDelete` (la corbeille bascule en restauration). |
|
|
47
47
|
| `add` | `DragAddEvent` | Clic sur un lien « Ajouter » (racine ou pied de carte). Payload : `{ parent?: DragItem; depth: number }` (`parent` = `undefined` à la racine). |
|
|
48
|
+
| `expandedChange` | `{ item: DragItem; expanded: boolean }` | L'utilisateur a plié / déplié une carte (chevron). À refléter dans `DragItem.expanded` pour que l'état survive au prochain `items`. **Jamais émis** pour un état posé par l'hôte (`expanded`, `expandSelected`). |
|
|
48
49
|
|
|
49
50
|
### Contenu projeté (corps de carte custom)
|
|
50
51
|
|
|
@@ -72,7 +73,9 @@ interface DragItem {
|
|
|
72
73
|
label: string; // libellé (fallback de title dans l'en-tête)
|
|
73
74
|
code?: string; // affiché seul dans le corps quand il n'y a pas d'itemTemplate
|
|
74
75
|
order?: number; // position 1..n (renumérotée si reorderOnDrop)
|
|
75
|
-
disabled?: boolean; // verrouille le drag de CETTE carte (poignée inactive)
|
|
76
|
+
disabled?: boolean; // verrouille le drag de CETTE carte (poignée affichée, inactive)
|
|
77
|
+
sortable?: boolean; // false : ordre non manipulable, AUCUNE poignée (défaut column.sortable → true)
|
|
78
|
+
expanded?: boolean; // état déplié voulu par l'hôte, réappliqué à chaque nouvel `items` (undefined : replié au départ)
|
|
76
79
|
children?: DragItem[]; // sous-arbre
|
|
77
80
|
|
|
78
81
|
title?: string; // titre de la carte (fallback sur label)
|
|
@@ -108,6 +111,8 @@ interface DragListColumn {
|
|
|
108
111
|
cssClass?: string; // classe sur chaque <ul> de niveau
|
|
109
112
|
|
|
110
113
|
collapsible?: boolean; // cartes pliables (défaut true) ; false désactive globalement
|
|
114
|
+
sortable?: boolean; // défaut de DragItem.sortable ; false = liste à ordre fixe (aucune poignée)
|
|
115
|
+
expandSelected?: boolean; // déplie les ancêtres de la carte selectedId (prime sur DragItem.expanded)
|
|
111
116
|
showView?: boolean; // visibilité par défaut des actions (surchargée par DragItem.actions)
|
|
112
117
|
showEdit?: boolean;
|
|
113
118
|
showDelete?: boolean;
|
|
@@ -132,6 +137,8 @@ interface DragAddEvent {
|
|
|
132
137
|
|
|
133
138
|
- **Ajout** (`canAdd`) : `item.actions.add` → `column.showAdd` → `depth < maxDepth` (si `maxDepth` défini) → `true`. Indépendant de la présence d'enfants (une carte vide reste addable).
|
|
134
139
|
- **Actions view/edit/delete** (`showAction`) : `item.actions[action]` → `column.show{View|Edit|Delete}` → `true`.
|
|
140
|
+
- **Triable** (`isSortable`) : `item.sortable` → `column.sortable` → `true`. Non triable : poignée **non rendue** et drag désactivé. Distinct de `disabled` (poignée affichée mais inerte) ; `disabled` et `pendingDelete` n'ont pas d'effet supplémentaire sur une carte non triable.
|
|
141
|
+
- **Déplié** (`isCollapsedCard`) : dernier état connu de la carte, mis à jour par le chevron (utilisateur), par `item.expanded` à chaque nouvelle valeur de `items`, puis par `column.expandSelected` (ancêtres de `selectedId` dépliés, à chaque changement de sélection ou d'`items`) ; à défaut, une carte pliable démarre repliée. L'état est indexé par `id` : une carte dont l'`id` change (id définitif après enregistrement) repart de zéro, d'où l'intérêt de lui passer `expanded`.
|
|
135
142
|
- **Pliable** (`isCollapsible`) : faux si `pendingDelete` ou `column.collapsible === false` ; sinon vrai si la carte a des enfants OU peut en recevoir.
|
|
136
143
|
- **Niveau plein** (`isLevelFull`) : vrai si `maxItemsByDepth[depth]` défini et atteint (`excludePendingDeleteFromMax` exclut les marqués du décompte).
|
|
137
144
|
|
|
@@ -200,6 +207,43 @@ items: DragItem[] = [
|
|
|
200
207
|
];
|
|
201
208
|
```
|
|
202
209
|
|
|
210
|
+
### Liste à ordre fixe (`sortable: false`)
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
// L'ordre n'est pas manuel (ex. trié côté API) : aucune poignée rendue, aucun drag.
|
|
214
|
+
// Le reste fonctionne (sélection, édition, suppression différée, ajout, sous-niveaux).
|
|
215
|
+
column: DragListColumn = { title: 'Seuils de zoom', sortable: false };
|
|
216
|
+
|
|
217
|
+
// Ou carte par carte (l'item prime sur la colonne) :
|
|
218
|
+
items: DragItem[] = [
|
|
219
|
+
{ id: 1, label: 'Racine', sortable: false, children: [
|
|
220
|
+
{ id: 11, label: 'Enfant réordonnable' }, // hérite de la colonne → triable
|
|
221
|
+
] },
|
|
222
|
+
];
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
> `disabled` ≠ `sortable: false` : `disabled` = « déplaçable en principe, verrouillé pour l'instant » (poignée affichée, inerte) ; `sortable: false` = « cet ordre ne se manipule pas » (pas de poignée).
|
|
226
|
+
|
|
227
|
+
### Dépliage piloté par l'hôte (`expanded`, `expandSelected`)
|
|
228
|
+
|
|
229
|
+
```html
|
|
230
|
+
<cw-drag-n-drop-nested-list [items]="items" [column]="column" [selectedId]="selectedId"
|
|
231
|
+
(expandedChange)="onExpandedChange($event)" />
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
// La sélection (ex. un enfant désigné par une erreur d'enregistrement) est toujours visible.
|
|
236
|
+
column: DragListColumn = { title: 'Seuils', expandSelected: true };
|
|
237
|
+
|
|
238
|
+
// Tout déplier : nouvel `items` avec `expanded` (réappliqué à chaque nouvelle valeur).
|
|
239
|
+
expandAll() { this.items = this.items.map(i => ({ ...i, expanded: true })); }
|
|
240
|
+
|
|
241
|
+
// Refléter les choix de l'utilisateur, pour qu'ils survivent au prochain rechargement.
|
|
242
|
+
onExpandedChange({ item, expanded }: { item: DragItem; expanded: boolean }) {
|
|
243
|
+
this.items = this.items.map(i => i.id === item.id ? { ...i, expanded } : i);
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
203
247
|
### Nombre max par niveau (`maxItemsByDepth`)
|
|
204
248
|
|
|
205
249
|
```ts
|
|
@@ -296,6 +340,8 @@ onReorder(items: DragItem[]) { this.items = items; }
|
|
|
296
340
|
- « Limite les rubriques à 3 par thème (`maxItemsByDepth: { 1: 3 }`) avec un message d'alerte i18n quand le max est atteint. »
|
|
297
341
|
- « Ajoute un soft-delete : *Supprimer* marque la carte (`pendingDelete`), *Restaurer* l'annule ; sélection exclusive de la carte en cours d'édition via `selectedId`. »
|
|
298
342
|
- « Affiche un corps de carte custom (titre + niveau) via `itemTemplate`, en gardant l'en-tête data-driven. »
|
|
343
|
+
- « Garde mes sections dépliées après enregistrement et ouvre automatiquement le parent de la carte en erreur (`expanded` + `expandSelected`). »
|
|
344
|
+
- « Ma liste de seuils est triée par l'API : retire les poignées de drag (`column.sortable: false`) en gardant édition et suppression. »
|
|
299
345
|
- « Rends la *Section A* non déplaçable (`disabled`) et masque l'action *supprimer* sur les feuilles via `DragItem.actions`. »
|
|
300
346
|
|
|
301
347
|
**Rappels pour Claude :**
|
|
@@ -52,8 +52,8 @@ Trois emplacements, dans l'ordre du template :
|
|
|
52
52
|
| Slot | Sélecteur | Position dans la barre | Usage |
|
|
53
53
|
|------|-----------|------------------------|-------|
|
|
54
54
|
| Import | `cwPageHeaderImport` | après *Colonnes*, avant l'export | `<cw-import-button>` |
|
|
55
|
-
| Export | `cwPageHeaderExport` | après l'import, avant
|
|
56
|
-
| Libre | *(aucun)* | après
|
|
55
|
+
| Export | `cwPageHeaderExport` | après l'import, avant le slot libre | `<cw-export-button>` |
|
|
56
|
+
| Libre | *(aucun)* | après l'export, avant *Réinitialiser* | tout le reste |
|
|
57
57
|
|
|
58
58
|
```html
|
|
59
59
|
<cw-page-header [title]="'DOMAIN.USERS.TITLE'" [actions]="[actionEnum.add]" (action)="onAction($event)">
|
|
@@ -215,7 +215,7 @@ Règles :
|
|
|
215
215
|
|
|
216
216
|
- **i18n** : `title` et `description` passent par `translate` → fournir des **clés**, pas du texte en dur. `description` est rendue en `[innerHTML]` (peut contenir du HTML/markup traduit).
|
|
217
217
|
- **Libellés des actions** : non paramétrables. Ils sont câblés sur les clés `_COMMON._ACTION.*` (`ADD`, `SAVE`, `RESET`) et `_COMMON._FORM.BACK` pour le retour. Ces clés doivent exister dans les bundles i18n de l'app.
|
|
218
|
-
- **Ordre d'affichage** : imposé par le template, indépendant de l'ordre du tableau `actions` et de l'ordre d'écriture du contenu projeté → Colonnes, *slot import*, *slot export*,
|
|
218
|
+
- **Ordre d'affichage** : imposé par le template, indépendant de l'ordre du tableau `actions` et de l'ordre d'écriture du contenu projeté → Colonnes, *slot import*, *slot export*, *slot libre*, Réinitialiser, Ajouter, Enregistrer. Lu de droite à gauche : Enregistrer, Réinitialiser, zone custom, Exporter, Importer — les actions sur le formulaire au plus près de l'action principale, les échanges de données à l'extérieur.
|
|
219
219
|
- **Bouton retour** : navigue via `Location.back()` (historique du navigateur). Aucune sortie ni cible configurable ; masquer avec `[showBack]="false"` si non pertinent.
|
|
220
220
|
- **États par action** : `isLoading` / `isDisabled` sont des maps partielles ; une action absente de la map vaut `false`.
|
|
221
221
|
- **Dépendance** : le composant projette des `cw-button` (`@cityway/basic-ui`) en interne — `basic-ui` doit être disponible.
|