@oneteme/jquery-table 0.0.14 → 0.0.15

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.
@@ -29,6 +29,11 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
29
29
  view?: TableViewConfig;
30
30
  columnLabels?: Record<string, string>;
31
31
  isLoading: boolean;
32
+ /**
33
+ * À passer à `true` quand la requête relancée après `lazyColumnsRequested` échoue : les colonnes en attente affichent un bouton
34
+ * « Réessayer ». Repasser à `false` au nouvel essai.
35
+ */
36
+ lazyError: boolean;
32
37
  copyFeedback: VisualCopyFeedbackConfig;
33
38
  /** Paramètre de contrôle pour réinitialiser barre de recherche. */
34
39
  set clearSearchInput(value: boolean | null | undefined);
@@ -51,6 +56,11 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
51
56
  /** Émis quand la liste des colonnes visibles change (clés dans l’ordre d’affichage). */
52
57
  readonly columnsChange: EventEmitter<string[]>;
53
58
  readonly visualCopied: EventEmitter<VisualSnapshot>;
59
+ /**
60
+ * Clés de toutes les colonnes `lazy` demandées jusqu'ici (cumul), émises quand l'une d'elles est activée pour la première fois.
61
+ * L'application relance sa requête complète en les incluant puis repasse les nouvelles `data`.
62
+ */
63
+ readonly lazyColumnsRequested: EventEmitter<string[]>;
54
64
  set paginator(value: MatPaginator | undefined);
55
65
  get paginator(): MatPaginator | undefined;
56
66
  private _paginator?;
@@ -120,12 +130,20 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
120
130
  set groupPageSize(v: number);
121
131
  get groupSortOrder(): 'asc' | 'desc';
122
132
  set groupSortOrder(v: 'asc' | 'desc');
123
- /** Gestionnaire du cycle de vie des colonnes lazy (fetch, annulation, statuts, données). */
124
- private _lazy;
125
- /** Compatibilité template : retourne la map de statuts lazy. */
126
- get _lazyColumnStatus(): Map<string, "error" | "loaded" | "idle" | "loading">;
127
- /** Compatibilité template : retourne la map de données lazy. */
128
- get _lazyColumnData(): Map<string, Map<any, any>>;
133
+ /**
134
+ * Statut des colonnes `lazy` déjà demandées (absente = pas encore demandée).
135
+ * `loading` dure jusqu'à la réception de nouvelles `data` ; la référence change à chaque mise à jour (panneau de slices).
136
+ */
137
+ _lazyColumnStatus: Map<string, "error" | "loaded" | "idle" | "loading">;
138
+ private _lazyFlushQueued;
139
+ /** Lignes retournées par `config.lazyLoader` : elles remplacent `data` jusqu'au prochain `data`. */
140
+ private _loaderRows;
141
+ private _loaderSub?;
142
+ private _lazyWarned;
143
+ /** Colonnes de la dernière config résolue : évite de reconstruire le tableau (et d'agiter le panneau de slices) à chaque rafraîchissement. */
144
+ private _columnsSource?;
145
+ private _columnsNormalized?;
146
+ private readonly _optionalLazyColumns;
129
147
  private _cdr;
130
148
  private _el;
131
149
  private _ngZone;
@@ -141,7 +159,9 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
141
159
  /** Retourne true si la ligne de groupe est une ligne normale (ni lazy, ni too-many). */
142
160
  isNormalGroupRow(row: any): boolean;
143
161
  isGroupRowLoading(row: any): boolean;
162
+ isGroupRowError(row: any): boolean;
144
163
  isGroupRowTooMany(row: any): boolean;
164
+ retryGroupByColumn(event?: Event): void;
145
165
  /** Gère le clic sur une ligne d'en-tête de groupe (no-op pour les états spéciaux). */
146
166
  onGroupHeaderClick(row: any): void;
147
167
  /** Gestionnaire export CSV. */
@@ -235,16 +255,38 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
235
255
  key: string;
236
256
  header?: string;
237
257
  }): string;
258
+ /** Traduit les options de la vue table vers celles de l'Organizer. */
259
+ private _organizerViewConfig;
260
+ /** Ne change la référence que si le contenu change : le panneau recalcule tout à chaque nouvelle référence. */
261
+ private _setSliceConfigs;
238
262
  onSearchChange(): void;
263
+ private _runSearch;
239
264
  private setGroupByAndEmit;
240
265
  onGroupByChange(key: string | null): void;
241
266
  onGroupPageSizeChange(size: number | string): void;
242
267
  onGroupSortToggle(dir: 'asc' | 'desc'): void;
243
268
  getLazyColumnStatus(key: string): 'idle' | 'loading' | 'loaded' | 'error';
244
269
  getLazyRenderType(rowValue: any): 'loading' | 'error' | 'value';
245
- retryLazyColumn(column: TableColumnProvider<T>): void;
246
- triggerLazyFetch(column: TableColumnProvider<T>): void;
247
- private _lazyCallbacks;
270
+ /** Relance la demande des colonnes en erreur : le chargeur est rappelé, ou l'application refait sa requête complète. */
271
+ retryLazyColumns(): void;
272
+ /** Colonnes lazy dont la valeur est nécessaire : affichées, utilisées en Group by ou en Slice by dynamique. */
273
+ private _usedLazyColumns;
274
+ /**
275
+ * Quel que soit le chemin d'activation (Organizer, Group by, Slice by, préférences...), les colonnes lazy utilisées et pas encore
276
+ * demandées sont réclamées en un seul événement. Hors cycle de détection, et seulement une fois des lignes affichées :
277
+ * la première réponse de l'application ne doit pas être prise pour celle qui contient les colonnes.
278
+ */
279
+ private _requestLazyColumns;
280
+ /** Appelle `config.lazyLoader` avec toutes les colonnes lazy demandées ; sa réponse remplace `data`. */
281
+ private _runLazyLoader;
282
+ /** Nouveau `data` : il l'emporte sur les lignes du chargeur. Avec un chargeur, les colonnes déjà demandées sont rechargées. */
283
+ private _onNewData;
284
+ /** Sans chargeur ni écouteur, la colonne demandée resterait en skeleton sans que rien ne l'explique. */
285
+ private _warnIfNoLazySource;
286
+ /** De nouvelles `data` sont arrivées : toutes les colonnes demandées sont considérées comme prêtes. */
287
+ private _settleLazyColumns;
288
+ private _applyLazyError;
289
+ private _setLazyStatus;
248
290
  toggleGroupCollapse(groupKey: string): void;
249
291
  private scrollToGroupHeader;
250
292
  isGroupCollapsed(groupKey: string): boolean;
@@ -290,6 +332,7 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
290
332
  getCellTemplate(key: string): TemplateRef<{
291
333
  $implicit: any;
292
334
  index: number;
335
+ value: any;
293
336
  }> | null;
294
337
  get hasCustomCellDefs(): boolean;
295
338
  get hasRowClickHandler(): boolean;
@@ -352,6 +395,9 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
352
395
  private _executeRender;
353
396
  private _projectCurrentPage;
354
397
  private buildEffectiveConfig;
398
+ /** Une colonne lazy est forcément optionnelle : `optional` est implicite, et `optional: false` est refusé. */
399
+ private _normalizeColumns;
400
+ private _withImpliedOptional;
355
401
  private applyConfigSearchReset;
356
402
  private applyInitialSearchQuery;
357
403
  private static _hashColumns;
@@ -359,8 +405,10 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
359
405
  private resolveColumnsFromCompat;
360
406
  private getCategoryFilteredData;
361
407
  private projectRows;
408
+ /** Comparateur dont les valeurs de tri sont calculées une seule fois par ligne. */
362
409
  private _buildSortComparator;
363
410
  private _buildCachedSortComparator;
411
+ private static readonly _collator;
364
412
  private _compareSortValues;
365
413
  private _normalizeSortValue;
366
414
  private _applySortDirection;
@@ -371,6 +419,10 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
371
419
  */
372
420
  private getDisplayValueForSearch;
373
421
  private getLazyAwareValue;
422
+ /** Les nombres et les dates gardent leur type pour un tri correct ; le reste est normalisé en texte. */
423
+ private _toSortInput;
424
+ /** Les statuts de chargement lazy ne doivent jamais apparaître dans un fichier exporté. */
425
+ private _resolveExportValue;
374
426
  private resolveCellValue;
375
427
  private resolvePageSize;
376
428
  private resolvePageSizeOptions;
@@ -380,6 +432,6 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
380
432
  private attachPaginator;
381
433
  private attachSort;
382
434
  static ɵfac: i0.ɵɵFactoryDeclaration<TableComponent<any>, never>;
383
- static ɵcmp: i0.ɵɵComponentDeclaration<TableComponent<any>, "jquery-table", never, { "config": { "alias": "config"; "required": false; }; "dataSource": { "alias": "dataSource"; "required": false; }; "data": { "alias": "data"; "required": false; }; "displayedColumns": { "alias": "displayedColumns"; "required": false; }; "columnsConfig": { "alias": "columnsConfig"; "required": false; }; "view": { "alias": "view"; "required": false; }; "columnLabels": { "alias": "columnLabels"; "required": false; }; "isLoading": { "alias": "isLoading"; "required": false; }; "copyFeedback": { "alias": "copyFeedback"; "required": false; }; "clearSearchInput": { "alias": "clearSearchInput"; "required": false; }; }, { "addRequested": "addRequested"; "columnAdded": "columnAdded"; "columnRemoved": "columnRemoved"; "categorySelected": "categorySelected"; "rowSelected": "rowSelected"; "sortChange": "sortChange"; "pageChange": "pageChange"; "searchChange": "searchChange"; "groupByChange": "groupByChange"; "columnsChange": "columnsChange"; "visualCopied": "visualCopied"; }, ["_cellDefs"], never, true, never>;
435
+ static ɵcmp: i0.ɵɵComponentDeclaration<TableComponent<any>, "jquery-table", never, { "config": { "alias": "config"; "required": false; }; "dataSource": { "alias": "dataSource"; "required": false; }; "data": { "alias": "data"; "required": false; }; "displayedColumns": { "alias": "displayedColumns"; "required": false; }; "columnsConfig": { "alias": "columnsConfig"; "required": false; }; "view": { "alias": "view"; "required": false; }; "columnLabels": { "alias": "columnLabels"; "required": false; }; "isLoading": { "alias": "isLoading"; "required": false; }; "lazyError": { "alias": "lazyError"; "required": false; }; "copyFeedback": { "alias": "copyFeedback"; "required": false; }; "clearSearchInput": { "alias": "clearSearchInput"; "required": false; }; }, { "addRequested": "addRequested"; "columnAdded": "columnAdded"; "columnRemoved": "columnRemoved"; "categorySelected": "categorySelected"; "rowSelected": "rowSelected"; "sortChange": "sortChange"; "pageChange": "pageChange"; "searchChange": "searchChange"; "groupByChange": "groupByChange"; "columnsChange": "columnsChange"; "visualCopied": "visualCopied"; "lazyColumnsRequested": "lazyColumnsRequested"; }, ["_cellDefs"], never, true, never>;
384
436
  }
385
437
  export {};
@@ -10,6 +10,8 @@ export declare const GROUP_ROW_COLUMN = "__group_row";
10
10
  export declare const GROUP_HEADER_MARKER = "__groupHeader";
11
11
  /** Clé du groupe spéciale « chargement lazy en cours ». */
12
12
  export declare const GROUP_KEY_LAZY_LOADING = "__lazy_loading__";
13
+ /** Clé du groupe spéciale « chargement lazy en erreur ». */
14
+ export declare const GROUP_KEY_LAZY_ERROR = "__lazy_error__";
13
15
  /** Clé du groupe spéciale « trop de groupes ». */
14
16
  export declare const GROUP_KEY_TOO_MANY = "__too_many_groups__";
15
17
  /** Propriété injectée dans chaque ligne projetée : référence vers la ligne brute d'origine. */
@@ -11,18 +11,22 @@ import * as i0 from "@angular/core";
11
11
  * </ng-template>
12
12
  * </jquery-table>
13
13
  * ```
14
- * Le contexte expose `$implicit` (ligne brute `T`) et `index` (index global).
14
+ * Le contexte expose `$implicit` (ligne brute `T`), `index` (index global) et `value` (valeur affichée de la cellule,
15
+ * y compris pour une colonne `lazy` dont la valeur n'est pas présente dans la ligne brute).
16
+ * Pour une colonne `lazy`, le template n'est rendu qu'une fois la valeur chargée ; le chargement et l'erreur sont gérés par le tableau.
15
17
  */
16
18
  export declare class JqtCellDefDirective {
17
19
  readonly template: TemplateRef<{
18
20
  $implicit: any;
19
21
  index: number;
22
+ value: any;
20
23
  }>;
21
24
  /** Clé de la colonne à laquelle ce template s'applique. */
22
25
  columnKey: string;
23
26
  constructor(template: TemplateRef<{
24
27
  $implicit: any;
25
28
  index: number;
29
+ value: any;
26
30
  }>);
27
31
  static ɵfac: i0.ɵɵFactoryDeclaration<JqtCellDefDirective, never>;
28
32
  static ɵdir: i0.ɵɵDirectiveDeclaration<JqtCellDefDirective, "[jqtCellDef]", never, { "columnKey": { "alias": "jqtCellDef"; "required": false; }; }, {}, never, never, true, never>;
@@ -2,7 +2,8 @@ import { DataProvider } from '@oneteme/jquery-core';
2
2
  import { Observable } from 'rxjs';
3
3
  import { OrganizerConfig, SliceConfig } from '@oneteme/jquery-organizer';
4
4
  export { SliceConfig } from '@oneteme/jquery-organizer';
5
- export interface TableColumnProvider<T = any> {
5
+ /** Propriétés communes à toutes les colonnes ; voir `TableColumnProvider`. */
6
+ export interface TableColumnBase<T = any> {
6
7
  key: string;
7
8
  /** Libellé affiché dans l'en-tête de colonne. Optionnel si la colonne utilise un template custom. */
8
9
  header?: string;
@@ -20,18 +21,36 @@ export interface TableColumnProvider<T = any> {
20
21
  /** Active le tri ; `true` par défaut. */
21
22
  sortable?: boolean;
22
23
  removable?: boolean;
23
- optional?: boolean;
24
24
  width?: string;
25
25
  /** Rend la colonne disponible dans Group by ; `true` par défaut si `header` est défini. */
26
26
  groupable?: boolean;
27
27
  /** Rend la colonne disponible comme Slice by dynamique ; `true` par défaut si `header` est défini. */
28
28
  sliceable?: boolean;
29
- /** Chargement différé : la présence de cet objet active le mode lazy. */
30
- lazy?: {
31
- /** Fonction appelée pour charger les valeurs de la colonne. Retourne un tableau dans le même ordre que les lignes. */
32
- fetchFn: () => Observable<any[]>;
33
- };
34
29
  }
30
+ /**
31
+ * Colonne du tableau.
32
+ *
33
+ * - `optional: true` : masquée par défaut, ajoutable depuis le menu View.
34
+ * - `lazy: true` : absente de la requête de base, demandée à sa première activation (Organizer, Group by, Slice by).
35
+ * Une colonne lazy est forcément optionnelle : `optional: true` est implicite et `optional: false` est refusé
36
+ * (la colonne serait demandée dès le premier rendu, soit une requête de plus pour rien).
37
+ * Le chargement passe par `TableProvider.lazyLoader`, ou par l'événement `lazyColumnsRequested` si l'application
38
+ * préfère relancer elle-même sa requête. La cellule affiche un skeleton jusqu'à la réception des lignes complètes ;
39
+ * la colonne supporte ensuite tri, recherche, Group by et Slice by.
40
+ */
41
+ export type TableColumnMode = {
42
+ lazy?: undefined;
43
+ optional?: boolean;
44
+ } | {
45
+ lazy: true;
46
+ optional?: true;
47
+ };
48
+ export type TableColumnProvider<T = any> = TableColumnBase<T> & TableColumnMode;
49
+ /**
50
+ * Charge les colonnes `lazy` : reçoit les clés des colonnes lazy demandées jusqu'ici (cumul) et retourne les lignes complètes,
51
+ * qui remplacent `data` ; la requête est celle de l'application, la table ne connaît pas la source.
52
+ */
53
+ export type TableLazyLoader<T = any> = (lazyColumns: string[]) => Observable<T[]>;
35
54
  /** Configuration de la barre de recherche. */
36
55
  export interface TableSearchConfig {
37
56
  enabled?: boolean;
@@ -86,7 +105,7 @@ export interface TableOrganizerConfig {
86
105
  * ]
87
106
  * ```
88
107
  */
89
- export declare function col<T = any>(key: string, header: string, overrides?: Partial<TableColumnProvider<T>>): TableColumnProvider<T>;
108
+ export declare function col<T = any>(key: string, header: string, overrides?: Partial<TableColumnBase<T>> & TableColumnMode): TableColumnProvider<T>;
90
109
  /** Configuration de l’export CSV déclenché depuis la toolbar. */
91
110
  export interface TableExportConfig<T = any> {
92
111
  /** Affiche le bouton Export dans la toolbar. Par défaut : `true`. */
@@ -175,6 +194,11 @@ export interface TableProvider<T = any> {
175
194
  onRowSelected?: (row: T, event: MouseEvent | null) => void;
176
195
  /** Configuration de l'export CSV. */
177
196
  export?: TableExportConfig<T>;
197
+ /**
198
+ * Chargeur des colonnes `lazy` : appelé à l'activation d'une colonne lazy (et après chaque nouveau `data` si des colonnes
199
+ * ont déjà été demandées). Sans chargeur, la table émet seulement `lazyColumnsRequested`.
200
+ */
201
+ lazyLoader?: TableLazyLoader<T>;
178
202
  /** Configuration de la fonctionnalité Préférences (édition + persistance localStorage). */
179
203
  preferences?: TablePreferencesConfig;
180
204
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneteme/jquery-table",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "description": "jquery table lib",
5
5
  "homepage": "https://github.com/oneteme/jquery-charts",
6
6
  "bugs": "https://github.com/oneteme/jquery-charts/issues",
@@ -13,8 +13,8 @@
13
13
  "@angular/core": ">=16.1.0",
14
14
  "@angular/material": "^16.1.0",
15
15
  "@angular/cdk": "^16.1.0",
16
- "@oneteme/jquery-core": "^0.0.37",
17
- "@oneteme/jquery-organizer": "^0.0.6"
16
+ "@oneteme/jquery-core": "^0.0.38",
17
+ "@oneteme/jquery-organizer": "^0.0.7"
18
18
  },
19
19
  "dependencies": {
20
20
  "tslib": "^2.3.0"