@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.
@@ -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. */
@@ -149,6 +169,8 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
149
169
  pageSize: number;
150
170
  pageSizeOptions: number[];
151
171
  pageSizeOptionsGroupBy: number[];
172
+ /** Taille de page choisie par l'utilisateur ou restaurée des préférences ; prioritaire sur la config tant que le paginator est absent (mode Group by). */
173
+ private _userPageSize;
152
174
  draggedColumnKey: string | null;
153
175
  dragOverColumnKey: string | null;
154
176
  /** Vrai quand le mode édition est actif (resize + drag colonnes, interactions désactivées). */
@@ -235,16 +257,38 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
235
257
  key: string;
236
258
  header?: string;
237
259
  }): string;
260
+ /** Traduit les options de la vue table vers celles de l'Organizer. */
261
+ private _organizerViewConfig;
262
+ /** Ne change la référence que si le contenu change : le panneau recalcule tout à chaque nouvelle référence. */
263
+ private _setSliceConfigs;
238
264
  onSearchChange(): void;
265
+ private _runSearch;
239
266
  private setGroupByAndEmit;
240
267
  onGroupByChange(key: string | null): void;
241
268
  onGroupPageSizeChange(size: number | string): void;
242
269
  onGroupSortToggle(dir: 'asc' | 'desc'): void;
243
270
  getLazyColumnStatus(key: string): 'idle' | 'loading' | 'loaded' | 'error';
244
271
  getLazyRenderType(rowValue: any): 'loading' | 'error' | 'value';
245
- retryLazyColumn(column: TableColumnProvider<T>): void;
246
- triggerLazyFetch(column: TableColumnProvider<T>): void;
247
- private _lazyCallbacks;
272
+ /** Relance la demande des colonnes en erreur : le chargeur est rappelé, ou l'application refait sa requête complète. */
273
+ retryLazyColumns(): void;
274
+ /** Colonnes lazy dont la valeur est nécessaire : affichées, utilisées en Group by ou en Slice by dynamique. */
275
+ private _usedLazyColumns;
276
+ /**
277
+ * Quel que soit le chemin d'activation (Organizer, Group by, Slice by, préférences...), les colonnes lazy utilisées et pas encore
278
+ * demandées sont réclamées en un seul événement. Hors cycle de détection, et seulement une fois des lignes affichées :
279
+ * la première réponse de l'application ne doit pas être prise pour celle qui contient les colonnes.
280
+ */
281
+ private _requestLazyColumns;
282
+ /** Appelle `config.lazyLoader` avec toutes les colonnes lazy demandées ; sa réponse remplace `data`. */
283
+ private _runLazyLoader;
284
+ /** Nouveau `data` : il l'emporte sur les lignes du chargeur. Avec un chargeur, les colonnes déjà demandées sont rechargées. */
285
+ private _onNewData;
286
+ /** Sans chargeur ni écouteur, la colonne demandée resterait en skeleton sans que rien ne l'explique. */
287
+ private _warnIfNoLazySource;
288
+ /** De nouvelles `data` sont arrivées : toutes les colonnes demandées sont considérées comme prêtes. */
289
+ private _settleLazyColumns;
290
+ private _applyLazyError;
291
+ private _setLazyStatus;
248
292
  toggleGroupCollapse(groupKey: string): void;
249
293
  private scrollToGroupHeader;
250
294
  isGroupCollapsed(groupKey: string): boolean;
@@ -290,6 +334,7 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
290
334
  getCellTemplate(key: string): TemplateRef<{
291
335
  $implicit: any;
292
336
  index: number;
337
+ value: any;
293
338
  }> | null;
294
339
  get hasCustomCellDefs(): boolean;
295
340
  get hasRowClickHandler(): boolean;
@@ -352,6 +397,9 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
352
397
  private _executeRender;
353
398
  private _projectCurrentPage;
354
399
  private buildEffectiveConfig;
400
+ /** Une colonne lazy est forcément optionnelle : `optional` est implicite, et `optional: false` est refusé. */
401
+ private _normalizeColumns;
402
+ private _withImpliedOptional;
355
403
  private applyConfigSearchReset;
356
404
  private applyInitialSearchQuery;
357
405
  private static _hashColumns;
@@ -359,8 +407,10 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
359
407
  private resolveColumnsFromCompat;
360
408
  private getCategoryFilteredData;
361
409
  private projectRows;
410
+ /** Comparateur dont les valeurs de tri sont calculées une seule fois par ligne. */
362
411
  private _buildSortComparator;
363
412
  private _buildCachedSortComparator;
413
+ private static readonly _collator;
364
414
  private _compareSortValues;
365
415
  private _normalizeSortValue;
366
416
  private _applySortDirection;
@@ -371,6 +421,10 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
371
421
  */
372
422
  private getDisplayValueForSearch;
373
423
  private getLazyAwareValue;
424
+ /** Les nombres et les dates gardent leur type pour un tri correct ; le reste est normalisé en texte. */
425
+ private _toSortInput;
426
+ /** Les statuts de chargement lazy ne doivent jamais apparaître dans un fichier exporté. */
427
+ private _resolveExportValue;
374
428
  private resolveCellValue;
375
429
  private resolvePageSize;
376
430
  private resolvePageSizeOptions;
@@ -380,6 +434,6 @@ export declare class TableComponent<T = any> implements OnChanges, AfterContentI
380
434
  private attachPaginator;
381
435
  private attachSort;
382
436
  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>;
437
+ 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
438
  }
385
439
  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`. */
@@ -127,6 +146,10 @@ export interface SavedTableConfig {
127
146
  search?: string;
128
147
  /** Clé de la colonne utilisée pour le group by. `null` = aucun. */
129
148
  groupBy?: string | null;
149
+ /** Nombre de lignes par page (mode normal). */
150
+ pageSize?: number;
151
+ /** Nombre de lignes par groupe (mode Group by). `0` = tout afficher. */
152
+ groupPageSize?: number;
130
153
  /** Ordre des clés de colonnes (position). */
131
154
  columnOrder?: string[];
132
155
  /** Clés des colonnes visibles. */
@@ -175,6 +198,11 @@ export interface TableProvider<T = any> {
175
198
  onRowSelected?: (row: T, event: MouseEvent | null) => void;
176
199
  /** Configuration de l'export CSV. */
177
200
  export?: TableExportConfig<T>;
201
+ /**
202
+ * Chargeur des colonnes `lazy` : appelé à l'activation d'une colonne lazy (et après chaque nouveau `data` si des colonnes
203
+ * ont déjà été demandées). Sans chargeur, la table émet seulement `lazyColumnsRequested`.
204
+ */
205
+ lazyLoader?: TableLazyLoader<T>;
178
206
  /** Configuration de la fonctionnalité Préférences (édition + persistance localStorage). */
179
207
  preferences?: TablePreferencesConfig;
180
208
  }
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.16",
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.8"
18
18
  },
19
19
  "dependencies": {
20
20
  "tslib": "^2.3.0"