@oneteme/jquery-table 0.0.14 → 0.0.16
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/README.md +72 -18
- package/esm2022/lib/component/export.manager.mjs +4 -3
- package/esm2022/lib/component/table-preferences.manager.mjs +13 -3
- package/esm2022/lib/component/table.component.mjs +274 -102
- package/esm2022/lib/component/table.constants.mjs +3 -1
- package/esm2022/lib/directive/jqt-cell-def.directive.mjs +4 -2
- package/esm2022/lib/jquery-table.model.mjs +1 -1
- package/fesm2022/oneteme-jquery-table.mjs +292 -105
- package/fesm2022/oneteme-jquery-table.mjs.map +1 -1
- package/lib/component/table.component.d.ts +64 -10
- package/lib/component/table.constants.d.ts +2 -0
- package/lib/directive/jqt-cell-def.directive.d.ts +5 -1
- package/lib/jquery-table.model.d.ts +36 -8
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Bibliothèque Angular qui encapsule Angular Material Table avec une API orienté
|
|
|
24
24
|
- Pagination standard et pagination par groupe
|
|
25
25
|
- **Group by** : regroupement des lignes par colonne, groupes pliables/dépliables, pagination indépendante par groupe
|
|
26
26
|
- **Slice panel** : filtres catégoriels latéraux, statiques (prédéfinis) ou dynamiques (colonne valeurs uniques), multi-sélection configurable
|
|
27
|
-
- **Chargement paresseux** (lazy) de
|
|
27
|
+
- **Chargement paresseux** (lazy) de colonnes : `lazy: true` + `lazyLoader` dans la config (la colonne n'est demandée qu'à son activation)
|
|
28
28
|
- Rendus de cellule personnalisés via directive `jqtCellDef`
|
|
29
29
|
- État de chargement (`isLoading`) et état vide configurable
|
|
30
30
|
- Événement de clic sur ligne (`rowSelected`)
|
|
@@ -119,6 +119,7 @@ Le `config` complet reste disponible pour activer les fonctionnalités avancées
|
|
|
119
119
|
| `columnsConfig` | `TableColumnProvider<T>[]` | Configuration des colonnes (remplace `config.columns`) |
|
|
120
120
|
| `columnLabels` | `Record<string, string>` | Labels des colonnes pour le mode allégé |
|
|
121
121
|
| `isLoading` | `boolean` | Affiche l'état de chargement (défaut : `false`) |
|
|
122
|
+
| `lazyError` | `boolean` | `true` quand la requête relancée après `lazyColumnsRequested` échoue : les colonnes lazy en attente affichent « Réessayer » (voir colonnes lazy) |
|
|
122
123
|
| `view` | `TableViewConfig` | Surcharge `config.view` si défini (mode HTML) |
|
|
123
124
|
|
|
124
125
|
### Outputs
|
|
@@ -131,6 +132,7 @@ Le `config` complet reste disponible pour activer les fonctionnalités avancées
|
|
|
131
132
|
| `searchChange` | `string` | Frappe dans la barre de recherche |
|
|
132
133
|
| `groupByChange` | `string \| null` | Group by activé (clé) ou désactivé (`null`) |
|
|
133
134
|
| `columnsChange` | `string[]` | Colonnes visibles modifiées (clés dans l'ordre d'affichage) |
|
|
135
|
+
| `lazyColumnsRequested` | `string[]` | Clés cumulées des colonnes `lazy` demandées, émises à l'activation d'une nouvelle colonne (voir colonnes lazy) |
|
|
134
136
|
| `columnAdded` | `TableColumnProvider<T>` | Colonne ajoutée aux colonnes actives |
|
|
135
137
|
| `columnRemoved` | `TableColumnProvider<T>` | Colonne retirée des colonnes actives |
|
|
136
138
|
| `categorySelected` | `string` | Catégorie de slice sélectionnée |
|
|
@@ -153,6 +155,7 @@ interface TableProvider<T = any> {
|
|
|
153
155
|
view?: TableViewConfig;
|
|
154
156
|
labels?: TableLabelsConfig;
|
|
155
157
|
export?: TableExportConfig<T>;
|
|
158
|
+
lazyLoader?: (lazyColumns: string[]) => Observable<T[]>; // Charge les colonnes lazy (lignes complètes)
|
|
156
159
|
preferences?: TablePreferencesConfig; // Sauvegarde dans localStorage
|
|
157
160
|
|
|
158
161
|
defaultSort?: { active: string; direction: 'asc' | 'desc' };
|
|
@@ -180,16 +183,14 @@ interface TableColumnProvider<T = any> {
|
|
|
180
183
|
width?: string; // Largeur CSS en px uniquement pour le calcul min-width (ex: '120px')
|
|
181
184
|
// Les unités %, em, rem sont ignorées dans le calcul de tableMinWidth
|
|
182
185
|
|
|
183
|
-
optional?: boolean; // Colonne masquée par défaut, ajoutables via View menu
|
|
186
|
+
optional?: boolean; // Colonne masquée par défaut, ajoutables via View menu (implicite pour une colonne lazy)
|
|
184
187
|
removable?: boolean; // Peut être retirée manuellement
|
|
185
188
|
|
|
186
189
|
groupable?: boolean; // Disponible comme critère de regroupement dans View menu
|
|
187
190
|
sliceable?: boolean; // Disponible comme slice dynamique dans View menu
|
|
188
191
|
searchValue?: DataProvider<string>; // Valeur utilisée par la recherche texte (si différente de value)
|
|
189
192
|
|
|
190
|
-
lazy?:
|
|
191
|
-
fetchFn: () => Observable<any[]>; // Retourne un tableau dans le même ordre que les lignes
|
|
192
|
-
};
|
|
193
|
+
lazy?: true; // Absente de la requête de base, forcément optionnelle : demandée à sa première activation
|
|
193
194
|
}
|
|
194
195
|
```
|
|
195
196
|
|
|
@@ -398,19 +399,70 @@ interface SliceCategory<T = any> {
|
|
|
398
399
|
|
|
399
400
|
## Fonctionnalité — lazy columns
|
|
400
401
|
|
|
402
|
+
Une colonne `lazy: true` est absente de la requête de base : elle réduit la réponse du premier rendu et n'est demandée que si l'utilisateur l'affiche. Elle est donc **forcément optionnelle** : `optional: true` est implicite (inutile de l'écrire) et `optional: false` lève une erreur explicite, car la colonne serait demandée dès le premier rendu, soit une requête de plus pour rien. Le type refuse aussi cette combinaison à la compilation.
|
|
403
|
+
|
|
404
|
+
### Avec `lazyLoader` (le plus simple)
|
|
405
|
+
|
|
406
|
+
`[data]` reste la requête de base de l'application. Le chargeur de la config est appelé à l'activation d'une colonne lazy et retourne les **lignes complètes** (colonnes de base + colonnes lazy demandées) :
|
|
407
|
+
|
|
401
408
|
```ts
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
lazy:
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
]
|
|
409
|
+
config: TableProvider<Country> = {
|
|
410
|
+
columns: [
|
|
411
|
+
col('code', 'Code'),
|
|
412
|
+
col('name', 'Pays'),
|
|
413
|
+
col('capital', 'Capitale', { lazy: true }),
|
|
414
|
+
col('currency', 'Devise', { lazy: true }),
|
|
415
|
+
],
|
|
416
|
+
// colonnes lazy demandées (cumul) : ['capital'], puis ['capital', 'currency']
|
|
417
|
+
lazyLoader: columns => this.api.fetchCountries(columns), // Observable<Country[]>
|
|
418
|
+
};
|
|
411
419
|
```
|
|
412
420
|
|
|
413
|
-
|
|
421
|
+
```html
|
|
422
|
+
<jquery-table [config]="config" [data]="countries"></jquery-table>
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
La table appelle `lazyLoader`, affiche le skeleton, remplace ses lignes par la réponse, gère l'erreur et le bouton « Réessayer » (sans `[lazyError]`), et annule l'appel en cours si une nouvelle demande arrive.
|
|
426
|
+
|
|
427
|
+
- Un nouveau `[data]` (rafraîchissement de l'application) l'emporte sur les lignes du chargeur : si des colonnes lazy ont déjà été demandées, la table rappelle `lazyLoader` avec ce cumul (le skeleton réapparaît le temps de la requête). Pour une page rafraîchie en continu, préférer le mode événement ci-dessous afin d'éviter cette seconde requête.
|
|
428
|
+
- Rien n'est appelé tant que le tableau n'a aucune ligne.
|
|
429
|
+
|
|
430
|
+
### Avec l'événement `lazyColumnsRequested` (l'application garde la main)
|
|
431
|
+
|
|
432
|
+
Sans `lazyLoader`, la table émet `(lazyColumnsRequested)` ; l'application **relance sa requête complète en incluant ces colonnes** et repasse les nouvelles `data`. Tant qu'elles ne sont pas arrivées, la colonne affiche un skeleton ; à leur arrivée, elles remplacent les anciennes lignes.
|
|
433
|
+
|
|
434
|
+
```ts
|
|
435
|
+
config: TableProvider<Session> = {
|
|
436
|
+
columns: [
|
|
437
|
+
col('name', 'Nom'),
|
|
438
|
+
col('address', 'Adresse', { lazy: true }),
|
|
439
|
+
col('status', 'Statut', { lazy: true }),
|
|
440
|
+
],
|
|
441
|
+
};
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
```html
|
|
445
|
+
<jquery-table [config]="config" [data]="rows" [lazyError]="lazyFailed" (lazyColumnsRequested)="onLazyColumns($event)"></jquery-table>
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
```ts
|
|
449
|
+
onLazyColumns(columns: string[]) { // ex. ['address'], puis ['address', 'status']
|
|
450
|
+
this.lazyFailed = false;
|
|
451
|
+
this.api.fetchRows(columns).subscribe({ // même requête que la base + ces colonnes
|
|
452
|
+
next: rows => this.rows = rows,
|
|
453
|
+
error: () => this.lazyFailed = true,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
- `lazyColumnsRequested` émet **toutes** les colonnes lazy demandées depuis le début (cumul) : la requête complète peut être reconstruite à partir de cette seule liste, y compris lors d'un rafraîchissement périodique.
|
|
459
|
+
- Les colonnes `lazy: true` apparaissent dans Organizer > Champs sans être demandées ; l'événement part à l'activation (ou si la colonne sert de Group by / Slice by, y compris `defaultGroupBy`, une préférence restaurée ou un snapshot). Plusieurs colonnes activées dans le même tick partent dans un seul événement.
|
|
460
|
+
- Rien n'est émis tant que le tableau n'a aucune ligne : la première réponse de l'application ne doit pas être prise pour celle qui contient les colonnes.
|
|
461
|
+
- Les nouvelles `data` (changement de `[data]` ou `[dataSource]`) marquent toutes les colonnes demandées comme prêtes. Les données fournies ensuite (rafraîchissement, changement de `config`) doivent donc déjà contenir les colonnes demandées : la table ne les redemande pas.
|
|
462
|
+
- Pour garder le tableau visible pendant la requête, ne pas passer `isLoading` à `true` : seul le skeleton de la colonne apparaît. Annuler la requête précédente (`switchMap`) évite qu'une réponse périmée soit prise pour la bonne.
|
|
463
|
+
- En cas d'échec, passer `[lazyError]` à `true` : les colonnes en attente affichent « Réessayer » (cellule, ou en-tête de groupe si la colonne sert de Group by). Le clic réémet `lazyColumnsRequested` ; repasser `lazyError` à `false` au nouvel essai.
|
|
464
|
+
- Sans `lazyLoader` ni écouteur, une colonne lazy activée resterait en skeleton : en développement, la table l'indique par un avertissement dans la console.
|
|
465
|
+
- Une fois reçue, la colonne se comporte comme une colonne ordinaire : tri, recherche, Group by, Slice by, `value`, `sortValue`, `searchValue`, `jqtCellDef` et export CSV. L'export n'écrit jamais d'état de chargement ou d'erreur (cellule vide).
|
|
414
466
|
|
|
415
467
|
---
|
|
416
468
|
|
|
@@ -433,6 +485,7 @@ Le composant gère l'état `idle | loading | loaded | error` par colonne, avec p
|
|
|
433
485
|
Contexte du template :
|
|
434
486
|
- `$implicit` la ligne brute (`T`)
|
|
435
487
|
- `index` index global de la ligne
|
|
488
|
+
- `value` valeur affichée de la cellule ; seul moyen de lire la valeur d'une colonne `lazy`, absente de la ligne brute (`let-value="value"`). Pour une colonne lazy, le template n'est rendu qu'une fois la valeur chargée : le skeleton et le bouton d'erreur sont gérés par le tableau.
|
|
436
489
|
|
|
437
490
|
---
|
|
438
491
|
|
|
@@ -473,8 +526,7 @@ config: TableProvider<Row> = {
|
|
|
473
526
|
| `sliceConfigs` | `SliceConfig<T>[]` | Configurations des slices |
|
|
474
527
|
| `columns` | `SliceColumnDef<T>[]` | Définitions des colonnes pour la résolution des valeurs |
|
|
475
528
|
| `data` | `T[]` | Données source |
|
|
476
|
-
| `
|
|
477
|
-
| `lazyStatus` | `Map<string, 'idle'\|'loading'\|'loaded'\|'error'>` | État par colonne lazy |
|
|
529
|
+
| `lazyStatus` | `Map<string, 'idle'\|'loading'\|'loaded'\|'error'>` | État par colonne lazy (leurs valeurs sont lues dans les lignes de `data`) |
|
|
478
530
|
| `showToggle` | `boolean` | Affiche le bouton collapse du panel (défaut : `true`) |
|
|
479
531
|
| `showCounts` | `boolean` | Affiche le nombre de lignes par catégorie (défaut : `true`) |
|
|
480
532
|
| `collapsedByDefault` | `boolean` | Les slices démarrent repliés (défaut : `false`) |
|
|
@@ -596,7 +648,7 @@ import { normalizeCellValue, humanizeKey, getFrenchPaginatorIntl } from '@onetem
|
|
|
596
648
|
|
|
597
649
|
Ajoute un sous-menu **Préférences** dans le menu View permettant :
|
|
598
650
|
- **Mode édition** : redimensionner et réordonner les colonnes à la souris
|
|
599
|
-
- **Enregistrer** : persiste la configuration dans le `localStorage` (colonnes visibles, ordre, largeurs, tri, group by, filtres slice)
|
|
651
|
+
- **Enregistrer** : persiste la configuration dans le `localStorage` (colonnes visibles, ordre, largeurs, tri, group by, filtres slice, nombre de lignes par page et par groupe)
|
|
600
652
|
- **Effacer** : supprime la configuration sauvegardée
|
|
601
653
|
|
|
602
654
|
```ts
|
|
@@ -620,6 +672,8 @@ interface TablePreferencesConfig {
|
|
|
620
672
|
|
|
621
673
|
La configuration est persistée sous la clé `jqt_prefs_<tableId>` et restaurée automatiquement au chargement suivant.
|
|
622
674
|
|
|
675
|
+
Le nombre de lignes (`pageSize` en mode normal, `groupPageSize` en mode Group by, `0` = tout afficher) est restauré uniquement s'il figure encore dans `pagination.pageSizeOptions` / `pageSizeOptionsGroupBy` ; sinon la valeur de la config est conservée. L'index de page n'est pas sauvegardé.
|
|
676
|
+
|
|
623
677
|
---
|
|
624
678
|
|
|
625
679
|
## Build
|
|
@@ -17,7 +17,8 @@ export class ExportManager {
|
|
|
17
17
|
return;
|
|
18
18
|
const rows = this.getRows();
|
|
19
19
|
const columns = this.getColumns();
|
|
20
|
-
const
|
|
20
|
+
const baseName = cfg.filename || 'export';
|
|
21
|
+
const filename = baseName.toLowerCase().endsWith('.csv') ? baseName : baseName + '.csv';
|
|
21
22
|
const header = columns.map(c => this._csvEscape(c.header || c.key)).join(',');
|
|
22
23
|
const lines = rows.map((row, idx) => {
|
|
23
24
|
if (cfg.transform) {
|
|
@@ -31,7 +32,7 @@ export class ExportManager {
|
|
|
31
32
|
const url = URL.createObjectURL(blob);
|
|
32
33
|
const a = document.createElement('a');
|
|
33
34
|
a.href = url;
|
|
34
|
-
a.download = filename
|
|
35
|
+
a.download = filename;
|
|
35
36
|
a.click();
|
|
36
37
|
URL.revokeObjectURL(url);
|
|
37
38
|
}
|
|
@@ -42,4 +43,4 @@ export class ExportManager {
|
|
|
42
43
|
return value;
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
46
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0Lm1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbmV0ZW1lL2pxdWVyeS10YWJsZS9zcmMvbGliL2NvbXBvbmVudC9leHBvcnQubWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQ21CLE9BQWtCLEVBQ2xCLFVBQTBDLEVBQzFDLFNBQWlELEVBQ2pELGdCQUE2RTtRQUg3RSxZQUFPLEdBQVAsT0FBTyxDQUFXO1FBQ2xCLGVBQVUsR0FBVixVQUFVLENBQWdDO1FBQzFDLGNBQVMsR0FBVCxTQUFTLENBQXdDO1FBQ2pELHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBNkQ7SUFDN0YsQ0FBQztJQUVKLE1BQU07UUFDSixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPO1lBQUUsT0FBTztRQUMxQixNQUFNLElBQUksR0FBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDO1FBQzFDLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQztRQUV4RixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM5RSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQ2xDLElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRTtnQkFDakIsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDN0IsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQzVFO1lBQ0QsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2RyxDQUFDLENBQUMsQ0FBQztRQUVILG1EQUFtRDtRQUNuRCxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLFFBQVEsR0FBRyxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHdCQUF3QixFQUFFLENBQUMsQ0FBQztRQUN0RyxNQUFNLEdBQUcsR0FBSSxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxHQUFNLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUM7UUFDYixDQUFDLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN0QixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDVixHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFTyxVQUFVLENBQUMsS0FBYTtRQUM5QixJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDOUYsT0FBTyxHQUFHLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO1NBQ2hEO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUYWJsZUNvbHVtblByb3ZpZGVyLCBUYWJsZUV4cG9ydENvbmZpZyB9IGZyb20gJy4uL2pxdWVyeS10YWJsZS5tb2RlbCc7XG5cbi8qKlxuICogRXhwb3J0TWFuYWdlclxuICpcbiAqIEVuY2Fwc3VsZSBsJ2V4cG9ydCBDU1YgOiBjb25zdHJ1Y3Rpb24gZHUgZmljaGllciBCT00vVVRGLTgsIMOpY2hhcHBlbWVudCBldCBkw6ljbGVuY2hlbWVudCBkdSB0w6lsw6ljaGFyZ2VtZW50LlxuICogQXVjdW5lIGTDqXBlbmRhbmNlIEFuZ3VsYXIg4oCUIGluZMOpcGVuZGFudCBkdSBjeWNsZSBkZSB2aWUgZHUgY29tcG9zYW50LlxuICovXG5leHBvcnQgY2xhc3MgRXhwb3J0TWFuYWdlcjxUPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ2V0Um93czogKCkgPT4gVFtdLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ2V0Q29sdW1uczogKCkgPT4gVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ2V0Q29uZmlnOiAoKSA9PiBUYWJsZUV4cG9ydENvbmZpZzxUPiB8IHVuZGVmaW5lZCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlc29sdmVDZWxsVmFsdWU6IChjb2w6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4sIHJvdzogVCwgaW5kZXg6IG51bWJlcikgPT4gYW55LFxuICApIHt9XG5cbiAgZXhwb3J0KCk6IHZvaWQge1xuICAgIGNvbnN0IGNmZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjZmc/LmVuYWJsZWQpIHJldHVybjtcbiAgICBjb25zdCByb3dzICAgID0gdGhpcy5nZXRSb3dzKCk7XG4gICAgY29uc3QgY29sdW1ucyA9IHRoaXMuZ2V0Q29sdW1ucygpO1xuICAgIGNvbnN0IGJhc2VOYW1lID0gY2ZnLmZpbGVuYW1lIHx8ICdleHBvcnQnO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gYmFzZU5hbWUudG9Mb3dlckNhc2UoKS5lbmRzV2l0aCgnLmNzdicpID8gYmFzZU5hbWUgOiBiYXNlTmFtZSArICcuY3N2JztcblxuICAgIGNvbnN0IGhlYWRlciA9IGNvbHVtbnMubWFwKGMgPT4gdGhpcy5fY3N2RXNjYXBlKGMuaGVhZGVyIHx8IGMua2V5KSkuam9pbignLCcpO1xuICAgIGNvbnN0IGxpbmVzID0gcm93cy5tYXAoKHJvdywgaWR4KSA9PiB7XG4gICAgICBpZiAoY2ZnLnRyYW5zZm9ybSkge1xuICAgICAgICBjb25zdCB0ID0gY2ZnLnRyYW5zZm9ybShyb3cpO1xuICAgICAgICByZXR1cm4gY29sdW1ucy5tYXAoYyA9PiB0aGlzLl9jc3ZFc2NhcGUoU3RyaW5nKHRbYy5rZXldID8/ICcnKSkpLmpvaW4oJywnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb2x1bW5zLm1hcChjID0+IHRoaXMuX2NzdkVzY2FwZShTdHJpbmcodGhpcy5yZXNvbHZlQ2VsbFZhbHVlKGMsIHJvdywgaWR4KSA/PyAnJykpKS5qb2luKCcsJyk7XG4gICAgfSk7XG5cbiAgICAvLyBCT00gVVRGLTggcG91ciB1bmUgb3V2ZXJ0dXJlIGNvcnJlY3RlIHNvdXMgRXhjZWxcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoWydcXHVGRUZGJyArIFtoZWFkZXIsIC4uLmxpbmVzXS5qb2luKCdcXG4nKV0sIHsgdHlwZTogJ3RleHQvY3N2O2NoYXJzZXQ9dXRmLTgnIH0pO1xuICAgIGNvbnN0IHVybCAgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgIGNvbnN0IGEgICAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgYS5ocmVmID0gdXJsO1xuICAgIGEuZG93bmxvYWQgPSBmaWxlbmFtZTtcbiAgICBhLmNsaWNrKCk7XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY3N2RXNjYXBlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZS5pbmNsdWRlcygnLCcpIHx8IHZhbHVlLmluY2x1ZGVzKCdcIicpIHx8IHZhbHVlLmluY2x1ZGVzKCdcXG4nKSB8fCB2YWx1ZS5pbmNsdWRlcygnXFxyJykpIHtcbiAgICAgIHJldHVybiAnXCInICsgdmFsdWUucmVwbGFjZUFsbCgnXCInLCAnXCJcIicpICsgJ1wiJztcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG4iXX0=
|
|
@@ -28,11 +28,21 @@ export class TablePreferencesManager {
|
|
|
28
28
|
}
|
|
29
29
|
/** Supprime la configuration sauvegardée. */
|
|
30
30
|
clear() {
|
|
31
|
-
|
|
31
|
+
try {
|
|
32
|
+
localStorage.removeItem(this.key);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// stockage indisponible : rien à effacer
|
|
36
|
+
}
|
|
32
37
|
}
|
|
33
38
|
/** Indique si une configuration est actuellement sauvegardée. */
|
|
34
39
|
hasSaved() {
|
|
35
|
-
|
|
40
|
+
try {
|
|
41
|
+
return localStorage.getItem(this.key) !== null;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
36
46
|
}
|
|
37
47
|
}
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
48
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtcHJlZmVyZW5jZXMubWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29uZXRlbWUvanF1ZXJ5LXRhYmxlL3NyYy9saWIvY29tcG9uZW50L3RhYmxlLXByZWZlcmVuY2VzLm1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDO0FBRXBDOzs7R0FHRztBQUNILE1BQU0sT0FBTyx1QkFBdUI7SUFHbEMsWUFBWSxPQUFlO1FBQ3pCLElBQUksQ0FBQyxHQUFHLEdBQUcsY0FBYyxHQUFHLE9BQU8sQ0FBQztJQUN0QyxDQUFDO0lBRUQsK0VBQStFO0lBQy9FLElBQUk7UUFDRixJQUFJO1lBQ0YsTUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDM0MsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7U0FDM0Q7UUFBQyxNQUFNO1lBQ04sT0FBTyxJQUFJLENBQUM7U0FDYjtJQUNILENBQUM7SUFFRCxzREFBc0Q7SUFDdEQsSUFBSSxDQUFDLE1BQXdCO1FBQzNCLElBQUk7WUFDRixZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ3hEO1FBQUMsTUFBTTtZQUNOLDBFQUEwRTtTQUMzRTtJQUNILENBQUM7SUFFRCw2Q0FBNkM7SUFDN0MsS0FBSztRQUNILElBQUk7WUFDRixZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNuQztRQUFDLE1BQU07WUFDTix5Q0FBeUM7U0FDMUM7SUFDSCxDQUFDO0lBRUQsaUVBQWlFO0lBQ2pFLFFBQVE7UUFDTixJQUFJO1lBQ0YsT0FBTyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxJQUFJLENBQUM7U0FDaEQ7UUFBQyxNQUFNO1lBQ04sT0FBTyxLQUFLLENBQUM7U0FDZDtJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNhdmVkVGFibGVDb25maWcgfSBmcm9tICcuLi9qcXVlcnktdGFibGUubW9kZWwnO1xuXG5jb25zdCBTVE9SQUdFX1BSRUZJWCA9ICdqcXRfcHJlZnNfJztcblxuLyoqXG4gKiBHw6hyZSBsYSBwZXJzaXN0YW5jZSBkZSBsYSBjb25maWd1cmF0aW9uIGQndW4gdGFibGVhdSBkYW5zIGxlIGxvY2FsU3RvcmFnZS5cbiAqIElkZW50aWZpZSBjaGFxdWUgdGFibGVhdSBwYXIgdW4gYHRhYmxlSWRgIHVuaXF1ZSBmb3VybmkgcGFyIGwndXRpbGlzYXRldXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBUYWJsZVByZWZlcmVuY2VzTWFuYWdlciB7XG4gIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHRhYmxlSWQ6IHN0cmluZykge1xuICAgIHRoaXMua2V5ID0gU1RPUkFHRV9QUkVGSVggKyB0YWJsZUlkO1xuICB9XG5cbiAgLyoqIFJldG91cm5lIGxhIGNvbmZpZ3VyYXRpb24gc2F1dmVnYXJkw6llLCBvdSBgbnVsbGAgc2kgYWJzZW50ZSAvIGNvcnJvbXB1ZS4gKi9cbiAgbG9hZCgpOiBTYXZlZFRhYmxlQ29uZmlnIHwgbnVsbCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhdyA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMua2V5KTtcbiAgICAgIHJldHVybiByYXcgPyAoSlNPTi5wYXJzZShyYXcpIGFzIFNhdmVkVGFibGVDb25maWcpIDogbnVsbDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBQZXJzaXN0ZSBsYSBjb25maWd1cmF0aW9uIGRhbnMgbGUgbG9jYWxTdG9yYWdlLiAqL1xuICBzYXZlKGNvbmZpZzogU2F2ZWRUYWJsZUNvbmZpZyk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLmtleSwgSlNPTi5zdHJpbmdpZnkoY29uZmlnKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBsb2NhbFN0b3JhZ2UgcGV1dCDDqnRyZSBpbmRpc3BvbmlibGUgKG1vZGUgcHJpdsOpIHN0cmljdCwgcXVvdGEgZMOpcGFzc8Op4oCmKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBTdXBwcmltZSBsYSBjb25maWd1cmF0aW9uIHNhdXZlZ2FyZMOpZS4gKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKHRoaXMua2V5KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIHN0b2NrYWdlIGluZGlzcG9uaWJsZSA6IHJpZW4gw6AgZWZmYWNlclxuICAgIH1cbiAgfVxuXG4gIC8qKiBJbmRpcXVlIHNpIHVuZSBjb25maWd1cmF0aW9uIGVzdCBhY3R1ZWxsZW1lbnQgc2F1dmVnYXJkw6llLiAqL1xuICBoYXNTYXZlZCgpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMua2V5KSAhPT0gbnVsbDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|