@oneteme/jquery-table 0.0.1 → 0.0.3

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 +732 -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 +304 -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 +1434 -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 +165 -27
  24. package/lib/component/table.constants.d.ts +30 -0
  25. package/lib/component/view/view.facade.d.ts +95 -0
  26. package/lib/jqt-i18n.token.d.ts +87 -0
  27. package/lib/jquery-table.model.d.ts +82 -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,108 @@ 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
+ /** true une fois que le group-by par défaut a été initialisé (évite de reconfigurer GroupByManager à chaque changement de données). */
154
+ private _defaultGroupByApplied;
155
+ private _resizeState;
156
+ /** Dynamic slice keys à restaurer après ngAfterViewInit (slicePanelRef pas encore dispo). */
157
+ private _pendingDynamicSliceKeys;
158
+ /** Filtres de slice à restaurer après ngAfterViewInit (slicePanelRef pas encore dispo). */
159
+ private _pendingSliceFilters;
75
160
  private resolvedConfig;
76
161
  private _columnMap;
77
162
  private _resolvedData;
@@ -80,16 +165,17 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
80
165
  private static readonly MAX_GROUP_COUNT;
81
166
  private _allFilteredRows;
82
167
  private _paginatorSubscribed;
83
- private _groupCacheRows;
84
- private _groupCacheKey;
85
- private _groupCacheSortOrder;
86
- private _groupCacheSortActive;
87
- private _groupCacheSortDir;
88
- private _groupCacheOrder;
89
- private _groupCacheMap;
168
+ /** Cache groupBy — invalidé dès que rows/key/tri changent. */
169
+ private _groupCache;
90
170
  private _pendingRender;
171
+ private _staticSliceHiddenKeys;
172
+ private _configHiddenKeys;
173
+ /** Clés des colonnes visibles du dernier émission columnsChange (pour éviter les émissions dupliquement). */
174
+ private _prevColumnKeys;
91
175
  ngOnChanges(changes: SimpleChanges): void;
176
+ ngAfterContentInit(): void;
92
177
  ngAfterViewInit(): void;
178
+ private _applyPendingDynamicSliceKeys;
93
179
  ngOnDestroy(): void;
94
180
  private _measureHeaderHeight;
95
181
  get title(): string;
@@ -97,7 +183,12 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
97
183
  get visibleColumns(): TableColumnProvider<T>[];
98
184
  get showSearchBar(): boolean;
99
185
  get showViewButton(): boolean;
186
+ get showSliceExpandBtn(): boolean;
187
+ get showExportButton(): boolean;
188
+ get showPreferencesMenu(): boolean;
189
+ get hasSavedPreferences(): boolean;
100
190
  get showToolbar(): boolean;
191
+ expandSlicePanel(): void;
101
192
  get showFields(): boolean;
102
193
  get showGroupBySection(): boolean;
103
194
  get filteredRowCount(): number;
@@ -119,6 +210,7 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
119
210
  getLazyRenderType(rowValue: any): 'loading' | 'error' | 'value';
120
211
  retryLazyColumn(column: TableColumnProvider<T>): void;
121
212
  triggerLazyFetch(column: TableColumnProvider<T>): void;
213
+ private _lazyCallbacks;
122
214
  toggleGroupCollapse(groupKey: string): void;
123
215
  private scrollToGroupHeader;
124
216
  isGroupCollapsed(groupKey: string): boolean;
@@ -131,6 +223,8 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
131
223
  get allowColumnRemoval(): boolean;
132
224
  get hasSliceConfig(): boolean;
133
225
  get showSlicePanel(): boolean;
226
+ onSlicePanelCollapsedChange(collapsed: boolean): void;
227
+ private _recomputeShowSlicePanel;
134
228
  get showAddSliceButton(): boolean;
135
229
  get staticSlicesForMenu(): Array<{
136
230
  key: string;
@@ -157,12 +251,17 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
157
251
  onColumnVisibilityChange(column: TableColumnProvider<T>, checked: boolean): void;
158
252
  isColumnVisible(columnKey: string): boolean;
159
253
  onRemoveColumn(columnKey: string, event?: Event): void;
254
+ private _rebuildCellDefMap;
160
255
  getCellTemplate(key: string): TemplateRef<{
161
256
  $implicit: any;
162
257
  index: number;
163
258
  }> | null;
164
259
  get hasCustomCellDefs(): boolean;
165
260
  get hasRowClickHandler(): boolean;
261
+ /** Largeur minimale du tableau en px, calculée depuis les largeurs explicites des colonnes actives.
262
+ * Retourne null si aucune colonne n'a de largeur définie (le tableau remplit alors 100% du conteneur).
263
+ * Seules les valeurs explicitement en `px` sont sommables ; les pourcentages ou autres unités sont ignorés. */
264
+ get tableMinWidth(): string | null;
166
265
  trackRowFn: (_index: number, row: any) => any;
167
266
  getRowClass(row: any): string | string[] | Record<string, boolean>;
168
267
  onRowClick(row: any, event: MouseEvent | null): void;
@@ -171,20 +270,59 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
171
270
  onHeaderDrop(targetColumnKey: string, event: DragEvent): void;
172
271
  onHeaderDragEnd(): void;
173
272
  isHeaderDropTarget(columnKey: string): boolean;
273
+ enterEditMode(): void;
274
+ confirmEditMode(): void;
275
+ /** Démarre le resize d'une colonne (mousedown sur la poignée droite). */
276
+ onResizeStart(columnKey: string, event: MouseEvent): void;
277
+ /** Retourne la largeur CSS d'une colonne (px si personnalisée, sinon la valeur de config ou auto). */
278
+ getColumnWidth(key: string): string;
279
+ savePreferences(): void;
280
+ clearPreferences(): void;
281
+ private _preferencesMessageTimer;
282
+ private _showPreferencesMessage;
283
+ private _applyPreferences;
174
284
  canRemoveColumn(column: TableColumnProvider<T>): boolean;
175
285
  isCellEmpty(value: any): boolean;
176
286
  asTitle(value: any): string;
287
+ onExport(): void;
177
288
  private refreshViewModel;
178
- private _computeSliceLabel;
289
+ /** Retourne uniquement les slices visibles (non cachées par _staticSliceHiddenKeys).
290
+ * Le SlicePanelComponent affiche tout ce qu'il reçoit — c'est ici que se fait le filtrage. */
291
+ private _computeSliceConfigs;
292
+ private static _setsEqual;
293
+ private _buildSliceByMenuItems;
294
+ get sliceByMenuItems(): {
295
+ isStatic: boolean;
296
+ key: string;
297
+ title: string;
298
+ icon?: string;
299
+ col?: TableColumnProvider<T>;
300
+ }[];
301
+ onSliceMenuItemClick(item: {
302
+ isStatic: boolean;
303
+ key: string;
304
+ col?: TableColumnProvider<T>;
305
+ }): void;
306
+ isSliceMenuItemActive(item: {
307
+ isStatic: boolean;
308
+ key: string;
309
+ }): boolean;
179
310
  private _scheduleRender;
180
311
  private _executeRender;
181
312
  private _projectCurrentPage;
182
313
  private buildEffectiveConfig;
314
+ private static _hashColumns;
183
315
  private resolveData;
184
316
  private resolveColumnsFromCompat;
185
317
  private getCategoryFilteredData;
186
318
  private projectRows;
187
319
  private _buildSortComparator;
320
+ /**
321
+ * Retourne la valeur telle qu'elle est affichée dans la cellule, en suivant exactement
322
+ * le même chemin que resolveCellValue — utilisée pour la recherche plein-texte.
323
+ * Ne passe pas par sortValue (valeur brute de tri) contrairement à getLazyAwareValue.
324
+ */
325
+ private getDisplayValueForSearch;
188
326
  private getLazyAwareValue;
189
327
  private resolveCellValue;
190
328
  private resolvePageSize;
@@ -195,5 +333,5 @@ export declare class TableComponent<T = any> implements OnChanges, AfterViewInit
195
333
  private attachPaginator;
196
334
  private attachSort;
197
335
  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>;
336
+ 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
337
  }
@@ -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,95 @@
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
+ userCustomized: boolean;
14
+ }
15
+ export interface ViewSliceByState {
16
+ activeDynamicColumns: TableColumnProvider<any>[];
17
+ availableForDynamic: TableColumnProvider<any>[];
18
+ allDynamicColumns: TableColumnProvider<any>[];
19
+ activeLabel: string;
20
+ }
21
+ export interface ViewPanelConfig {
22
+ /** Config brute issue de TableProvider.view */
23
+ config?: TableViewConfig;
24
+ /** Toutes les colonnes résolues (non filtrées) */
25
+ columns: TableColumnProvider<any>[];
26
+ /** Slices statiques */
27
+ sliceConfigs: SliceConfig<any>[];
28
+ /** Label utilisé quand aucun groupe / aucune slice n’est actif. Défaut : 'Aucun'. */
29
+ noneLabel?: string; /** Clé de colonne utilisée comme group-by par défaut au chargement. */
30
+ defaultGroupBy?: string | null;
31
+ }
32
+ /**
33
+ * Centralise l'état et les actions du panneau View (Champs / Group by / Slice by).
34
+ * Pas de dépendance Angular/DOM : peut être extraite vers jquery-core à terme.
35
+ *
36
+ * Usage :
37
+ * this._view = new ViewFacade();
38
+ * this._view.events$.subscribe(e => { ... });
39
+ * this._view.update({ config, columns, sliceConfigs });
40
+ */
41
+ export declare class ViewFacade<T = any> {
42
+ readonly fields: ViewFieldState;
43
+ readonly groupBy: ViewGroupByState;
44
+ readonly sliceBy: ViewSliceByState;
45
+ private _panelConfig;
46
+ private _hiddenStaticKeys;
47
+ private readonly _events$;
48
+ readonly events$: import("rxjs").Observable<ViewEvent>;
49
+ get enabled(): boolean;
50
+ get showFields(): boolean;
51
+ get showGroupBySection(): boolean;
52
+ get showSliceBySection(): boolean;
53
+ get allowColumnRemoval(): boolean;
54
+ get isColumnDragDropEnabled(): boolean;
55
+ get menuBaseColumns(): TableColumnProvider<T>[];
56
+ get menuOptionalColumns(): TableColumnProvider<T>[];
57
+ get totalColumnCount(): number;
58
+ get groupByColumns(): TableColumnProvider<T>[];
59
+ get activeGroupByLabel(): string;
60
+ get staticSlicesForMenu(): Array<{
61
+ key: string;
62
+ title: string;
63
+ icon?: string;
64
+ }>;
65
+ colLabel(col: {
66
+ key: string;
67
+ header?: string;
68
+ }): string;
69
+ update(panelConfig: ViewPanelConfig): void;
70
+ setActiveColumns(columns: TableColumnProvider<T>[]): void;
71
+ setUserCustomized(value: boolean): void;
72
+ /** Remet la vue dans son état initial : colonnes par défaut, groupBy par défaut, pas de dynamic slices. */
73
+ resetToDefaults(): void;
74
+ addColumn(column: TableColumnProvider<T>): void;
75
+ removeColumn(columnKey: string): boolean;
76
+ toggleColumnVisibility(column: TableColumnProvider<T>, visible: boolean): void;
77
+ reorderColumns(fromKey: string, toKey: string): boolean;
78
+ isColumnVisible(key: string): boolean;
79
+ setGroupBy(key: string | null): void;
80
+ /** Appelée quand le SlicePanelComponent émet dynamicSliceKeysChange */
81
+ onDynamicSliceKeysChange(keys: string[]): void;
82
+ isDynamicSliceActive(key: string): boolean;
83
+ /** Retourne un snapshot ViewState (contrat core) de l'état courant. */
84
+ toViewState(): ViewState;
85
+ /** Convertit une TableColumnProvider en ViewField (contrat core). */
86
+ static toViewField(col: TableColumnProvider<any>): ViewField;
87
+ destroy(): void;
88
+ private _refreshDefaultColumns;
89
+ private _refreshDynamicSliceMeta;
90
+ /** Notifie la facade des slices statiques actuellement cachées (géré par table.component).
91
+ * Recalcule le label slice afin qu'il reflète uniquement les slices visibles. */
92
+ updateHiddenStaticKeys(keys: Set<string>): void;
93
+ private _computeSliceLabel;
94
+ private _uniqueByKey;
95
+ }