@ai-matrx/design-system 0.18.7 → 0.18.9
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.
- package/CHANGELOG.md +22 -0
- package/dist/data-table/index.cjs +434 -541
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.js +434 -546
- package/dist/data-table/index.js.map +1 -1
- package/dist/styles.css +4 -1
- package/package.json +1 -1
package/dist/data-table/index.js
CHANGED
|
@@ -1,412 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __esm = (fn, res) => function __init() {
|
|
5
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
-
};
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
// src/data-table/layered-filters.ts
|
|
13
|
-
import { z } from "zod";
|
|
14
|
-
function operatorsForLayeredField(field) {
|
|
15
|
-
if (field.operators) return field.operators;
|
|
16
|
-
if (field.kind === "number") return NUMBER_OPERATORS;
|
|
17
|
-
if (field.kind === "select") return SELECT_OPERATORS;
|
|
18
|
-
return TEXT_OPERATORS;
|
|
19
|
-
}
|
|
20
|
-
function layeredFilterNeedsValue(operator) {
|
|
21
|
-
return operator !== "is_empty" && operator !== "is_not_empty";
|
|
22
|
-
}
|
|
23
|
-
function isCompleteLayeredFilterRule(rule) {
|
|
24
|
-
if (!layeredFilterNeedsValue(rule.operator)) return true;
|
|
25
|
-
if (rule.value.trim() === "") return false;
|
|
26
|
-
return rule.operator !== "between" || Boolean(rule.valueTo?.trim());
|
|
27
|
-
}
|
|
28
|
-
function completeLayeredFilterRules(rules) {
|
|
29
|
-
return (rules ?? []).filter(isCompleteLayeredFilterRule);
|
|
30
|
-
}
|
|
31
|
-
function isLayeredFilterOperator(value) {
|
|
32
|
-
return LAYERED_FILTER_OPERATORS.some((operator) => operator === value);
|
|
33
|
-
}
|
|
34
|
-
function normalizedText(value) {
|
|
35
|
-
if (value === null || value === void 0) return "";
|
|
36
|
-
return String(value).trim().toLocaleLowerCase();
|
|
37
|
-
}
|
|
38
|
-
function words(value) {
|
|
39
|
-
return value.split(/[^\p{L}\p{N}]+/u).filter(Boolean);
|
|
40
|
-
}
|
|
41
|
-
function layeredFilterMatchesValue(value, rule) {
|
|
42
|
-
const actual = normalizedText(value);
|
|
43
|
-
const expected = rule.value.trim().toLocaleLowerCase();
|
|
44
|
-
const expectedTo = rule.valueTo?.trim().toLocaleLowerCase() ?? "";
|
|
45
|
-
switch (rule.operator) {
|
|
46
|
-
case "contains":
|
|
47
|
-
return actual.includes(expected);
|
|
48
|
-
case "not_contains":
|
|
49
|
-
return !actual.includes(expected);
|
|
50
|
-
case "equals":
|
|
51
|
-
return actual === expected;
|
|
52
|
-
case "not_equals":
|
|
53
|
-
return actual !== expected;
|
|
54
|
-
case "starts_with":
|
|
55
|
-
return actual.startsWith(expected);
|
|
56
|
-
case "ends_with":
|
|
57
|
-
return actual.endsWith(expected);
|
|
58
|
-
case "word":
|
|
59
|
-
return words(actual).includes(expected);
|
|
60
|
-
case "not_word":
|
|
61
|
-
return !words(actual).includes(expected);
|
|
62
|
-
case "is_empty":
|
|
63
|
-
return actual === "";
|
|
64
|
-
case "is_not_empty":
|
|
65
|
-
return actual !== "";
|
|
66
|
-
case "greater_than":
|
|
67
|
-
return Number(actual) > Number(expected);
|
|
68
|
-
case "greater_or_equal":
|
|
69
|
-
return Number(actual) >= Number(expected);
|
|
70
|
-
case "less_than":
|
|
71
|
-
return Number(actual) < Number(expected);
|
|
72
|
-
case "less_or_equal":
|
|
73
|
-
return Number(actual) <= Number(expected);
|
|
74
|
-
case "between": {
|
|
75
|
-
const numeric = Number(actual);
|
|
76
|
-
return numeric >= Number(expected) && numeric <= Number(expectedTo);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
function layeredFilterRuleSummary(rule, fields) {
|
|
81
|
-
const field = fields.find((candidate) => candidate.id === rule.field);
|
|
82
|
-
const fieldLabel = field?.label ?? rule.field;
|
|
83
|
-
const operator = LAYERED_FILTER_OPERATOR_LABELS[rule.operator];
|
|
84
|
-
if (!layeredFilterNeedsValue(rule.operator))
|
|
85
|
-
return `${fieldLabel} ${operator}`;
|
|
86
|
-
const selectedLabel = field?.kind === "select" ? field.options.find((option) => option.value === rule.value)?.label : void 0;
|
|
87
|
-
const value = selectedLabel ?? rule.value;
|
|
88
|
-
return rule.operator === "between" ? `${fieldLabel} ${operator} ${value} and ${rule.valueTo ?? ""}` : `${fieldLabel} ${operator} ${value}`;
|
|
89
|
-
}
|
|
90
|
-
var LAYERED_FILTER_OPERATORS, layeredFilterRuleSchema, layeredFilterRulesSchema, TEXT_OPERATORS, NUMBER_OPERATORS, SELECT_OPERATORS, LAYERED_FILTER_OPERATOR_LABELS;
|
|
91
|
-
var init_layered_filters = __esm({
|
|
92
|
-
"src/data-table/layered-filters.ts"() {
|
|
93
|
-
"use strict";
|
|
94
|
-
LAYERED_FILTER_OPERATORS = [
|
|
95
|
-
"contains",
|
|
96
|
-
"not_contains",
|
|
97
|
-
"equals",
|
|
98
|
-
"not_equals",
|
|
99
|
-
"starts_with",
|
|
100
|
-
"ends_with",
|
|
101
|
-
"word",
|
|
102
|
-
"not_word",
|
|
103
|
-
"is_empty",
|
|
104
|
-
"is_not_empty",
|
|
105
|
-
"greater_than",
|
|
106
|
-
"greater_or_equal",
|
|
107
|
-
"less_than",
|
|
108
|
-
"less_or_equal",
|
|
109
|
-
"between"
|
|
110
|
-
];
|
|
111
|
-
layeredFilterRuleSchema = z.object({
|
|
112
|
-
id: z.string().min(1),
|
|
113
|
-
field: z.string().min(1),
|
|
114
|
-
operator: z.enum(LAYERED_FILTER_OPERATORS),
|
|
115
|
-
value: z.string(),
|
|
116
|
-
valueTo: z.string().optional()
|
|
117
|
-
});
|
|
118
|
-
layeredFilterRulesSchema = z.array(layeredFilterRuleSchema).max(20);
|
|
119
|
-
TEXT_OPERATORS = [
|
|
120
|
-
"contains",
|
|
121
|
-
"not_contains",
|
|
122
|
-
"equals",
|
|
123
|
-
"not_equals",
|
|
124
|
-
"starts_with",
|
|
125
|
-
"ends_with",
|
|
126
|
-
"word",
|
|
127
|
-
"not_word",
|
|
128
|
-
"is_empty",
|
|
129
|
-
"is_not_empty"
|
|
130
|
-
];
|
|
131
|
-
NUMBER_OPERATORS = [
|
|
132
|
-
"equals",
|
|
133
|
-
"not_equals",
|
|
134
|
-
"greater_than",
|
|
135
|
-
"greater_or_equal",
|
|
136
|
-
"less_than",
|
|
137
|
-
"less_or_equal",
|
|
138
|
-
"between",
|
|
139
|
-
"is_empty",
|
|
140
|
-
"is_not_empty"
|
|
141
|
-
];
|
|
142
|
-
SELECT_OPERATORS = [
|
|
143
|
-
"equals",
|
|
144
|
-
"not_equals",
|
|
145
|
-
"is_empty",
|
|
146
|
-
"is_not_empty"
|
|
147
|
-
];
|
|
148
|
-
LAYERED_FILTER_OPERATOR_LABELS = {
|
|
149
|
-
contains: "contains",
|
|
150
|
-
not_contains: "doesn't contain",
|
|
151
|
-
equals: "is",
|
|
152
|
-
not_equals: "is not",
|
|
153
|
-
starts_with: "starts with",
|
|
154
|
-
ends_with: "ends with",
|
|
155
|
-
word: "has the word",
|
|
156
|
-
not_word: "doesn't have the word",
|
|
157
|
-
is_empty: "is empty",
|
|
158
|
-
is_not_empty: "is not empty",
|
|
159
|
-
greater_than: "is greater than",
|
|
160
|
-
greater_or_equal: "is at least",
|
|
161
|
-
less_than: "is less than",
|
|
162
|
-
less_or_equal: "is at most",
|
|
163
|
-
between: "is between"
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
// src/data-table/filter-engine.ts
|
|
169
|
-
function columnId(col) {
|
|
170
|
-
if (col.id) return col.id;
|
|
171
|
-
if (col.accessorKey) return String(col.accessorKey);
|
|
172
|
-
throw new Error("MatrxDataTable column requires `id` or `accessorKey`");
|
|
173
|
-
}
|
|
174
|
-
function getCellValue(row, col) {
|
|
175
|
-
if (col.accessorFn) return col.accessorFn(row);
|
|
176
|
-
if (col.accessorKey) {
|
|
177
|
-
return row[col.accessorKey];
|
|
178
|
-
}
|
|
179
|
-
return void 0;
|
|
180
|
-
}
|
|
181
|
-
function getFilterValue(row, col) {
|
|
182
|
-
return col.filterValue ? col.filterValue(row) : getCellValue(row, col);
|
|
183
|
-
}
|
|
184
|
-
function getSortValue(row, col) {
|
|
185
|
-
return col.sortValue ? col.sortValue(row) : getCellValue(row, col);
|
|
186
|
-
}
|
|
187
|
-
function stringifyCellValue(value) {
|
|
188
|
-
if (value == null) return "";
|
|
189
|
-
if (typeof value === "string") return value;
|
|
190
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
191
|
-
return String(value);
|
|
192
|
-
}
|
|
193
|
-
if (value instanceof Date) return value.toISOString();
|
|
194
|
-
try {
|
|
195
|
-
return JSON.stringify(value);
|
|
196
|
-
} catch {
|
|
197
|
-
return String(value);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
function tableSearchWords(value) {
|
|
201
|
-
return value.toLocaleLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean);
|
|
202
|
-
}
|
|
203
|
-
function matchesTableSearch(searchableText, query, mode = "contains") {
|
|
204
|
-
const normalizedQuery = query.trim().toLocaleLowerCase();
|
|
205
|
-
if (!normalizedQuery) return true;
|
|
206
|
-
if (mode === "contains") {
|
|
207
|
-
return searchableText.toLocaleLowerCase().includes(normalizedQuery);
|
|
208
|
-
}
|
|
209
|
-
const actualWords = new Set(tableSearchWords(searchableText));
|
|
210
|
-
const expectedWords = tableSearchWords(normalizedQuery);
|
|
211
|
-
return expectedWords.length > 0 && expectedWords.every((word) => actualWords.has(word));
|
|
212
|
-
}
|
|
213
|
-
function compareValues(a, b) {
|
|
214
|
-
if (a == null && b == null) return 0;
|
|
215
|
-
if (a == null) return -1;
|
|
216
|
-
if (b == null) return 1;
|
|
217
|
-
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
218
|
-
if (typeof a === "boolean" && typeof b === "boolean") {
|
|
219
|
-
return Number(a) - Number(b);
|
|
220
|
-
}
|
|
221
|
-
return stringifyCellValue(a).localeCompare(stringifyCellValue(b), void 0, {
|
|
222
|
-
numeric: true,
|
|
223
|
-
sensitivity: "base"
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
function passesColumnFilter(value, filter) {
|
|
227
|
-
const matches = (() => {
|
|
228
|
-
switch (filter.kind) {
|
|
229
|
-
case "text": {
|
|
230
|
-
const s = stringifyCellValue(value);
|
|
231
|
-
if (filter.mode === "null") return value == null;
|
|
232
|
-
if (filter.mode === "not_null") return value != null;
|
|
233
|
-
if (filter.mode === "empty") return s.trim() === "";
|
|
234
|
-
if (filter.mode === "not_empty") return s.trim() !== "";
|
|
235
|
-
const q = filter.value.trim().toLowerCase();
|
|
236
|
-
if (!q) return true;
|
|
237
|
-
return s.toLowerCase().includes(q);
|
|
238
|
-
}
|
|
239
|
-
case "select": {
|
|
240
|
-
const selected = filter.values ?? (filter.value && filter.value !== "__all__" ? [filter.value] : []);
|
|
241
|
-
if (selected.length === 0) return true;
|
|
242
|
-
const s = stringifyCellValue(value);
|
|
243
|
-
return selected.some(
|
|
244
|
-
(v) => v === SELECT_EMPTY_VALUE ? s === "" : v === SELECT_NOT_EMPTY_VALUE ? s !== "" : s === v
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
case "boolean": {
|
|
248
|
-
return Boolean(value) === filter.value;
|
|
249
|
-
}
|
|
250
|
-
case "number": {
|
|
251
|
-
const n = typeof value === "number" ? value : Number(stringifyCellValue(value).replace(/[^0-9.-]/g, ""));
|
|
252
|
-
if (Number.isNaN(n)) return false;
|
|
253
|
-
if (filter.min !== void 0 && n < filter.min) return false;
|
|
254
|
-
if (filter.max !== void 0 && n > filter.max) return false;
|
|
255
|
-
return true;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
})();
|
|
259
|
-
return filter.negated ? !matches : matches;
|
|
260
|
-
}
|
|
261
|
-
function filterAndSortRows(rows, columns, columnFilters, sort, globalSearch, anyOf, layeredFilters, globalSearchMode = "contains", searchText) {
|
|
262
|
-
const colById = new Map(columns.map((c) => [columnId(c), c]));
|
|
263
|
-
const q = globalSearch.trim().toLowerCase();
|
|
264
|
-
const anyQ = anyOf?.query.trim().toLowerCase() ?? "";
|
|
265
|
-
const activeLayeredFilters = completeLayeredFilterRules(layeredFilters);
|
|
266
|
-
let result = rows.filter((row) => {
|
|
267
|
-
for (const [id, filter] of Object.entries(columnFilters)) {
|
|
268
|
-
if (!filter) continue;
|
|
269
|
-
const col = colById.get(id);
|
|
270
|
-
if (!col || col.filter === false) continue;
|
|
271
|
-
if (!passesColumnFilter(getFilterValue(row, col), filter)) return false;
|
|
272
|
-
}
|
|
273
|
-
for (const rule of activeLayeredFilters) {
|
|
274
|
-
const col = colById.get(rule.field);
|
|
275
|
-
if (!col || !layeredFilterMatchesValue(getFilterValue(row, col), rule)) {
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
if (anyQ && anyOf) {
|
|
280
|
-
const hit = anyOf.columnIds.some((id) => {
|
|
281
|
-
const col = colById.get(id);
|
|
282
|
-
if (!col) return false;
|
|
283
|
-
return stringifyCellValue(getFilterValue(row, col)).toLowerCase().includes(anyQ);
|
|
284
|
-
});
|
|
285
|
-
if (!hit) return false;
|
|
286
|
-
}
|
|
287
|
-
if (!q) return true;
|
|
288
|
-
const searchableValues = columns.filter(
|
|
289
|
-
(col) => col.filter !== false || Boolean(col.accessorKey || col.accessorFn)
|
|
290
|
-
).map((col) => stringifyCellValue(getFilterValue(row, col)));
|
|
291
|
-
const additionalSearchText = searchText?.(row);
|
|
292
|
-
if (additionalSearchText) searchableValues.push(additionalSearchText);
|
|
293
|
-
if (globalSearchMode === "contains") {
|
|
294
|
-
return searchableValues.some(
|
|
295
|
-
(value) => matchesTableSearch(value, q, "contains")
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
return matchesTableSearch(searchableValues.join(" "), q, "whole_words");
|
|
299
|
-
});
|
|
300
|
-
if (sort) {
|
|
301
|
-
const col = colById.get(sort.id);
|
|
302
|
-
if (col && col.sortable !== false) {
|
|
303
|
-
const dir = sort.direction === "asc" ? 1 : -1;
|
|
304
|
-
result = [...result].sort((a, b) => {
|
|
305
|
-
const va = getSortValue(a, col);
|
|
306
|
-
const vb = getSortValue(b, col);
|
|
307
|
-
const ea = va == null || stringifyCellValue(va) === "";
|
|
308
|
-
const eb = vb == null || stringifyCellValue(vb) === "";
|
|
309
|
-
if (ea !== eb) return ea ? 1 : -1;
|
|
310
|
-
return compareValues(va, vb) * dir;
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return result;
|
|
315
|
-
}
|
|
316
|
-
function countActiveColumnFilters(filters) {
|
|
317
|
-
let n = 0;
|
|
318
|
-
for (const f of Object.values(filters)) {
|
|
319
|
-
if (!f) continue;
|
|
320
|
-
switch (f.kind) {
|
|
321
|
-
case "text":
|
|
322
|
-
if (f.value.trim() || f.mode && f.mode !== "contains") n += 1;
|
|
323
|
-
break;
|
|
324
|
-
case "select":
|
|
325
|
-
if (f.values ? f.values.length > 0 : f.value && f.value !== "__all__")
|
|
326
|
-
n += 1;
|
|
327
|
-
break;
|
|
328
|
-
case "boolean":
|
|
329
|
-
n += 1;
|
|
330
|
-
break;
|
|
331
|
-
case "number":
|
|
332
|
-
if (f.min !== void 0 || f.max !== void 0) n += 1;
|
|
333
|
-
break;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
return n;
|
|
337
|
-
}
|
|
338
|
-
function isColumnFilterActive(filter) {
|
|
339
|
-
if (!filter) return false;
|
|
340
|
-
switch (filter.kind) {
|
|
341
|
-
case "text":
|
|
342
|
-
return filter.value.trim().length > 0 || filter.mode !== void 0 && filter.mode !== "contains";
|
|
343
|
-
case "select":
|
|
344
|
-
return filter.values ? filter.values.length > 0 : Boolean(filter.value) && filter.value !== "__all__";
|
|
345
|
-
case "boolean":
|
|
346
|
-
return true;
|
|
347
|
-
case "number":
|
|
348
|
-
return filter.min !== void 0 || filter.max !== void 0;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
function applyRowEdits(row, edits) {
|
|
352
|
-
if (!edits || Object.keys(edits).length === 0) return row;
|
|
353
|
-
return { ...row, ...edits };
|
|
354
|
-
}
|
|
355
|
-
var SELECT_EMPTY_VALUE, SELECT_NOT_EMPTY_VALUE;
|
|
356
|
-
var init_filter_engine = __esm({
|
|
357
|
-
"src/data-table/filter-engine.ts"() {
|
|
358
|
-
"use strict";
|
|
359
|
-
init_layered_filters();
|
|
360
|
-
SELECT_EMPTY_VALUE = "__empty__";
|
|
361
|
-
SELECT_NOT_EMPTY_VALUE = "__not_empty__";
|
|
362
|
-
}
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
// src/data-table/tableXlsx.ts
|
|
366
|
-
var tableXlsx_exports = {};
|
|
367
|
-
__export(tableXlsx_exports, {
|
|
368
|
-
downloadTableAsXlsx: () => downloadTableAsXlsx
|
|
369
|
-
});
|
|
370
|
-
import * as XLSX from "xlsx";
|
|
371
|
-
function downloadTableAsXlsx({
|
|
372
|
-
rows,
|
|
373
|
-
columns,
|
|
374
|
-
label
|
|
375
|
-
}) {
|
|
376
|
-
const visibleColumns = columns.filter(
|
|
377
|
-
(column) => column.filter !== false || column.accessorKey
|
|
378
|
-
);
|
|
379
|
-
const headers = visibleColumns.map(
|
|
380
|
-
(column) => typeof column.header === "string" ? column.header : columnId(column)
|
|
381
|
-
);
|
|
382
|
-
const values = rows.map(
|
|
383
|
-
(row) => visibleColumns.map(
|
|
384
|
-
(column) => stringifyCellValue(getCellValue(row, column))
|
|
385
|
-
)
|
|
386
|
-
);
|
|
387
|
-
const worksheet = XLSX.utils.aoa_to_sheet([headers, ...values]);
|
|
388
|
-
const workbook = XLSX.utils.book_new();
|
|
389
|
-
const sheetName = label.replace(/[\\/?*[\]:]/g, " ").trim().slice(0, 31) || "Data";
|
|
390
|
-
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
|
|
391
|
-
const bytes = XLSX.write(workbook, {
|
|
392
|
-
type: "array",
|
|
393
|
-
bookType: "xlsx",
|
|
394
|
-
compression: true
|
|
395
|
-
});
|
|
396
|
-
const blob = new Blob([bytes], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
|
|
397
|
-
const url = URL.createObjectURL(blob);
|
|
398
|
-
const anchor = document.createElement("a");
|
|
399
|
-
anchor.href = url;
|
|
400
|
-
anchor.download = `${label.toLowerCase().replace(/[^a-z0-9]+/g, "-") || "table"}.xlsx`;
|
|
401
|
-
anchor.click();
|
|
402
|
-
URL.revokeObjectURL(url);
|
|
403
|
-
}
|
|
404
|
-
var init_tableXlsx = __esm({
|
|
405
|
-
"src/data-table/tableXlsx.ts"() {
|
|
406
|
-
"use strict";
|
|
407
|
-
init_filter_engine();
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
2
|
|
|
411
3
|
// src/data-table/MatrxDataTable.tsx
|
|
412
4
|
import {
|
|
@@ -3847,55 +3439,390 @@ function SourceConfiguration({
|
|
|
3847
3439
|
}
|
|
3848
3440
|
)
|
|
3849
3441
|
}
|
|
3850
|
-
);
|
|
3442
|
+
);
|
|
3443
|
+
}
|
|
3444
|
+
|
|
3445
|
+
// src/data-table/copy-payload.ts
|
|
3446
|
+
function tableAgentText(value) {
|
|
3447
|
+
if (typeof value === "string") return value;
|
|
3448
|
+
const attributes = Object.entries(value.attributes ?? {}).filter(([, entry]) => entry !== null && entry !== void 0 && entry !== "").map(([key, entry]) => ` ${key}="${String(entry)}"`).join("");
|
|
3449
|
+
const context = Object.entries(value.context ?? {}).filter(([, entry]) => entry !== null && entry !== void 0 && entry !== "").map(([key, entry]) => `<${key}>${String(entry)}</${key}>`).join("\n");
|
|
3450
|
+
const url = typeof window === "undefined" ? "" : window.location.href;
|
|
3451
|
+
const route = typeof window === "undefined" ? "" : window.location.pathname;
|
|
3452
|
+
return `<${value.kind}${attributes}>
|
|
3453
|
+
<context>
|
|
3454
|
+
<location>${value.location}</location>
|
|
3455
|
+
${url ? `<url>${url}</url>` : ""}
|
|
3456
|
+
${route ? `<route>${route}</route>` : ""}
|
|
3457
|
+
<copied>${value.description}</copied>
|
|
3458
|
+
<copied-at>${(/* @__PURE__ */ new Date()).toISOString()}</copied-at>
|
|
3459
|
+
${context}
|
|
3460
|
+
</context>
|
|
3461
|
+
${value.summary ? `<summary>
|
|
3462
|
+
${value.summary}
|
|
3463
|
+
</summary>
|
|
3464
|
+
` : ""}<data format="json">
|
|
3465
|
+
\`\`\`json
|
|
3466
|
+
${JSON.stringify(value.data, null, 2)}
|
|
3467
|
+
\`\`\`
|
|
3468
|
+
</data>
|
|
3469
|
+
</${value.kind}>`;
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3472
|
+
// src/data-table/copy.tsx
|
|
3473
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
3474
|
+
function CopyButtons(props) {
|
|
3475
|
+
const { CopyControls } = useMatrxDataTableHost();
|
|
3476
|
+
const copyProps = props.export?.sheetRows ? { ...props, primarySource: "table" } : props;
|
|
3477
|
+
if (CopyControls) return /* @__PURE__ */ jsx23(CopyControls, { ...copyProps });
|
|
3478
|
+
return /* @__PURE__ */ jsx23(MatrxCopyMenu, { ...copyProps });
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
// src/data-table/CopySubset.tsx
|
|
3482
|
+
import { useState as useState7 } from "react";
|
|
3483
|
+
import { useClipboard } from "@ai-matrx/kit/clipboard";
|
|
3484
|
+
|
|
3485
|
+
// src/data-table/layered-filters.ts
|
|
3486
|
+
import { z } from "zod";
|
|
3487
|
+
var LAYERED_FILTER_OPERATORS = [
|
|
3488
|
+
"contains",
|
|
3489
|
+
"not_contains",
|
|
3490
|
+
"equals",
|
|
3491
|
+
"not_equals",
|
|
3492
|
+
"starts_with",
|
|
3493
|
+
"ends_with",
|
|
3494
|
+
"word",
|
|
3495
|
+
"not_word",
|
|
3496
|
+
"is_empty",
|
|
3497
|
+
"is_not_empty",
|
|
3498
|
+
"greater_than",
|
|
3499
|
+
"greater_or_equal",
|
|
3500
|
+
"less_than",
|
|
3501
|
+
"less_or_equal",
|
|
3502
|
+
"between"
|
|
3503
|
+
];
|
|
3504
|
+
var layeredFilterRuleSchema = z.object({
|
|
3505
|
+
id: z.string().min(1),
|
|
3506
|
+
field: z.string().min(1),
|
|
3507
|
+
operator: z.enum(LAYERED_FILTER_OPERATORS),
|
|
3508
|
+
value: z.string(),
|
|
3509
|
+
valueTo: z.string().optional()
|
|
3510
|
+
});
|
|
3511
|
+
var layeredFilterRulesSchema = z.array(layeredFilterRuleSchema).max(20);
|
|
3512
|
+
var TEXT_OPERATORS = [
|
|
3513
|
+
"contains",
|
|
3514
|
+
"not_contains",
|
|
3515
|
+
"equals",
|
|
3516
|
+
"not_equals",
|
|
3517
|
+
"starts_with",
|
|
3518
|
+
"ends_with",
|
|
3519
|
+
"word",
|
|
3520
|
+
"not_word",
|
|
3521
|
+
"is_empty",
|
|
3522
|
+
"is_not_empty"
|
|
3523
|
+
];
|
|
3524
|
+
var NUMBER_OPERATORS = [
|
|
3525
|
+
"equals",
|
|
3526
|
+
"not_equals",
|
|
3527
|
+
"greater_than",
|
|
3528
|
+
"greater_or_equal",
|
|
3529
|
+
"less_than",
|
|
3530
|
+
"less_or_equal",
|
|
3531
|
+
"between",
|
|
3532
|
+
"is_empty",
|
|
3533
|
+
"is_not_empty"
|
|
3534
|
+
];
|
|
3535
|
+
var SELECT_OPERATORS = [
|
|
3536
|
+
"equals",
|
|
3537
|
+
"not_equals",
|
|
3538
|
+
"is_empty",
|
|
3539
|
+
"is_not_empty"
|
|
3540
|
+
];
|
|
3541
|
+
var LAYERED_FILTER_OPERATOR_LABELS = {
|
|
3542
|
+
contains: "contains",
|
|
3543
|
+
not_contains: "doesn't contain",
|
|
3544
|
+
equals: "is",
|
|
3545
|
+
not_equals: "is not",
|
|
3546
|
+
starts_with: "starts with",
|
|
3547
|
+
ends_with: "ends with",
|
|
3548
|
+
word: "has the word",
|
|
3549
|
+
not_word: "doesn't have the word",
|
|
3550
|
+
is_empty: "is empty",
|
|
3551
|
+
is_not_empty: "is not empty",
|
|
3552
|
+
greater_than: "is greater than",
|
|
3553
|
+
greater_or_equal: "is at least",
|
|
3554
|
+
less_than: "is less than",
|
|
3555
|
+
less_or_equal: "is at most",
|
|
3556
|
+
between: "is between"
|
|
3557
|
+
};
|
|
3558
|
+
function operatorsForLayeredField(field) {
|
|
3559
|
+
if (field.operators) return field.operators;
|
|
3560
|
+
if (field.kind === "number") return NUMBER_OPERATORS;
|
|
3561
|
+
if (field.kind === "select") return SELECT_OPERATORS;
|
|
3562
|
+
return TEXT_OPERATORS;
|
|
3563
|
+
}
|
|
3564
|
+
function layeredFilterNeedsValue(operator) {
|
|
3565
|
+
return operator !== "is_empty" && operator !== "is_not_empty";
|
|
3566
|
+
}
|
|
3567
|
+
function isCompleteLayeredFilterRule(rule) {
|
|
3568
|
+
if (!layeredFilterNeedsValue(rule.operator)) return true;
|
|
3569
|
+
if (rule.value.trim() === "") return false;
|
|
3570
|
+
return rule.operator !== "between" || Boolean(rule.valueTo?.trim());
|
|
3571
|
+
}
|
|
3572
|
+
function completeLayeredFilterRules(rules) {
|
|
3573
|
+
return (rules ?? []).filter(isCompleteLayeredFilterRule);
|
|
3574
|
+
}
|
|
3575
|
+
function isLayeredFilterOperator(value) {
|
|
3576
|
+
return LAYERED_FILTER_OPERATORS.some((operator) => operator === value);
|
|
3577
|
+
}
|
|
3578
|
+
function normalizedText(value) {
|
|
3579
|
+
if (value === null || value === void 0) return "";
|
|
3580
|
+
return String(value).trim().toLocaleLowerCase();
|
|
3581
|
+
}
|
|
3582
|
+
function words(value) {
|
|
3583
|
+
return value.split(/[^\p{L}\p{N}]+/u).filter(Boolean);
|
|
3584
|
+
}
|
|
3585
|
+
function layeredFilterMatchesValue(value, rule) {
|
|
3586
|
+
const actual = normalizedText(value);
|
|
3587
|
+
const expected = rule.value.trim().toLocaleLowerCase();
|
|
3588
|
+
const expectedTo = rule.valueTo?.trim().toLocaleLowerCase() ?? "";
|
|
3589
|
+
switch (rule.operator) {
|
|
3590
|
+
case "contains":
|
|
3591
|
+
return actual.includes(expected);
|
|
3592
|
+
case "not_contains":
|
|
3593
|
+
return !actual.includes(expected);
|
|
3594
|
+
case "equals":
|
|
3595
|
+
return actual === expected;
|
|
3596
|
+
case "not_equals":
|
|
3597
|
+
return actual !== expected;
|
|
3598
|
+
case "starts_with":
|
|
3599
|
+
return actual.startsWith(expected);
|
|
3600
|
+
case "ends_with":
|
|
3601
|
+
return actual.endsWith(expected);
|
|
3602
|
+
case "word":
|
|
3603
|
+
return words(actual).includes(expected);
|
|
3604
|
+
case "not_word":
|
|
3605
|
+
return !words(actual).includes(expected);
|
|
3606
|
+
case "is_empty":
|
|
3607
|
+
return actual === "";
|
|
3608
|
+
case "is_not_empty":
|
|
3609
|
+
return actual !== "";
|
|
3610
|
+
case "greater_than":
|
|
3611
|
+
return Number(actual) > Number(expected);
|
|
3612
|
+
case "greater_or_equal":
|
|
3613
|
+
return Number(actual) >= Number(expected);
|
|
3614
|
+
case "less_than":
|
|
3615
|
+
return Number(actual) < Number(expected);
|
|
3616
|
+
case "less_or_equal":
|
|
3617
|
+
return Number(actual) <= Number(expected);
|
|
3618
|
+
case "between": {
|
|
3619
|
+
const numeric = Number(actual);
|
|
3620
|
+
return numeric >= Number(expected) && numeric <= Number(expectedTo);
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
}
|
|
3624
|
+
function layeredFilterRuleSummary(rule, fields) {
|
|
3625
|
+
const field = fields.find((candidate) => candidate.id === rule.field);
|
|
3626
|
+
const fieldLabel = field?.label ?? rule.field;
|
|
3627
|
+
const operator = LAYERED_FILTER_OPERATOR_LABELS[rule.operator];
|
|
3628
|
+
if (!layeredFilterNeedsValue(rule.operator))
|
|
3629
|
+
return `${fieldLabel} ${operator}`;
|
|
3630
|
+
const selectedLabel = field?.kind === "select" ? field.options.find((option) => option.value === rule.value)?.label : void 0;
|
|
3631
|
+
const value = selectedLabel ?? rule.value;
|
|
3632
|
+
return rule.operator === "between" ? `${fieldLabel} ${operator} ${value} and ${rule.valueTo ?? ""}` : `${fieldLabel} ${operator} ${value}`;
|
|
3633
|
+
}
|
|
3634
|
+
|
|
3635
|
+
// src/data-table/filter-engine.ts
|
|
3636
|
+
var SELECT_EMPTY_VALUE = "__empty__";
|
|
3637
|
+
var SELECT_NOT_EMPTY_VALUE = "__not_empty__";
|
|
3638
|
+
function columnId(col) {
|
|
3639
|
+
if (col.id) return col.id;
|
|
3640
|
+
if (col.accessorKey) return String(col.accessorKey);
|
|
3641
|
+
throw new Error("MatrxDataTable column requires `id` or `accessorKey`");
|
|
3642
|
+
}
|
|
3643
|
+
function getCellValue(row, col) {
|
|
3644
|
+
if (col.accessorFn) return col.accessorFn(row);
|
|
3645
|
+
if (col.accessorKey) {
|
|
3646
|
+
return row[col.accessorKey];
|
|
3647
|
+
}
|
|
3648
|
+
return void 0;
|
|
3649
|
+
}
|
|
3650
|
+
function getFilterValue(row, col) {
|
|
3651
|
+
return col.filterValue ? col.filterValue(row) : getCellValue(row, col);
|
|
3652
|
+
}
|
|
3653
|
+
function getSortValue(row, col) {
|
|
3654
|
+
return col.sortValue ? col.sortValue(row) : getCellValue(row, col);
|
|
3655
|
+
}
|
|
3656
|
+
function stringifyCellValue(value) {
|
|
3657
|
+
if (value == null) return "";
|
|
3658
|
+
if (typeof value === "string") return value;
|
|
3659
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
3660
|
+
return String(value);
|
|
3661
|
+
}
|
|
3662
|
+
if (value instanceof Date) return value.toISOString();
|
|
3663
|
+
try {
|
|
3664
|
+
return JSON.stringify(value);
|
|
3665
|
+
} catch {
|
|
3666
|
+
return String(value);
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
function tableSearchWords(value) {
|
|
3670
|
+
return value.toLocaleLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean);
|
|
3671
|
+
}
|
|
3672
|
+
function matchesTableSearch(searchableText, query, mode = "contains") {
|
|
3673
|
+
const normalizedQuery = query.trim().toLocaleLowerCase();
|
|
3674
|
+
if (!normalizedQuery) return true;
|
|
3675
|
+
if (mode === "contains") {
|
|
3676
|
+
return searchableText.toLocaleLowerCase().includes(normalizedQuery);
|
|
3677
|
+
}
|
|
3678
|
+
const actualWords = new Set(tableSearchWords(searchableText));
|
|
3679
|
+
const expectedWords = tableSearchWords(normalizedQuery);
|
|
3680
|
+
return expectedWords.length > 0 && expectedWords.every((word) => actualWords.has(word));
|
|
3681
|
+
}
|
|
3682
|
+
function compareValues(a, b) {
|
|
3683
|
+
if (a == null && b == null) return 0;
|
|
3684
|
+
if (a == null) return -1;
|
|
3685
|
+
if (b == null) return 1;
|
|
3686
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
3687
|
+
if (typeof a === "boolean" && typeof b === "boolean") {
|
|
3688
|
+
return Number(a) - Number(b);
|
|
3689
|
+
}
|
|
3690
|
+
return stringifyCellValue(a).localeCompare(stringifyCellValue(b), void 0, {
|
|
3691
|
+
numeric: true,
|
|
3692
|
+
sensitivity: "base"
|
|
3693
|
+
});
|
|
3694
|
+
}
|
|
3695
|
+
function passesColumnFilter(value, filter) {
|
|
3696
|
+
const matches = (() => {
|
|
3697
|
+
switch (filter.kind) {
|
|
3698
|
+
case "text": {
|
|
3699
|
+
const s = stringifyCellValue(value);
|
|
3700
|
+
if (filter.mode === "null") return value == null;
|
|
3701
|
+
if (filter.mode === "not_null") return value != null;
|
|
3702
|
+
if (filter.mode === "empty") return s.trim() === "";
|
|
3703
|
+
if (filter.mode === "not_empty") return s.trim() !== "";
|
|
3704
|
+
const q = filter.value.trim().toLowerCase();
|
|
3705
|
+
if (!q) return true;
|
|
3706
|
+
return s.toLowerCase().includes(q);
|
|
3707
|
+
}
|
|
3708
|
+
case "select": {
|
|
3709
|
+
const selected = filter.values ?? (filter.value && filter.value !== "__all__" ? [filter.value] : []);
|
|
3710
|
+
if (selected.length === 0) return true;
|
|
3711
|
+
const s = stringifyCellValue(value);
|
|
3712
|
+
return selected.some(
|
|
3713
|
+
(v) => v === SELECT_EMPTY_VALUE ? s === "" : v === SELECT_NOT_EMPTY_VALUE ? s !== "" : s === v
|
|
3714
|
+
);
|
|
3715
|
+
}
|
|
3716
|
+
case "boolean": {
|
|
3717
|
+
return Boolean(value) === filter.value;
|
|
3718
|
+
}
|
|
3719
|
+
case "number": {
|
|
3720
|
+
const n = typeof value === "number" ? value : Number(stringifyCellValue(value).replace(/[^0-9.-]/g, ""));
|
|
3721
|
+
if (Number.isNaN(n)) return false;
|
|
3722
|
+
if (filter.min !== void 0 && n < filter.min) return false;
|
|
3723
|
+
if (filter.max !== void 0 && n > filter.max) return false;
|
|
3724
|
+
return true;
|
|
3725
|
+
}
|
|
3726
|
+
}
|
|
3727
|
+
})();
|
|
3728
|
+
return filter.negated ? !matches : matches;
|
|
3851
3729
|
}
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
const
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3730
|
+
function filterAndSortRows(rows, columns, columnFilters, sort, globalSearch, anyOf, layeredFilters, globalSearchMode = "contains", searchText) {
|
|
3731
|
+
const colById = new Map(columns.map((c) => [columnId(c), c]));
|
|
3732
|
+
const q = globalSearch.trim().toLowerCase();
|
|
3733
|
+
const anyQ = anyOf?.query.trim().toLowerCase() ?? "";
|
|
3734
|
+
const activeLayeredFilters = completeLayeredFilterRules(layeredFilters);
|
|
3735
|
+
let result = rows.filter((row) => {
|
|
3736
|
+
for (const [id, filter] of Object.entries(columnFilters)) {
|
|
3737
|
+
if (!filter) continue;
|
|
3738
|
+
const col = colById.get(id);
|
|
3739
|
+
if (!col || col.filter === false) continue;
|
|
3740
|
+
if (!passesColumnFilter(getFilterValue(row, col), filter)) return false;
|
|
3741
|
+
}
|
|
3742
|
+
for (const rule of activeLayeredFilters) {
|
|
3743
|
+
const col = colById.get(rule.field);
|
|
3744
|
+
if (!col || !layeredFilterMatchesValue(getFilterValue(row, col), rule)) {
|
|
3745
|
+
return false;
|
|
3746
|
+
}
|
|
3747
|
+
}
|
|
3748
|
+
if (anyQ && anyOf) {
|
|
3749
|
+
const hit = anyOf.columnIds.some((id) => {
|
|
3750
|
+
const col = colById.get(id);
|
|
3751
|
+
if (!col) return false;
|
|
3752
|
+
return stringifyCellValue(getFilterValue(row, col)).toLowerCase().includes(anyQ);
|
|
3753
|
+
});
|
|
3754
|
+
if (!hit) return false;
|
|
3755
|
+
}
|
|
3756
|
+
if (!q) return true;
|
|
3757
|
+
const searchableValues = columns.filter(
|
|
3758
|
+
(col) => col.filter !== false || Boolean(col.accessorKey || col.accessorFn)
|
|
3759
|
+
).map((col) => stringifyCellValue(getFilterValue(row, col)));
|
|
3760
|
+
const additionalSearchText = searchText?.(row);
|
|
3761
|
+
if (additionalSearchText) searchableValues.push(additionalSearchText);
|
|
3762
|
+
if (globalSearchMode === "contains") {
|
|
3763
|
+
return searchableValues.some(
|
|
3764
|
+
(value) => matchesTableSearch(value, q, "contains")
|
|
3765
|
+
);
|
|
3766
|
+
}
|
|
3767
|
+
return matchesTableSearch(searchableValues.join(" "), q, "whole_words");
|
|
3768
|
+
});
|
|
3769
|
+
if (sort) {
|
|
3770
|
+
const col = colById.get(sort.id);
|
|
3771
|
+
if (col && col.sortable !== false) {
|
|
3772
|
+
const dir = sort.direction === "asc" ? 1 : -1;
|
|
3773
|
+
result = [...result].sort((a, b) => {
|
|
3774
|
+
const va = getSortValue(a, col);
|
|
3775
|
+
const vb = getSortValue(b, col);
|
|
3776
|
+
const ea = va == null || stringifyCellValue(va) === "";
|
|
3777
|
+
const eb = vb == null || stringifyCellValue(vb) === "";
|
|
3778
|
+
if (ea !== eb) return ea ? 1 : -1;
|
|
3779
|
+
return compareValues(va, vb) * dir;
|
|
3780
|
+
});
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
return result;
|
|
3878
3784
|
}
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3785
|
+
function countActiveColumnFilters(filters) {
|
|
3786
|
+
let n = 0;
|
|
3787
|
+
for (const f of Object.values(filters)) {
|
|
3788
|
+
if (!f) continue;
|
|
3789
|
+
switch (f.kind) {
|
|
3790
|
+
case "text":
|
|
3791
|
+
if (f.value.trim() || f.mode && f.mode !== "contains") n += 1;
|
|
3792
|
+
break;
|
|
3793
|
+
case "select":
|
|
3794
|
+
if (f.values ? f.values.length > 0 : f.value && f.value !== "__all__")
|
|
3795
|
+
n += 1;
|
|
3796
|
+
break;
|
|
3797
|
+
case "boolean":
|
|
3798
|
+
n += 1;
|
|
3799
|
+
break;
|
|
3800
|
+
case "number":
|
|
3801
|
+
if (f.min !== void 0 || f.max !== void 0) n += 1;
|
|
3802
|
+
break;
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
3805
|
+
return n;
|
|
3887
3806
|
}
|
|
3888
|
-
function
|
|
3889
|
-
|
|
3807
|
+
function isColumnFilterActive(filter) {
|
|
3808
|
+
if (!filter) return false;
|
|
3809
|
+
switch (filter.kind) {
|
|
3810
|
+
case "text":
|
|
3811
|
+
return filter.value.trim().length > 0 || filter.mode !== void 0 && filter.mode !== "contains";
|
|
3812
|
+
case "select":
|
|
3813
|
+
return filter.values ? filter.values.length > 0 : Boolean(filter.value) && filter.value !== "__all__";
|
|
3814
|
+
case "boolean":
|
|
3815
|
+
return true;
|
|
3816
|
+
case "number":
|
|
3817
|
+
return filter.min !== void 0 || filter.max !== void 0;
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
function applyRowEdits(row, edits) {
|
|
3821
|
+
if (!edits || Object.keys(edits).length === 0) return row;
|
|
3822
|
+
return { ...row, ...edits };
|
|
3890
3823
|
}
|
|
3891
|
-
|
|
3892
|
-
// src/data-table/CopySubset.tsx
|
|
3893
|
-
import { useState as useState7 } from "react";
|
|
3894
|
-
import { useClipboard } from "@ai-matrx/kit/clipboard";
|
|
3895
|
-
init_filter_engine();
|
|
3896
3824
|
|
|
3897
3825
|
// src/data-table/tableCopy.ts
|
|
3898
|
-
init_filter_engine();
|
|
3899
3826
|
import { normalizeTransferJson as normalizeTransferJson2 } from "@ai-matrx/kit/content-transfer";
|
|
3900
3827
|
function projectDefaultTableCopyRow(row, columns) {
|
|
3901
3828
|
const record = /* @__PURE__ */ Object.create(null);
|
|
@@ -4497,7 +4424,6 @@ var CommandShortcut = ({
|
|
|
4497
4424
|
CommandShortcut.displayName = "CommandShortcut";
|
|
4498
4425
|
|
|
4499
4426
|
// src/data-table/ColumnHeaderCell.tsx
|
|
4500
|
-
init_filter_engine();
|
|
4501
4427
|
import { Fragment as Fragment4, jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4502
4428
|
var HeaderButton = forwardRef12(({ dragDescription, "aria-describedby": tooltipDescription, ...props }, ref) => {
|
|
4503
4429
|
const descriptions = [tooltipDescription, dragDescription].filter((value) => Boolean(value)).join(" ");
|
|
@@ -5141,7 +5067,6 @@ function parseOptionalNumber(raw) {
|
|
|
5141
5067
|
// src/data-table/ColumnManager.tsx
|
|
5142
5068
|
import { useEffect as useEffect7, useMemo as useMemo4, useState as useState10 } from "react";
|
|
5143
5069
|
import { useDndMonitor, useDraggable as useDraggable2, useDroppable } from "@dnd-kit/core";
|
|
5144
|
-
init_filter_engine();
|
|
5145
5070
|
import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5146
5071
|
function ColumnManager({
|
|
5147
5072
|
open,
|
|
@@ -5825,7 +5750,6 @@ function DirtySavePill({
|
|
|
5825
5750
|
|
|
5826
5751
|
// src/data-table/EditableTableCell.tsx
|
|
5827
5752
|
import { useState as useState13 } from "react";
|
|
5828
|
-
init_filter_engine();
|
|
5829
5753
|
import { jsx as jsx33, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5830
5754
|
function CellEditShell({
|
|
5831
5755
|
href,
|
|
@@ -6341,7 +6265,6 @@ function resetToolbarFacets(facets) {
|
|
|
6341
6265
|
|
|
6342
6266
|
// src/data-table/LayeredFilterBuilder.tsx
|
|
6343
6267
|
import { useState as useState14 } from "react";
|
|
6344
|
-
init_layered_filters();
|
|
6345
6268
|
import { Fragment as Fragment5, jsx as jsx35, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
6346
6269
|
function moveRule(rules, from, to) {
|
|
6347
6270
|
if (from === to || to < 0 || to >= rules.length) return [...rules];
|
|
@@ -6709,12 +6632,7 @@ function LayeredRuleRow({
|
|
|
6709
6632
|
);
|
|
6710
6633
|
}
|
|
6711
6634
|
|
|
6712
|
-
// src/data-table/MatrxDataTable.tsx
|
|
6713
|
-
init_layered_filters();
|
|
6714
|
-
init_filter_engine();
|
|
6715
|
-
|
|
6716
6635
|
// src/data-table/infer-filter.ts
|
|
6717
|
-
init_filter_engine();
|
|
6718
6636
|
var SELECT_CARDINALITY_CAP = 24;
|
|
6719
6637
|
function resolveFilterKind(col, sampleRows) {
|
|
6720
6638
|
if (col.filter === false) return null;
|
|
@@ -6809,24 +6727,6 @@ import { Fragment as Fragment7, jsx as jsx36, jsxs as jsxs27 } from "react/jsx-r
|
|
|
6809
6727
|
function hasSameRowReferences(previous, next) {
|
|
6810
6728
|
return previous.length === next.length && previous.every((row, index) => row === next[index]);
|
|
6811
6729
|
}
|
|
6812
|
-
function forwardUnboundedVerticalWheel(event) {
|
|
6813
|
-
const tableScroller = event.currentTarget;
|
|
6814
|
-
const isVerticalGesture = !event.shiftKey && Math.abs(event.deltaY) > Math.abs(event.deltaX);
|
|
6815
|
-
const tableOwnsVerticalScroll = tableScroller.scrollHeight > tableScroller.clientHeight + 1;
|
|
6816
|
-
if (!isVerticalGesture || tableOwnsVerticalScroll || event.deltaY === 0) return;
|
|
6817
|
-
let ancestor = tableScroller.parentElement;
|
|
6818
|
-
while (ancestor) {
|
|
6819
|
-
const overflowY = window.getComputedStyle(ancestor).overflowY;
|
|
6820
|
-
const canScroll = (overflowY === "auto" || overflowY === "scroll") && ancestor.scrollHeight > ancestor.clientHeight + 1;
|
|
6821
|
-
if (canScroll) {
|
|
6822
|
-
const scale = event.deltaMode === WheelEvent.DOM_DELTA_LINE ? 16 : event.deltaMode === WheelEvent.DOM_DELTA_PAGE ? ancestor.clientHeight : 1;
|
|
6823
|
-
event.preventDefault();
|
|
6824
|
-
ancestor.scrollTop += event.deltaY * scale;
|
|
6825
|
-
return;
|
|
6826
|
-
}
|
|
6827
|
-
ancestor = ancestor.parentElement;
|
|
6828
|
-
}
|
|
6829
|
-
}
|
|
6830
6730
|
function TableRowCopyControl({
|
|
6831
6731
|
copy,
|
|
6832
6732
|
row,
|
|
@@ -7887,6 +7787,11 @@ function MatrxDataTableCore({
|
|
|
7887
7787
|
id: tableDndContextId,
|
|
7888
7788
|
sensors: hierarchySensors,
|
|
7889
7789
|
collisionDetection: pointerWithin,
|
|
7790
|
+
accessibility: {
|
|
7791
|
+
screenReaderInstructions: {
|
|
7792
|
+
draggable: "Drag with a pointer. To reorder columns with a keyboard, open Columns and use Move earlier or Move later."
|
|
7793
|
+
}
|
|
7794
|
+
},
|
|
7890
7795
|
measuring: { droppable: { strategy: MeasuringStrategy.Always } },
|
|
7891
7796
|
onDragStart: (event) => {
|
|
7892
7797
|
const kind = event.active.data.current?.matrxDragKind;
|
|
@@ -8148,37 +8053,14 @@ function MatrxDataTableCore({
|
|
|
8148
8053
|
],
|
|
8149
8054
|
...effectiveCopy.aiCustom ? { aiCustom: effectiveCopy.aiCustom(processed, data) } : {},
|
|
8150
8055
|
export: {
|
|
8151
|
-
items:
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
)
|
|
8158
|
-
|
|
8159
|
-
id: "csv",
|
|
8160
|
-
label: "CSV (current view)",
|
|
8161
|
-
build: () => ({
|
|
8162
|
-
content: rowsToCsvFromColumns(processed, effectiveCopyColumns),
|
|
8163
|
-
extension: "csv",
|
|
8164
|
-
mime: "text/csv"
|
|
8165
|
-
})
|
|
8166
|
-
},
|
|
8167
|
-
{
|
|
8168
|
-
id: "xlsx",
|
|
8169
|
-
label: "Excel (.xlsx)",
|
|
8170
|
-
onSelect: async () => {
|
|
8171
|
-
const { downloadTableAsXlsx: downloadTableAsXlsx2 } = await Promise.resolve().then(() => (init_tableXlsx(), tableXlsx_exports));
|
|
8172
|
-
downloadTableAsXlsx2({
|
|
8173
|
-
rows: processed,
|
|
8174
|
-
columns: effectiveCopyColumns,
|
|
8175
|
-
label: effectiveCopy.listLabel ?? effectiveCopy.label
|
|
8176
|
-
});
|
|
8177
|
-
}
|
|
8178
|
-
}
|
|
8179
|
-
],
|
|
8180
|
-
sheetRows: () => copy === void 0 ? processed.map((row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)) : rowsToRecordsFromColumns(processed, effectiveCopyColumns),
|
|
8181
|
-
...copy === void 0 ? { sheetColumns: () => declaredVisibleCopyColumns.map((column) => ({ id: columnId(column), label: column.label ?? (typeof column.header === "string" ? column.header : columnId(column)) })) } : {}
|
|
8056
|
+
items: [],
|
|
8057
|
+
sheetRows: () => processed.map(
|
|
8058
|
+
(row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)
|
|
8059
|
+
),
|
|
8060
|
+
sheetColumns: () => declaredVisibleCopyColumns.map((column) => ({
|
|
8061
|
+
id: columnId(column),
|
|
8062
|
+
label: column.label ?? (typeof column.header === "string" ? column.header : columnId(column))
|
|
8063
|
+
}))
|
|
8182
8064
|
}
|
|
8183
8065
|
}
|
|
8184
8066
|
) : null,
|
|
@@ -8252,40 +8134,14 @@ function MatrxDataTableCore({
|
|
|
8252
8134
|
"selected"
|
|
8253
8135
|
),
|
|
8254
8136
|
export: {
|
|
8255
|
-
items:
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
)
|
|
8262
|
-
|
|
8263
|
-
id: "csv",
|
|
8264
|
-
label: "CSV (selected rows)",
|
|
8265
|
-
build: () => ({
|
|
8266
|
-
content: rowsToCsvFromColumns(
|
|
8267
|
-
selectedRows,
|
|
8268
|
-
effectiveCopyColumns
|
|
8269
|
-
),
|
|
8270
|
-
extension: "csv",
|
|
8271
|
-
mime: "text/csv"
|
|
8272
|
-
})
|
|
8273
|
-
},
|
|
8274
|
-
{
|
|
8275
|
-
id: "xlsx",
|
|
8276
|
-
label: "Excel (.xlsx)",
|
|
8277
|
-
onSelect: async () => {
|
|
8278
|
-
const { downloadTableAsXlsx: downloadTableAsXlsx2 } = await Promise.resolve().then(() => (init_tableXlsx(), tableXlsx_exports));
|
|
8279
|
-
downloadTableAsXlsx2({
|
|
8280
|
-
rows: selectedRows,
|
|
8281
|
-
columns: effectiveCopyColumns,
|
|
8282
|
-
label: `${effectiveCopy.listLabel ?? effectiveCopy.label} selected`
|
|
8283
|
-
});
|
|
8284
|
-
}
|
|
8285
|
-
}
|
|
8286
|
-
],
|
|
8287
|
-
sheetRows: () => copy === void 0 ? selectedRows.map((row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)) : rowsToRecordsFromColumns(selectedRows, effectiveCopyColumns),
|
|
8288
|
-
...copy === void 0 ? { sheetColumns: () => declaredVisibleCopyColumns.map((column) => ({ id: columnId(column), label: column.label ?? (typeof column.header === "string" ? column.header : columnId(column)) })) } : {}
|
|
8137
|
+
items: [],
|
|
8138
|
+
sheetRows: () => selectedRows.map(
|
|
8139
|
+
(row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)
|
|
8140
|
+
),
|
|
8141
|
+
sheetColumns: () => declaredVisibleCopyColumns.map((column) => ({
|
|
8142
|
+
id: columnId(column),
|
|
8143
|
+
label: column.label ?? (typeof column.header === "string" ? column.header : columnId(column))
|
|
8144
|
+
}))
|
|
8289
8145
|
}
|
|
8290
8146
|
}
|
|
8291
8147
|
) : null,
|
|
@@ -8401,7 +8257,6 @@ function MatrxDataTableCore({
|
|
|
8401
8257
|
ref: scrollRef,
|
|
8402
8258
|
"data-matrx-table-scroll": true,
|
|
8403
8259
|
onScroll: updateScrollHint,
|
|
8404
|
-
onWheel: forwardUnboundedVerticalWheel,
|
|
8405
8260
|
"aria-busy": isLoading || isFetching,
|
|
8406
8261
|
...appendQuery === null ? {} : { style: { containerType: "inline-size" } },
|
|
8407
8262
|
className: cn(
|
|
@@ -9374,8 +9229,41 @@ function resolveStringTitle(title, fallback) {
|
|
|
9374
9229
|
return fallback;
|
|
9375
9230
|
}
|
|
9376
9231
|
|
|
9377
|
-
// src/data-table/
|
|
9378
|
-
|
|
9232
|
+
// src/data-table/tableXlsx.ts
|
|
9233
|
+
import * as XLSX from "xlsx";
|
|
9234
|
+
function downloadTableAsXlsx({
|
|
9235
|
+
rows,
|
|
9236
|
+
columns,
|
|
9237
|
+
label
|
|
9238
|
+
}) {
|
|
9239
|
+
const visibleColumns = columns.filter(
|
|
9240
|
+
(column) => column.filter !== false || column.accessorKey
|
|
9241
|
+
);
|
|
9242
|
+
const headers = visibleColumns.map(
|
|
9243
|
+
(column) => typeof column.header === "string" ? column.header : columnId(column)
|
|
9244
|
+
);
|
|
9245
|
+
const values = rows.map(
|
|
9246
|
+
(row) => visibleColumns.map(
|
|
9247
|
+
(column) => stringifyCellValue(getCellValue(row, column))
|
|
9248
|
+
)
|
|
9249
|
+
);
|
|
9250
|
+
const worksheet = XLSX.utils.aoa_to_sheet([headers, ...values]);
|
|
9251
|
+
const workbook = XLSX.utils.book_new();
|
|
9252
|
+
const sheetName = label.replace(/[\\/?*[\]:]/g, " ").trim().slice(0, 31) || "Data";
|
|
9253
|
+
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
|
|
9254
|
+
const bytes = XLSX.write(workbook, {
|
|
9255
|
+
type: "array",
|
|
9256
|
+
bookType: "xlsx",
|
|
9257
|
+
compression: true
|
|
9258
|
+
});
|
|
9259
|
+
const blob = new Blob([bytes], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
|
|
9260
|
+
const url = URL.createObjectURL(blob);
|
|
9261
|
+
const anchor = document.createElement("a");
|
|
9262
|
+
anchor.href = url;
|
|
9263
|
+
anchor.download = `${label.toLowerCase().replace(/[^a-z0-9]+/g, "-") || "table"}.xlsx`;
|
|
9264
|
+
anchor.click();
|
|
9265
|
+
URL.revokeObjectURL(url);
|
|
9266
|
+
}
|
|
9379
9267
|
export {
|
|
9380
9268
|
DataRowInspector,
|
|
9381
9269
|
DataRowWindow,
|