@oneteme/jquery-table 0.0.1 → 0.0.2

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.
Files changed (29) hide show
  1. package/README.md +439 -122
  2. package/esm2022/lib/component/export.manager.mjs +45 -0
  3. package/esm2022/lib/component/group-by.manager.mjs +99 -0
  4. package/esm2022/lib/component/lazy-column-manager.mjs +99 -0
  5. package/esm2022/lib/component/slice-panel/slice-panel.component.mjs +43 -37
  6. package/esm2022/lib/component/slice-panel/slice-panel.model.mjs +1 -1
  7. package/esm2022/lib/component/table-preferences.manager.mjs +38 -0
  8. package/esm2022/lib/component/table.component.mjs +681 -370
  9. package/esm2022/lib/component/table.constants.mjs +31 -0
  10. package/esm2022/lib/component/table.utils.mjs +2 -2
  11. package/esm2022/lib/component/view/view.facade.mjs +298 -0
  12. package/esm2022/lib/jqt-i18n.token.mjs +41 -0
  13. package/esm2022/lib/jquery-table.model.mjs +14 -2
  14. package/esm2022/public-api.mjs +2 -1
  15. package/fesm2022/oneteme-jquery-table.mjs +1377 -408
  16. package/fesm2022/oneteme-jquery-table.mjs.map +1 -1
  17. package/lib/component/export.manager.d.ts +16 -0
  18. package/lib/component/group-by.manager.d.ts +44 -0
  19. package/lib/component/lazy-column-manager.d.ts +26 -0
  20. package/lib/component/slice-panel/slice-panel.component.d.ts +11 -3
  21. package/lib/component/slice-panel/slice-panel.model.d.ts +11 -1
  22. package/lib/component/table-preferences.manager.d.ts +17 -0
  23. package/lib/component/table.component.d.ts +162 -27
  24. package/lib/component/table.constants.d.ts +30 -0
  25. package/lib/component/view/view.facade.d.ts +93 -0
  26. package/lib/jqt-i18n.token.d.ts +87 -0
  27. package/lib/jquery-table.model.d.ts +79 -0
  28. package/package.json +2 -2
  29. package/public-api.d.ts +1 -0
@@ -0,0 +1,16 @@
1
+ import { TableColumnProvider, TableExportConfig } from '../jquery-table.model';
2
+ /**
3
+ * ExportManager
4
+ *
5
+ * Encapsule l'export CSV : construction du fichier BOM/UTF-8, échappement et déclenchement du téléchargement.
6
+ * Aucune dépendance Angular — indépendant du cycle de vie du composant.
7
+ */
8
+ export declare class ExportManager<T> {
9
+ private readonly getRows;
10
+ private readonly getColumns;
11
+ private readonly getConfig;
12
+ private readonly resolveCellValue;
13
+ constructor(getRows: () => T[], getColumns: () => TableColumnProvider<T>[], getConfig: () => TableExportConfig<T> | undefined, resolveCellValue: (col: TableColumnProvider<T>, row: T, index: number) => any);
14
+ export(): void;
15
+ private _csvEscape;
16
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * GroupByManager
3
+ *
4
+ * Encapsule tout l'état et la logique liés au mode Group By :
5
+ * - état collapsed / expanded des groupes
6
+ * - pagination interne par groupe
7
+ * - tri des groupes (asc / desc)
8
+ * - scroll vers un groupe
9
+ *
10
+ * Le composant TableComponent l'instancie et lui passe deux callbacks :
11
+ * - `onNeedProjection` : demande une reprojection légère de la page courante
12
+ * - `onNeedRender` : demande un rebuild complet (tri changé etc.)
13
+ */
14
+ export declare class GroupByManager {
15
+ private readonly onNeedProjection;
16
+ private readonly onNeedRender;
17
+ /** Groupes actuellement ouverts (mode default-collapsed) ou fermés (mode default-expanded). */
18
+ private readonly _collapsedGroups;
19
+ /** Page courante par clé de groupe. */
20
+ private readonly _groupPages;
21
+ /** Taille de page pour la pagination interne des groupes. */
22
+ groupPageSize: number;
23
+ /** Ordre de tri des groupes ('asc' | 'desc'). */
24
+ groupSortOrder: 'asc' | 'desc';
25
+ /**
26
+ * Quand `true`, tous les groupes sont collapsés par défaut.
27
+ * `_collapsedGroups` contient alors le seul groupe ouvert.
28
+ */
29
+ private _defaultGroupCollapsed;
30
+ constructor(onNeedProjection: () => void, onNeedRender: () => void);
31
+ /** Initialise le mode par défaut selon qu'un groupBy vient d'être activé. */
32
+ setDefaultCollapsed(collapsed: boolean): void;
33
+ /** Réinitialise l'état (à appeler quand le groupBy change de colonne). */
34
+ reset(): void;
35
+ isGroupCollapsed(groupKey: string): boolean;
36
+ toggleGroupCollapse(groupKey: string, scrollTo: (key: string) => void): void;
37
+ /** Retourne le groupe actuellement ouvert (seulement en mode default-collapsed avec exactement 1 ouvert). */
38
+ getSingleOpenGroup(): string | null;
39
+ getPage(groupKey: string): number;
40
+ groupPageBack(groupKey: string): void;
41
+ groupPageForward(groupKey: string, totalCount: number): void;
42
+ onGroupPageSizeChange(size: number): void;
43
+ onGroupSortToggle(dir: 'asc' | 'desc', scrollTo: (key: string) => void): void;
44
+ }
@@ -0,0 +1,26 @@
1
+ import { TableColumnProvider } from '../jquery-table.model';
2
+ export interface LazyCallbacks {
3
+ onRefresh(): void;
4
+ onMarkForCheck(): void;
5
+ }
6
+ /**
7
+ * Gère le cycle de vie des colonnes à chargement différé (lazy) :
8
+ * statuts, données, annulation des requêtes en cours.
9
+ *
10
+ * Pas de dépendance Angular/DOM — peut être instancié manuellement dans le composant.
11
+ */
12
+ export declare class LazyColumnManager<T = any> {
13
+ private _status;
14
+ private _data;
15
+ private _cancels;
16
+ get status(): Map<string, 'idle' | 'loading' | 'loaded' | 'error'>;
17
+ get data(): Map<string, Map<any, any>>;
18
+ getStatus(key: string): 'idle' | 'loading' | 'loaded' | 'error';
19
+ getRenderType(rowValue: any): 'loading' | 'error' | 'value';
20
+ /** Annule tous les fetches en cours et réinitialise l'état (appeler lors d'un changement de données). */
21
+ cancelAll(): void;
22
+ /** Réinitialise une colonne et relance son fetch. */
23
+ retry(column: TableColumnProvider<T>, resolvedData: T[], callbacks: LazyCallbacks): void;
24
+ /** Lance le chargement différé d'une colonne. No-op si déjà en cours. */
25
+ fetch(column: TableColumnProvider<T>, resolvedData: T[], callbacks: LazyCallbacks): void;
26
+ }
@@ -1,5 +1,6 @@
1
1
  import { ElementRef, EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
2
2
  import { SliceColumnDef, SliceConfig } from './slice-panel.model';
3
+ import { JqtI18n } from '../../jqt-i18n.token';
3
4
  import * as i0 from "@angular/core";
4
5
  export declare class SlicePanelComponent<T = any> implements OnChanges, OnInit {
5
6
  sliceConfigs: SliceConfig<T>[];
@@ -17,6 +18,8 @@ export declare class SlicePanelComponent<T = any> implements OnChanges, OnInit {
17
18
  collapsedChange: EventEmitter<boolean>;
18
19
  slicePanelBodyRef?: ElementRef<HTMLElement>;
19
20
  private _cdr;
21
+ private _i18nRaw;
22
+ readonly i18n: JqtI18n;
20
23
  isCollapsed: boolean;
21
24
  activeKeysBySlice: Map<number, Set<string>>;
22
25
  private _expandedSlices;
@@ -24,7 +27,6 @@ export declare class SlicePanelComponent<T = any> implements OnChanges, OnInit {
24
27
  key: string;
25
28
  slice: SliceConfig<T>;
26
29
  }>;
27
- private _hiddenStaticSliceKeys;
28
30
  _cachedSlices: SliceConfig<T>[];
29
31
  private _countCache;
30
32
  readonly trackBySliceIndex: (index: number, _: any) => number;
@@ -46,8 +48,8 @@ export declare class SlicePanelComponent<T = any> implements OnChanges, OnInit {
46
48
  togglePanel(): void;
47
49
  isSliceDynamic(sliceIndex: number): boolean;
48
50
  isSliceLoading(sliceIndex: number): boolean;
49
- isStaticSliceVisible(columnKey: string): boolean;
50
- toggleStaticSlice(columnKey: string): void;
51
+ isStaticSliceVisible(_columnKey: string): boolean;
52
+ toggleStaticSlice(_columnKey: string): void;
51
53
  getSliceIcon(slice: SliceConfig<T>): string | undefined;
52
54
  isSliceCategoryActive(sliceIndex: number, categoryKey: string): boolean;
53
55
  isSliceAllActive(sliceIndex: number): boolean;
@@ -55,6 +57,12 @@ export declare class SlicePanelComponent<T = any> implements OnChanges, OnInit {
55
57
  isSliceEmpty(sliceIndex: number): boolean;
56
58
  onSliceCategorySelected(sliceIndex: number, categoryKey: string): void;
57
59
  onSliceAllSelected(sliceIndex: number): void;
60
+ /** Retourne l'état des filtres actifs sous forme sérialisable (sliceIndex → tableau de clés).
61
+ * Inclut les slices sans sélection (tableau vide) pour distinguer "aucune tranche sélectionnée"
62
+ * (= filtre ouvert, rien coché) de "slice absente". */
63
+ getActiveFilters(): Record<number, string[]>;
64
+ /** Restaure les filtres actifs depuis un snapshot sérialisé et réémet le filtre. */
65
+ restoreFilters(filters: Record<number, string[]>): void;
58
66
  addDynamicSlice(column: SliceColumnDef<T>): void;
59
67
  removeDynamicSlice(sliceIndex: number): void;
60
68
  removeDynamicSliceByKey(key: string): void;
@@ -4,7 +4,17 @@ import { Observable } from 'rxjs';
4
4
  export interface SliceCategory<T = any> {
5
5
  key: string;
6
6
  label: string;
7
- filter: (row: T) => boolean;
7
+ /**
8
+ * Prédicat de filtrage en mémoire — **optionnel**.
9
+ *
10
+ * - **Tableau** : requis. Le slice-panel applique ce prédicat sur les lignes locales.
11
+ * - **Graphique** : omis. Le parent écoute `(activeKeysChange)` pour déclencher
12
+ * une nouvelle requête API avec les clés sélectionnées.
13
+ *
14
+ * Si `filter` est absent, la sélection n'a aucun effet sur les données locales ;
15
+ * c'est au composant parent de réagir via `(activeKeysChange)`.
16
+ */
17
+ filter?: (row: T) => boolean;
8
18
  }
9
19
  /**
10
20
  * Groupe de filtres affiché dans le panneau latéral.
@@ -0,0 +1,17 @@
1
+ import { SavedTableConfig } from '../jquery-table.model';
2
+ /**
3
+ * Gère la persistance de la configuration d'un tableau dans le localStorage.
4
+ * Identifie chaque tableau par un `tableId` unique fourni par l'utilisateur.
5
+ */
6
+ export declare class TablePreferencesManager {
7
+ readonly key: string;
8
+ constructor(tableId: string);
9
+ /** Retourne la configuration sauvegardée, ou `null` si absente / corrompue. */
10
+ load(): SavedTableConfig | null;
11
+ /** Persiste la configuration dans le localStorage. */
12
+ save(config: SavedTableConfig): void;
13
+ /** Supprime la configuration sauvegardée. */
14
+ clear(): void;
15
+ /** Indique si une configuration est actuellement sauvegardée. */
16
+ hasSaved(): boolean;
17
+ }
@@ -1,13 +1,16 @@
1
- import { AfterViewInit, ElementRef, EventEmitter, OnChanges, OnDestroy, QueryList, SimpleChanges, TemplateRef } from '@angular/core';
1
+ import { AfterContentInit, AfterViewInit, ElementRef, EventEmitter, OnChanges, OnDestroy, QueryList, SimpleChanges, TemplateRef } from '@angular/core';
2
2
  import { MatMenuTrigger } from '@angular/material/menu';
3
3
  import { MatPaginator } from '@angular/material/paginator';
4
4
  import { MatSort } from '@angular/material/sort';
5
5
  import { MatTableDataSource } from '@angular/material/table';
6
- import { TableColumnProvider, TableProvider } from '../jquery-table.model';
6
+ import { TableColumnProvider, TableProvider, TableViewConfig } from '../jquery-table.model';
7
+ import { JqtI18n } from '../jqt-i18n.token';
7
8
  import { JqtCellDefDirective } from '../directive/jqt-cell-def.directive';
8
9
  import { SlicePanelComponent } from './slice-panel/slice-panel.component';
10
+ import { ViewFacade } from './view/view.facade';
11
+ import { GroupByManager } from './group-by.manager';
9
12
  import * as i0 from "@angular/core";
10
- export declare class TableComponent<T = any> implements OnChanges, AfterViewInit, OnDestroy {
13
+ export declare class TableComponent<T = any> implements OnChanges, AfterContentInit, AfterViewInit, OnDestroy {
11
14
  config?: TableProvider<T>;
12
15
  dataSource?: T[] | {
13
16
  data: T[];
@@ -15,6 +18,12 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
15
18
  data?: T[];
16
19
  displayedColumns?: string[];
17
20
  columnsConfig?: TableColumnProvider<T>[];
21
+ /**
22
+ * Mode HTML : active et configure le panneau View indépendamment du `[config]`.
23
+ * Prend le dessus sur `config.view` si défini.
24
+ * Exemple : `<jquery-table [view]="{ enabled: true }">`
25
+ */
26
+ view?: TableViewConfig;
18
27
  columnLabels?: Record<string, string>;
19
28
  isLoading: boolean;
20
29
  addRequested: EventEmitter<void>;
@@ -22,6 +31,22 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
22
31
  columnRemoved: EventEmitter<TableColumnProvider<T>>;
23
32
  categorySelected: EventEmitter<string>;
24
33
  rowSelected: EventEmitter<T>;
34
+ /** Émis à chaque changement de tri (y compris le tri initial). */
35
+ sortChange: EventEmitter<{
36
+ active: string;
37
+ direction: 'asc' | 'desc' | '';
38
+ }>;
39
+ /** Émis à chaque changement de page ou de taille de page. */
40
+ pageChange: EventEmitter<{
41
+ pageIndex: number;
42
+ pageSize: number;
43
+ }>;
44
+ /** Émis à chaque changement de la recherche texte. */
45
+ searchChange: EventEmitter<string>;
46
+ /** Émis quand le Group by change (clé de colonne, ou `null` si désactivé). */
47
+ groupByChange: EventEmitter<string>;
48
+ /** Émis quand la liste des colonnes visibles change (clés dans l’ordre d’affichage). */
49
+ columnsChange: EventEmitter<string[]>;
25
50
  set paginator(value: MatPaginator | undefined);
26
51
  get paginator(): MatPaginator | undefined;
27
52
  private _paginator?;
@@ -30,48 +55,106 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
30
55
  slicePanelRef?: SlicePanelComponent<T>;
31
56
  viewMenuTrigger?: MatMenuTrigger;
32
57
  _cellDefs: QueryList<JqtCellDefDirective>;
58
+ /** Map clé→TemplateRef pré-calculée depuis _cellDefs. Mise à jour dans ngAfterContentInit et sur _cellDefs.changes. */
59
+ private _cellDefMap;
33
60
  renderedColumns: string[];
34
61
  tableDataSource: MatTableDataSource<any, import("@angular/material/table").MatTableDataSourcePaginator>;
62
+ /** Constante exposée au template pour le matColumnDef de la ligne de groupe. */
63
+ readonly _GROUP_ROW_COLUMN = "__group_row";
64
+ /** Clés d'accès aux propriétés des lignes projetées — exposées pour le template. */
65
+ readonly _ROW_RAW_KEY = "__raw";
66
+ readonly _ROW_INDEX_KEY = "__index";
67
+ readonly _ROW_GROUP_KEY = "__groupKey";
68
+ readonly _ROW_GROUP_COUNT = "__groupCount";
69
+ readonly _ROW_GROUP_PAGE = "__groupPage";
70
+ readonly _ROW_GROUP_PAGE_COUNT = "__groupPageCount";
71
+ /** Facade View : état et actions centralisés (Champs / Group by / Slice by) */
72
+ readonly _view: ViewFacade<T>;
73
+ /**
74
+ * Snapshot stable synchronisé depuis _view.fields.activeColumns dans refreshViewModel().
75
+ * Propriété (non getter) pour qu'Angular puisse la suivre sans NG0100.
76
+ */
35
77
  activeColumns: TableColumnProvider<T>[];
36
78
  activeSliceFilter: (row: T) => boolean;
37
79
  _sliceConfigs: any[];
38
80
  _sliceColumns: TableColumnProvider<T>[];
39
81
  _sliceData: T[];
40
82
  _sliceShowToggle: boolean;
41
- _staticSlicesForMenu: Array<{
83
+ /** Snapshot stable de la visibilité du panneau slice — jamais calculé depuis @ViewChild */
84
+ _showSlicePanel: boolean;
85
+ /** Snapshot stable de l'état collapsed du panneau slice, mis à jour via (collapsedChange) */
86
+ _slicePanelCollapsed: boolean;
87
+ get _staticSlicesForMenu(): Array<{
88
+ key: string;
89
+ title: string;
90
+ icon?: string;
91
+ }>;
92
+ get _activeDynamicSliceColumns(): TableColumnProvider<T>[];
93
+ get _availableColumnsForDynamicSlice(): TableColumnProvider<T>[];
94
+ get _allDynamicSliceColumns(): TableColumnProvider<T>[];
95
+ get _activeSliceByLabel(): string;
96
+ _sliceByMenuItems: Array<{
97
+ isStatic: boolean;
42
98
  key: string;
43
99
  title: string;
44
100
  icon?: string;
101
+ col?: TableColumnProvider<T>;
45
102
  }>;
46
- _activeDynamicSliceColumns: TableColumnProvider<T>[];
47
- _availableColumnsForDynamicSlice: TableColumnProvider<T>[];
48
- _allDynamicSliceColumns: TableColumnProvider<T>[];
49
- _activeSliceByLabel: string;
50
103
  searchQuery: string;
51
- activeGroupByKey: string | null;
104
+ get activeGroupByKey(): string | null;
52
105
  _matSortActive: string;
53
106
  _matSortDirection: 'asc' | 'desc' | '';
54
- private _collapsedGroups;
55
107
  private _activeSort;
56
108
  private _sortSubscribed;
57
109
  private _destroy$;
58
- private _defaultGroupCollapsed;
59
- private _groupPages;
60
110
  private _totalFilteredCount;
61
- _lazyColumnStatus: Map<string, "error" | "loaded" | "idle" | "loading">;
62
- _lazyColumnData: Map<string, Map<any, any>>;
63
- private _lazyFetchCancels;
111
+ /** Gestionnaire du mode Group By (état collapsed, pagination, tri des groupes). */
112
+ readonly _groupBy: GroupByManager;
113
+ /** Délégués vers GroupByManager pour la compatibilité des templates. */
114
+ get groupPageSize(): number;
115
+ set groupPageSize(v: number);
116
+ get groupSortOrder(): 'asc' | 'desc';
117
+ set groupSortOrder(v: 'asc' | 'desc');
118
+ /** Gestionnaire du cycle de vie des colonnes lazy (fetch, annulation, statuts, données). */
119
+ private _lazy;
120
+ /** Compatibilité template : retourne la map de statuts lazy. */
121
+ get _lazyColumnStatus(): Map<string, "error" | "loaded" | "idle" | "loading">;
122
+ /** Compatibilité template : retourne la map de données lazy. */
123
+ get _lazyColumnData(): Map<string, Map<any, any>>;
64
124
  private _cdr;
65
125
  private _el;
126
+ private _ngZone;
127
+ private _i18nRaw;
128
+ /** Labels de l’interface. Fusionnés depuis JQT_I18N_DEFAULTS et le token JQT_I18N injecté. */
129
+ readonly i18n: JqtI18n;
66
130
  isGroupHeader: (_: number, row: any) => boolean;
131
+ /** Retourne true si la ligne de groupe est une ligne normale (ni lazy, ni too-many). */
132
+ isNormalGroupRow(row: any): boolean;
133
+ isGroupRowLoading(row: any): boolean;
134
+ isGroupRowTooMany(row: any): boolean;
135
+ /** Gère le clic sur une ligne d'en-tête de groupe (no-op pour les états spéciaux). */
136
+ onGroupHeaderClick(row: any): void;
137
+ /** Gestionnaire export CSV. */
138
+ private readonly _export;
67
139
  pageSize: number;
68
140
  pageSizeOptions: number[];
69
141
  pageSizeOptionsGroupBy: number[];
70
- groupPageSize: number;
71
- groupSortOrder: 'asc' | 'desc';
72
142
  draggedColumnKey: string | null;
73
143
  dragOverColumnKey: string | null;
74
- private userCustomizedColumns;
144
+ /** Vrai quand le mode édition est actif (resize + drag colonnes, interactions désactivées). */
145
+ _editMode: boolean;
146
+ /** Largeurs de colonnes personnalisées par l'utilisateur (clé → px). */
147
+ _columnWidths: Record<string, number>;
148
+ /** Message de feedback après save/clear. `null` = pas de message. */
149
+ _preferencesMessage: string | null;
150
+ /** Vrai si une configuration est sauvegardée pour ce tableau. */
151
+ _hasSavedConfig: boolean;
152
+ private _preferencesManager;
153
+ private _resizeState;
154
+ /** Dynamic slice keys à restaurer après ngAfterViewInit (slicePanelRef pas encore dispo). */
155
+ private _pendingDynamicSliceKeys;
156
+ /** Filtres de slice à restaurer après ngAfterViewInit (slicePanelRef pas encore dispo). */
157
+ private _pendingSliceFilters;
75
158
  private resolvedConfig;
76
159
  private _columnMap;
77
160
  private _resolvedData;
@@ -80,16 +163,17 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
80
163
  private static readonly MAX_GROUP_COUNT;
81
164
  private _allFilteredRows;
82
165
  private _paginatorSubscribed;
83
- private _groupCacheRows;
84
- private _groupCacheKey;
85
- private _groupCacheSortOrder;
86
- private _groupCacheSortActive;
87
- private _groupCacheSortDir;
88
- private _groupCacheOrder;
89
- private _groupCacheMap;
166
+ /** Cache groupBy — invalidé dès que rows/key/tri changent. */
167
+ private _groupCache;
90
168
  private _pendingRender;
169
+ private _staticSliceHiddenKeys;
170
+ private _configHiddenKeys;
171
+ /** Clés des colonnes visibles du dernier émission columnsChange (pour éviter les émissions dupliquement). */
172
+ private _prevColumnKeys;
91
173
  ngOnChanges(changes: SimpleChanges): void;
174
+ ngAfterContentInit(): void;
92
175
  ngAfterViewInit(): void;
176
+ private _applyPendingDynamicSliceKeys;
93
177
  ngOnDestroy(): void;
94
178
  private _measureHeaderHeight;
95
179
  get title(): string;
@@ -97,7 +181,12 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
97
181
  get visibleColumns(): TableColumnProvider<T>[];
98
182
  get showSearchBar(): boolean;
99
183
  get showViewButton(): boolean;
184
+ get showSliceExpandBtn(): boolean;
185
+ get showExportButton(): boolean;
186
+ get showPreferencesMenu(): boolean;
187
+ get hasSavedPreferences(): boolean;
100
188
  get showToolbar(): boolean;
189
+ expandSlicePanel(): void;
101
190
  get showFields(): boolean;
102
191
  get showGroupBySection(): boolean;
103
192
  get filteredRowCount(): number;
@@ -119,6 +208,7 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
119
208
  getLazyRenderType(rowValue: any): 'loading' | 'error' | 'value';
120
209
  retryLazyColumn(column: TableColumnProvider<T>): void;
121
210
  triggerLazyFetch(column: TableColumnProvider<T>): void;
211
+ private _lazyCallbacks;
122
212
  toggleGroupCollapse(groupKey: string): void;
123
213
  private scrollToGroupHeader;
124
214
  isGroupCollapsed(groupKey: string): boolean;
@@ -131,6 +221,8 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
131
221
  get allowColumnRemoval(): boolean;
132
222
  get hasSliceConfig(): boolean;
133
223
  get showSlicePanel(): boolean;
224
+ onSlicePanelCollapsedChange(collapsed: boolean): void;
225
+ private _recomputeShowSlicePanel;
134
226
  get showAddSliceButton(): boolean;
135
227
  get staticSlicesForMenu(): Array<{
136
228
  key: string;
@@ -157,12 +249,17 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
157
249
  onColumnVisibilityChange(column: TableColumnProvider<T>, checked: boolean): void;
158
250
  isColumnVisible(columnKey: string): boolean;
159
251
  onRemoveColumn(columnKey: string, event?: Event): void;
252
+ private _rebuildCellDefMap;
160
253
  getCellTemplate(key: string): TemplateRef<{
161
254
  $implicit: any;
162
255
  index: number;
163
256
  }> | null;
164
257
  get hasCustomCellDefs(): boolean;
165
258
  get hasRowClickHandler(): boolean;
259
+ /** Largeur minimale du tableau en px, calculée depuis les largeurs explicites des colonnes actives.
260
+ * Retourne null si aucune colonne n'a de largeur définie (le tableau remplit alors 100% du conteneur).
261
+ * Seules les valeurs explicitement en `px` sont sommables ; les pourcentages ou autres unités sont ignorés. */
262
+ get tableMinWidth(): string | null;
166
263
  trackRowFn: (_index: number, row: any) => any;
167
264
  getRowClass(row: any): string | string[] | Record<string, boolean>;
168
265
  onRowClick(row: any, event: MouseEvent | null): void;
@@ -171,11 +268,43 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
171
268
  onHeaderDrop(targetColumnKey: string, event: DragEvent): void;
172
269
  onHeaderDragEnd(): void;
173
270
  isHeaderDropTarget(columnKey: string): boolean;
271
+ enterEditMode(): void;
272
+ confirmEditMode(): void;
273
+ /** Démarre le resize d'une colonne (mousedown sur la poignée droite). */
274
+ onResizeStart(columnKey: string, event: MouseEvent): void;
275
+ /** Retourne la largeur CSS d'une colonne (px si personnalisée, sinon la valeur de config ou auto). */
276
+ getColumnWidth(key: string): string;
277
+ savePreferences(): void;
278
+ clearPreferences(): void;
279
+ private _preferencesMessageTimer;
280
+ private _showPreferencesMessage;
281
+ private _applyPreferences;
174
282
  canRemoveColumn(column: TableColumnProvider<T>): boolean;
175
283
  isCellEmpty(value: any): boolean;
176
284
  asTitle(value: any): string;
285
+ onExport(): void;
177
286
  private refreshViewModel;
178
- private _computeSliceLabel;
287
+ /** Retourne uniquement les slices visibles (non cachées par _staticSliceHiddenKeys).
288
+ * Le SlicePanelComponent affiche tout ce qu'il reçoit — c'est ici que se fait le filtrage. */
289
+ private _computeSliceConfigs;
290
+ private static _setsEqual;
291
+ private _buildSliceByMenuItems;
292
+ get sliceByMenuItems(): {
293
+ isStatic: boolean;
294
+ key: string;
295
+ title: string;
296
+ icon?: string;
297
+ col?: TableColumnProvider<T>;
298
+ }[];
299
+ onSliceMenuItemClick(item: {
300
+ isStatic: boolean;
301
+ key: string;
302
+ col?: TableColumnProvider<T>;
303
+ }): void;
304
+ isSliceMenuItemActive(item: {
305
+ isStatic: boolean;
306
+ key: string;
307
+ }): boolean;
179
308
  private _scheduleRender;
180
309
  private _executeRender;
181
310
  private _projectCurrentPage;
@@ -185,6 +314,12 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
185
314
  private getCategoryFilteredData;
186
315
  private projectRows;
187
316
  private _buildSortComparator;
317
+ /**
318
+ * Retourne la valeur telle qu'elle est affichée dans la cellule, en suivant exactement
319
+ * le même chemin que resolveCellValue — utilisée pour la recherche plein-texte.
320
+ * Ne passe pas par sortValue (valeur brute de tri) contrairement à getLazyAwareValue.
321
+ */
322
+ private getDisplayValueForSearch;
188
323
  private getLazyAwareValue;
189
324
  private resolveCellValue;
190
325
  private resolvePageSize;
@@ -195,5 +330,5 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
195
330
  private attachPaginator;
196
331
  private attachSort;
197
332
  static ɵfac: i0.ɵɵFactoryDeclaration<TableComponent<any>, never>;
198
- 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; }; "columnLabels": { "alias": "columnLabels"; "required": false; }; "isLoading": { "alias": "isLoading"; "required": false; }; }, { "addRequested": "addRequested"; "columnAdded": "columnAdded"; "columnRemoved": "columnRemoved"; "categorySelected": "categorySelected"; "rowSelected": "rowSelected"; }, ["_cellDefs"], never, true, never>;
333
+ 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; }; }, { "addRequested": "addRequested"; "columnAdded": "columnAdded"; "columnRemoved": "columnRemoved"; "categorySelected": "categorySelected"; "rowSelected": "rowSelected"; "sortChange": "sortChange"; "pageChange": "pageChange"; "searchChange": "searchChange"; "groupByChange": "groupByChange"; "columnsChange": "columnsChange"; }, ["_cellDefs"], never, true, never>;
199
334
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Constantes sentinel utilisées pour les identifiants de colonnes et les valeurs
3
+ * projetées dans le datasource interne de la table.
4
+ *
5
+ * Centraliser ici évite les typos silencieuses et facilite les tests unitaires.
6
+ */
7
+ /** Identifiant de la colonne virtuelle rendue sur toute la largeur pour les en-têtes de groupe. */
8
+ export declare const GROUP_ROW_COLUMN = "__group_row";
9
+ /** Marqueur posé sur les objets de ligne pour signaler une ligne d'en-tête de groupe. */
10
+ export declare const GROUP_HEADER_MARKER = "__groupHeader";
11
+ /** Clé du groupe spéciale « chargement lazy en cours ». */
12
+ export declare const GROUP_KEY_LAZY_LOADING = "__lazy_loading__";
13
+ /** Clé du groupe spéciale « trop de groupes ». */
14
+ export declare const GROUP_KEY_TOO_MANY = "__too_many_groups__";
15
+ /** Propriété injectée dans chaque ligne projetée : référence vers la ligne brute d'origine. */
16
+ export declare const ROW_RAW_KEY = "__raw";
17
+ /** Propriété injectée dans chaque ligne projetée : index global de la ligne dans le jeu de données filtré. */
18
+ export declare const ROW_INDEX_KEY = "__index";
19
+ /** Propriété injectée dans chaque ligne projetée : clé du groupe auquel appartient la ligne d'en-tête. */
20
+ export declare const ROW_GROUP_KEY = "__groupKey";
21
+ /** Propriété injectée dans chaque ligne projetée : nombre de lignes dans le groupe. */
22
+ export declare const ROW_GROUP_COUNT = "__groupCount";
23
+ /** Propriété injectée dans chaque ligne projetée : page courante du groupe. */
24
+ export declare const ROW_GROUP_PAGE = "__groupPage";
25
+ /** Propriété injectée dans chaque ligne projetée : nombre de pages du groupe. */
26
+ export declare const ROW_GROUP_PAGE_COUNT = "__groupPageCount";
27
+ /** Valeur sentinelle posée dans une cellule lazy en cours de chargement. */
28
+ export declare const LAZY_LOADING_VALUE = "__lazy_loading__";
29
+ /** Valeur sentinelle posée dans une cellule lazy en erreur. */
30
+ export declare const LAZY_ERROR_VALUE = "__lazy_error__";
@@ -0,0 +1,93 @@
1
+ import { ViewEvent, ViewField, ViewState } from '@oneteme/jquery-core';
2
+ import { TableColumnProvider, TableViewConfig } from '../../jquery-table.model';
3
+ import { SliceConfig } from '../slice-panel/slice-panel.model';
4
+ export type { ViewField, ViewConfig, ViewState, ViewEvent } from '@oneteme/jquery-core';
5
+ export { viewField, groupableViewFields, sliceableViewFields, initialViewState } from '@oneteme/jquery-core';
6
+ export interface ViewFieldState {
7
+ activeColumns: TableColumnProvider<any>[];
8
+ /** true si l'utilisateur a déjà personnalisé la sélection de colonnes */
9
+ userCustomized: boolean;
10
+ }
11
+ export interface ViewGroupByState {
12
+ activeKey: string | null;
13
+ }
14
+ export interface ViewSliceByState {
15
+ activeDynamicColumns: TableColumnProvider<any>[];
16
+ availableForDynamic: TableColumnProvider<any>[];
17
+ allDynamicColumns: TableColumnProvider<any>[];
18
+ activeLabel: string;
19
+ }
20
+ export interface ViewPanelConfig {
21
+ /** Config brute issue de TableProvider.view */
22
+ config?: TableViewConfig;
23
+ /** Toutes les colonnes résolues (non filtrées) */
24
+ columns: TableColumnProvider<any>[];
25
+ /** Slices statiques */
26
+ sliceConfigs: SliceConfig<any>[];
27
+ /** Label utilisé quand aucun groupe / aucune slice n’est actif. Défaut : 'Aucun'. */
28
+ noneLabel?: string;
29
+ }
30
+ /**
31
+ * Centralise l'état et les actions du panneau View (Champs / Group by / Slice by).
32
+ * Pas de dépendance Angular/DOM : peut être extraite vers jquery-core à terme.
33
+ *
34
+ * Usage :
35
+ * this._view = new ViewFacade();
36
+ * this._view.events$.subscribe(e => { ... });
37
+ * this._view.update({ config, columns, sliceConfigs });
38
+ */
39
+ export declare class ViewFacade<T = any> {
40
+ readonly fields: ViewFieldState;
41
+ readonly groupBy: ViewGroupByState;
42
+ readonly sliceBy: ViewSliceByState;
43
+ private _panelConfig;
44
+ private _hiddenStaticKeys;
45
+ private readonly _events$;
46
+ readonly events$: import("rxjs").Observable<ViewEvent>;
47
+ get enabled(): boolean;
48
+ get showFields(): boolean;
49
+ get showGroupBySection(): boolean;
50
+ get showSliceBySection(): boolean;
51
+ get allowColumnRemoval(): boolean;
52
+ get isColumnDragDropEnabled(): boolean;
53
+ get menuBaseColumns(): TableColumnProvider<T>[];
54
+ get menuOptionalColumns(): TableColumnProvider<T>[];
55
+ get totalColumnCount(): number;
56
+ get groupByColumns(): TableColumnProvider<T>[];
57
+ get activeGroupByLabel(): string;
58
+ get staticSlicesForMenu(): Array<{
59
+ key: string;
60
+ title: string;
61
+ icon?: string;
62
+ }>;
63
+ colLabel(col: {
64
+ key: string;
65
+ header?: string;
66
+ }): string;
67
+ update(panelConfig: ViewPanelConfig): void;
68
+ setActiveColumns(columns: TableColumnProvider<T>[]): void;
69
+ setUserCustomized(value: boolean): void;
70
+ /** Remet la vue dans son état initial : colonnes par défaut, pas de groupBy, pas de dynamic slices. */
71
+ resetToDefaults(): void;
72
+ addColumn(column: TableColumnProvider<T>): void;
73
+ removeColumn(columnKey: string): boolean;
74
+ toggleColumnVisibility(column: TableColumnProvider<T>, visible: boolean): void;
75
+ reorderColumns(fromKey: string, toKey: string): boolean;
76
+ isColumnVisible(key: string): boolean;
77
+ setGroupBy(key: string | null): void;
78
+ /** Appelée quand le SlicePanelComponent émet dynamicSliceKeysChange */
79
+ onDynamicSliceKeysChange(keys: string[]): void;
80
+ isDynamicSliceActive(key: string): boolean;
81
+ /** Retourne un snapshot ViewState (contrat core) de l'état courant. */
82
+ toViewState(): ViewState;
83
+ /** Convertit une TableColumnProvider en ViewField (contrat core). */
84
+ static toViewField(col: TableColumnProvider<any>): ViewField;
85
+ destroy(): void;
86
+ private _refreshDefaultColumns;
87
+ private _refreshDynamicSliceMeta;
88
+ /** Notifie la facade des slices statiques actuellement cachées (géré par table.component).
89
+ * Recalcule le label slice afin qu'il reflète uniquement les slices visibles. */
90
+ updateHiddenStaticKeys(keys: Set<string>): void;
91
+ private _computeSliceLabel;
92
+ private _uniqueByKey;
93
+ }