@r2digisolutions/ui 0.27.3 → 0.28.0

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 (35) hide show
  1. package/dist/components/container/DataTableShell/DataTableShell.svelte +631 -0
  2. package/dist/components/container/DataTableShell/DataTableShell.svelte.d.ts +48 -0
  3. package/dist/components/container/DataTableShell/components/AdvancedFiltersBuilder.svelte +311 -0
  4. package/dist/components/container/DataTableShell/components/AdvancedFiltersBuilder.svelte.d.ts +7 -0
  5. package/dist/components/container/DataTableShell/components/ColumnVisibilityMenu.svelte +112 -0
  6. package/dist/components/container/DataTableShell/components/ColumnVisibilityMenu.svelte.d.ts +8 -0
  7. package/dist/components/container/DataTableShell/components/ContextMenu.svelte +70 -0
  8. package/dist/components/container/DataTableShell/components/ContextMenu.svelte.d.ts +30 -0
  9. package/dist/components/container/DataTableShell/components/DataTableFiltersSidebar.svelte +0 -0
  10. package/dist/components/container/DataTableShell/components/DataTableFiltersSidebar.svelte.d.ts +26 -0
  11. package/dist/components/container/DataTableShell/components/DataTableFooter.svelte +36 -0
  12. package/dist/components/container/DataTableShell/components/DataTableFooter.svelte.d.ts +18 -0
  13. package/dist/components/container/DataTableShell/components/DataTableToolbar.svelte +822 -0
  14. package/dist/components/container/DataTableShell/components/DataTableToolbar.svelte.d.ts +30 -0
  15. package/dist/components/container/DataTableShell/components/Pagination.svelte +117 -0
  16. package/dist/components/container/DataTableShell/components/Pagination.svelte.d.ts +28 -0
  17. package/dist/components/container/DataTableShell/components/Submenu.svelte +109 -0
  18. package/dist/components/container/DataTableShell/components/Submenu.svelte.d.ts +30 -0
  19. package/dist/components/container/DataTableShell/components/Toolbar.svelte +0 -0
  20. package/dist/components/container/DataTableShell/components/Toolbar.svelte.d.ts +26 -0
  21. package/dist/components/container/DataTableShell/core/DataTableController.svelte.d.ts +54 -0
  22. package/dist/components/container/DataTableShell/core/DataTableController.svelte.js +148 -0
  23. package/dist/components/container/DataTableShell/core/DataTableEngine.svelte.d.ts +68 -0
  24. package/dist/components/container/DataTableShell/core/DataTableEngine.svelte.js +319 -0
  25. package/dist/components/container/DataTableShell/core/DataTableInternal.svelte.d.ts +68 -0
  26. package/dist/components/container/DataTableShell/core/DataTableInternal.svelte.js +396 -0
  27. package/dist/components/container/DataTableShell/core/context.d.ts +3 -0
  28. package/dist/components/container/DataTableShell/core/context.js +12 -0
  29. package/dist/components/container/DataTableShell/core/filters-types.d.ts +14 -0
  30. package/dist/components/container/DataTableShell/core/filters-types.js +1 -0
  31. package/dist/components/container/DataTableShell/core/types.d.ts +60 -0
  32. package/dist/components/container/DataTableShell/core/types.js +1 -0
  33. package/dist/components/container/index.d.ts +3 -1
  34. package/dist/components/container/index.js +3 -1
  35. package/package.json +13 -13
@@ -0,0 +1,319 @@
1
+ import { SvelteSet } from 'svelte/reactivity';
2
+ function toLower(value) {
3
+ if (value == null)
4
+ return '';
5
+ return String(value).toLowerCase();
6
+ }
7
+ function evaluateFilter(row, filter) {
8
+ const [field, operator, rawValue] = filter;
9
+ const value = row[field];
10
+ switch (operator) {
11
+ case 'equals':
12
+ return value === rawValue;
13
+ case 'not_equals':
14
+ return value !== rawValue;
15
+ case 'contains':
16
+ return toLower(value).includes(toLower(rawValue));
17
+ case 'not_contains':
18
+ return !toLower(value).includes(toLower(rawValue));
19
+ case 'greater_than':
20
+ return Number(value) > Number(rawValue);
21
+ case 'less_than':
22
+ return Number(value) < Number(rawValue);
23
+ case 'startsWith':
24
+ return toLower(value).startsWith(toLower(rawValue));
25
+ case 'endsWith':
26
+ return toLower(value).endsWith(toLower(rawValue));
27
+ case 'is_empty':
28
+ return value == null || String(value).trim() === '';
29
+ case 'is_not_empty':
30
+ return !(value == null || String(value).trim() === '');
31
+ case 'in':
32
+ return Array.isArray(rawValue) && rawValue.includes(value);
33
+ case 'not_in':
34
+ return Array.isArray(rawValue) && !rawValue.includes(value);
35
+ default:
36
+ return true;
37
+ }
38
+ }
39
+ function evaluateQueryGroup(row, group) {
40
+ const join = group.joinOperation === 'OR' ? 'OR' : 'AND';
41
+ const filters = group.filters ?? [];
42
+ if (!filters.length)
43
+ return true;
44
+ if (join === 'AND') {
45
+ for (const item of filters) {
46
+ if (item.type === 'group') {
47
+ if (!evaluateQueryGroup(row, item))
48
+ return false;
49
+ }
50
+ else {
51
+ if (!evaluateFilter(row, item))
52
+ return false;
53
+ }
54
+ }
55
+ return true;
56
+ }
57
+ else {
58
+ for (const item of filters) {
59
+ if (item.type === 'group') {
60
+ if (evaluateQueryGroup(row, item))
61
+ return true;
62
+ }
63
+ else {
64
+ if (evaluateFilter(row, item))
65
+ return true;
66
+ }
67
+ }
68
+ return false;
69
+ }
70
+ }
71
+ export class DataTableEngine {
72
+ options;
73
+ rows = $state([]);
74
+ loading = $state(false);
75
+ search = $state('');
76
+ query = $state(null);
77
+ sortColumn = $state(null);
78
+ sortDirection = $state('asc');
79
+ page = $state(1);
80
+ pageSize = $state(10);
81
+ columnState = $state([]);
82
+ selectedIds = new SvelteSet();
83
+ allColumns = $derived(this.options.columns);
84
+ visibleColumns = $derived.by(() => {
85
+ return this.options.columns.filter((col) => {
86
+ const st = this.columnState.find((c) => c.id === col.id);
87
+ return st ? st.visible : true;
88
+ });
89
+ });
90
+ mainColumns = $derived.by(() => {
91
+ const visible = this.visibleColumns;
92
+ const max = this.options.maxVisibleColumns && this.options.maxVisibleColumns > 0
93
+ ? this.options.maxVisibleColumns
94
+ : visible.length;
95
+ return visible.slice(0, max);
96
+ });
97
+ overflowColumns = $derived.by(() => {
98
+ const visible = this.visibleColumns;
99
+ const max = this.options.maxVisibleColumns && this.options.maxVisibleColumns > 0
100
+ ? this.options.maxVisibleColumns
101
+ : visible.length;
102
+ return visible.slice(max);
103
+ });
104
+ processedRows = $derived.by(() => {
105
+ let result = this.rows.slice();
106
+ // SEARCH
107
+ const term = this.search.trim().toLowerCase();
108
+ if (term) {
109
+ result = result.filter((row) => {
110
+ return this.visibleColumns.some((col) => {
111
+ if (col.searchable === false)
112
+ return false;
113
+ const value = col.accessor ? col.accessor(row) : row[col.id];
114
+ return toLower(value).includes(term);
115
+ });
116
+ });
117
+ }
118
+ // ADVANCED QUERY
119
+ if (this.query && this.query.useQuery && this.query.filters?.length) {
120
+ result = result.filter((row) => evaluateQueryGroup(row, this.query));
121
+ }
122
+ // SORT
123
+ if (this.sortColumn) {
124
+ const col = this.options.columns.find((c) => c.id === this.sortColumn);
125
+ if (col) {
126
+ const dir = this.sortDirection === 'desc' ? -1 : 1;
127
+ result.sort((a, b) => {
128
+ const va = col.accessor ? col.accessor(a) : a[col.id];
129
+ const vb = col.accessor ? col.accessor(b) : b[col.id];
130
+ if (va == null && vb == null)
131
+ return 0;
132
+ if (va == null)
133
+ return -1 * dir;
134
+ if (vb == null)
135
+ return 1 * dir;
136
+ if (typeof va === 'number' && typeof vb === 'number') {
137
+ return (va - vb) * dir;
138
+ }
139
+ const sa = String(va);
140
+ const sb = String(vb);
141
+ if (sa < sb)
142
+ return -1 * dir;
143
+ if (sa > sb)
144
+ return 1 * dir;
145
+ return 0;
146
+ });
147
+ }
148
+ }
149
+ return result;
150
+ });
151
+ totalRows = $derived(this.rows.length);
152
+ totalFilteredRows = $derived(this.processedRows.length);
153
+ totalPages = $derived.by(() => {
154
+ const size = this.pageSize || 1;
155
+ const pages = Math.ceil(this.totalFilteredRows / size);
156
+ return pages || 1;
157
+ });
158
+ currentPageRows = $derived.by(() => {
159
+ if (this.options.mode === 'infinite') {
160
+ return this.processedRows;
161
+ }
162
+ const p = this.page < 1 ? 1 : this.page > this.totalPages ? this.totalPages : this.page;
163
+ const size = this.pageSize || 1;
164
+ const start = (p - 1) * size;
165
+ return this.processedRows.slice(start, start + size);
166
+ });
167
+ selectedCount = $derived(this.selectedIds.size);
168
+ allVisibleSelected = $derived.by(() => {
169
+ if (!this.currentPageRows.length)
170
+ return false;
171
+ const ids = this.currentPageRows.map((row, index) => this.getRowId(row, index));
172
+ return ids.every((id) => this.selectedIds.has(id));
173
+ });
174
+ someVisibleSelected = $derived.by(() => {
175
+ if (!this.currentPageRows.length)
176
+ return false;
177
+ const ids = this.currentPageRows.map((row, index) => this.getRowId(row, index));
178
+ const selected = ids.filter((id) => this.selectedIds.has(id)).length;
179
+ return selected > 0 && selected < ids.length;
180
+ });
181
+ // NUEVO: estado de selección de toda la página
182
+ isAllPageSelected = $derived.by(() => {
183
+ if (!this.currentPageRows.length)
184
+ return false;
185
+ const ids = this.currentPageRows.map((row, index) => this.getRowId(row, index));
186
+ return ids.every((id) => this.selectedIds.has(id));
187
+ });
188
+ constructor(options) {
189
+ this.options = options;
190
+ this.pageSize = options.pageSize ?? 10;
191
+ this.columnState = options.columns.map((col) => ({
192
+ id: col.id,
193
+ visible: col.hidden ? false : true,
194
+ width: col.defaultWidth ?? col.minWidth,
195
+ minWidth: col.minWidth,
196
+ defaultWidth: col.defaultWidth
197
+ }));
198
+ }
199
+ getRowId(row, index) {
200
+ if (this.options.getRowId)
201
+ return this.options.getRowId(row, index);
202
+ const val = row.id;
203
+ if (val != null)
204
+ return String(val);
205
+ return String(index);
206
+ }
207
+ setRows(rows) {
208
+ this.rows = rows;
209
+ this.page = 1;
210
+ }
211
+ setLoading(v) {
212
+ this.loading = v;
213
+ }
214
+ setSearch(term) {
215
+ this.search = term;
216
+ this.page = 1;
217
+ }
218
+ setQuery(q) {
219
+ this.query = q;
220
+ this.page = 1;
221
+ }
222
+ setSort(columnId, direction = 'asc') {
223
+ this.sortColumn = columnId;
224
+ this.sortDirection = direction;
225
+ this.page = 1;
226
+ }
227
+ toggleSort(columnId) {
228
+ if (this.sortColumn !== columnId) {
229
+ this.sortColumn = columnId;
230
+ this.sortDirection = 'asc';
231
+ }
232
+ else {
233
+ if (this.sortDirection === 'asc') {
234
+ this.sortDirection = 'desc';
235
+ }
236
+ else {
237
+ this.sortColumn = null;
238
+ }
239
+ }
240
+ this.page = 1;
241
+ }
242
+ setPage(page) {
243
+ if (page < 1)
244
+ page = 1;
245
+ if (page > this.totalPages)
246
+ page = this.totalPages;
247
+ this.page = page;
248
+ }
249
+ setPageSize(size) {
250
+ if (size <= 0)
251
+ size = 1;
252
+ this.pageSize = size;
253
+ this.page = 1;
254
+ }
255
+ clearSelection() {
256
+ this.selectedIds.clear();
257
+ }
258
+ toggleRowSelection(id) {
259
+ if (this.selectedIds.has(id))
260
+ this.selectedIds.delete(id);
261
+ else
262
+ this.selectedIds.add(id);
263
+ }
264
+ // Selección por página (lo que usas para el check-all)
265
+ selectAllVisible() {
266
+ this.currentPageRows.forEach((row, index) => {
267
+ const id = this.getRowId(row, index);
268
+ this.selectedIds.add(id);
269
+ });
270
+ }
271
+ unselectAllVisible() {
272
+ if (!this.currentPageRows.length)
273
+ return;
274
+ const idsToRemove = this.currentPageRows.map((row, index) => this.getRowId(row, index));
275
+ for (const id of idsToRemove)
276
+ this.selectedIds.delete(id);
277
+ }
278
+ selectAllCurrentPage() {
279
+ this.selectAllVisible();
280
+ }
281
+ unselectAllCurrentPage() {
282
+ this.unselectAllVisible();
283
+ }
284
+ setColumnHidden(id, hidden) {
285
+ this.columnState = this.columnState.map((c) => (c.id === id ? { ...c, visible: !hidden } : c));
286
+ }
287
+ resizeColumn(id, width) {
288
+ this.columnState = this.columnState.map((c) => {
289
+ if (c.id !== id)
290
+ return c;
291
+ const min = c.minWidth ?? 80;
292
+ const w = width < min ? min : width;
293
+ return { ...c, width: w };
294
+ });
295
+ }
296
+ resetLayout() {
297
+ this.columnState = this.options.columns.map((col) => ({
298
+ id: col.id,
299
+ visible: col.hidden ? false : true,
300
+ width: col.defaultWidth ?? col.minWidth,
301
+ minWidth: col.minWidth,
302
+ defaultWidth: col.defaultWidth
303
+ }));
304
+ this.sortColumn = null;
305
+ this.sortDirection = 'asc';
306
+ this.page = 1;
307
+ this.pageSize = this.options.pageSize ?? 10;
308
+ this.selectedIds.clear();
309
+ this.search = '';
310
+ this.query = null;
311
+ }
312
+ getColumnWidth(id) {
313
+ const st = this.columnState.find((c) => c.id === id);
314
+ if (st?.width)
315
+ return st.width;
316
+ const col = this.options.columns.find((c) => c.id === id);
317
+ return col?.defaultWidth ?? col?.minWidth ?? 180;
318
+ }
319
+ }
@@ -0,0 +1,68 @@
1
+ import type { ColumnDef, ColumnFilter, DataTableMode, DataTableOptions, QueryStructure, SortDirection } from './types.js';
2
+ export declare class DataTableInternal<T> {
3
+ options: DataTableOptions<T>;
4
+ rows: T[];
5
+ loading: boolean;
6
+ page: number;
7
+ pageSize: number;
8
+ mode: DataTableMode;
9
+ sortColumn: string | null;
10
+ sortDirection: SortDirection;
11
+ search: string;
12
+ filters: Record<string, ColumnFilter>;
13
+ selectedIds: Set<string>;
14
+ hiddenColumnIds: Set<string>;
15
+ columnWidths: Record<string, number>;
16
+ multiSelect: boolean;
17
+ maxVisibleColumns: number | undefined;
18
+ columns: ColumnDef<T>[];
19
+ stickyColumnsIds: string[];
20
+ stickyRowsPredicate: ((row: T, index: number) => boolean) | undefined;
21
+ query: QueryStructure | null;
22
+ constructor(options: DataTableOptions<T>);
23
+ getRowId(row: T, index: number): string;
24
+ setRows(rows: T[]): void;
25
+ appendRows(rows: T[]): void;
26
+ setLoading(value: boolean): void;
27
+ setMode(mode: DataTableMode): void;
28
+ setPage(page: number): void;
29
+ nextPage(): void;
30
+ prevPage(): void;
31
+ setPageSize(size: number): void;
32
+ setSearch(value: string): void;
33
+ setFilter(id: string, value: string): void;
34
+ clearFilters(): void;
35
+ setSort(columnId: string): void;
36
+ clearSort(): void;
37
+ setQuery(query: QueryStructure | null): void;
38
+ clearQuery(): void;
39
+ toggleRowSelection(id: string): void;
40
+ selectAllVisible(rows: T[]): void;
41
+ clearSelection(): void;
42
+ isRowSelected(id: string): boolean;
43
+ toggleColumnVisibility(id: string): void;
44
+ hideColumn(id: string): void;
45
+ showColumn(id: string): void;
46
+ showAllColumns(): void;
47
+ hideAllColumns(): void;
48
+ setColumnWidth(id: string, width: number): void;
49
+ resetColumnWidths(): void;
50
+ getColumnWidth(id: string): number;
51
+ allColumns: ColumnDef<T>[];
52
+ visibleColumns: ColumnDef<T>[];
53
+ mainColumns: ColumnDef<T>[];
54
+ overflowColumns: ColumnDef<T>[];
55
+ private getFieldValue;
56
+ private evalOperator;
57
+ private evalFilter;
58
+ private evalQueryFilters;
59
+ private evalQueryGroup;
60
+ private evalQuery;
61
+ filteredRows: T[];
62
+ totalRows: number;
63
+ pageCount: number;
64
+ currentRows: T[];
65
+ selectedCount: number;
66
+ allVisibleSelected: boolean;
67
+ someVisibleSelected: boolean;
68
+ }