@toolbox-web/grid 0.2.5 → 0.2.7
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/all.d.ts +486 -80
- package/all.js +1364 -1029
- package/all.js.map +1 -1
- package/index-DG2CZ_Zo.js +3229 -0
- package/index-DG2CZ_Zo.js.map +1 -0
- package/index.d.ts +222 -11
- package/index.js +25 -3143
- package/index.js.map +1 -1
- package/lib/plugins/clipboard/index.js +1 -1
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/export/index.js +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +184 -149
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +46 -45
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js +117 -83
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +140 -82
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +18 -18
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +1 -1
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +55 -47
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +385 -351
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/reorder/index.js +278 -85
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js +28 -27
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js +2 -2
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/index.js +181 -170
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +1 -1
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +22 -22
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +12 -12
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-columns.umd.js +1 -1
- package/umd/plugins/grouping-columns.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +1 -1
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/pinned-rows.umd.js +1 -1
- package/umd/plugins/pinned-rows.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +1 -1
- package/umd/plugins/selection.umd.js.map +1 -1
- package/umd/plugins/server-side.umd.js +1 -1
- package/umd/plugins/server-side.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
package/all.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
function Be(
|
|
1
|
+
import { B as v, D as Ve, r as se, P as N, g as le, a as Oe, e as Ge } from "./index-DG2CZ_Zo.js";
|
|
2
|
+
import { k as Kn, i as Nn, b as qn, F as Dn, o as Hn, G as Vn, p as On, b as Gn, q as Bn, j as zn, c as Wn, d as $n, m as jn, n as Un, l as Yn, f as Zn, h as Xn, u as Jn } from "./index-DG2CZ_Zo.js";
|
|
3
|
+
function Be(s, e, t, n) {
|
|
4
4
|
if (n.processCell)
|
|
5
|
-
return n.processCell(
|
|
6
|
-
if (
|
|
7
|
-
if (
|
|
8
|
-
if (typeof
|
|
9
|
-
const o = String(
|
|
5
|
+
return n.processCell(s, e, t);
|
|
6
|
+
if (s == null) return "";
|
|
7
|
+
if (s instanceof Date) return s.toISOString();
|
|
8
|
+
if (typeof s == "object") return JSON.stringify(s);
|
|
9
|
+
const o = String(s), i = n.delimiter ?? " ", r = n.newline ?? `
|
|
10
10
|
`;
|
|
11
|
-
return n.quoteStrings || o.includes(i) || o.includes(
|
|
11
|
+
return n.quoteStrings || o.includes(i) || o.includes(r) || o.includes('"') ? `"${o.replace(/"/g, '""')}"` : o;
|
|
12
12
|
}
|
|
13
|
-
function
|
|
14
|
-
const { rows: e, columns: t, selectedIndices: n, config: o } =
|
|
13
|
+
function V(s) {
|
|
14
|
+
const { rows: e, columns: t, selectedIndices: n, config: o } = s, i = o.delimiter ?? " ", r = o.newline ?? `
|
|
15
15
|
`, l = t.filter((u) => !u.hidden && !u.field.startsWith("__")), a = [];
|
|
16
16
|
if (o.includeHeaders) {
|
|
17
17
|
const u = l.map((h) => {
|
|
18
18
|
const g = h.header || h.field;
|
|
19
|
-
return g.includes(i) || g.includes(
|
|
19
|
+
return g.includes(i) || g.includes(r) || g.includes('"') ? `"${g.replace(/"/g, '""')}"` : g;
|
|
20
20
|
});
|
|
21
21
|
a.push(u.join(i));
|
|
22
22
|
}
|
|
@@ -25,42 +25,42 @@ function H(r) {
|
|
|
25
25
|
const h = e[u];
|
|
26
26
|
if (!h) continue;
|
|
27
27
|
const g = l.map(
|
|
28
|
-
(
|
|
28
|
+
(f) => Be(h[f.field], f.field, h, o)
|
|
29
29
|
);
|
|
30
30
|
a.push(g.join(i));
|
|
31
31
|
}
|
|
32
|
-
return a.join(
|
|
32
|
+
return a.join(r);
|
|
33
33
|
}
|
|
34
|
-
async function
|
|
34
|
+
async function O(s) {
|
|
35
35
|
try {
|
|
36
|
-
return await navigator.clipboard.writeText(
|
|
36
|
+
return await navigator.clipboard.writeText(s), !0;
|
|
37
37
|
} catch {
|
|
38
38
|
const e = document.createElement("textarea");
|
|
39
|
-
e.value =
|
|
39
|
+
e.value = s, e.style.position = "fixed", e.style.opacity = "0", e.style.pointerEvents = "none", document.body.appendChild(e), e.select();
|
|
40
40
|
const t = document.execCommand("copy");
|
|
41
41
|
return document.body.removeChild(e), t;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
function
|
|
44
|
+
function ae(s, e) {
|
|
45
45
|
const t = e.delimiter ?? " ", n = e.newline ?? `
|
|
46
|
-
`, o =
|
|
46
|
+
`, o = s.replace(/\r\n/g, `
|
|
47
47
|
`).replace(/\r/g, `
|
|
48
48
|
`), i = [];
|
|
49
|
-
let
|
|
49
|
+
let r = [], l = "", a = !1;
|
|
50
50
|
for (let d = 0; d < o.length; d++) {
|
|
51
51
|
const c = o[d];
|
|
52
|
-
c === '"' && !a ? a = !0 : c === '"' && a ? o[d + 1] === '"' ? (l += '"', d++) : a = !1 : c === t && !a ? (
|
|
52
|
+
c === '"' && !a ? a = !0 : c === '"' && a ? o[d + 1] === '"' ? (l += '"', d++) : a = !1 : c === t && !a ? (r.push(l), l = "") : c === n && !a ? (r.push(l), l = "", (r.length > 1 || r.some((u) => u.trim() !== "")) && i.push(r), r = []) : l += c;
|
|
53
53
|
}
|
|
54
|
-
return
|
|
54
|
+
return r.push(l), (r.length > 1 || r.some((d) => d.trim() !== "")) && i.push(r), i;
|
|
55
55
|
}
|
|
56
|
-
async function
|
|
56
|
+
async function de() {
|
|
57
57
|
try {
|
|
58
58
|
return await navigator.clipboard.readText();
|
|
59
59
|
} catch {
|
|
60
60
|
return "";
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
class
|
|
63
|
+
class bn extends v {
|
|
64
64
|
name = "clipboard";
|
|
65
65
|
version = "1.0.0";
|
|
66
66
|
get defaultConfig() {
|
|
@@ -92,16 +92,16 @@ class wn extends x {
|
|
|
92
92
|
* Handle copy operation
|
|
93
93
|
*/
|
|
94
94
|
#t(e) {
|
|
95
|
-
const t = this.#n(), n = t?.getSelectedRows() ?? [], o = n.length > 0, i = t?.getRanges() ?? [],
|
|
95
|
+
const t = this.#n(), n = t?.getSelectedRows() ?? [], o = n.length > 0, i = t?.getRanges() ?? [], r = i.length > 0, l = t?.getSelectedCell() != null;
|
|
96
96
|
let a, d, c;
|
|
97
97
|
if (o && t)
|
|
98
|
-
a =
|
|
98
|
+
a = V({
|
|
99
99
|
rows: this.rows,
|
|
100
100
|
columns: [...this.columns],
|
|
101
101
|
selectedIndices: n,
|
|
102
102
|
config: this.config
|
|
103
103
|
}), d = n.length, c = this.columns.filter((u) => !u.hidden && !u.field.startsWith("__")).length;
|
|
104
|
-
else if (
|
|
104
|
+
else if (r && t) {
|
|
105
105
|
const u = i[i.length - 1], h = this.#i({
|
|
106
106
|
startRow: u.from.row,
|
|
107
107
|
startCol: u.from.col,
|
|
@@ -118,7 +118,7 @@ class wn extends x {
|
|
|
118
118
|
if (!u) return;
|
|
119
119
|
a = u.text, d = 1, c = 1;
|
|
120
120
|
}
|
|
121
|
-
|
|
121
|
+
O(a).then(() => {
|
|
122
122
|
this.lastCopied = { text: a, timestamp: Date.now() }, this.emit("copy", { text: a, rowCount: d, columnCount: c });
|
|
123
123
|
});
|
|
124
124
|
}
|
|
@@ -126,9 +126,9 @@ class wn extends x {
|
|
|
126
126
|
* Handle paste operation
|
|
127
127
|
*/
|
|
128
128
|
#e() {
|
|
129
|
-
|
|
129
|
+
de().then((e) => {
|
|
130
130
|
if (!e) return;
|
|
131
|
-
const t =
|
|
131
|
+
const t = ae(e, this.config);
|
|
132
132
|
this.emit("paste", { rows: t, text: e });
|
|
133
133
|
});
|
|
134
134
|
}
|
|
@@ -154,11 +154,11 @@ class wn extends x {
|
|
|
154
154
|
if (!n) return null;
|
|
155
155
|
const o = this.columns[t];
|
|
156
156
|
if (!o) return null;
|
|
157
|
-
const i = n[o.field],
|
|
157
|
+
const i = n[o.field], r = o.header || o.field;
|
|
158
158
|
let l;
|
|
159
159
|
if (this.config.includeHeaders) {
|
|
160
160
|
const a = i == null ? "" : String(i);
|
|
161
|
-
l = `${
|
|
161
|
+
l = `${r}: ${a}`;
|
|
162
162
|
} else
|
|
163
163
|
l = i == null ? "" : String(i);
|
|
164
164
|
return { text: l };
|
|
@@ -167,24 +167,24 @@ class wn extends x {
|
|
|
167
167
|
* Build text for a rectangular range of cells.
|
|
168
168
|
*/
|
|
169
169
|
#i(e) {
|
|
170
|
-
const { startRow: t, startCol: n, endRow: o, endCol: i } = e,
|
|
170
|
+
const { startRow: t, startCol: n, endRow: o, endCol: i } = e, r = Math.min(t, o), l = Math.max(t, o), a = Math.min(n, i), d = Math.max(n, i), c = this.config.delimiter ?? " ", u = this.config.newline ?? `
|
|
171
171
|
`, h = [], g = this.columns.slice(a, d + 1);
|
|
172
172
|
if (this.config.includeHeaders) {
|
|
173
|
-
const
|
|
174
|
-
h.push(
|
|
173
|
+
const f = g.map((m) => m.header || m.field);
|
|
174
|
+
h.push(f.join(c));
|
|
175
175
|
}
|
|
176
|
-
for (let
|
|
177
|
-
const
|
|
178
|
-
if (!
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
return
|
|
176
|
+
for (let f = r; f <= l; f++) {
|
|
177
|
+
const m = this.rows[f];
|
|
178
|
+
if (!m) continue;
|
|
179
|
+
const p = g.map((R) => {
|
|
180
|
+
const E = m[R.field];
|
|
181
|
+
return E == null ? "" : E instanceof Date ? E.toISOString() : String(E);
|
|
182
182
|
});
|
|
183
|
-
h.push(
|
|
183
|
+
h.push(p.join(c));
|
|
184
184
|
}
|
|
185
185
|
return {
|
|
186
186
|
text: h.join(u),
|
|
187
|
-
rowCount: l -
|
|
187
|
+
rowCount: l - r + 1,
|
|
188
188
|
columnCount: d - a + 1
|
|
189
189
|
};
|
|
190
190
|
}
|
|
@@ -201,9 +201,9 @@ class wn extends x {
|
|
|
201
201
|
if (!o) return null;
|
|
202
202
|
const i = parseInt(o, 10);
|
|
203
203
|
if (isNaN(i)) return null;
|
|
204
|
-
const
|
|
205
|
-
if (!
|
|
206
|
-
const l =
|
|
204
|
+
const r = this.rows[i];
|
|
205
|
+
if (!r) return null;
|
|
206
|
+
const l = r[n], d = this.columns.find((u) => u.field === n)?.header || n;
|
|
207
207
|
let c;
|
|
208
208
|
if (this.config.includeHeaders) {
|
|
209
209
|
const u = l == null ? "" : String(l);
|
|
@@ -219,13 +219,13 @@ class wn extends x {
|
|
|
219
219
|
* @returns The copied text
|
|
220
220
|
*/
|
|
221
221
|
async copy() {
|
|
222
|
-
const t = this.#n()?.getSelectedRows() ?? [], n =
|
|
222
|
+
const t = this.#n()?.getSelectedRows() ?? [], n = V({
|
|
223
223
|
rows: this.rows,
|
|
224
224
|
columns: [...this.columns],
|
|
225
225
|
selectedIndices: t,
|
|
226
226
|
config: this.config
|
|
227
227
|
});
|
|
228
|
-
return await
|
|
228
|
+
return await O(n), this.lastCopied = { text: n, timestamp: Date.now() }, n;
|
|
229
229
|
}
|
|
230
230
|
/**
|
|
231
231
|
* Copy specific rows by index to clipboard.
|
|
@@ -233,21 +233,21 @@ class wn extends x {
|
|
|
233
233
|
* @returns The copied text
|
|
234
234
|
*/
|
|
235
235
|
async copyRows(e) {
|
|
236
|
-
const t =
|
|
236
|
+
const t = V({
|
|
237
237
|
rows: this.rows,
|
|
238
238
|
columns: [...this.columns],
|
|
239
239
|
selectedIndices: e,
|
|
240
240
|
config: this.config
|
|
241
241
|
});
|
|
242
|
-
return await
|
|
242
|
+
return await O(t), this.lastCopied = { text: t, timestamp: Date.now() }, t;
|
|
243
243
|
}
|
|
244
244
|
/**
|
|
245
245
|
* Read and parse clipboard content.
|
|
246
246
|
* @returns Parsed 2D array of cell values, or null if clipboard is empty
|
|
247
247
|
*/
|
|
248
248
|
async paste() {
|
|
249
|
-
const e = await
|
|
250
|
-
return e ?
|
|
249
|
+
const e = await de();
|
|
250
|
+
return e ? ae(e, this.config) : null;
|
|
251
251
|
}
|
|
252
252
|
/**
|
|
253
253
|
* Get the last copied text and timestamp.
|
|
@@ -258,37 +258,37 @@ class wn extends x {
|
|
|
258
258
|
}
|
|
259
259
|
// #endregion
|
|
260
260
|
}
|
|
261
|
-
const
|
|
262
|
-
function
|
|
263
|
-
if (
|
|
264
|
-
return
|
|
265
|
-
if (typeof
|
|
266
|
-
return
|
|
267
|
-
const e = parseFloat(
|
|
268
|
-
return isNaN(e) ?
|
|
261
|
+
const ce = 100;
|
|
262
|
+
function ee(s) {
|
|
263
|
+
if (s == null)
|
|
264
|
+
return ce;
|
|
265
|
+
if (typeof s == "number")
|
|
266
|
+
return s;
|
|
267
|
+
const e = parseFloat(s);
|
|
268
|
+
return isNaN(e) ? ce : e;
|
|
269
269
|
}
|
|
270
|
-
function
|
|
271
|
-
return
|
|
270
|
+
function ue(s) {
|
|
271
|
+
return s.map((e) => ee(e.width));
|
|
272
272
|
}
|
|
273
|
-
function
|
|
273
|
+
function he(s) {
|
|
274
274
|
const e = [];
|
|
275
275
|
let t = 0;
|
|
276
|
-
for (const n of
|
|
277
|
-
e.push(t), t +=
|
|
276
|
+
for (const n of s)
|
|
277
|
+
e.push(t), t += ee(n.width);
|
|
278
278
|
return e;
|
|
279
279
|
}
|
|
280
|
-
function
|
|
281
|
-
return
|
|
280
|
+
function ge(s) {
|
|
281
|
+
return s.reduce((e, t) => e + ee(t.width), 0);
|
|
282
282
|
}
|
|
283
|
-
function
|
|
283
|
+
function ze(s, e, t, n, o) {
|
|
284
284
|
const i = t.length;
|
|
285
285
|
if (i === 0)
|
|
286
286
|
return { startCol: 0, endCol: 0, visibleColumns: [] };
|
|
287
|
-
let
|
|
288
|
-
|
|
289
|
-
const l =
|
|
290
|
-
let a =
|
|
291
|
-
for (let c =
|
|
287
|
+
let r = We(s, t, n);
|
|
288
|
+
r = Math.max(0, r - o);
|
|
289
|
+
const l = s + e;
|
|
290
|
+
let a = r;
|
|
291
|
+
for (let c = r; c < i; c++) {
|
|
292
292
|
if (t[c] >= l) {
|
|
293
293
|
a = c - 1;
|
|
294
294
|
break;
|
|
@@ -297,22 +297,22 @@ function Ve(r, e, t, n, o) {
|
|
|
297
297
|
}
|
|
298
298
|
a = Math.min(i - 1, a + o);
|
|
299
299
|
const d = [];
|
|
300
|
-
for (let c =
|
|
300
|
+
for (let c = r; c <= a; c++)
|
|
301
301
|
d.push(c);
|
|
302
|
-
return { startCol:
|
|
302
|
+
return { startCol: r, endCol: a, visibleColumns: d };
|
|
303
303
|
}
|
|
304
|
-
function
|
|
304
|
+
function We(s, e, t) {
|
|
305
305
|
let n = 0, o = e.length - 1;
|
|
306
306
|
for (; n < o; ) {
|
|
307
307
|
const i = Math.floor((n + o) / 2);
|
|
308
|
-
e[i] + t[i] <=
|
|
308
|
+
e[i] + t[i] <= s ? n = i + 1 : o = i;
|
|
309
309
|
}
|
|
310
310
|
return n;
|
|
311
311
|
}
|
|
312
|
-
function
|
|
313
|
-
return t ?
|
|
312
|
+
function $e(s, e, t) {
|
|
313
|
+
return t ? s > e : !1;
|
|
314
314
|
}
|
|
315
|
-
class
|
|
315
|
+
class vn extends v {
|
|
316
316
|
name = "columnVirtualization";
|
|
317
317
|
version = "1.0.0";
|
|
318
318
|
get defaultConfig() {
|
|
@@ -335,7 +335,7 @@ class bn extends x {
|
|
|
335
335
|
attach(e) {
|
|
336
336
|
super.attach(e);
|
|
337
337
|
const t = this.columns;
|
|
338
|
-
this.columnWidths =
|
|
338
|
+
this.columnWidths = ue(t), this.columnOffsets = he(t), this.totalWidth = ge(t), this.endCol = t.length - 1;
|
|
339
339
|
}
|
|
340
340
|
detach() {
|
|
341
341
|
this.columnWidths = [], this.columnOffsets = [], this.isVirtualized = !1, this.startCol = 0, this.endCol = 0, this.scrollLeft = 0, this.totalWidth = 0;
|
|
@@ -343,10 +343,10 @@ class bn extends x {
|
|
|
343
343
|
// #endregion
|
|
344
344
|
// #region Hooks
|
|
345
345
|
processColumns(e) {
|
|
346
|
-
const t =
|
|
347
|
-
if (this.isVirtualized = t ?? !1, this.columnWidths =
|
|
346
|
+
const t = $e(e.length, this.config.threshold ?? 30, this.config.autoEnable ?? !0);
|
|
347
|
+
if (this.isVirtualized = t ?? !1, this.columnWidths = ue(e), this.columnOffsets = he(e), this.totalWidth = ge(e), !t)
|
|
348
348
|
return this.startCol = 0, this.endCol = e.length - 1, [...e];
|
|
349
|
-
const n = this.grid.clientWidth || 800, o =
|
|
349
|
+
const n = this.grid.clientWidth || 800, o = ze(
|
|
350
350
|
this.scrollLeft,
|
|
351
351
|
n,
|
|
352
352
|
this.columnOffsets,
|
|
@@ -360,8 +360,8 @@ class bn extends x {
|
|
|
360
360
|
const e = this.shadowRoot;
|
|
361
361
|
if (!e) return;
|
|
362
362
|
const t = this.columnOffsets[this.startCol] ?? 0, n = e.querySelector(".header-row"), o = e.querySelectorAll(".data-grid-row");
|
|
363
|
-
n && (n.style.paddingLeft = `${t}px`), o.forEach((
|
|
364
|
-
|
|
363
|
+
n && (n.style.paddingLeft = `${t}px`), o.forEach((r) => {
|
|
364
|
+
r.style.paddingLeft = `${t}px`;
|
|
365
365
|
});
|
|
366
366
|
const i = e.querySelector(".rows-viewport .rows");
|
|
367
367
|
i && (i.style.width = `${this.totalWidth}px`);
|
|
@@ -406,77 +406,77 @@ class bn extends x {
|
|
|
406
406
|
}
|
|
407
407
|
// #endregion
|
|
408
408
|
}
|
|
409
|
-
const
|
|
410
|
-
function
|
|
411
|
-
return (typeof
|
|
409
|
+
const je = ".tbw-context-menu{position:fixed;background:light-dark(#f5f5f5,#2a2a2a);color:light-dark(#222,#eee);border:1px solid light-dark(#d0d0d4,#454545);border-radius:4px;box-shadow:0 2px 10px #00000026;min-width:160px;padding:4px 0;z-index:10000;font-size:13px;font-family:system-ui,sans-serif}.tbw-context-menu-item{display:flex;align-items:center;padding:6px 12px;cursor:pointer;gap:8px}.tbw-context-menu-item:hover:not(.disabled){background:light-dark(#e8e8e8,#3a3a3a)}.tbw-context-menu-item.disabled{opacity:.5;cursor:default}.tbw-context-menu-item.danger{color:light-dark(#c00,#f66)}.tbw-context-menu-icon{width:16px;text-align:center}.tbw-context-menu-label{flex:1}.tbw-context-menu-shortcut{color:light-dark(#888,#888);font-size:11px}.tbw-context-menu-arrow{font-size:10px;color:light-dark(#888,#888)}.tbw-context-menu-separator{height:1px;background:light-dark(#d0d0d4,#454545);margin:4px 0}";
|
|
410
|
+
function Z(s, e) {
|
|
411
|
+
return (typeof s == "function" ? s(e) : s).filter((n) => !(n.hidden === !0 || typeof n.hidden == "function" && n.hidden(e)));
|
|
412
412
|
}
|
|
413
|
-
function
|
|
414
|
-
return
|
|
413
|
+
function Ue(s, e) {
|
|
414
|
+
return s.disabled === !0 ? !0 : typeof s.disabled == "function" ? s.disabled(e) : !1;
|
|
415
415
|
}
|
|
416
|
-
function
|
|
416
|
+
function X(s, e, t, n = Ve.submenuArrow) {
|
|
417
417
|
const o = document.createElement("div");
|
|
418
418
|
o.className = "tbw-context-menu", o.setAttribute("role", "menu");
|
|
419
|
-
for (const i of
|
|
419
|
+
for (const i of s) {
|
|
420
420
|
if (i.separator) {
|
|
421
421
|
const d = document.createElement("div");
|
|
422
422
|
d.className = "tbw-context-menu-separator", d.setAttribute("role", "separator"), o.appendChild(d);
|
|
423
423
|
continue;
|
|
424
424
|
}
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
const l =
|
|
428
|
-
if (l && (
|
|
425
|
+
const r = document.createElement("div");
|
|
426
|
+
r.className = "tbw-context-menu-item", i.cssClass && r.classList.add(i.cssClass), r.setAttribute("role", "menuitem"), r.setAttribute("data-id", i.id);
|
|
427
|
+
const l = Ue(i, e);
|
|
428
|
+
if (l && (r.classList.add("disabled"), r.setAttribute("aria-disabled", "true")), i.icon) {
|
|
429
429
|
const d = document.createElement("span");
|
|
430
|
-
d.className = "tbw-context-menu-icon", d.innerHTML = i.icon,
|
|
430
|
+
d.className = "tbw-context-menu-icon", d.innerHTML = i.icon, r.appendChild(d);
|
|
431
431
|
}
|
|
432
432
|
const a = document.createElement("span");
|
|
433
|
-
if (a.className = "tbw-context-menu-label", a.textContent = i.name,
|
|
433
|
+
if (a.className = "tbw-context-menu-label", a.textContent = i.name, r.appendChild(a), i.shortcut) {
|
|
434
434
|
const d = document.createElement("span");
|
|
435
|
-
d.className = "tbw-context-menu-shortcut", d.textContent = i.shortcut,
|
|
435
|
+
d.className = "tbw-context-menu-shortcut", d.textContent = i.shortcut, r.appendChild(d);
|
|
436
436
|
}
|
|
437
437
|
if (i.subMenu?.length) {
|
|
438
438
|
const d = document.createElement("span");
|
|
439
|
-
d.className = "tbw-context-menu-arrow", typeof n == "string" ? d.innerHTML = n : n instanceof HTMLElement && d.appendChild(n.cloneNode(!0)),
|
|
440
|
-
if (
|
|
441
|
-
const u =
|
|
442
|
-
h.classList.add("tbw-context-submenu"), h.style.position = "absolute", h.style.left = "100%", h.style.top = "0",
|
|
443
|
-
}),
|
|
444
|
-
const c =
|
|
439
|
+
d.className = "tbw-context-menu-arrow", typeof n == "string" ? d.innerHTML = n : n instanceof HTMLElement && d.appendChild(n.cloneNode(!0)), r.appendChild(d), r.addEventListener("mouseenter", () => {
|
|
440
|
+
if (r.querySelector(".tbw-context-menu") || !i.subMenu) return;
|
|
441
|
+
const u = Z(i.subMenu, e), h = X(u, e, t, n);
|
|
442
|
+
h.classList.add("tbw-context-submenu"), h.style.position = "absolute", h.style.left = "100%", h.style.top = "0", r.style.position = "relative", r.appendChild(h);
|
|
443
|
+
}), r.addEventListener("mouseleave", () => {
|
|
444
|
+
const c = r.querySelector(".tbw-context-menu");
|
|
445
445
|
c && c.remove();
|
|
446
446
|
});
|
|
447
447
|
}
|
|
448
|
-
!l && i.action && !i.subMenu &&
|
|
448
|
+
!l && i.action && !i.subMenu && r.addEventListener("click", (d) => {
|
|
449
449
|
d.stopPropagation(), t(i);
|
|
450
|
-
}), o.appendChild(
|
|
450
|
+
}), o.appendChild(r);
|
|
451
451
|
}
|
|
452
452
|
return o;
|
|
453
453
|
}
|
|
454
|
-
function
|
|
455
|
-
|
|
456
|
-
const n =
|
|
457
|
-
let
|
|
458
|
-
e + n.width > o && (
|
|
454
|
+
function fe(s, e, t) {
|
|
455
|
+
s.style.position = "fixed", s.style.left = `${e}px`, s.style.top = `${t}px`, s.style.visibility = "hidden", s.style.zIndex = "10000";
|
|
456
|
+
const n = s.getBoundingClientRect(), o = window.innerWidth, i = window.innerHeight;
|
|
457
|
+
let r = e, l = t;
|
|
458
|
+
e + n.width > o && (r = e - n.width), t + n.height > i && (l = t - n.height), r = Math.max(0, r), l = Math.max(0, l), s.style.left = `${r}px`, s.style.top = `${l}px`, s.style.visibility = "visible";
|
|
459
459
|
}
|
|
460
|
-
let _ = null, I = null,
|
|
460
|
+
let _ = null, I = null, k = null, G = 0;
|
|
461
461
|
const B = [
|
|
462
462
|
{
|
|
463
463
|
id: "copy",
|
|
464
464
|
name: "Copy",
|
|
465
465
|
shortcut: "Ctrl+C",
|
|
466
|
-
action: (
|
|
467
|
-
|
|
466
|
+
action: (s) => {
|
|
467
|
+
s.grid?.plugins?.clipboard?.copy?.();
|
|
468
468
|
}
|
|
469
469
|
},
|
|
470
470
|
{ separator: !0, id: "sep1", name: "" },
|
|
471
471
|
{
|
|
472
472
|
id: "export-csv",
|
|
473
473
|
name: "Export CSV",
|
|
474
|
-
action: (
|
|
475
|
-
|
|
474
|
+
action: (s) => {
|
|
475
|
+
s.grid?.plugins?.export?.exportCsv?.();
|
|
476
476
|
}
|
|
477
477
|
}
|
|
478
478
|
];
|
|
479
|
-
class
|
|
479
|
+
class xn extends v {
|
|
480
480
|
name = "contextMenu";
|
|
481
481
|
version = "1.0.0";
|
|
482
482
|
get defaultConfig() {
|
|
@@ -492,7 +492,7 @@ class vn extends x {
|
|
|
492
492
|
// #endregion
|
|
493
493
|
// #region Lifecycle
|
|
494
494
|
attach(e) {
|
|
495
|
-
super.attach(e), this.installGlobalHandlers(),
|
|
495
|
+
super.attach(e), this.installGlobalHandlers(), G++;
|
|
496
496
|
}
|
|
497
497
|
detach() {
|
|
498
498
|
this.menuElement && (this.menuElement.remove(), this.menuElement = null), this.isOpen = !1, this.params = null, this.uninstallGlobalHandlers();
|
|
@@ -500,7 +500,7 @@ class vn extends x {
|
|
|
500
500
|
// #endregion
|
|
501
501
|
// #region Private Methods
|
|
502
502
|
installGlobalHandlers() {
|
|
503
|
-
!
|
|
503
|
+
!k && typeof document < "u" && (k = document.createElement("style"), k.id = "tbw-context-menu-styles", k.textContent = je, document.head.appendChild(k)), _ || (_ = () => {
|
|
504
504
|
document.querySelectorAll(".tbw-context-menu").forEach((t) => t.remove());
|
|
505
505
|
}, document.addEventListener("click", _)), I || (I = (e) => {
|
|
506
506
|
e.key === "Escape" && document.querySelectorAll(".tbw-context-menu").forEach((n) => n.remove());
|
|
@@ -511,7 +511,7 @@ class vn extends x {
|
|
|
511
511
|
* Uses reference counting to ensure handlers persist while any grid uses the plugin.
|
|
512
512
|
*/
|
|
513
513
|
uninstallGlobalHandlers() {
|
|
514
|
-
|
|
514
|
+
G--, !(G > 0) && (_ && (document.removeEventListener("click", _), _ = null), I && (document.removeEventListener("keydown", I), I = null), k && (k.remove(), k = null));
|
|
515
515
|
}
|
|
516
516
|
// #endregion
|
|
517
517
|
// #region Hooks
|
|
@@ -522,10 +522,10 @@ class vn extends x {
|
|
|
522
522
|
t && t.getAttribute("data-context-menu-bound") !== "true" && (t.setAttribute("data-context-menu-bound", "true"), t.addEventListener("contextmenu", (n) => {
|
|
523
523
|
const o = n;
|
|
524
524
|
o.preventDefault();
|
|
525
|
-
const i = o.target,
|
|
525
|
+
const i = o.target, r = i.closest("[data-row][data-col]"), l = i.closest(".header-cell");
|
|
526
526
|
let a;
|
|
527
|
-
if (
|
|
528
|
-
const c = parseInt(
|
|
527
|
+
if (r) {
|
|
528
|
+
const c = parseInt(r.getAttribute("data-row") ?? "-1", 10), u = parseInt(r.getAttribute("data-col") ?? "-1", 10), h = this.columns[u], g = this.rows[c];
|
|
529
529
|
a = {
|
|
530
530
|
row: g,
|
|
531
531
|
rowIndex: c,
|
|
@@ -551,15 +551,15 @@ class vn extends x {
|
|
|
551
551
|
} else
|
|
552
552
|
return;
|
|
553
553
|
this.params = a, this.position = { x: o.clientX, y: o.clientY };
|
|
554
|
-
const d =
|
|
555
|
-
d.length && (this.menuElement && this.menuElement.remove(), this.menuElement =
|
|
554
|
+
const d = Z(this.config.items ?? B, a);
|
|
555
|
+
d.length && (this.menuElement && this.menuElement.remove(), this.menuElement = X(
|
|
556
556
|
d,
|
|
557
557
|
a,
|
|
558
558
|
(c) => {
|
|
559
559
|
c.action && c.action(a), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
|
|
560
560
|
},
|
|
561
561
|
this.gridIcons.submenuArrow
|
|
562
|
-
), document.body.appendChild(this.menuElement),
|
|
562
|
+
), document.body.appendChild(this.menuElement), fe(this.menuElement, o.clientX, o.clientY), this.isOpen = !0, this.emit("context-menu-open", { params: a, items: d }));
|
|
563
563
|
}));
|
|
564
564
|
}
|
|
565
565
|
// #endregion
|
|
@@ -580,15 +580,15 @@ class vn extends x {
|
|
|
580
580
|
value: n.value ?? null,
|
|
581
581
|
isHeader: n.isHeader ?? !1,
|
|
582
582
|
event: n.event ?? new MouseEvent("contextmenu")
|
|
583
|
-
}, i =
|
|
584
|
-
this.menuElement && this.menuElement.remove(), this.menuElement =
|
|
583
|
+
}, i = Z(this.config.items ?? B, o);
|
|
584
|
+
this.menuElement && this.menuElement.remove(), this.menuElement = X(
|
|
585
585
|
i,
|
|
586
586
|
o,
|
|
587
|
-
(
|
|
588
|
-
|
|
587
|
+
(r) => {
|
|
588
|
+
r.action && r.action(o), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
|
|
589
589
|
},
|
|
590
590
|
this.gridIcons.submenuArrow
|
|
591
|
-
), document.body.appendChild(this.menuElement),
|
|
591
|
+
), document.body.appendChild(this.menuElement), fe(this.menuElement, e, t), this.isOpen = !0;
|
|
592
592
|
}
|
|
593
593
|
/**
|
|
594
594
|
* Hide the context menu.
|
|
@@ -606,45 +606,45 @@ class vn extends x {
|
|
|
606
606
|
// #endregion
|
|
607
607
|
// Styles are injected globally via installGlobalHandlers() since menu renders in document.body
|
|
608
608
|
}
|
|
609
|
-
function pe(
|
|
610
|
-
if (
|
|
611
|
-
if (
|
|
612
|
-
if (typeof
|
|
613
|
-
const t = String(
|
|
609
|
+
function pe(s, e = !0) {
|
|
610
|
+
if (s == null) return "";
|
|
611
|
+
if (s instanceof Date) return s.toISOString();
|
|
612
|
+
if (typeof s == "object") return JSON.stringify(s);
|
|
613
|
+
const t = String(s);
|
|
614
614
|
return e && (t.includes(",") || t.includes('"') || t.includes(`
|
|
615
615
|
`) || t.includes("\r")) ? `"${t.replace(/"/g, '""')}"` : t;
|
|
616
616
|
}
|
|
617
|
-
function
|
|
617
|
+
function Ye(s, e, t, n = {}) {
|
|
618
618
|
const o = n.delimiter ?? ",", i = n.newline ?? `
|
|
619
|
-
`,
|
|
619
|
+
`, r = [], l = n.bom ? "\uFEFF" : "";
|
|
620
620
|
if (t.includeHeaders !== !1) {
|
|
621
621
|
const a = e.map((d) => {
|
|
622
622
|
const c = d.header || d.field, u = t.processHeader ? t.processHeader(c, d.field) : c;
|
|
623
623
|
return pe(u);
|
|
624
624
|
});
|
|
625
|
-
|
|
625
|
+
r.push(a.join(o));
|
|
626
626
|
}
|
|
627
|
-
for (const a of
|
|
627
|
+
for (const a of s) {
|
|
628
628
|
const d = e.map((c) => {
|
|
629
629
|
let u = a[c.field];
|
|
630
630
|
return t.processCell && (u = t.processCell(u, c.field, a)), pe(u);
|
|
631
631
|
});
|
|
632
|
-
|
|
632
|
+
r.push(d.join(o));
|
|
633
633
|
}
|
|
634
|
-
return l +
|
|
634
|
+
return l + r.join(i);
|
|
635
635
|
}
|
|
636
|
-
function
|
|
637
|
-
const t = URL.createObjectURL(
|
|
636
|
+
function te(s, e) {
|
|
637
|
+
const t = URL.createObjectURL(s), n = document.createElement("a");
|
|
638
638
|
n.href = t, n.download = e, n.style.display = "none", document.body.appendChild(n), n.click(), document.body.removeChild(n), URL.revokeObjectURL(t);
|
|
639
639
|
}
|
|
640
|
-
function
|
|
641
|
-
const t = new Blob([
|
|
642
|
-
|
|
640
|
+
function Ze(s, e) {
|
|
641
|
+
const t = new Blob([s], { type: "text/csv;charset=utf-8;" });
|
|
642
|
+
te(t, e);
|
|
643
643
|
}
|
|
644
|
-
function
|
|
645
|
-
return
|
|
644
|
+
function me(s) {
|
|
645
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
646
646
|
}
|
|
647
|
-
function
|
|
647
|
+
function Xe(s, e, t) {
|
|
648
648
|
let n = `<?xml version="1.0" encoding="UTF-8"?>
|
|
649
649
|
<?mso-application progid="Excel.Sheet"?>
|
|
650
650
|
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
|
@@ -655,19 +655,19 @@ function Ze(r, e, t) {
|
|
|
655
655
|
n += `
|
|
656
656
|
<Row>`;
|
|
657
657
|
for (const o of e) {
|
|
658
|
-
const i = o.header || o.field,
|
|
659
|
-
n += `<Cell><Data ss:Type="String">${
|
|
658
|
+
const i = o.header || o.field, r = t.processHeader ? t.processHeader(i, o.field) : i;
|
|
659
|
+
n += `<Cell><Data ss:Type="String">${me(r)}</Data></Cell>`;
|
|
660
660
|
}
|
|
661
661
|
n += "</Row>";
|
|
662
662
|
}
|
|
663
|
-
for (const o of
|
|
663
|
+
for (const o of s) {
|
|
664
664
|
n += `
|
|
665
665
|
<Row>`;
|
|
666
666
|
for (const i of e) {
|
|
667
|
-
let
|
|
668
|
-
t.processCell && (
|
|
667
|
+
let r = o[i.field];
|
|
668
|
+
t.processCell && (r = t.processCell(r, i.field, o));
|
|
669
669
|
let l = "String", a = "";
|
|
670
|
-
|
|
670
|
+
r == null ? a = "" : typeof r == "number" && !isNaN(r) ? (l = "Number", a = String(r)) : r instanceof Date ? (l = "DateTime", a = r.toISOString()) : a = me(String(r)), n += `<Cell><Data ss:Type="${l}">${a}</Data></Cell>`;
|
|
671
671
|
}
|
|
672
672
|
n += "</Row>";
|
|
673
673
|
}
|
|
@@ -676,13 +676,13 @@ function Ze(r, e, t) {
|
|
|
676
676
|
</Worksheet>
|
|
677
677
|
</Workbook>`, n;
|
|
678
678
|
}
|
|
679
|
-
function
|
|
680
|
-
const t = e.endsWith(".xls") ? e : `${e}.xls`, n = new Blob([
|
|
679
|
+
function Je(s, e) {
|
|
680
|
+
const t = e.endsWith(".xls") ? e : `${e}.xls`, n = new Blob([s], {
|
|
681
681
|
type: "application/vnd.ms-excel;charset=utf-8;"
|
|
682
682
|
});
|
|
683
|
-
|
|
683
|
+
te(n, t);
|
|
684
684
|
}
|
|
685
|
-
class
|
|
685
|
+
class yn extends v {
|
|
686
686
|
name = "export";
|
|
687
687
|
version = "1.0.0";
|
|
688
688
|
get defaultConfig() {
|
|
@@ -713,44 +713,44 @@ class xn extends x {
|
|
|
713
713
|
const a = new Set(t.columns);
|
|
714
714
|
i = i.filter((d) => a.has(d.field));
|
|
715
715
|
}
|
|
716
|
-
let
|
|
716
|
+
let r = [...this.rows];
|
|
717
717
|
if (n.onlySelected) {
|
|
718
718
|
const a = this.getSelectionState();
|
|
719
|
-
a?.selected?.size && (
|
|
719
|
+
a?.selected?.size && (r = [...a.selected].sort((c, u) => c - u).map((c) => this.rows[c]).filter(Boolean));
|
|
720
720
|
}
|
|
721
|
-
t?.rowIndices && (
|
|
721
|
+
t?.rowIndices && (r = t.rowIndices.map((a) => this.rows[a]).filter(Boolean)), this.isExportingFlag = !0;
|
|
722
722
|
let l = o.fileName;
|
|
723
723
|
try {
|
|
724
724
|
switch (e) {
|
|
725
725
|
case "csv": {
|
|
726
|
-
const a =
|
|
727
|
-
l = l.endsWith(".csv") ? l : `${l}.csv`,
|
|
726
|
+
const a = Ye(r, i, o, { bom: !0 });
|
|
727
|
+
l = l.endsWith(".csv") ? l : `${l}.csv`, Ze(a, l);
|
|
728
728
|
break;
|
|
729
729
|
}
|
|
730
730
|
case "excel": {
|
|
731
|
-
const a =
|
|
732
|
-
l = l.endsWith(".xls") ? l : `${l}.xls`,
|
|
731
|
+
const a = Xe(r, i, o);
|
|
732
|
+
l = l.endsWith(".xls") ? l : `${l}.xls`, Je(a, l);
|
|
733
733
|
break;
|
|
734
734
|
}
|
|
735
735
|
case "json": {
|
|
736
|
-
const a =
|
|
736
|
+
const a = r.map((u) => {
|
|
737
737
|
const h = {};
|
|
738
738
|
for (const g of i) {
|
|
739
|
-
let
|
|
740
|
-
o.processCell && (
|
|
739
|
+
let f = u[g.field];
|
|
740
|
+
o.processCell && (f = o.processCell(f, g.field, u)), h[g.field] = f;
|
|
741
741
|
}
|
|
742
742
|
return h;
|
|
743
743
|
}), d = JSON.stringify(a, null, 2);
|
|
744
744
|
l = l.endsWith(".json") ? l : `${l}.json`;
|
|
745
745
|
const c = new Blob([d], { type: "application/json" });
|
|
746
|
-
|
|
746
|
+
te(c, l);
|
|
747
747
|
break;
|
|
748
748
|
}
|
|
749
749
|
}
|
|
750
750
|
this.lastExportInfo = { format: e, timestamp: /* @__PURE__ */ new Date() }, this.emit("export-complete", {
|
|
751
751
|
format: e,
|
|
752
752
|
fileName: l,
|
|
753
|
-
rowCount:
|
|
753
|
+
rowCount: r.length,
|
|
754
754
|
columnCount: i.length
|
|
755
755
|
});
|
|
756
756
|
} finally {
|
|
@@ -803,43 +803,43 @@ class xn extends x {
|
|
|
803
803
|
}
|
|
804
804
|
// #endregion
|
|
805
805
|
}
|
|
806
|
-
function
|
|
807
|
-
const { totalRows: e, viewportHeight: t, scrollTop: n, rowHeight: o, overscan: i } =
|
|
806
|
+
function Qe(s) {
|
|
807
|
+
const { totalRows: e, viewportHeight: t, scrollTop: n, rowHeight: o, overscan: i } = s, r = Math.ceil(t / o);
|
|
808
808
|
let l = Math.floor(n / o) - i;
|
|
809
809
|
l < 0 && (l = 0);
|
|
810
|
-
let a = l +
|
|
811
|
-
return a > e && (a = e), a === e && l > 0 && (l = Math.max(0, a -
|
|
810
|
+
let a = l + r + i * 2;
|
|
811
|
+
return a > e && (a = e), a === e && l > 0 && (l = Math.max(0, a - r - i * 2)), {
|
|
812
812
|
start: l,
|
|
813
813
|
end: a,
|
|
814
814
|
offsetY: l * o,
|
|
815
815
|
totalHeight: e * o
|
|
816
816
|
};
|
|
817
817
|
}
|
|
818
|
-
function
|
|
819
|
-
return
|
|
818
|
+
function et(s, e) {
|
|
819
|
+
return s <= e;
|
|
820
820
|
}
|
|
821
|
-
function
|
|
822
|
-
const n =
|
|
821
|
+
function tt(s, e, t = !1) {
|
|
822
|
+
const n = s[e.field];
|
|
823
823
|
if (e.operator === "blank")
|
|
824
824
|
return n == null || n === "";
|
|
825
825
|
if (e.operator === "notBlank")
|
|
826
826
|
return n != null && n !== "";
|
|
827
827
|
if (n == null) return !1;
|
|
828
|
-
const o = String(n), i = t ? o : o.toLowerCase(),
|
|
828
|
+
const o = String(n), i = t ? o : o.toLowerCase(), r = t ? String(e.value) : String(e.value).toLowerCase();
|
|
829
829
|
switch (e.operator) {
|
|
830
830
|
// Text operators
|
|
831
831
|
case "contains":
|
|
832
|
-
return i.includes(
|
|
832
|
+
return i.includes(r);
|
|
833
833
|
case "notContains":
|
|
834
|
-
return !i.includes(
|
|
834
|
+
return !i.includes(r);
|
|
835
835
|
case "equals":
|
|
836
|
-
return i ===
|
|
836
|
+
return i === r;
|
|
837
837
|
case "notEquals":
|
|
838
|
-
return i !==
|
|
838
|
+
return i !== r;
|
|
839
839
|
case "startsWith":
|
|
840
|
-
return i.startsWith(
|
|
840
|
+
return i.startsWith(r);
|
|
841
841
|
case "endsWith":
|
|
842
|
-
return i.endsWith(
|
|
842
|
+
return i.endsWith(r);
|
|
843
843
|
// Number/Date operators (use raw numeric values)
|
|
844
844
|
case "lessThan":
|
|
845
845
|
return Number(n) < Number(e.value);
|
|
@@ -860,12 +860,12 @@ function et(r, e, t = !1) {
|
|
|
860
860
|
return !0;
|
|
861
861
|
}
|
|
862
862
|
}
|
|
863
|
-
function
|
|
864
|
-
return e.length ?
|
|
863
|
+
function nt(s, e, t = !1) {
|
|
864
|
+
return e.length ? s.filter((n) => e.every((o) => tt(n, o, t))) : s;
|
|
865
865
|
}
|
|
866
|
-
function
|
|
866
|
+
function ot(s) {
|
|
867
867
|
return JSON.stringify(
|
|
868
|
-
|
|
868
|
+
s.map((e) => ({
|
|
869
869
|
field: e.field,
|
|
870
870
|
operator: e.operator,
|
|
871
871
|
value: e.value,
|
|
@@ -873,16 +873,16 @@ function nt(r) {
|
|
|
873
873
|
}))
|
|
874
874
|
);
|
|
875
875
|
}
|
|
876
|
-
function
|
|
876
|
+
function we(s, e) {
|
|
877
877
|
const t = /* @__PURE__ */ new Set();
|
|
878
|
-
for (const n of
|
|
878
|
+
for (const n of s) {
|
|
879
879
|
const o = n[e];
|
|
880
880
|
o != null && t.add(o);
|
|
881
881
|
}
|
|
882
882
|
return [...t].sort((n, o) => typeof n == "number" && typeof o == "number" ? n - o : String(n).localeCompare(String(o)));
|
|
883
883
|
}
|
|
884
|
-
const
|
|
885
|
-
class A extends
|
|
884
|
+
const it = '.header-cell.filtered:before{content:"";position:absolute;top:4px;right:4px;width:6px;height:6px;background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));border-radius:50%}.tbw-filter-btn{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:2px;margin-left:4px;opacity:.4;transition:opacity .15s;color:inherit;vertical-align:middle}.tbw-filter-btn:hover,.tbw-filter-btn.active{opacity:1}.tbw-filter-btn.active{color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}', rt = ".tbw-filter-panel{position:fixed;background:var(--tbw-filter-panel-bg, var(--tbw-color-panel-bg, light-dark(#eeeeee, #222222)));color:var(--tbw-filter-panel-fg, var(--tbw-color-fg, light-dark(#222222, #eeeeee)));border:1px solid var(--tbw-filter-panel-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:var(--tbw-filter-panel-radius, var(--tbw-border-radius, 4px));box-shadow:0 4px 16px var(--tbw-filter-panel-shadow, var(--tbw-color-shadow, light-dark(rgba(0, 0, 0, .1), rgba(0, 0, 0, .3))));padding:12px;z-index:10000;min-width:200px;max-width:280px;max-height:350px;display:flex;flex-direction:column;font-family:var(--tbw-font-family, system-ui, sans-serif);font-size:var(--tbw-font-size, 13px)}.tbw-filter-search{margin-bottom:8px}.tbw-filter-search-input{width:100%;padding:6px 10px;background:var(--tbw-filter-input-bg, var(--tbw-color-bg, transparent));color:inherit;border:1px solid var(--tbw-filter-input-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:var(--tbw-filter-input-radius, 4px);font-size:inherit;box-sizing:border-box}.tbw-filter-search-input:focus{outline:none;border-color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));box-shadow:0 0 0 2px rgba(from var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6)) r g b / 15%)}.tbw-filter-actions{display:flex;padding:4px 2px;margin-bottom:8px;border-bottom:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-action-btn{background:transparent;border:none;color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));cursor:pointer;font-size:12px;padding:2px 0}.tbw-filter-action-btn:hover{text-decoration:underline}.tbw-filter-values{flex:1;overflow-y:auto;margin-bottom:8px;max-height:180px;position:relative}.tbw-filter-values-spacer{width:1px}.tbw-filter-values-content{position:absolute;top:0;left:0;right:0}.tbw-filter-value-item{display:flex;align-items:center;gap:8px;padding:4px 2px;cursor:pointer;border-radius:3px}.tbw-filter-value-item:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}.tbw-filter-checkbox{margin:0;cursor:pointer;accent-color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}.tbw-filter-no-match{color:var(--tbw-filter-muted, var(--tbw-color-fg-muted, light-dark(#555555, #aaaaaa)));padding:8px 0;text-align:center;font-style:italic}.tbw-filter-buttons{display:flex;gap:8px;padding-top:8px;border-top:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-apply-btn{flex:1;padding:6px 12px;background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));color:var(--tbw-filter-accent-fg, var(--tbw-color-accent-fg, light-dark(#ffffff, #000000)));border:none;border-radius:4px;cursor:pointer;font-size:13px}.tbw-filter-apply-btn:hover{filter:brightness(.9)}.tbw-filter-clear-btn{flex:1;padding:6px 12px;background:transparent;color:var(--tbw-filter-muted, var(--tbw-color-fg-muted, light-dark(#555555, #aaaaaa)));border:1px solid var(--tbw-filter-input-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:4px;cursor:pointer;font-size:13px}.tbw-filter-clear-btn:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}";
|
|
885
|
+
class A extends v {
|
|
886
886
|
name = "filtering";
|
|
887
887
|
version = "1.0.0";
|
|
888
888
|
get defaultConfig() {
|
|
@@ -922,10 +922,12 @@ class A extends x {
|
|
|
922
922
|
processRows(e) {
|
|
923
923
|
const t = [...this.filters.values()];
|
|
924
924
|
if (!t.length) return [...e];
|
|
925
|
-
|
|
925
|
+
if (this.config.filterHandler)
|
|
926
|
+
return this.cachedResult ? this.cachedResult : [...e];
|
|
927
|
+
const n = ot(t);
|
|
926
928
|
if (this.cacheKey === n && this.cachedResult)
|
|
927
929
|
return this.cachedResult;
|
|
928
|
-
const o =
|
|
930
|
+
const o = nt([...e], t, this.config.caseSensitive);
|
|
929
931
|
return this.cachedResult = o, this.cacheKey = n, o;
|
|
930
932
|
}
|
|
931
933
|
afterRender() {
|
|
@@ -934,14 +936,19 @@ class A extends x {
|
|
|
934
936
|
e.querySelectorAll('[part~="header-cell"]').forEach((n) => {
|
|
935
937
|
const o = n.getAttribute("data-col");
|
|
936
938
|
if (o === null) return;
|
|
937
|
-
const i = this.
|
|
938
|
-
if (!i || i.filterable === !1
|
|
939
|
-
const
|
|
940
|
-
if (!
|
|
941
|
-
const l =
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
939
|
+
const i = this.visibleColumns[parseInt(o, 10)];
|
|
940
|
+
if (!i || i.filterable === !1) return;
|
|
941
|
+
const r = i.field;
|
|
942
|
+
if (!r) return;
|
|
943
|
+
const l = this.filters.has(r);
|
|
944
|
+
let a = n.querySelector(".tbw-filter-btn");
|
|
945
|
+
if (a) {
|
|
946
|
+
a.classList.toggle("active", l), n.classList.toggle("filtered", l);
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
a = document.createElement("button"), a.className = "tbw-filter-btn", a.setAttribute("aria-label", `Filter ${i.header ?? r}`), a.innerHTML = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', l && (a.classList.add("active"), n.classList.add("filtered")), a.addEventListener("click", (d) => {
|
|
950
|
+
d.stopPropagation(), this.toggleFilterPanel(r, i, a);
|
|
951
|
+
}), n.appendChild(a);
|
|
945
952
|
});
|
|
946
953
|
}
|
|
947
954
|
// #endregion
|
|
@@ -951,7 +958,7 @@ class A extends x {
|
|
|
951
958
|
* Pass null to remove the filter.
|
|
952
959
|
*/
|
|
953
960
|
setFilter(e, t) {
|
|
954
|
-
t === null ? this.filters.delete(e) : this.filters.set(e, { ...t, field: e }), this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
|
|
961
|
+
t === null ? (this.filters.delete(e), this.excludedValues.delete(e)) : (this.filters.set(e, { ...t, field: e }), t.type === "set" && t.operator === "notIn" && Array.isArray(t.value) ? this.excludedValues.set(e, new Set(t.value)) : t.type === "set" && this.excludedValues.delete(e)), this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
|
|
955
962
|
filters: [...this.filters.values()],
|
|
956
963
|
filteredRowCount: 0
|
|
957
964
|
// Will be accurate after processRows
|
|
@@ -979,9 +986,9 @@ class A extends x {
|
|
|
979
986
|
* Set filters from an array (replaces all existing filters).
|
|
980
987
|
*/
|
|
981
988
|
setFilterModel(e) {
|
|
982
|
-
this.filters.clear();
|
|
989
|
+
this.filters.clear(), this.excludedValues.clear();
|
|
983
990
|
for (const t of e)
|
|
984
|
-
this.filters.set(t.field, t);
|
|
991
|
+
this.filters.set(t.field, t), t.type === "set" && t.operator === "notIn" && Array.isArray(t.value) && this.excludedValues.set(t.field, new Set(t.value));
|
|
985
992
|
this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
|
|
986
993
|
filters: [...this.filters.values()],
|
|
987
994
|
filteredRowCount: 0
|
|
@@ -991,19 +998,13 @@ class A extends x {
|
|
|
991
998
|
* Clear all filters.
|
|
992
999
|
*/
|
|
993
1000
|
clearAllFilters() {
|
|
994
|
-
this.filters.clear(), this.excludedValues.clear(), this.searchText.clear(), this.
|
|
995
|
-
filters: [],
|
|
996
|
-
filteredRowCount: this.rows.length
|
|
997
|
-
}), this.requestRender();
|
|
1001
|
+
this.filters.clear(), this.excludedValues.clear(), this.searchText.clear(), this.applyFiltersInternal();
|
|
998
1002
|
}
|
|
999
1003
|
/**
|
|
1000
1004
|
* Clear filter for a specific field.
|
|
1001
1005
|
*/
|
|
1002
1006
|
clearFieldFilter(e) {
|
|
1003
|
-
this.filters.delete(e), this.excludedValues.delete(e), this.searchText.delete(e), this.
|
|
1004
|
-
filters: [...this.filters.values()],
|
|
1005
|
-
filteredRowCount: 0
|
|
1006
|
-
}), this.requestRender();
|
|
1007
|
+
this.filters.delete(e), this.excludedValues.delete(e), this.searchText.delete(e), this.applyFiltersInternal();
|
|
1007
1008
|
}
|
|
1008
1009
|
/**
|
|
1009
1010
|
* Check if a field has an active filter.
|
|
@@ -1028,7 +1029,7 @@ class A extends x {
|
|
|
1028
1029
|
* Uses sourceRows to include all values regardless of current filter.
|
|
1029
1030
|
*/
|
|
1030
1031
|
getUniqueValues(e) {
|
|
1031
|
-
return
|
|
1032
|
+
return we(this.sourceRows, e);
|
|
1032
1033
|
}
|
|
1033
1034
|
// #endregion
|
|
1034
1035
|
// #region Private Methods
|
|
@@ -1042,7 +1043,7 @@ class A extends x {
|
|
|
1042
1043
|
return;
|
|
1043
1044
|
}
|
|
1044
1045
|
const e = document.createElement("style");
|
|
1045
|
-
e.id = "tbw-filter-panel-styles", e.textContent =
|
|
1046
|
+
e.id = "tbw-filter-panel-styles", e.textContent = rt, document.head.appendChild(e), this.globalStylesInjected = !0;
|
|
1046
1047
|
}
|
|
1047
1048
|
/**
|
|
1048
1049
|
* Toggle the filter panel for a field
|
|
@@ -1054,33 +1055,50 @@ class A extends x {
|
|
|
1054
1055
|
}
|
|
1055
1056
|
this.closeFilterPanel();
|
|
1056
1057
|
const o = document.createElement("div");
|
|
1057
|
-
o.className = "tbw-filter-panel", this.panelElement = o, this.openPanelField = e
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1058
|
+
if (o.className = "tbw-filter-panel", this.panelElement = o, this.openPanelField = e, this.config.valuesHandler) {
|
|
1059
|
+
o.innerHTML = '<div class="tbw-filter-loading">Loading...</div>', document.body.appendChild(o), this.positionPanel(o, n), this.setupPanelCloseHandler(o, n), this.config.valuesHandler(e, t).then((r) => {
|
|
1060
|
+
this.openPanelField !== e || !this.panelElement || (o.innerHTML = "", this.renderPanelContent(e, t, o, r));
|
|
1061
|
+
});
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
const i = we(this.sourceRows, e);
|
|
1065
|
+
this.renderPanelContent(e, t, o, i), document.body.appendChild(o), this.positionPanel(o, n), this.setupPanelCloseHandler(o, n);
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Render filter panel content with given values
|
|
1069
|
+
*/
|
|
1070
|
+
renderPanelContent(e, t, n, o) {
|
|
1071
|
+
let i = this.excludedValues.get(e);
|
|
1072
|
+
i || (i = /* @__PURE__ */ new Set(), this.excludedValues.set(e, i));
|
|
1073
|
+
const r = this.searchText.get(e) ?? "", l = {
|
|
1062
1074
|
field: e,
|
|
1063
1075
|
column: t,
|
|
1064
|
-
uniqueValues:
|
|
1065
|
-
excludedValues:
|
|
1066
|
-
searchText:
|
|
1067
|
-
applySetFilter: (
|
|
1068
|
-
this.applySetFilter(e,
|
|
1076
|
+
uniqueValues: o,
|
|
1077
|
+
excludedValues: i,
|
|
1078
|
+
searchText: r,
|
|
1079
|
+
applySetFilter: (d) => {
|
|
1080
|
+
this.applySetFilter(e, d), this.closeFilterPanel();
|
|
1069
1081
|
},
|
|
1070
|
-
applyTextFilter: (c, u
|
|
1071
|
-
this.applyTextFilter(e, c, u
|
|
1082
|
+
applyTextFilter: (d, c, u) => {
|
|
1083
|
+
this.applyTextFilter(e, d, c, u), this.closeFilterPanel();
|
|
1072
1084
|
},
|
|
1073
1085
|
clearFilter: () => {
|
|
1074
1086
|
this.clearFieldFilter(e), this.closeFilterPanel();
|
|
1075
1087
|
},
|
|
1076
1088
|
closePanel: () => this.closeFilterPanel()
|
|
1077
1089
|
};
|
|
1078
|
-
let
|
|
1079
|
-
this.config.filterPanelRenderer && (this.config.filterPanelRenderer(
|
|
1090
|
+
let a = !1;
|
|
1091
|
+
this.config.filterPanelRenderer && (this.config.filterPanelRenderer(n, l), a = n.children.length > 0), a || this.renderDefaultFilterPanel(n, l, o, i);
|
|
1092
|
+
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Setup click-outside handler to close the panel
|
|
1095
|
+
*/
|
|
1096
|
+
setupPanelCloseHandler(e, t) {
|
|
1097
|
+
this.panelAbortController = new AbortController(), setTimeout(() => {
|
|
1080
1098
|
document.addEventListener(
|
|
1081
1099
|
"click",
|
|
1082
|
-
(
|
|
1083
|
-
!
|
|
1100
|
+
(n) => {
|
|
1101
|
+
!e.contains(n.target) && n.target !== t && this.closeFilterPanel();
|
|
1084
1102
|
},
|
|
1085
1103
|
{ signal: this.panelAbortController?.signal }
|
|
1086
1104
|
);
|
|
@@ -1106,10 +1124,10 @@ class A extends x {
|
|
|
1106
1124
|
* Render the default filter panel content
|
|
1107
1125
|
*/
|
|
1108
1126
|
renderDefaultFilterPanel(e, t, n, o) {
|
|
1109
|
-
const { field: i } = t,
|
|
1110
|
-
|
|
1127
|
+
const { field: i } = t, r = document.createElement("div");
|
|
1128
|
+
r.className = "tbw-filter-search";
|
|
1111
1129
|
const l = document.createElement("input");
|
|
1112
|
-
l.type = "text", l.placeholder = "Search...", l.className = "tbw-filter-search-input", l.value = this.searchText.get(i) ?? "",
|
|
1130
|
+
l.type = "text", l.placeholder = "Search...", l.className = "tbw-filter-search-input", l.value = this.searchText.get(i) ?? "", r.appendChild(l), e.appendChild(r);
|
|
1113
1131
|
const a = document.createElement("div");
|
|
1114
1132
|
a.className = "tbw-filter-actions";
|
|
1115
1133
|
const d = document.createElement("label");
|
|
@@ -1119,71 +1137,71 @@ class A extends x {
|
|
|
1119
1137
|
const u = document.createElement("span");
|
|
1120
1138
|
u.textContent = "Select All", d.appendChild(c), d.appendChild(u), a.appendChild(d);
|
|
1121
1139
|
const h = () => {
|
|
1122
|
-
const
|
|
1123
|
-
c.checked =
|
|
1140
|
+
const w = [...p.values()], y = w.every((x) => x), C = w.every((x) => !x);
|
|
1141
|
+
c.checked = y, c.indeterminate = !y && !C;
|
|
1124
1142
|
};
|
|
1125
1143
|
c.addEventListener("change", () => {
|
|
1126
|
-
const
|
|
1127
|
-
for (const
|
|
1128
|
-
|
|
1129
|
-
h(),
|
|
1144
|
+
const w = c.checked;
|
|
1145
|
+
for (const y of p.keys())
|
|
1146
|
+
p.set(y, w);
|
|
1147
|
+
h(), H();
|
|
1130
1148
|
}), e.appendChild(a);
|
|
1131
1149
|
const g = document.createElement("div");
|
|
1132
1150
|
g.className = "tbw-filter-values";
|
|
1133
|
-
const p = document.createElement("div");
|
|
1134
|
-
p.className = "tbw-filter-values-spacer", g.appendChild(p);
|
|
1135
1151
|
const f = document.createElement("div");
|
|
1136
|
-
f.className = "tbw-filter-values-
|
|
1137
|
-
const m =
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1152
|
+
f.className = "tbw-filter-values-spacer", g.appendChild(f);
|
|
1153
|
+
const m = document.createElement("div");
|
|
1154
|
+
m.className = "tbw-filter-values-content", g.appendChild(m);
|
|
1155
|
+
const p = /* @__PURE__ */ new Map();
|
|
1156
|
+
n.forEach((w) => {
|
|
1157
|
+
const y = w == null ? "__null__" : String(w);
|
|
1158
|
+
p.set(y, !o.has(w));
|
|
1141
1159
|
}), h();
|
|
1142
|
-
let
|
|
1143
|
-
const
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1160
|
+
let R = [];
|
|
1161
|
+
const E = (w, y) => {
|
|
1162
|
+
const C = w == null ? "(Blank)" : String(w), x = w == null ? "__null__" : String(w), b = document.createElement("label");
|
|
1163
|
+
b.className = "tbw-filter-value-item", b.style.position = "absolute", b.style.top = `${y * A.LIST_ITEM_HEIGHT}px`, b.style.left = "0", b.style.right = "0", b.style.height = `${A.LIST_ITEM_HEIGHT}px`, b.style.boxSizing = "border-box";
|
|
1146
1164
|
const S = document.createElement("input");
|
|
1147
|
-
S.type = "checkbox", S.className = "tbw-filter-checkbox", S.checked =
|
|
1148
|
-
|
|
1165
|
+
S.type = "checkbox", S.className = "tbw-filter-checkbox", S.checked = p.get(x) ?? !0, S.dataset.value = x, S.addEventListener("change", () => {
|
|
1166
|
+
p.set(x, S.checked), h();
|
|
1149
1167
|
});
|
|
1150
1168
|
const re = document.createElement("span");
|
|
1151
|
-
return re.textContent =
|
|
1152
|
-
},
|
|
1153
|
-
const
|
|
1154
|
-
if (
|
|
1155
|
-
|
|
1156
|
-
|
|
1169
|
+
return re.textContent = C, b.appendChild(S), b.appendChild(re), b;
|
|
1170
|
+
}, H = () => {
|
|
1171
|
+
const w = R.length, y = g.clientHeight, C = g.scrollTop;
|
|
1172
|
+
if (f.style.height = `${w * A.LIST_ITEM_HEIGHT}px`, et(w, A.LIST_BYPASS_THRESHOLD / 3)) {
|
|
1173
|
+
m.innerHTML = "", m.style.transform = "translateY(0px)", R.forEach((b, S) => {
|
|
1174
|
+
m.appendChild(E(b, S));
|
|
1157
1175
|
});
|
|
1158
1176
|
return;
|
|
1159
1177
|
}
|
|
1160
|
-
const
|
|
1161
|
-
totalRows:
|
|
1162
|
-
viewportHeight:
|
|
1163
|
-
scrollTop:
|
|
1178
|
+
const x = Qe({
|
|
1179
|
+
totalRows: w,
|
|
1180
|
+
viewportHeight: y,
|
|
1181
|
+
scrollTop: C,
|
|
1164
1182
|
rowHeight: A.LIST_ITEM_HEIGHT,
|
|
1165
1183
|
overscan: A.LIST_OVERSCAN
|
|
1166
1184
|
});
|
|
1167
|
-
|
|
1168
|
-
for (let
|
|
1169
|
-
|
|
1170
|
-
}, oe = (
|
|
1171
|
-
const
|
|
1172
|
-
if (
|
|
1173
|
-
const
|
|
1174
|
-
return !
|
|
1175
|
-
}),
|
|
1176
|
-
|
|
1177
|
-
const
|
|
1178
|
-
|
|
1185
|
+
m.style.transform = `translateY(${x.offsetY}px)`, m.innerHTML = "";
|
|
1186
|
+
for (let b = x.start; b < x.end; b++)
|
|
1187
|
+
m.appendChild(E(R[b], b - x.start));
|
|
1188
|
+
}, oe = (w) => {
|
|
1189
|
+
const y = w.toLowerCase();
|
|
1190
|
+
if (R = n.filter((C) => {
|
|
1191
|
+
const x = C == null ? "(Blank)" : String(C);
|
|
1192
|
+
return !w || x.toLowerCase().includes(y);
|
|
1193
|
+
}), R.length === 0) {
|
|
1194
|
+
f.style.height = "0px", m.innerHTML = "";
|
|
1195
|
+
const C = document.createElement("div");
|
|
1196
|
+
C.className = "tbw-filter-no-match", C.textContent = "No matching values", m.appendChild(C);
|
|
1179
1197
|
return;
|
|
1180
1198
|
}
|
|
1181
|
-
|
|
1199
|
+
H();
|
|
1182
1200
|
};
|
|
1183
1201
|
g.addEventListener(
|
|
1184
1202
|
"scroll",
|
|
1185
1203
|
() => {
|
|
1186
|
-
|
|
1204
|
+
R.length > 0 && H();
|
|
1187
1205
|
},
|
|
1188
1206
|
{ passive: !0 }
|
|
1189
1207
|
), oe(l.value), e.appendChild(g);
|
|
@@ -1193,25 +1211,25 @@ class A extends x {
|
|
|
1193
1211
|
this.searchText.set(i, l.value), oe(l.value);
|
|
1194
1212
|
}, this.config.debounceMs ?? 150);
|
|
1195
1213
|
});
|
|
1196
|
-
const
|
|
1197
|
-
|
|
1198
|
-
const
|
|
1199
|
-
|
|
1200
|
-
const
|
|
1201
|
-
for (const [
|
|
1202
|
-
if (!
|
|
1203
|
-
if (
|
|
1204
|
-
|
|
1214
|
+
const P = document.createElement("div");
|
|
1215
|
+
P.className = "tbw-filter-buttons";
|
|
1216
|
+
const M = document.createElement("button");
|
|
1217
|
+
M.className = "tbw-filter-apply-btn", M.textContent = "Apply", M.addEventListener("click", () => {
|
|
1218
|
+
const w = [];
|
|
1219
|
+
for (const [y, C] of p)
|
|
1220
|
+
if (!C)
|
|
1221
|
+
if (y === "__null__")
|
|
1222
|
+
w.push(null);
|
|
1205
1223
|
else {
|
|
1206
|
-
const
|
|
1207
|
-
|
|
1224
|
+
const x = n.find((b) => String(b) === y);
|
|
1225
|
+
w.push(x !== void 0 ? x : y);
|
|
1208
1226
|
}
|
|
1209
|
-
t.applySetFilter(
|
|
1210
|
-
}),
|
|
1211
|
-
const
|
|
1212
|
-
|
|
1227
|
+
t.applySetFilter(w);
|
|
1228
|
+
}), P.appendChild(M);
|
|
1229
|
+
const K = document.createElement("button");
|
|
1230
|
+
K.className = "tbw-filter-clear-btn", K.textContent = "Clear Filter", K.addEventListener("click", () => {
|
|
1213
1231
|
t.clearFilter();
|
|
1214
|
-
}),
|
|
1232
|
+
}), P.appendChild(K), e.appendChild(P);
|
|
1215
1233
|
}
|
|
1216
1234
|
/**
|
|
1217
1235
|
* Apply a set filter (exclude values)
|
|
@@ -1222,10 +1240,7 @@ class A extends x {
|
|
|
1222
1240
|
type: "set",
|
|
1223
1241
|
operator: "notIn",
|
|
1224
1242
|
value: t
|
|
1225
|
-
}), this.
|
|
1226
|
-
filters: [...this.filters.values()],
|
|
1227
|
-
filteredRowCount: 0
|
|
1228
|
-
}), this.requestRender();
|
|
1243
|
+
}), this.applyFiltersInternal();
|
|
1229
1244
|
}
|
|
1230
1245
|
/**
|
|
1231
1246
|
* Apply a text filter
|
|
@@ -1237,8 +1252,28 @@ class A extends x {
|
|
|
1237
1252
|
operator: t,
|
|
1238
1253
|
value: n,
|
|
1239
1254
|
valueTo: o
|
|
1240
|
-
}), this.
|
|
1241
|
-
|
|
1255
|
+
}), this.applyFiltersInternal();
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Internal method to apply filters (sync or async based on config)
|
|
1259
|
+
*/
|
|
1260
|
+
applyFiltersInternal() {
|
|
1261
|
+
this.cachedResult = null, this.cacheKey = null;
|
|
1262
|
+
const e = [...this.filters.values()];
|
|
1263
|
+
if (this.config.filterHandler) {
|
|
1264
|
+
const t = this.grid;
|
|
1265
|
+
t.setAttribute("aria-busy", "true");
|
|
1266
|
+
const n = this.config.filterHandler(e, this.sourceRows), o = (i) => {
|
|
1267
|
+
t.removeAttribute("aria-busy"), this.cachedResult = i, this.grid.rows = i, this.emit("filter-change", {
|
|
1268
|
+
filters: e,
|
|
1269
|
+
filteredRowCount: i.length
|
|
1270
|
+
}), this.requestRender();
|
|
1271
|
+
};
|
|
1272
|
+
n && typeof n.then == "function" ? n.then(o) : o(n);
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
this.emit("filter-change", {
|
|
1276
|
+
filters: e,
|
|
1242
1277
|
filteredRowCount: 0
|
|
1243
1278
|
}), this.requestRender();
|
|
1244
1279
|
}
|
|
@@ -1278,31 +1313,31 @@ class A extends x {
|
|
|
1278
1313
|
}
|
|
1279
1314
|
// #endregion
|
|
1280
1315
|
// #region Styles
|
|
1281
|
-
styles =
|
|
1316
|
+
styles = it;
|
|
1282
1317
|
// #endregion
|
|
1283
1318
|
}
|
|
1284
|
-
function
|
|
1285
|
-
if (!
|
|
1286
|
-
const e = /* @__PURE__ */ new Map(), t = [], n = (
|
|
1319
|
+
function st(s) {
|
|
1320
|
+
if (!s.length) return [];
|
|
1321
|
+
const e = /* @__PURE__ */ new Map(), t = [], n = (r, l) => {
|
|
1287
1322
|
if (!l.length) return;
|
|
1288
1323
|
const a = t[t.length - 1];
|
|
1289
|
-
if (a && a.implicit && a.firstIndex + a.columns.length ===
|
|
1324
|
+
if (a && a.implicit && a.firstIndex + a.columns.length === r) {
|
|
1290
1325
|
a.columns.push(...l);
|
|
1291
1326
|
return;
|
|
1292
1327
|
}
|
|
1293
1328
|
t.push({
|
|
1294
|
-
id: "__implicit__" +
|
|
1329
|
+
id: "__implicit__" + r,
|
|
1295
1330
|
label: void 0,
|
|
1296
1331
|
columns: l,
|
|
1297
|
-
firstIndex:
|
|
1332
|
+
firstIndex: r,
|
|
1298
1333
|
implicit: !0
|
|
1299
1334
|
});
|
|
1300
1335
|
};
|
|
1301
1336
|
let o = [], i = 0;
|
|
1302
|
-
return
|
|
1303
|
-
const a =
|
|
1337
|
+
return s.forEach((r, l) => {
|
|
1338
|
+
const a = r.group;
|
|
1304
1339
|
if (!a) {
|
|
1305
|
-
o.length === 0 && (i = l), o.push(
|
|
1340
|
+
o.length === 0 && (i = l), o.push(r);
|
|
1306
1341
|
return;
|
|
1307
1342
|
}
|
|
1308
1343
|
o.length && (n(i, o.slice()), o = []);
|
|
@@ -1313,40 +1348,40 @@ function rt(r) {
|
|
|
1313
1348
|
label: typeof a == "string" ? void 0 : a.label,
|
|
1314
1349
|
columns: [],
|
|
1315
1350
|
firstIndex: l
|
|
1316
|
-
}, e.set(d, c), t.push(c)), c.columns.push(
|
|
1317
|
-
}), o.length && n(i, o), t.length === 1 && t[0].implicit && t[0].columns.length ===
|
|
1351
|
+
}, e.set(d, c), t.push(c)), c.columns.push(r);
|
|
1352
|
+
}), o.length && n(i, o), t.length === 1 && t[0].implicit && t[0].columns.length === s.length ? [] : t;
|
|
1318
1353
|
}
|
|
1319
|
-
function
|
|
1320
|
-
if (!e.length || !
|
|
1354
|
+
function lt(s, e, t) {
|
|
1355
|
+
if (!e.length || !s) return;
|
|
1321
1356
|
const n = /* @__PURE__ */ new Map();
|
|
1322
1357
|
for (const i of e)
|
|
1323
|
-
for (const
|
|
1324
|
-
|
|
1325
|
-
const o = Array.from(
|
|
1358
|
+
for (const r of i.columns)
|
|
1359
|
+
r?.field && n.set(r.field, i.id);
|
|
1360
|
+
const o = Array.from(s.querySelectorAll(".cell[data-field]"));
|
|
1326
1361
|
o.forEach((i) => {
|
|
1327
|
-
const
|
|
1362
|
+
const r = i.getAttribute("data-field") || "", l = n.get(r);
|
|
1328
1363
|
l && (i.classList.add("grouped"), i.getAttribute("data-group") || i.setAttribute("data-group", l));
|
|
1329
1364
|
});
|
|
1330
1365
|
for (const i of e) {
|
|
1331
|
-
const
|
|
1366
|
+
const r = i.columns[i.columns.length - 1], l = o.find((a) => a.getAttribute("data-field") === r.field);
|
|
1332
1367
|
l && l.classList.add("group-end");
|
|
1333
1368
|
}
|
|
1334
1369
|
}
|
|
1335
|
-
function
|
|
1336
|
-
if (
|
|
1370
|
+
function at(s, e) {
|
|
1371
|
+
if (s.length === 0) return null;
|
|
1337
1372
|
const t = document.createElement("div");
|
|
1338
1373
|
t.className = "header-group-row", t.setAttribute("role", "row");
|
|
1339
|
-
for (const n of
|
|
1340
|
-
const o = n.firstIndex != null ? n.firstIndex : e.findIndex((a) => n.columns.includes(a)), i = String(n.id).startsWith("__implicit__"),
|
|
1341
|
-
l.className = "cell header-group-cell", i && l.classList.add("implicit-group"), l.setAttribute("data-group", String(n.id)), l.style.gridColumn = `${o + 1} / span ${n.columns.length}`, l.textContent =
|
|
1374
|
+
for (const n of s) {
|
|
1375
|
+
const o = n.firstIndex != null ? n.firstIndex : e.findIndex((a) => n.columns.includes(a)), i = String(n.id).startsWith("__implicit__"), r = i ? "" : n.label || n.id, l = document.createElement("div");
|
|
1376
|
+
l.className = "cell header-group-cell", i && l.classList.add("implicit-group"), l.setAttribute("data-group", String(n.id)), l.style.gridColumn = `${o + 1} / span ${n.columns.length}`, l.textContent = r, t.appendChild(l);
|
|
1342
1377
|
}
|
|
1343
1378
|
return t;
|
|
1344
1379
|
}
|
|
1345
|
-
function
|
|
1346
|
-
return
|
|
1380
|
+
function dt(s) {
|
|
1381
|
+
return s.some((e) => e.group != null);
|
|
1347
1382
|
}
|
|
1348
|
-
const
|
|
1349
|
-
class
|
|
1383
|
+
const ct = ".header-group-row{display:grid;grid-auto-flow:column;background:var(--tbw-grouping-columns-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell{display:flex;align-items:center;justify-content:center;padding:4px 8px;font-weight:600;font-size:.9em;text-transform:uppercase;letter-spacing:.5px;border-right:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell:last-child{border-right:none}.header-row .cell.grouped{border-top:none}.header-row .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong))}.header-row .cell.group-end:last-child{border-right:none}.header-group-row.no-borders{border-bottom:none}.header-group-row.no-borders .header-group-cell{border-right:none}.header-row.no-group-borders .cell.group-end{border-right:1px solid var(--tbw-color-border)}";
|
|
1384
|
+
class Cn extends v {
|
|
1350
1385
|
name = "groupingColumns";
|
|
1351
1386
|
version = "1.0.0";
|
|
1352
1387
|
get defaultConfig() {
|
|
@@ -1369,31 +1404,32 @@ class yn extends x {
|
|
|
1369
1404
|
*/
|
|
1370
1405
|
static detect(e, t) {
|
|
1371
1406
|
const n = t?.columns;
|
|
1372
|
-
return Array.isArray(n) ?
|
|
1407
|
+
return Array.isArray(n) ? dt(n) : !1;
|
|
1373
1408
|
}
|
|
1374
1409
|
// #endregion
|
|
1375
1410
|
// #region Hooks
|
|
1376
1411
|
processColumns(e) {
|
|
1377
|
-
const t =
|
|
1412
|
+
const t = st(e);
|
|
1378
1413
|
return t.length === 0 ? (this.isActive = !1, this.groups = [], [...e]) : (this.isActive = !0, this.groups = t, [...e]);
|
|
1379
1414
|
}
|
|
1380
1415
|
afterRender() {
|
|
1381
1416
|
if (!this.isActive || this.groups.length === 0) {
|
|
1382
|
-
const
|
|
1383
|
-
|
|
1417
|
+
const r = this.shadowRoot?.querySelector(".header")?.querySelector(".header-group-row");
|
|
1418
|
+
r && r.remove();
|
|
1384
1419
|
return;
|
|
1385
1420
|
}
|
|
1386
1421
|
const e = this.shadowRoot?.querySelector(".header");
|
|
1387
1422
|
if (!e) return;
|
|
1388
1423
|
const t = e.querySelector(".header-group-row");
|
|
1389
1424
|
t && t.remove();
|
|
1390
|
-
const n =
|
|
1425
|
+
const n = at(this.groups, this.columns);
|
|
1391
1426
|
if (n) {
|
|
1427
|
+
n.classList.toggle("no-borders", !this.config.showGroupBorders);
|
|
1392
1428
|
const i = e.querySelector(".header-row");
|
|
1393
1429
|
i ? e.insertBefore(n, i) : e.appendChild(n);
|
|
1394
1430
|
}
|
|
1395
1431
|
const o = e.querySelector(".header-row");
|
|
1396
|
-
o &&
|
|
1432
|
+
o && (o.classList.toggle("no-group-borders", !this.config.showGroupBorders), lt(o, this.groups, this.columns));
|
|
1397
1433
|
}
|
|
1398
1434
|
// #endregion
|
|
1399
1435
|
// #region Public API
|
|
@@ -1428,28 +1464,28 @@ class yn extends x {
|
|
|
1428
1464
|
}
|
|
1429
1465
|
// #endregion
|
|
1430
1466
|
// #region Styles
|
|
1431
|
-
styles =
|
|
1467
|
+
styles = ct;
|
|
1432
1468
|
// #endregion
|
|
1433
1469
|
}
|
|
1434
|
-
function
|
|
1470
|
+
function ut({ rows: s, config: e, expanded: t }) {
|
|
1435
1471
|
const n = e.groupOn;
|
|
1436
1472
|
if (typeof n != "function")
|
|
1437
1473
|
return [];
|
|
1438
1474
|
const o = { key: "__root__", value: null, depth: -1, rows: [], children: /* @__PURE__ */ new Map() };
|
|
1439
|
-
if (
|
|
1475
|
+
if (s.forEach((l) => {
|
|
1440
1476
|
let a = n(l);
|
|
1441
1477
|
a == null || a === !1 ? a = ["__ungrouped__"] : Array.isArray(a) || (a = [a]);
|
|
1442
1478
|
let d = o;
|
|
1443
1479
|
a.forEach((c, u) => {
|
|
1444
1480
|
const h = c == null ? "∅" : String(c), g = d.key === "__root__" ? h : d.key + "||" + h;
|
|
1445
|
-
let
|
|
1446
|
-
|
|
1481
|
+
let f = d.children.get(h);
|
|
1482
|
+
f || (f = { key: g, value: c, depth: u, rows: [], children: /* @__PURE__ */ new Map(), parent: d }, d.children.set(h, f)), d = f;
|
|
1447
1483
|
}), d.rows.push(l);
|
|
1448
|
-
}), o.children.size === 1 && o.children.has("__ungrouped__") && o.children.get("__ungrouped__").rows.length ===
|
|
1484
|
+
}), o.children.size === 1 && o.children.has("__ungrouped__") && o.children.get("__ungrouped__").rows.length === s.length)
|
|
1449
1485
|
return [];
|
|
1450
|
-
const i = [],
|
|
1486
|
+
const i = [], r = (l) => {
|
|
1451
1487
|
if (l === o) {
|
|
1452
|
-
l.children.forEach((d) =>
|
|
1488
|
+
l.children.forEach((d) => r(d));
|
|
1453
1489
|
return;
|
|
1454
1490
|
}
|
|
1455
1491
|
const a = t.has(l.key);
|
|
@@ -1460,28 +1496,28 @@ function ct({ rows: r, config: e, expanded: t }) {
|
|
|
1460
1496
|
depth: l.depth,
|
|
1461
1497
|
rows: l.rows,
|
|
1462
1498
|
expanded: a
|
|
1463
|
-
}), a && (l.children.size ? l.children.forEach((d) =>
|
|
1499
|
+
}), a && (l.children.size ? l.children.forEach((d) => r(d)) : l.rows.forEach((d) => i.push({ kind: "data", row: d, rowIndex: s.indexOf(d) })));
|
|
1464
1500
|
};
|
|
1465
|
-
return
|
|
1501
|
+
return r(o), i;
|
|
1466
1502
|
}
|
|
1467
|
-
function
|
|
1468
|
-
const t = new Set(
|
|
1503
|
+
function ht(s, e) {
|
|
1504
|
+
const t = new Set(s);
|
|
1469
1505
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
1470
1506
|
}
|
|
1471
|
-
function
|
|
1507
|
+
function gt(s) {
|
|
1472
1508
|
const e = /* @__PURE__ */ new Set();
|
|
1473
|
-
for (const t of
|
|
1509
|
+
for (const t of s)
|
|
1474
1510
|
t.kind === "group" && e.add(t.key);
|
|
1475
1511
|
return e;
|
|
1476
1512
|
}
|
|
1477
|
-
function
|
|
1513
|
+
function ft() {
|
|
1478
1514
|
return /* @__PURE__ */ new Set();
|
|
1479
1515
|
}
|
|
1480
|
-
function pt(
|
|
1481
|
-
return
|
|
1516
|
+
function pt(s) {
|
|
1517
|
+
return s.kind !== "group" ? 0 : s.rows.length;
|
|
1482
1518
|
}
|
|
1483
|
-
const
|
|
1484
|
-
class
|
|
1519
|
+
const mt = '.group-row{background:var(--tbw-grouping-rows-bg, var(--tbw-color-panel-bg));font-weight:500}.group-row:hover{background:var(--tbw-grouping-rows-bg-hover, var(--tbw-color-row-hover))}.group-toggle{cursor:pointer;user-select:none;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:4px}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));border-radius:2px}.group-label{display:inline-flex;align-items:center;gap:8px}.group-count{color:var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));font-size:.85em;font-weight:400}[data-group-depth="0"] .group-label{padding-left:0}[data-group-depth="1"] .group-label{padding-left:20px}[data-group-depth="2"] .group-label{padding-left:40px}[data-group-depth="3"] .group-label{padding-left:60px}[data-group-depth="4"] .group-label{padding-left:80px}.data-grid-row.tbw-group-slide-in{animation:tbw-group-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-group-fade-in{animation:tbw-group-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-fade-in{0%{opacity:0}to{opacity:1}}';
|
|
1520
|
+
class Rn extends v {
|
|
1485
1521
|
name = "groupingRows";
|
|
1486
1522
|
version = "1.0.0";
|
|
1487
1523
|
get defaultConfig() {
|
|
@@ -1489,17 +1525,32 @@ class Cn extends x {
|
|
|
1489
1525
|
defaultExpanded: !1,
|
|
1490
1526
|
showRowCount: !0,
|
|
1491
1527
|
indentWidth: 20,
|
|
1492
|
-
aggregators: {}
|
|
1528
|
+
aggregators: {},
|
|
1529
|
+
animation: "slide"
|
|
1493
1530
|
};
|
|
1494
1531
|
}
|
|
1495
1532
|
// #region Internal State
|
|
1496
1533
|
expandedKeys = /* @__PURE__ */ new Set();
|
|
1497
1534
|
flattenedRows = [];
|
|
1498
1535
|
isActive = !1;
|
|
1536
|
+
previousVisibleKeys = /* @__PURE__ */ new Set();
|
|
1537
|
+
keysToAnimate = /* @__PURE__ */ new Set();
|
|
1538
|
+
// #endregion
|
|
1539
|
+
// #region Animation
|
|
1540
|
+
get animationStyle() {
|
|
1541
|
+
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
1542
|
+
if (t === !1 || t === "off") return !1;
|
|
1543
|
+
if (t !== !0 && t !== "on") {
|
|
1544
|
+
const n = this.shadowRoot?.host;
|
|
1545
|
+
if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
1546
|
+
return !1;
|
|
1547
|
+
}
|
|
1548
|
+
return this.config.animation ?? "slide";
|
|
1549
|
+
}
|
|
1499
1550
|
// #endregion
|
|
1500
1551
|
// #region Lifecycle
|
|
1501
1552
|
detach() {
|
|
1502
|
-
this.expandedKeys.clear(), this.flattenedRows = [], this.isActive = !1;
|
|
1553
|
+
this.expandedKeys.clear(), this.flattenedRows = [], this.isActive = !1, this.previousVisibleKeys.clear(), this.keysToAnimate.clear();
|
|
1503
1554
|
}
|
|
1504
1555
|
// #endregion
|
|
1505
1556
|
// #region Hooks
|
|
@@ -1514,20 +1565,29 @@ class Cn extends x {
|
|
|
1514
1565
|
const t = this.config;
|
|
1515
1566
|
if (typeof t.groupOn != "function")
|
|
1516
1567
|
return this.isActive = !1, this.flattenedRows = [], [...e];
|
|
1517
|
-
const n =
|
|
1568
|
+
const n = ut({
|
|
1518
1569
|
rows: e,
|
|
1519
1570
|
config: t,
|
|
1520
1571
|
expanded: this.expandedKeys
|
|
1521
1572
|
});
|
|
1522
|
-
|
|
1573
|
+
if (n.length === 0)
|
|
1574
|
+
return this.isActive = !1, this.flattenedRows = [], [...e];
|
|
1575
|
+
this.isActive = !0, this.flattenedRows = n, this.keysToAnimate.clear();
|
|
1576
|
+
const o = /* @__PURE__ */ new Set();
|
|
1577
|
+
return n.forEach((i, r) => {
|
|
1578
|
+
if (i.kind === "data") {
|
|
1579
|
+
const l = `data-${r}`;
|
|
1580
|
+
o.add(l), this.previousVisibleKeys.has(l) || this.keysToAnimate.add(l);
|
|
1581
|
+
}
|
|
1582
|
+
}), this.previousVisibleKeys = o, n.map((i) => i.kind === "group" ? {
|
|
1523
1583
|
__isGroupRow: !0,
|
|
1524
|
-
__groupKey:
|
|
1525
|
-
__groupValue:
|
|
1526
|
-
__groupDepth:
|
|
1527
|
-
__groupRows:
|
|
1528
|
-
__groupExpanded:
|
|
1529
|
-
__groupRowCount: pt(
|
|
1530
|
-
} :
|
|
1584
|
+
__groupKey: i.key,
|
|
1585
|
+
__groupValue: i.value,
|
|
1586
|
+
__groupDepth: i.depth,
|
|
1587
|
+
__groupRows: i.rows,
|
|
1588
|
+
__groupExpanded: i.expanded,
|
|
1589
|
+
__groupRowCount: pt(i)
|
|
1590
|
+
} : i.row);
|
|
1531
1591
|
}
|
|
1532
1592
|
onCellClick(e) {
|
|
1533
1593
|
const t = e.row;
|
|
@@ -1561,16 +1621,26 @@ class Cn extends x {
|
|
|
1561
1621
|
return t.className = "group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), t.setAttribute("role", "row"), t.setAttribute("aria-expanded", String(e.__groupExpanded)), t.style.paddingLeft = `${(e.__groupDepth || 0) * (o.indentWidth ?? 20)}px`, t.innerHTML = "", o.fullWidth !== !1 ? this.renderFullWidthGroupRow(e, t, i) : this.renderPerColumnGroupRow(e, t, i), !0;
|
|
1562
1622
|
}
|
|
1563
1623
|
afterRender() {
|
|
1624
|
+
const e = this.animationStyle;
|
|
1625
|
+
if (e === !1 || this.keysToAnimate.size === 0) return;
|
|
1626
|
+
const t = this.shadowRoot?.querySelector(".rows");
|
|
1627
|
+
if (!t) return;
|
|
1628
|
+
const n = e === "fade" ? "tbw-group-fade-in" : "tbw-group-slide-in";
|
|
1629
|
+
for (const o of t.querySelectorAll(".data-grid-row:not(.group-row)")) {
|
|
1630
|
+
const i = o.querySelector(".cell[data-row]"), r = i ? parseInt(i.getAttribute("data-row") ?? "-1", 10) : -1, a = this.flattenedRows[r]?.kind === "data" ? `data-${r}` : void 0;
|
|
1631
|
+
a && this.keysToAnimate.has(a) && (o.classList.add(n), o.addEventListener("animationend", () => o.classList.remove(n), { once: !0 }));
|
|
1632
|
+
}
|
|
1633
|
+
this.keysToAnimate.clear();
|
|
1564
1634
|
}
|
|
1565
1635
|
// #endregion
|
|
1566
1636
|
// #region Private Rendering Helpers
|
|
1567
1637
|
renderFullWidthGroupRow(e, t, n) {
|
|
1568
1638
|
const o = this.config, i = document.createElement("div");
|
|
1569
1639
|
i.className = "cell group-full", i.style.gridColumn = "1 / -1", i.setAttribute("role", "gridcell");
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1640
|
+
const r = document.createElement("button");
|
|
1641
|
+
r.type = "button", r.className = `group-toggle${e.__groupExpanded ? " expanded" : ""}`, r.setAttribute("aria-label", e.__groupExpanded ? "Collapse group" : "Expand group"), this.setIcon(r, this.resolveIcon(e.__groupExpanded ? "collapse" : "expand")), r.addEventListener("click", (d) => {
|
|
1572
1642
|
d.stopPropagation(), n();
|
|
1573
|
-
}), i.appendChild(
|
|
1643
|
+
}), i.appendChild(r);
|
|
1574
1644
|
const l = document.createElement("span");
|
|
1575
1645
|
l.className = "group-label";
|
|
1576
1646
|
const a = o.formatLabel ? o.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
|
|
@@ -1581,31 +1651,31 @@ class Cn extends x {
|
|
|
1581
1651
|
t.appendChild(i);
|
|
1582
1652
|
}
|
|
1583
1653
|
renderPerColumnGroupRow(e, t, n) {
|
|
1584
|
-
const o = this.config, i = o.aggregators ?? {},
|
|
1585
|
-
d && (t.style.display = "grid", t.style.gridTemplateColumns = d),
|
|
1654
|
+
const o = this.config, i = o.aggregators ?? {}, r = this.columns, l = e.__groupRows ?? [], d = this.shadowRoot?.querySelector(".body")?.style.gridTemplateColumns || "";
|
|
1655
|
+
d && (t.style.display = "grid", t.style.gridTemplateColumns = d), r.forEach((c, u) => {
|
|
1586
1656
|
const h = document.createElement("div");
|
|
1587
1657
|
if (h.className = "cell group-cell", h.setAttribute("data-col", String(u)), h.setAttribute("role", "gridcell"), u === 0) {
|
|
1588
1658
|
const g = document.createElement("button");
|
|
1589
|
-
g.type = "button", g.className =
|
|
1590
|
-
|
|
1659
|
+
g.type = "button", g.className = `group-toggle${e.__groupExpanded ? " expanded" : ""}`, g.setAttribute("aria-label", e.__groupExpanded ? "Collapse group" : "Expand group"), this.setIcon(g, this.resolveIcon(e.__groupExpanded ? "collapse" : "expand")), g.addEventListener("click", (p) => {
|
|
1660
|
+
p.stopPropagation(), n();
|
|
1591
1661
|
}), h.appendChild(g);
|
|
1592
|
-
const
|
|
1593
|
-
if (
|
|
1594
|
-
const
|
|
1595
|
-
|
|
1662
|
+
const f = document.createElement("span"), m = i[c.field];
|
|
1663
|
+
if (m) {
|
|
1664
|
+
const p = se(m, l, c.field, c);
|
|
1665
|
+
f.textContent = p != null ? String(p) : String(e.__groupValue);
|
|
1596
1666
|
} else {
|
|
1597
|
-
const
|
|
1598
|
-
|
|
1667
|
+
const p = o.formatLabel ? o.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
|
|
1668
|
+
f.textContent = p;
|
|
1599
1669
|
}
|
|
1600
|
-
if (h.appendChild(
|
|
1601
|
-
const
|
|
1602
|
-
|
|
1670
|
+
if (h.appendChild(f), o.showRowCount !== !1) {
|
|
1671
|
+
const p = document.createElement("span");
|
|
1672
|
+
p.className = "group-count", p.textContent = ` (${l.length})`, h.appendChild(p);
|
|
1603
1673
|
}
|
|
1604
1674
|
} else {
|
|
1605
1675
|
const g = i[c.field];
|
|
1606
1676
|
if (g) {
|
|
1607
|
-
const
|
|
1608
|
-
h.textContent =
|
|
1677
|
+
const f = se(g, l, c.field, c);
|
|
1678
|
+
h.textContent = f != null ? String(f) : "";
|
|
1609
1679
|
} else
|
|
1610
1680
|
h.textContent = "";
|
|
1611
1681
|
}
|
|
@@ -1618,20 +1688,20 @@ class Cn extends x {
|
|
|
1618
1688
|
* Expand all groups.
|
|
1619
1689
|
*/
|
|
1620
1690
|
expandAll() {
|
|
1621
|
-
this.expandedKeys =
|
|
1691
|
+
this.expandedKeys = gt(this.flattenedRows), this.requestRender();
|
|
1622
1692
|
}
|
|
1623
1693
|
/**
|
|
1624
1694
|
* Collapse all groups.
|
|
1625
1695
|
*/
|
|
1626
1696
|
collapseAll() {
|
|
1627
|
-
this.expandedKeys =
|
|
1697
|
+
this.expandedKeys = ft(), this.requestRender();
|
|
1628
1698
|
}
|
|
1629
1699
|
/**
|
|
1630
1700
|
* Toggle expansion of a specific group.
|
|
1631
1701
|
* @param key - The group key to toggle
|
|
1632
1702
|
*/
|
|
1633
1703
|
toggle(e) {
|
|
1634
|
-
this.expandedKeys =
|
|
1704
|
+
this.expandedKeys = ht(this.expandedKeys, e);
|
|
1635
1705
|
const t = this.flattenedRows.find((n) => n.kind === "group" && n.key === e);
|
|
1636
1706
|
this.emit("group-toggle", {
|
|
1637
1707
|
key: e,
|
|
@@ -1722,34 +1792,34 @@ class Cn extends x {
|
|
|
1722
1792
|
}
|
|
1723
1793
|
// #endregion
|
|
1724
1794
|
// #region Styles
|
|
1725
|
-
styles =
|
|
1795
|
+
styles = mt;
|
|
1726
1796
|
// #endregion
|
|
1727
1797
|
}
|
|
1728
|
-
function
|
|
1729
|
-
const t = new Set(
|
|
1798
|
+
function z(s, e) {
|
|
1799
|
+
const t = new Set(s);
|
|
1730
1800
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
1731
1801
|
}
|
|
1732
|
-
function
|
|
1733
|
-
const t = new Set(
|
|
1802
|
+
function wt(s, e) {
|
|
1803
|
+
const t = new Set(s);
|
|
1734
1804
|
return t.add(e), t;
|
|
1735
1805
|
}
|
|
1736
|
-
function
|
|
1737
|
-
const t = new Set(
|
|
1806
|
+
function bt(s, e) {
|
|
1807
|
+
const t = new Set(s);
|
|
1738
1808
|
return t.delete(e), t;
|
|
1739
1809
|
}
|
|
1740
|
-
function
|
|
1741
|
-
return
|
|
1810
|
+
function vt(s, e) {
|
|
1811
|
+
return s.has(e);
|
|
1742
1812
|
}
|
|
1743
|
-
function
|
|
1813
|
+
function xt(s, e, t, n) {
|
|
1744
1814
|
const o = document.createElement("div");
|
|
1745
1815
|
o.className = "master-detail-row", o.setAttribute("data-detail-for", String(e)), o.setAttribute("role", "row");
|
|
1746
1816
|
const i = document.createElement("div");
|
|
1747
1817
|
i.className = "master-detail-cell", i.setAttribute("role", "cell"), i.style.gridColumn = `1 / ${n + 1}`;
|
|
1748
|
-
const
|
|
1749
|
-
return typeof
|
|
1818
|
+
const r = t(s, e);
|
|
1819
|
+
return typeof r == "string" ? i.innerHTML = r : r instanceof HTMLElement && i.appendChild(r), o.appendChild(i), o;
|
|
1750
1820
|
}
|
|
1751
|
-
const
|
|
1752
|
-
class
|
|
1821
|
+
const yt = ".master-detail-cell-wrapper{display:flex;align-items:center;gap:4px}.master-detail-toggle{cursor:pointer;opacity:.7;user-select:none;display:inline-flex;align-items:center;justify-content:center}.master-detail-toggle:hover{opacity:1}.master-detail-row{grid-column:1 / -1;display:grid;background:var(--tbw-master-detail-bg, var(--tbw-color-row-alt));border-bottom:1px solid var(--tbw-master-detail-border, var(--tbw-color-border));overflow:hidden}.master-detail-cell{padding:16px;overflow:auto}.master-detail-row.tbw-expanding{animation:tbw-detail-expand var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}.master-detail-row.tbw-collapsing{animation:tbw-detail-collapse var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-detail-expand{0%{opacity:0;max-height:0;padding-top:0;padding-bottom:0}to{opacity:1;max-height:500px;padding-top:16px;padding-bottom:16px}}@keyframes tbw-detail-collapse{0%{opacity:1;max-height:500px}to{opacity:0;max-height:0}}";
|
|
1822
|
+
class Sn extends v {
|
|
1753
1823
|
name = "masterDetail";
|
|
1754
1824
|
version = "1.0.0";
|
|
1755
1825
|
get defaultConfig() {
|
|
@@ -1757,9 +1827,67 @@ class Rn extends x {
|
|
|
1757
1827
|
detailHeight: "auto",
|
|
1758
1828
|
expandOnRowClick: !1,
|
|
1759
1829
|
collapseOnClickOutside: !1,
|
|
1760
|
-
showExpandColumn: !0
|
|
1830
|
+
showExpandColumn: !0,
|
|
1831
|
+
animation: "slide"
|
|
1832
|
+
// Plugin's own default
|
|
1761
1833
|
};
|
|
1762
1834
|
}
|
|
1835
|
+
// #region Animation Helpers
|
|
1836
|
+
/**
|
|
1837
|
+
* Check if animations are enabled at the grid level.
|
|
1838
|
+
* Respects gridConfig.animation.mode and CSS variable.
|
|
1839
|
+
*/
|
|
1840
|
+
get isAnimationEnabled() {
|
|
1841
|
+
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
1842
|
+
if (t === !1 || t === "off") return !1;
|
|
1843
|
+
if (t === !0 || t === "on") return !0;
|
|
1844
|
+
const n = this.shadowRoot?.host;
|
|
1845
|
+
return n ? getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
1846
|
+
}
|
|
1847
|
+
/**
|
|
1848
|
+
* Get expand/collapse animation style from plugin config.
|
|
1849
|
+
*/
|
|
1850
|
+
get animationStyle() {
|
|
1851
|
+
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
1852
|
+
}
|
|
1853
|
+
/**
|
|
1854
|
+
* Get animation duration from CSS variable (set by grid).
|
|
1855
|
+
*/
|
|
1856
|
+
get animationDuration() {
|
|
1857
|
+
const e = this.shadowRoot?.host;
|
|
1858
|
+
if (e) {
|
|
1859
|
+
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
|
|
1860
|
+
if (!isNaN(n)) return n;
|
|
1861
|
+
}
|
|
1862
|
+
return 200;
|
|
1863
|
+
}
|
|
1864
|
+
/**
|
|
1865
|
+
* Apply expand animation to a detail element.
|
|
1866
|
+
*/
|
|
1867
|
+
animateExpand(e) {
|
|
1868
|
+
!this.isAnimationEnabled || this.animationStyle === !1 || (e.classList.add("tbw-expanding"), e.addEventListener(
|
|
1869
|
+
"animationend",
|
|
1870
|
+
() => {
|
|
1871
|
+
e.classList.remove("tbw-expanding");
|
|
1872
|
+
},
|
|
1873
|
+
{ once: !0 }
|
|
1874
|
+
));
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* Apply collapse animation to a detail element and remove after animation.
|
|
1878
|
+
*/
|
|
1879
|
+
animateCollapse(e, t) {
|
|
1880
|
+
if (!this.isAnimationEnabled || this.animationStyle === !1) {
|
|
1881
|
+
t();
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
1884
|
+
e.classList.add("tbw-collapsing");
|
|
1885
|
+
const n = () => {
|
|
1886
|
+
e.classList.remove("tbw-collapsing"), t();
|
|
1887
|
+
};
|
|
1888
|
+
e.addEventListener("animationend", n, { once: !0 }), setTimeout(n, this.animationDuration + 50);
|
|
1889
|
+
}
|
|
1890
|
+
// #endregion
|
|
1763
1891
|
// #region Internal State
|
|
1764
1892
|
expandedRows = /* @__PURE__ */ new Set();
|
|
1765
1893
|
detailElements = /* @__PURE__ */ new Map();
|
|
@@ -1778,22 +1906,22 @@ class Rn extends x {
|
|
|
1778
1906
|
const n = { ...t[0] }, o = n.viewRenderer;
|
|
1779
1907
|
if (o?.__masterDetailWrapped)
|
|
1780
1908
|
return t;
|
|
1781
|
-
const i = (
|
|
1782
|
-
const { value: l, row: a } =
|
|
1909
|
+
const i = (r) => {
|
|
1910
|
+
const { value: l, row: a } = r, d = this.expandedRows.has(a), c = document.createElement("span");
|
|
1783
1911
|
c.className = "master-detail-cell-wrapper";
|
|
1784
1912
|
const u = document.createElement("span");
|
|
1785
|
-
u.className =
|
|
1913
|
+
u.className = `master-detail-toggle${d ? " expanded" : ""}`, this.setIcon(u, this.resolveIcon(d ? "collapse" : "expand")), u.setAttribute("role", "button"), u.setAttribute("tabindex", "0"), u.setAttribute("aria-expanded", String(d)), u.setAttribute("aria-label", d ? "Collapse details" : "Expand details"), u.addEventListener("click", (g) => {
|
|
1786
1914
|
g.stopPropagation();
|
|
1787
|
-
const
|
|
1788
|
-
this.expandedRows =
|
|
1789
|
-
rowIndex:
|
|
1915
|
+
const f = this.rows.indexOf(a);
|
|
1916
|
+
this.expandedRows = z(this.expandedRows, a), this.emit("detail-expand", {
|
|
1917
|
+
rowIndex: f,
|
|
1790
1918
|
row: a,
|
|
1791
1919
|
expanded: this.expandedRows.has(a)
|
|
1792
1920
|
}), this.requestRender();
|
|
1793
1921
|
}), c.appendChild(u);
|
|
1794
1922
|
const h = document.createElement("span");
|
|
1795
1923
|
if (o) {
|
|
1796
|
-
const g = o(
|
|
1924
|
+
const g = o(r);
|
|
1797
1925
|
g instanceof Node ? h.appendChild(g) : h.textContent = String(g ?? l ?? "");
|
|
1798
1926
|
} else
|
|
1799
1927
|
h.textContent = String(l ?? "");
|
|
@@ -1805,7 +1933,7 @@ class Rn extends x {
|
|
|
1805
1933
|
}
|
|
1806
1934
|
onRowClick(e) {
|
|
1807
1935
|
if (!(!this.config.expandOnRowClick || !this.config.detailRenderer))
|
|
1808
|
-
return this.expandedRows =
|
|
1936
|
+
return this.expandedRows = z(this.expandedRows, e.row), this.emit("detail-expand", {
|
|
1809
1937
|
rowIndex: e.rowIndex,
|
|
1810
1938
|
row: e.row,
|
|
1811
1939
|
expanded: this.expandedRows.has(e.row)
|
|
@@ -1833,25 +1961,25 @@ class Rn extends x {
|
|
|
1833
1961
|
const e = this.shadowRoot?.querySelector(".rows");
|
|
1834
1962
|
if (!e) return;
|
|
1835
1963
|
const t = /* @__PURE__ */ new Map(), n = e.querySelectorAll(".data-grid-row"), o = this.columns.length;
|
|
1836
|
-
for (const
|
|
1837
|
-
const l =
|
|
1838
|
-
a >= 0 && t.set(a,
|
|
1964
|
+
for (const r of n) {
|
|
1965
|
+
const l = r.querySelector(".cell[data-row]"), a = l ? parseInt(l.getAttribute("data-row") ?? "-1", 10) : -1;
|
|
1966
|
+
a >= 0 && t.set(a, r);
|
|
1839
1967
|
}
|
|
1840
1968
|
const i = e.querySelectorAll(".master-detail-row");
|
|
1841
|
-
for (const
|
|
1842
|
-
const l = parseInt(
|
|
1843
|
-
(!d || !c) && (
|
|
1969
|
+
for (const r of i) {
|
|
1970
|
+
const l = parseInt(r.getAttribute("data-detail-for") ?? "-1", 10), a = l >= 0 ? this.rows[l] : void 0, d = a && this.expandedRows.has(a), c = t.has(l);
|
|
1971
|
+
(!d || !c) && (r.remove(), a && this.detailElements.delete(a));
|
|
1844
1972
|
}
|
|
1845
|
-
for (const [
|
|
1846
|
-
const a = this.rows[
|
|
1973
|
+
for (const [r, l] of t) {
|
|
1974
|
+
const a = this.rows[r];
|
|
1847
1975
|
if (!a || !this.expandedRows.has(a)) continue;
|
|
1848
1976
|
const d = this.detailElements.get(a);
|
|
1849
1977
|
if (d) {
|
|
1850
1978
|
d.previousElementSibling !== l && l.after(d);
|
|
1851
1979
|
continue;
|
|
1852
1980
|
}
|
|
1853
|
-
const c =
|
|
1854
|
-
typeof this.config.detailHeight == "number" && (c.style.height = `${this.config.detailHeight}px`), l.after(c), this.detailElements.set(a, c);
|
|
1981
|
+
const c = xt(a, r, this.config.detailRenderer, o);
|
|
1982
|
+
typeof this.config.detailHeight == "number" && (c.style.height = `${this.config.detailHeight}px`), l.after(c), this.detailElements.set(a, c), this.animateExpand(c);
|
|
1855
1983
|
}
|
|
1856
1984
|
}
|
|
1857
1985
|
/**
|
|
@@ -1884,8 +2012,8 @@ class Rn extends x {
|
|
|
1884
2012
|
if (i)
|
|
1885
2013
|
t += i.offsetHeight;
|
|
1886
2014
|
else {
|
|
1887
|
-
const
|
|
1888
|
-
t += typeof
|
|
2015
|
+
const r = this.config?.detailHeight;
|
|
2016
|
+
t += typeof r == "number" ? r : 150;
|
|
1889
2017
|
}
|
|
1890
2018
|
}
|
|
1891
2019
|
}
|
|
@@ -1903,10 +2031,10 @@ class Rn extends x {
|
|
|
1903
2031
|
a >= 0 && o.push({ index: a, row: l });
|
|
1904
2032
|
}
|
|
1905
2033
|
o.sort((l, a) => l.index - a.index);
|
|
1906
|
-
let i = e,
|
|
2034
|
+
let i = e, r = 0;
|
|
1907
2035
|
for (const { index: l, row: a } of o) {
|
|
1908
|
-
const d = l * n +
|
|
1909
|
-
|
|
2036
|
+
const d = l * n + r, u = this.detailElements.get(a)?.offsetHeight ?? (typeof this.config?.detailHeight == "number" ? this.config.detailHeight : 150), h = d + n + u;
|
|
2037
|
+
r += u, !(l >= e) && h > t && l < i && (i = l);
|
|
1910
2038
|
}
|
|
1911
2039
|
return i;
|
|
1912
2040
|
}
|
|
@@ -1918,7 +2046,7 @@ class Rn extends x {
|
|
|
1918
2046
|
*/
|
|
1919
2047
|
expand(e) {
|
|
1920
2048
|
const t = this.rows[e];
|
|
1921
|
-
t && (this.expandedRows =
|
|
2049
|
+
t && (this.expandedRows = wt(this.expandedRows, t), this.requestRender());
|
|
1922
2050
|
}
|
|
1923
2051
|
/**
|
|
1924
2052
|
* Collapse the detail row at the given index.
|
|
@@ -1926,7 +2054,7 @@ class Rn extends x {
|
|
|
1926
2054
|
*/
|
|
1927
2055
|
collapse(e) {
|
|
1928
2056
|
const t = this.rows[e];
|
|
1929
|
-
t && (this.expandedRows =
|
|
2057
|
+
t && (this.expandedRows = bt(this.expandedRows, t), this.requestRender());
|
|
1930
2058
|
}
|
|
1931
2059
|
/**
|
|
1932
2060
|
* Toggle the detail row at the given index.
|
|
@@ -1934,7 +2062,7 @@ class Rn extends x {
|
|
|
1934
2062
|
*/
|
|
1935
2063
|
toggle(e) {
|
|
1936
2064
|
const t = this.rows[e];
|
|
1937
|
-
t && (this.expandedRows =
|
|
2065
|
+
t && (this.expandedRows = z(this.expandedRows, t), this.requestRender());
|
|
1938
2066
|
}
|
|
1939
2067
|
/**
|
|
1940
2068
|
* Check if the detail row at the given index is expanded.
|
|
@@ -1943,7 +2071,7 @@ class Rn extends x {
|
|
|
1943
2071
|
*/
|
|
1944
2072
|
isExpanded(e) {
|
|
1945
2073
|
const t = this.rows[e];
|
|
1946
|
-
return t ?
|
|
2074
|
+
return t ? vt(this.expandedRows, t) : !1;
|
|
1947
2075
|
}
|
|
1948
2076
|
/**
|
|
1949
2077
|
* Expand all detail rows.
|
|
@@ -1982,35 +2110,35 @@ class Rn extends x {
|
|
|
1982
2110
|
}
|
|
1983
2111
|
// #endregion
|
|
1984
2112
|
// #region Styles
|
|
1985
|
-
styles =
|
|
2113
|
+
styles = yt;
|
|
1986
2114
|
// #endregion
|
|
1987
2115
|
}
|
|
1988
|
-
function
|
|
1989
|
-
return e.length ? [...
|
|
2116
|
+
function Ct(s, e, t) {
|
|
2117
|
+
return e.length ? [...s].sort((n, o) => {
|
|
1990
2118
|
for (const i of e) {
|
|
1991
|
-
const l = t.find((u) => u.field === i.field)?.sortComparator ??
|
|
2119
|
+
const l = t.find((u) => u.field === i.field)?.sortComparator ?? Rt, a = n[i.field], d = o[i.field], c = l(a, d, n, o);
|
|
1992
2120
|
if (c !== 0)
|
|
1993
2121
|
return i.direction === "asc" ? c : -c;
|
|
1994
2122
|
}
|
|
1995
2123
|
return 0;
|
|
1996
|
-
}) : [...
|
|
2124
|
+
}) : [...s];
|
|
1997
2125
|
}
|
|
1998
|
-
function
|
|
1999
|
-
return
|
|
2126
|
+
function Rt(s, e) {
|
|
2127
|
+
return s == null && e == null ? 0 : s == null ? 1 : e == null ? -1 : typeof s == "number" && typeof e == "number" ? s - e : s instanceof Date && e instanceof Date ? s.getTime() - e.getTime() : typeof s == "boolean" && typeof e == "boolean" ? s === e ? 0 : s ? -1 : 1 : String(s).localeCompare(String(e));
|
|
2000
2128
|
}
|
|
2001
|
-
function
|
|
2002
|
-
const o =
|
|
2003
|
-
return t ? o ? o.direction === "asc" ?
|
|
2129
|
+
function St(s, e, t, n) {
|
|
2130
|
+
const o = s.find((i) => i.field === e);
|
|
2131
|
+
return t ? o ? o.direction === "asc" ? s.map((i) => i.field === e ? { ...i, direction: "desc" } : i) : s.filter((i) => i.field !== e) : s.length < n ? [...s, { field: e, direction: "asc" }] : s : o?.direction === "asc" ? [{ field: e, direction: "desc" }] : o?.direction === "desc" ? [] : [{ field: e, direction: "asc" }];
|
|
2004
2132
|
}
|
|
2005
|
-
function
|
|
2006
|
-
const t =
|
|
2133
|
+
function be(s, e) {
|
|
2134
|
+
const t = s.findIndex((n) => n.field === e);
|
|
2007
2135
|
return t >= 0 ? t + 1 : void 0;
|
|
2008
2136
|
}
|
|
2009
|
-
function
|
|
2010
|
-
return
|
|
2137
|
+
function ve(s, e) {
|
|
2138
|
+
return s.find((t) => t.field === e)?.direction;
|
|
2011
2139
|
}
|
|
2012
|
-
const
|
|
2013
|
-
class
|
|
2140
|
+
const kt = '.header-cell[data-sort=asc]:after{content:"↑";margin-left:4px;opacity:.8}.header-cell[data-sort=desc]:after{content:"↓";margin-left:4px;opacity:.8}.sort-indicator{margin-left:4px;opacity:.8}.sort-index{font-size:10px;background:var(--tbw-multi-sort-badge-bg, var(--tbw-color-panel-bg));color:var(--tbw-multi-sort-badge-color, var(--tbw-color-fg));border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;margin-left:2px;font-weight:600}';
|
|
2141
|
+
class kn extends v {
|
|
2014
2142
|
name = "multiSort";
|
|
2015
2143
|
version = "1.0.0";
|
|
2016
2144
|
get defaultConfig() {
|
|
@@ -2029,12 +2157,12 @@ class Sn extends x {
|
|
|
2029
2157
|
// #endregion
|
|
2030
2158
|
// #region Hooks
|
|
2031
2159
|
processRows(e) {
|
|
2032
|
-
return this.sortModel.length === 0 ? [...e] :
|
|
2160
|
+
return this.sortModel.length === 0 ? [...e] : Ct([...e], this.sortModel, [...this.columns]);
|
|
2033
2161
|
}
|
|
2034
2162
|
onHeaderClick(e) {
|
|
2035
2163
|
if (!this.columns.find((i) => i.field === e.field)?.sortable) return !1;
|
|
2036
2164
|
const n = e.originalEvent.shiftKey, o = this.config.maxSortColumns ?? 3;
|
|
2037
|
-
return this.sortModel =
|
|
2165
|
+
return this.sortModel = St(this.sortModel, e.field, n, o), this.emit("sort-change", { sortModel: [...this.sortModel] }), this.requestRender(), !0;
|
|
2038
2166
|
}
|
|
2039
2167
|
afterRender() {
|
|
2040
2168
|
const e = this.shadowRoot;
|
|
@@ -2043,13 +2171,13 @@ class Sn extends x {
|
|
|
2043
2171
|
e.querySelectorAll(".header-row .cell[data-field]").forEach((o) => {
|
|
2044
2172
|
const i = o.getAttribute("data-field");
|
|
2045
2173
|
if (!i) return;
|
|
2046
|
-
const
|
|
2174
|
+
const r = be(this.sortModel, i), l = ve(this.sortModel, i);
|
|
2047
2175
|
if (o.querySelector(".sort-index")?.remove(), l) {
|
|
2048
2176
|
o.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove(), o.setAttribute("data-sort", l);
|
|
2049
2177
|
const c = document.createElement("span");
|
|
2050
|
-
if (c.className = "sort-indicator",
|
|
2178
|
+
if (c.className = "sort-indicator", this.setIcon(c, this.resolveIcon(l === "asc" ? "sortAsc" : "sortDesc")), o.appendChild(c), t && this.sortModel.length > 1 && r !== void 0) {
|
|
2051
2179
|
const u = document.createElement("span");
|
|
2052
|
-
u.className = "sort-index", u.textContent = String(
|
|
2180
|
+
u.className = "sort-index", u.textContent = String(r), o.appendChild(u);
|
|
2053
2181
|
}
|
|
2054
2182
|
} else
|
|
2055
2183
|
o.removeAttribute("data-sort");
|
|
@@ -2083,7 +2211,7 @@ class Sn extends x {
|
|
|
2083
2211
|
* @returns 1-based index or undefined if not sorted
|
|
2084
2212
|
*/
|
|
2085
2213
|
getSortIndex(e) {
|
|
2086
|
-
return
|
|
2214
|
+
return be(this.sortModel, e);
|
|
2087
2215
|
}
|
|
2088
2216
|
/**
|
|
2089
2217
|
* Get the sort direction for a specific field.
|
|
@@ -2091,7 +2219,7 @@ class Sn extends x {
|
|
|
2091
2219
|
* @returns Sort direction or undefined if not sorted
|
|
2092
2220
|
*/
|
|
2093
2221
|
getSortDirection(e) {
|
|
2094
|
-
return
|
|
2222
|
+
return ve(this.sortModel, e);
|
|
2095
2223
|
}
|
|
2096
2224
|
// #endregion
|
|
2097
2225
|
// #region Column State Hooks
|
|
@@ -2124,20 +2252,20 @@ class Sn extends x {
|
|
|
2124
2252
|
}
|
|
2125
2253
|
// #endregion
|
|
2126
2254
|
// #region Styles
|
|
2127
|
-
styles =
|
|
2255
|
+
styles = kt;
|
|
2128
2256
|
// #endregion
|
|
2129
2257
|
}
|
|
2130
|
-
function Et(
|
|
2131
|
-
return
|
|
2258
|
+
function Et(s) {
|
|
2259
|
+
return s.filter((e) => e.sticky === "left");
|
|
2132
2260
|
}
|
|
2133
|
-
function
|
|
2134
|
-
return
|
|
2261
|
+
function At(s) {
|
|
2262
|
+
return s.filter((e) => e.sticky === "right");
|
|
2135
2263
|
}
|
|
2136
|
-
function
|
|
2137
|
-
return
|
|
2264
|
+
function W(s) {
|
|
2265
|
+
return s.some((e) => e.sticky === "left" || e.sticky === "right");
|
|
2138
2266
|
}
|
|
2139
|
-
function
|
|
2140
|
-
const t =
|
|
2267
|
+
function xe(s, e) {
|
|
2268
|
+
const t = s.shadowRoot;
|
|
2141
2269
|
if (!t) return;
|
|
2142
2270
|
const n = Array.from(t.querySelectorAll(".header-row .cell"));
|
|
2143
2271
|
if (!n.length) return;
|
|
@@ -2153,23 +2281,23 @@ function ve(r, e) {
|
|
|
2153
2281
|
c.classList.add("sticky-left"), c.style.position = "sticky", c.style.left = i + "px";
|
|
2154
2282
|
}), i += d.offsetWidth);
|
|
2155
2283
|
}
|
|
2156
|
-
let
|
|
2284
|
+
let r = 0;
|
|
2157
2285
|
for (const l of [...e].reverse())
|
|
2158
2286
|
if (l.sticky === "right") {
|
|
2159
2287
|
const a = o.get(l.field), d = n.find((c) => c.getAttribute("data-field") === l.field);
|
|
2160
|
-
d && (d.classList.add("sticky-right"), d.style.position = "sticky", d.style.right =
|
|
2161
|
-
c.classList.add("sticky-right"), c.style.position = "sticky", c.style.right =
|
|
2162
|
-
}),
|
|
2288
|
+
d && (d.classList.add("sticky-right"), d.style.position = "sticky", d.style.right = r + "px", a !== void 0 && t.querySelectorAll(`.data-grid-row .cell[data-col="${a}"]`).forEach((c) => {
|
|
2289
|
+
c.classList.add("sticky-right"), c.style.position = "sticky", c.style.right = r + "px";
|
|
2290
|
+
}), r += d.offsetWidth);
|
|
2163
2291
|
}
|
|
2164
2292
|
}
|
|
2165
|
-
function
|
|
2166
|
-
const e =
|
|
2293
|
+
function ye(s) {
|
|
2294
|
+
const e = s.shadowRoot;
|
|
2167
2295
|
if (!e) return;
|
|
2168
2296
|
e.querySelectorAll(".sticky-left, .sticky-right").forEach((n) => {
|
|
2169
2297
|
n.classList.remove("sticky-left", "sticky-right"), n.style.position = "", n.style.left = "", n.style.right = "";
|
|
2170
2298
|
});
|
|
2171
2299
|
}
|
|
2172
|
-
class En extends
|
|
2300
|
+
class En extends v {
|
|
2173
2301
|
name = "pinnedColumns";
|
|
2174
2302
|
version = "1.0.0";
|
|
2175
2303
|
get defaultConfig() {
|
|
@@ -2191,23 +2319,23 @@ class En extends x {
|
|
|
2191
2319
|
*/
|
|
2192
2320
|
static detect(e, t) {
|
|
2193
2321
|
const n = t?.columns;
|
|
2194
|
-
return Array.isArray(n) ?
|
|
2322
|
+
return Array.isArray(n) ? W(n) : !1;
|
|
2195
2323
|
}
|
|
2196
2324
|
// #endregion
|
|
2197
2325
|
// #region Hooks
|
|
2198
2326
|
processColumns(e) {
|
|
2199
|
-
return this.isApplied =
|
|
2327
|
+
return this.isApplied = W([...e]), [...e];
|
|
2200
2328
|
}
|
|
2201
2329
|
afterRender() {
|
|
2202
2330
|
if (!this.isApplied)
|
|
2203
2331
|
return;
|
|
2204
2332
|
const e = this.grid, t = [...this.columns];
|
|
2205
|
-
if (!
|
|
2206
|
-
|
|
2333
|
+
if (!W(t)) {
|
|
2334
|
+
ye(e), this.isApplied = !1;
|
|
2207
2335
|
return;
|
|
2208
2336
|
}
|
|
2209
2337
|
queueMicrotask(() => {
|
|
2210
|
-
|
|
2338
|
+
xe(e, t);
|
|
2211
2339
|
});
|
|
2212
2340
|
}
|
|
2213
2341
|
/**
|
|
@@ -2215,7 +2343,7 @@ class En extends x {
|
|
|
2215
2343
|
*/
|
|
2216
2344
|
onPluginQuery(e) {
|
|
2217
2345
|
switch (e.type) {
|
|
2218
|
-
case
|
|
2346
|
+
case N.CAN_MOVE_COLUMN: {
|
|
2219
2347
|
const t = e.context, n = t.sticky;
|
|
2220
2348
|
if (n === "left" || n === "right")
|
|
2221
2349
|
return !1;
|
|
@@ -2233,7 +2361,7 @@ class En extends x {
|
|
|
2233
2361
|
*/
|
|
2234
2362
|
refreshStickyOffsets() {
|
|
2235
2363
|
const e = [...this.columns];
|
|
2236
|
-
|
|
2364
|
+
xe(this.grid, e);
|
|
2237
2365
|
}
|
|
2238
2366
|
/**
|
|
2239
2367
|
* Get columns pinned to the left.
|
|
@@ -2247,13 +2375,13 @@ class En extends x {
|
|
|
2247
2375
|
*/
|
|
2248
2376
|
getRightPinnedColumns() {
|
|
2249
2377
|
const e = [...this.columns];
|
|
2250
|
-
return
|
|
2378
|
+
return At(e);
|
|
2251
2379
|
}
|
|
2252
2380
|
/**
|
|
2253
2381
|
* Clear all sticky positioning.
|
|
2254
2382
|
*/
|
|
2255
2383
|
clearStickyPositions() {
|
|
2256
|
-
|
|
2384
|
+
ye(this.grid);
|
|
2257
2385
|
}
|
|
2258
2386
|
/**
|
|
2259
2387
|
* Report horizontal scroll boundary offsets for pinned columns.
|
|
@@ -2264,8 +2392,8 @@ class En extends x {
|
|
|
2264
2392
|
return;
|
|
2265
2393
|
let n = 0, o = 0;
|
|
2266
2394
|
if (e) {
|
|
2267
|
-
const
|
|
2268
|
-
|
|
2395
|
+
const r = e.querySelectorAll(".sticky-left"), l = e.querySelectorAll(".sticky-right");
|
|
2396
|
+
r.forEach((a) => {
|
|
2269
2397
|
n += a.offsetWidth;
|
|
2270
2398
|
}), l.forEach((a) => {
|
|
2271
2399
|
o += a.offsetWidth;
|
|
@@ -2281,7 +2409,10 @@ class En extends x {
|
|
|
2281
2409
|
}
|
|
2282
2410
|
// #endregion
|
|
2283
2411
|
}
|
|
2284
|
-
function
|
|
2412
|
+
function _t(s) {
|
|
2413
|
+
return typeof s == "object" && s !== null && "aggFunc" in s;
|
|
2414
|
+
}
|
|
2415
|
+
function $(s, e) {
|
|
2285
2416
|
const t = document.createElement("div");
|
|
2286
2417
|
t.className = "tbw-pinned-rows", t.setAttribute("role", "presentation"), t.setAttribute("aria-live", "polite");
|
|
2287
2418
|
const n = document.createElement("div");
|
|
@@ -2289,22 +2420,22 @@ function W(r, e) {
|
|
|
2289
2420
|
const o = document.createElement("div");
|
|
2290
2421
|
o.className = "tbw-pinned-rows-center";
|
|
2291
2422
|
const i = document.createElement("div");
|
|
2292
|
-
if (i.className = "tbw-pinned-rows-right",
|
|
2293
|
-
const
|
|
2294
|
-
|
|
2295
|
-
}
|
|
2296
|
-
if (
|
|
2297
|
-
const
|
|
2298
|
-
|
|
2299
|
-
}
|
|
2300
|
-
if (
|
|
2301
|
-
const
|
|
2302
|
-
|
|
2303
|
-
}
|
|
2304
|
-
if (
|
|
2305
|
-
for (const
|
|
2306
|
-
const l =
|
|
2307
|
-
switch (
|
|
2423
|
+
if (i.className = "tbw-pinned-rows-right", s.showRowCount !== !1) {
|
|
2424
|
+
const r = document.createElement("span");
|
|
2425
|
+
r.className = "tbw-status-panel tbw-status-panel-row-count", r.textContent = `Total: ${e.totalRows} rows`, n.appendChild(r);
|
|
2426
|
+
}
|
|
2427
|
+
if (s.showFilteredCount && e.filteredRows !== e.totalRows) {
|
|
2428
|
+
const r = document.createElement("span");
|
|
2429
|
+
r.className = "tbw-status-panel tbw-status-panel-filtered-count", r.textContent = `Filtered: ${e.filteredRows}`, n.appendChild(r);
|
|
2430
|
+
}
|
|
2431
|
+
if (s.showSelectedCount && e.selectedRows > 0) {
|
|
2432
|
+
const r = document.createElement("span");
|
|
2433
|
+
r.className = "tbw-status-panel tbw-status-panel-selected-count", r.textContent = `Selected: ${e.selectedRows}`, i.appendChild(r);
|
|
2434
|
+
}
|
|
2435
|
+
if (s.customPanels)
|
|
2436
|
+
for (const r of s.customPanels) {
|
|
2437
|
+
const l = It(r, e);
|
|
2438
|
+
switch (r.position) {
|
|
2308
2439
|
case "left":
|
|
2309
2440
|
n.appendChild(l);
|
|
2310
2441
|
break;
|
|
@@ -2318,53 +2449,58 @@ function W(r, e) {
|
|
|
2318
2449
|
}
|
|
2319
2450
|
return t.appendChild(n), t.appendChild(o), t.appendChild(i), t;
|
|
2320
2451
|
}
|
|
2321
|
-
function
|
|
2452
|
+
function Ce(s) {
|
|
2322
2453
|
const e = document.createElement("div");
|
|
2323
|
-
return e.className = `tbw-aggregation-rows tbw-aggregation-rows-${
|
|
2454
|
+
return e.className = `tbw-aggregation-rows tbw-aggregation-rows-${s}`, e.setAttribute("role", "presentation"), e;
|
|
2324
2455
|
}
|
|
2325
|
-
function
|
|
2326
|
-
|
|
2456
|
+
function Re(s, e, t, n) {
|
|
2457
|
+
s.innerHTML = "";
|
|
2327
2458
|
for (const o of e) {
|
|
2328
2459
|
const i = document.createElement("div");
|
|
2329
2460
|
if (i.className = "tbw-aggregation-row", i.setAttribute("role", "presentation"), o.id && i.setAttribute("data-aggregation-id", o.id), o.fullWidth) {
|
|
2330
|
-
const
|
|
2331
|
-
|
|
2461
|
+
const r = document.createElement("div");
|
|
2462
|
+
r.className = "tbw-aggregation-cell tbw-aggregation-cell-full", r.style.gridColumn = "1 / -1", r.textContent = o.label || "", i.appendChild(r);
|
|
2332
2463
|
} else
|
|
2333
|
-
for (const
|
|
2464
|
+
for (const r of t) {
|
|
2334
2465
|
const l = document.createElement("div");
|
|
2335
|
-
l.className = "tbw-aggregation-cell", l.setAttribute("data-field",
|
|
2336
|
-
let a;
|
|
2337
|
-
const
|
|
2338
|
-
if (
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2466
|
+
l.className = "tbw-aggregation-cell", l.setAttribute("data-field", r.field);
|
|
2467
|
+
let a, d;
|
|
2468
|
+
const c = o.aggregators?.[r.field];
|
|
2469
|
+
if (c)
|
|
2470
|
+
if (_t(c)) {
|
|
2471
|
+
const u = le(c.aggFunc);
|
|
2472
|
+
u && (a = u(n, r.field, r)), d = c.formatter;
|
|
2473
|
+
} else {
|
|
2474
|
+
const u = le(c);
|
|
2475
|
+
u && (a = u(n, r.field, r));
|
|
2476
|
+
}
|
|
2477
|
+
else if (o.cells && Object.prototype.hasOwnProperty.call(o.cells, r.field)) {
|
|
2478
|
+
const u = o.cells[r.field];
|
|
2479
|
+
typeof u == "function" ? a = u(n, r.field, r) : a = u;
|
|
2344
2480
|
}
|
|
2345
|
-
l.textContent = a
|
|
2481
|
+
a != null ? l.textContent = d ? d(a, r.field, r) : String(a) : l.textContent = "", i.appendChild(l);
|
|
2346
2482
|
}
|
|
2347
|
-
|
|
2483
|
+
s.appendChild(i);
|
|
2348
2484
|
}
|
|
2349
2485
|
}
|
|
2350
|
-
function
|
|
2486
|
+
function It(s, e) {
|
|
2351
2487
|
const t = document.createElement("div");
|
|
2352
|
-
t.className = "tbw-status-panel tbw-status-panel-custom", t.id = `status-panel-${
|
|
2353
|
-
const n =
|
|
2488
|
+
t.className = "tbw-status-panel tbw-status-panel-custom", t.id = `status-panel-${s.id}`;
|
|
2489
|
+
const n = s.render(e);
|
|
2354
2490
|
return typeof n == "string" ? t.innerHTML = n : t.appendChild(n), t;
|
|
2355
2491
|
}
|
|
2356
|
-
function
|
|
2492
|
+
function Se(s, e, t, n, o) {
|
|
2357
2493
|
return {
|
|
2358
|
-
totalRows:
|
|
2359
|
-
filteredRows: o?.cachedResult?.length ??
|
|
2494
|
+
totalRows: s.length,
|
|
2495
|
+
filteredRows: o?.cachedResult?.length ?? s.length,
|
|
2360
2496
|
selectedRows: n?.selected?.size ?? 0,
|
|
2361
2497
|
columns: e,
|
|
2362
|
-
rows:
|
|
2498
|
+
rows: s,
|
|
2363
2499
|
grid: t
|
|
2364
2500
|
};
|
|
2365
2501
|
}
|
|
2366
|
-
const
|
|
2367
|
-
class
|
|
2502
|
+
const Lt = ".tbw-footer{position:sticky;bottom:0;z-index:var(--tbw-z-layer-pinned-rows, 20);background:var(--tbw-color-panel-bg)}.tbw-pinned-rows{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--tbw-pinned-rows-bg, var(--tbw-color-panel-bg));border-top:1px solid var(--tbw-pinned-rows-border, var(--tbw-color-border));font-size:12px;color:var(--tbw-pinned-rows-color, var(--tbw-color-fg-muted));min-height:32px;box-sizing:border-box;min-width:fit-content}.tbw-pinned-rows-left,.tbw-pinned-rows-center,.tbw-pinned-rows-right{display:flex;align-items:center;gap:16px}.tbw-pinned-rows-left{justify-content:flex-start}.tbw-pinned-rows-center{justify-content:center;flex:1}.tbw-pinned-rows-right{justify-content:flex-end}.tbw-status-panel{white-space:nowrap}.tbw-aggregation-rows{min-width:fit-content;background:var(--tbw-aggregation-bg, var(--tbw-color-header-bg))}.tbw-aggregation-rows-top{border-bottom:1px solid var(--tbw-aggregation-border, var(--tbw-color-border))}.tbw-aggregation-rows-bottom{border-top:1px solid var(--tbw-aggregation-border, var(--tbw-color-border))}.tbw-aggregation-row{display:grid;grid-template-columns:var(--tbw-column-template);font-size:var(--tbw-aggregation-font-size, .8em);font-weight:var(--tbw-aggregation-font-weight, 600)}.tbw-aggregation-cell{padding:var(--tbw-cell-padding, 2px 8px);min-height:var(--tbw-row-height, 28px);display:flex;align-items:center;border-right:1px solid var(--tbw-color-border-cell)}.tbw-aggregation-cell:last-child{border-right:0}.tbw-aggregation-cell-full{grid-column:1 / -1;border-right:0}";
|
|
2503
|
+
class An extends v {
|
|
2368
2504
|
name = "pinnedRows";
|
|
2369
2505
|
version = "1.0.0";
|
|
2370
2506
|
get defaultConfig() {
|
|
@@ -2392,20 +2528,20 @@ class kn extends x {
|
|
|
2392
2528
|
if (!e) return;
|
|
2393
2529
|
const t = e.querySelector(".tbw-scroll-area") ?? e.querySelector(".tbw-grid-content") ?? e.children[0];
|
|
2394
2530
|
if (!t) return;
|
|
2395
|
-
const n = this.getSelectionState(), o = this.getFilterState(), i =
|
|
2531
|
+
const n = this.getSelectionState(), o = this.getFilterState(), i = Se(
|
|
2396
2532
|
this.rows,
|
|
2397
2533
|
this.columns,
|
|
2398
2534
|
this.grid,
|
|
2399
2535
|
n,
|
|
2400
2536
|
o
|
|
2401
|
-
),
|
|
2537
|
+
), r = this.config.aggregationRows || [], l = r.filter((h) => h.position === "top"), a = r.filter((h) => h.position !== "top");
|
|
2402
2538
|
if (l.length > 0) {
|
|
2403
2539
|
if (!this.topAggregationContainer) {
|
|
2404
|
-
this.topAggregationContainer =
|
|
2540
|
+
this.topAggregationContainer = Ce("top");
|
|
2405
2541
|
const h = e.querySelector(".header");
|
|
2406
2542
|
h && h.nextSibling ? t.insertBefore(this.topAggregationContainer, h.nextSibling) : t.appendChild(this.topAggregationContainer);
|
|
2407
2543
|
}
|
|
2408
|
-
|
|
2544
|
+
Re(
|
|
2409
2545
|
this.topAggregationContainer,
|
|
2410
2546
|
l,
|
|
2411
2547
|
this.visibleColumns,
|
|
@@ -2415,18 +2551,18 @@ class kn extends x {
|
|
|
2415
2551
|
const d = this.config.showRowCount !== !1 || this.config.showSelectedCount && i.selectedRows > 0 || this.config.showFilteredCount && i.filteredRows !== i.totalRows || this.config.customPanels && this.config.customPanels.length > 0, c = d && this.config.position !== "top", u = a.length > 0 || c;
|
|
2416
2552
|
if (d && this.config.position === "top")
|
|
2417
2553
|
if (!this.infoBarElement)
|
|
2418
|
-
this.infoBarElement =
|
|
2554
|
+
this.infoBarElement = $(this.config, i), t.insertBefore(this.infoBarElement, t.firstChild);
|
|
2419
2555
|
else {
|
|
2420
|
-
const h =
|
|
2556
|
+
const h = $(this.config, i);
|
|
2421
2557
|
this.infoBarElement.replaceWith(h), this.infoBarElement = h;
|
|
2422
2558
|
}
|
|
2423
2559
|
else this.config.position === "top" && this.infoBarElement && (this.infoBarElement.remove(), this.infoBarElement = null);
|
|
2424
|
-
u ? (this.footerWrapper || (this.footerWrapper = document.createElement("div"), this.footerWrapper.className = "tbw-footer", t.appendChild(this.footerWrapper)), this.footerWrapper.innerHTML = "", a.length > 0 && (this.bottomAggregationContainer || (this.bottomAggregationContainer =
|
|
2560
|
+
u ? (this.footerWrapper || (this.footerWrapper = document.createElement("div"), this.footerWrapper.className = "tbw-footer", t.appendChild(this.footerWrapper)), this.footerWrapper.innerHTML = "", a.length > 0 && (this.bottomAggregationContainer || (this.bottomAggregationContainer = Ce("bottom")), this.footerWrapper.appendChild(this.bottomAggregationContainer), Re(
|
|
2425
2561
|
this.bottomAggregationContainer,
|
|
2426
2562
|
a,
|
|
2427
2563
|
this.visibleColumns,
|
|
2428
2564
|
this.rows
|
|
2429
|
-
)), c && (this.infoBarElement =
|
|
2565
|
+
)), c && (this.infoBarElement = $(this.config, i), this.footerWrapper.appendChild(this.infoBarElement))) : this.cleanupFooter();
|
|
2430
2566
|
}
|
|
2431
2567
|
// #endregion
|
|
2432
2568
|
// #region Private Methods
|
|
@@ -2464,7 +2600,7 @@ class kn extends x {
|
|
|
2464
2600
|
*/
|
|
2465
2601
|
getContext() {
|
|
2466
2602
|
const e = this.getSelectionState(), t = this.getFilterState();
|
|
2467
|
-
return
|
|
2603
|
+
return Se(
|
|
2468
2604
|
this.rows,
|
|
2469
2605
|
this.columns,
|
|
2470
2606
|
this.grid,
|
|
@@ -2502,20 +2638,20 @@ class kn extends x {
|
|
|
2502
2638
|
}
|
|
2503
2639
|
// #endregion
|
|
2504
2640
|
// #region Styles
|
|
2505
|
-
styles =
|
|
2641
|
+
styles = Lt;
|
|
2506
2642
|
// #endregion
|
|
2507
2643
|
}
|
|
2508
|
-
const
|
|
2509
|
-
function
|
|
2644
|
+
const Tt = Oe;
|
|
2645
|
+
function Ft(s) {
|
|
2510
2646
|
const e = [];
|
|
2511
|
-
return !
|
|
2647
|
+
return !s.rowGroupFields?.length && !s.columnGroupFields?.length && e.push("At least one row or column group field is required"), s.valueFields?.length || e.push("At least one value field is required"), e;
|
|
2512
2648
|
}
|
|
2513
|
-
function
|
|
2514
|
-
return [...
|
|
2649
|
+
function ne(s, e) {
|
|
2650
|
+
return [...s, e].join("|");
|
|
2515
2651
|
}
|
|
2516
|
-
function
|
|
2517
|
-
const t = e.rowGroupFields ?? [], n = e.columnGroupFields ?? [], o = e.valueFields ?? [], i =
|
|
2518
|
-
|
|
2652
|
+
function Pt(s, e) {
|
|
2653
|
+
const t = e.rowGroupFields ?? [], n = e.columnGroupFields ?? [], o = e.valueFields ?? [], i = Mt(s, n), r = qe(
|
|
2654
|
+
s,
|
|
2519
2655
|
t,
|
|
2520
2656
|
n,
|
|
2521
2657
|
i,
|
|
@@ -2524,148 +2660,148 @@ function Ft(r, e) {
|
|
|
2524
2660
|
// starting depth
|
|
2525
2661
|
""
|
|
2526
2662
|
// parent key prefix
|
|
2527
|
-
), l = Nt(
|
|
2663
|
+
), l = Nt(r, i, o), a = Object.values(l).reduce((d, c) => d + c, 0);
|
|
2528
2664
|
return {
|
|
2529
|
-
rows:
|
|
2665
|
+
rows: r,
|
|
2530
2666
|
columnKeys: i,
|
|
2531
2667
|
totals: l,
|
|
2532
2668
|
grandTotal: a
|
|
2533
2669
|
};
|
|
2534
2670
|
}
|
|
2535
|
-
function
|
|
2671
|
+
function Mt(s, e) {
|
|
2536
2672
|
if (e.length === 0) return ["value"];
|
|
2537
2673
|
const t = /* @__PURE__ */ new Set();
|
|
2538
|
-
for (const n of
|
|
2674
|
+
for (const n of s) {
|
|
2539
2675
|
const o = e.map((i) => String(n[i] ?? "")).join("|");
|
|
2540
2676
|
t.add(o);
|
|
2541
2677
|
}
|
|
2542
2678
|
return [...t].sort();
|
|
2543
2679
|
}
|
|
2544
|
-
function
|
|
2680
|
+
function Kt(s, e) {
|
|
2545
2681
|
const t = /* @__PURE__ */ new Map();
|
|
2546
|
-
for (const n of
|
|
2682
|
+
for (const n of s) {
|
|
2547
2683
|
const o = String(n[e] ?? ""), i = t.get(o);
|
|
2548
2684
|
i ? i.push(n) : t.set(o, [n]);
|
|
2549
2685
|
}
|
|
2550
2686
|
return t;
|
|
2551
2687
|
}
|
|
2552
|
-
function qe(
|
|
2688
|
+
function qe(s, e, t, n, o, i, r) {
|
|
2553
2689
|
const l = [];
|
|
2554
2690
|
if (e.length === 0) {
|
|
2555
|
-
const h =
|
|
2691
|
+
const h = ke(s, t, n, o), g = Ee(h);
|
|
2556
2692
|
return l.push({
|
|
2557
|
-
rowKey:
|
|
2558
|
-
rowLabel:
|
|
2693
|
+
rowKey: r || "all",
|
|
2694
|
+
rowLabel: r || "All",
|
|
2559
2695
|
depth: i,
|
|
2560
2696
|
values: h,
|
|
2561
2697
|
total: g,
|
|
2562
2698
|
isGroup: !1,
|
|
2563
|
-
rowCount:
|
|
2699
|
+
rowCount: s.length
|
|
2564
2700
|
}), l;
|
|
2565
2701
|
}
|
|
2566
|
-
const a = e[0], d = e.slice(1), c = d.length > 0, u =
|
|
2702
|
+
const a = e[0], d = e.slice(1), c = d.length > 0, u = Kt(s, a);
|
|
2567
2703
|
for (const [h, g] of u) {
|
|
2568
|
-
const
|
|
2569
|
-
let
|
|
2570
|
-
c && (
|
|
2704
|
+
const f = r ? `${r}|${h}` : h, m = ke(g, t, n, o), p = Ee(m);
|
|
2705
|
+
let R;
|
|
2706
|
+
c && (R = qe(
|
|
2571
2707
|
g,
|
|
2572
2708
|
d,
|
|
2573
2709
|
t,
|
|
2574
2710
|
n,
|
|
2575
2711
|
o,
|
|
2576
2712
|
i + 1,
|
|
2577
|
-
|
|
2713
|
+
f
|
|
2578
2714
|
)), l.push({
|
|
2579
|
-
rowKey:
|
|
2715
|
+
rowKey: f,
|
|
2580
2716
|
rowLabel: h || "(blank)",
|
|
2581
2717
|
depth: i,
|
|
2582
|
-
values:
|
|
2583
|
-
total:
|
|
2718
|
+
values: m,
|
|
2719
|
+
total: p,
|
|
2584
2720
|
isGroup: c,
|
|
2585
|
-
children:
|
|
2721
|
+
children: R,
|
|
2586
2722
|
rowCount: g.length
|
|
2587
2723
|
});
|
|
2588
2724
|
}
|
|
2589
2725
|
return l;
|
|
2590
2726
|
}
|
|
2591
|
-
function
|
|
2727
|
+
function ke(s, e, t, n) {
|
|
2592
2728
|
const o = {};
|
|
2593
2729
|
for (const i of t)
|
|
2594
|
-
for (const
|
|
2595
|
-
const a = (e.length > 0 ?
|
|
2730
|
+
for (const r of n) {
|
|
2731
|
+
const a = (e.length > 0 ? s.filter((h) => e.map((g) => String(h[g] ?? "")).join("|") === i) : s).map((h) => Number(h[r.field]) || 0), d = Tt(r.aggFunc), c = a.length > 0 ? d(a) : null, u = ne([i], r.field);
|
|
2596
2732
|
o[u] = c;
|
|
2597
2733
|
}
|
|
2598
2734
|
return o;
|
|
2599
2735
|
}
|
|
2600
|
-
function Ee(
|
|
2736
|
+
function Ee(s) {
|
|
2601
2737
|
let e = 0;
|
|
2602
|
-
for (const t of Object.values(
|
|
2738
|
+
for (const t of Object.values(s))
|
|
2603
2739
|
e += t ?? 0;
|
|
2604
2740
|
return e;
|
|
2605
2741
|
}
|
|
2606
|
-
function Nt(
|
|
2742
|
+
function Nt(s, e, t) {
|
|
2607
2743
|
const n = {};
|
|
2608
2744
|
function o(i) {
|
|
2609
|
-
for (const
|
|
2610
|
-
if (!
|
|
2745
|
+
for (const r of i)
|
|
2746
|
+
if (!r.isGroup || !r.children?.length)
|
|
2611
2747
|
for (const l of e)
|
|
2612
2748
|
for (const a of t) {
|
|
2613
|
-
const d =
|
|
2614
|
-
n[d] = (n[d] ?? 0) + (
|
|
2749
|
+
const d = ne([l], a.field);
|
|
2750
|
+
n[d] = (n[d] ?? 0) + (r.values[d] ?? 0);
|
|
2615
2751
|
}
|
|
2616
|
-
else
|
|
2752
|
+
else r.children && o(r.children);
|
|
2617
2753
|
}
|
|
2618
|
-
return o(
|
|
2754
|
+
return o(s), n;
|
|
2619
2755
|
}
|
|
2620
|
-
function
|
|
2756
|
+
function qt(s, e, t = !0) {
|
|
2621
2757
|
const n = [];
|
|
2622
2758
|
function o(i) {
|
|
2623
2759
|
n.push(i);
|
|
2624
|
-
const
|
|
2625
|
-
if (i.children &&
|
|
2760
|
+
const r = e ? e.has(i.rowKey) : t;
|
|
2761
|
+
if (i.children && r)
|
|
2626
2762
|
for (const l of i.children)
|
|
2627
2763
|
o(l);
|
|
2628
2764
|
}
|
|
2629
|
-
for (const i of
|
|
2765
|
+
for (const i of s)
|
|
2630
2766
|
o(i);
|
|
2631
2767
|
return n;
|
|
2632
2768
|
}
|
|
2633
|
-
function
|
|
2769
|
+
function j(s) {
|
|
2634
2770
|
const e = [];
|
|
2635
2771
|
function t(n) {
|
|
2636
2772
|
if (n.isGroup && e.push(n.rowKey), n.children)
|
|
2637
2773
|
for (const o of n.children)
|
|
2638
2774
|
t(o);
|
|
2639
2775
|
}
|
|
2640
|
-
for (const n of
|
|
2776
|
+
for (const n of s)
|
|
2641
2777
|
t(n);
|
|
2642
2778
|
return e;
|
|
2643
2779
|
}
|
|
2644
|
-
const
|
|
2645
|
-
function
|
|
2646
|
-
const o = new AbortController(), i = { config: e, callbacks: n, signal: o.signal },
|
|
2647
|
-
return
|
|
2648
|
-
o.abort(),
|
|
2780
|
+
const Dt = ["sum", "avg", "count", "min", "max", "first", "last"];
|
|
2781
|
+
function Ht(s, e, t, n) {
|
|
2782
|
+
const o = new AbortController(), i = { config: e, callbacks: n, signal: o.signal }, r = document.createElement("div");
|
|
2783
|
+
return r.className = "tbw-pivot-panel", r.appendChild(L("Options", () => zt(t, i))), r.appendChild(L("Row Groups", () => Ae("rowGroups", i))), r.appendChild(L("Column Groups", () => Ae("columnGroups", i))), r.appendChild(L("Values", () => Ot(i))), r.appendChild(L("Available Fields", () => Bt(i))), s.appendChild(r), () => {
|
|
2784
|
+
o.abort(), r.remove();
|
|
2649
2785
|
};
|
|
2650
2786
|
}
|
|
2651
|
-
function L(
|
|
2787
|
+
function L(s, e) {
|
|
2652
2788
|
const t = document.createElement("div");
|
|
2653
2789
|
t.className = "tbw-pivot-section";
|
|
2654
2790
|
const n = document.createElement("div");
|
|
2655
|
-
n.className = "tbw-pivot-section-header", n.textContent =
|
|
2791
|
+
n.className = "tbw-pivot-section-header", n.textContent = s;
|
|
2656
2792
|
const o = document.createElement("div");
|
|
2657
2793
|
return o.className = "tbw-pivot-section-content", o.appendChild(e()), t.appendChild(n), t.appendChild(o), t;
|
|
2658
2794
|
}
|
|
2659
|
-
function
|
|
2795
|
+
function Ae(s, e) {
|
|
2660
2796
|
const { config: t, callbacks: n, signal: o } = e, i = document.createElement("div");
|
|
2661
|
-
i.className = "tbw-pivot-drop-zone", i.setAttribute("data-zone",
|
|
2662
|
-
const
|
|
2663
|
-
if (
|
|
2797
|
+
i.className = "tbw-pivot-drop-zone", i.setAttribute("data-zone", s);
|
|
2798
|
+
const r = s === "rowGroups" ? t.rowGroupFields ?? [] : t.columnGroupFields ?? [];
|
|
2799
|
+
if (r.length === 0) {
|
|
2664
2800
|
const l = document.createElement("div");
|
|
2665
2801
|
l.className = "tbw-pivot-placeholder", l.textContent = "Drag fields here or click to add", i.appendChild(l);
|
|
2666
2802
|
} else
|
|
2667
|
-
for (const l of
|
|
2668
|
-
i.appendChild(
|
|
2803
|
+
for (const l of r)
|
|
2804
|
+
i.appendChild(Vt(l, s, e));
|
|
2669
2805
|
return i.addEventListener(
|
|
2670
2806
|
"dragover",
|
|
2671
2807
|
(l) => {
|
|
@@ -2683,27 +2819,27 @@ function ke(r, e) {
|
|
|
2683
2819
|
(l) => {
|
|
2684
2820
|
l.preventDefault(), i.classList.remove("drag-over");
|
|
2685
2821
|
const a = l.dataTransfer?.getData("text/plain");
|
|
2686
|
-
a && n.onAddFieldToZone(a,
|
|
2822
|
+
a && n.onAddFieldToZone(a, s);
|
|
2687
2823
|
},
|
|
2688
2824
|
{ signal: o }
|
|
2689
2825
|
), i;
|
|
2690
2826
|
}
|
|
2691
|
-
function
|
|
2827
|
+
function Vt(s, e, t) {
|
|
2692
2828
|
const { callbacks: n, signal: o } = t, i = document.createElement("div");
|
|
2693
2829
|
i.className = "tbw-pivot-field-chip", i.draggable = !0;
|
|
2694
|
-
const
|
|
2695
|
-
l.className = "tbw-pivot-chip-label", l.textContent =
|
|
2830
|
+
const r = n.getAvailableFields().find((d) => d.field === s), l = document.createElement("span");
|
|
2831
|
+
l.className = "tbw-pivot-chip-label", l.textContent = r?.header ?? s;
|
|
2696
2832
|
const a = document.createElement("button");
|
|
2697
2833
|
return a.className = "tbw-pivot-chip-remove", a.innerHTML = "×", a.title = "Remove field", a.addEventListener(
|
|
2698
2834
|
"click",
|
|
2699
2835
|
(d) => {
|
|
2700
|
-
d.stopPropagation(), n.onRemoveFieldFromZone(
|
|
2836
|
+
d.stopPropagation(), n.onRemoveFieldFromZone(s, e);
|
|
2701
2837
|
},
|
|
2702
2838
|
{ signal: o }
|
|
2703
2839
|
), i.appendChild(l), i.appendChild(a), i.addEventListener(
|
|
2704
2840
|
"dragstart",
|
|
2705
2841
|
(d) => {
|
|
2706
|
-
d.dataTransfer?.setData("text/plain",
|
|
2842
|
+
d.dataTransfer?.setData("text/plain", s), d.dataTransfer?.setData("source-zone", e), i.classList.add("dragging");
|
|
2707
2843
|
},
|
|
2708
2844
|
{ signal: o }
|
|
2709
2845
|
), i.addEventListener(
|
|
@@ -2714,20 +2850,20 @@ function Kt(r, e, t) {
|
|
|
2714
2850
|
{ signal: o }
|
|
2715
2851
|
), i;
|
|
2716
2852
|
}
|
|
2717
|
-
function
|
|
2718
|
-
const { config: e, callbacks: t, signal: n } =
|
|
2853
|
+
function Ot(s) {
|
|
2854
|
+
const { config: e, callbacks: t, signal: n } = s, o = document.createElement("div");
|
|
2719
2855
|
o.className = "tbw-pivot-drop-zone tbw-pivot-values-zone", o.setAttribute("data-zone", "values");
|
|
2720
2856
|
const i = e.valueFields ?? [];
|
|
2721
2857
|
if (i.length === 0) {
|
|
2722
|
-
const
|
|
2723
|
-
|
|
2858
|
+
const r = document.createElement("div");
|
|
2859
|
+
r.className = "tbw-pivot-placeholder", r.textContent = "Drag numeric fields here for aggregation", o.appendChild(r);
|
|
2724
2860
|
} else
|
|
2725
|
-
for (const
|
|
2726
|
-
o.appendChild(Gt(
|
|
2861
|
+
for (const r of i)
|
|
2862
|
+
o.appendChild(Gt(r, s));
|
|
2727
2863
|
return o.addEventListener(
|
|
2728
2864
|
"dragover",
|
|
2729
|
-
(
|
|
2730
|
-
|
|
2865
|
+
(r) => {
|
|
2866
|
+
r.preventDefault(), o.classList.add("drag-over");
|
|
2731
2867
|
},
|
|
2732
2868
|
{ signal: n }
|
|
2733
2869
|
), o.addEventListener(
|
|
@@ -2738,31 +2874,31 @@ function Ht(r) {
|
|
|
2738
2874
|
{ signal: n }
|
|
2739
2875
|
), o.addEventListener(
|
|
2740
2876
|
"drop",
|
|
2741
|
-
(
|
|
2742
|
-
|
|
2743
|
-
const l =
|
|
2877
|
+
(r) => {
|
|
2878
|
+
r.preventDefault(), o.classList.remove("drag-over");
|
|
2879
|
+
const l = r.dataTransfer?.getData("text/plain");
|
|
2744
2880
|
l && t.onAddValueField(l, "sum");
|
|
2745
2881
|
},
|
|
2746
2882
|
{ signal: n }
|
|
2747
2883
|
), o;
|
|
2748
2884
|
}
|
|
2749
|
-
function Gt(
|
|
2885
|
+
function Gt(s, e) {
|
|
2750
2886
|
const { callbacks: t, signal: n } = e, o = document.createElement("div");
|
|
2751
2887
|
o.className = "tbw-pivot-field-chip tbw-pivot-value-chip";
|
|
2752
|
-
const i = t.getAvailableFields().find((c) => c.field ===
|
|
2753
|
-
|
|
2888
|
+
const i = t.getAvailableFields().find((c) => c.field === s.field), r = document.createElement("div");
|
|
2889
|
+
r.className = "tbw-pivot-value-label-wrapper";
|
|
2754
2890
|
const l = document.createElement("span");
|
|
2755
|
-
l.className = "tbw-pivot-chip-label", l.textContent = i?.header ??
|
|
2891
|
+
l.className = "tbw-pivot-chip-label", l.textContent = i?.header ?? s.field;
|
|
2756
2892
|
const a = document.createElement("select");
|
|
2757
2893
|
a.className = "tbw-pivot-agg-select", a.title = "Aggregation function";
|
|
2758
|
-
for (const c of
|
|
2894
|
+
for (const c of Dt) {
|
|
2759
2895
|
const u = document.createElement("option");
|
|
2760
|
-
u.value = c, u.textContent = c.toUpperCase(), u.selected = c ===
|
|
2896
|
+
u.value = c, u.textContent = c.toUpperCase(), u.selected = c === s.aggFunc, a.appendChild(u);
|
|
2761
2897
|
}
|
|
2762
2898
|
a.addEventListener(
|
|
2763
2899
|
"change",
|
|
2764
2900
|
() => {
|
|
2765
|
-
t.onUpdateValueAggFunc(
|
|
2901
|
+
t.onUpdateValueAggFunc(s.field, a.value);
|
|
2766
2902
|
},
|
|
2767
2903
|
{ signal: n }
|
|
2768
2904
|
);
|
|
@@ -2770,19 +2906,19 @@ function Gt(r, e) {
|
|
|
2770
2906
|
return d.className = "tbw-pivot-chip-remove", d.innerHTML = "×", d.title = "Remove value field", d.addEventListener(
|
|
2771
2907
|
"click",
|
|
2772
2908
|
(c) => {
|
|
2773
|
-
c.stopPropagation(), t.onRemoveValueField(
|
|
2909
|
+
c.stopPropagation(), t.onRemoveValueField(s.field);
|
|
2774
2910
|
},
|
|
2775
2911
|
{ signal: n }
|
|
2776
|
-
),
|
|
2912
|
+
), r.appendChild(l), r.appendChild(a), o.appendChild(r), o.appendChild(d), o;
|
|
2777
2913
|
}
|
|
2778
|
-
function
|
|
2779
|
-
const { config: e, callbacks: t, signal: n } =
|
|
2914
|
+
function Bt(s) {
|
|
2915
|
+
const { config: e, callbacks: t, signal: n } = s, o = document.createElement("div");
|
|
2780
2916
|
o.className = "tbw-pivot-available-fields";
|
|
2781
|
-
const i = t.getAvailableFields(),
|
|
2917
|
+
const i = t.getAvailableFields(), r = /* @__PURE__ */ new Set([
|
|
2782
2918
|
...e.rowGroupFields ?? [],
|
|
2783
2919
|
...e.columnGroupFields ?? [],
|
|
2784
2920
|
...e.valueFields?.map((a) => a.field) ?? []
|
|
2785
|
-
]), l = i.filter((a) => !
|
|
2921
|
+
]), l = i.filter((a) => !r.has(a.field));
|
|
2786
2922
|
if (l.length === 0) {
|
|
2787
2923
|
const a = document.createElement("div");
|
|
2788
2924
|
a.className = "tbw-pivot-placeholder", a.textContent = "All fields are in use", o.appendChild(a);
|
|
@@ -2805,96 +2941,96 @@ function Ot(r) {
|
|
|
2805
2941
|
}
|
|
2806
2942
|
return o;
|
|
2807
2943
|
}
|
|
2808
|
-
function
|
|
2944
|
+
function zt(s, e) {
|
|
2809
2945
|
const { config: t, callbacks: n, signal: o } = e, i = document.createElement("div");
|
|
2810
2946
|
return i.className = "tbw-pivot-options", i.appendChild(
|
|
2811
|
-
|
|
2947
|
+
U(
|
|
2812
2948
|
"Enable Pivot View",
|
|
2813
|
-
|
|
2814
|
-
(
|
|
2815
|
-
n.onTogglePivot(
|
|
2949
|
+
s,
|
|
2950
|
+
(r) => {
|
|
2951
|
+
n.onTogglePivot(r);
|
|
2816
2952
|
},
|
|
2817
2953
|
o
|
|
2818
2954
|
)
|
|
2819
2955
|
), i.appendChild(
|
|
2820
|
-
|
|
2956
|
+
U(
|
|
2821
2957
|
"Show Row Totals",
|
|
2822
2958
|
t.showTotals ?? !0,
|
|
2823
|
-
(
|
|
2824
|
-
n.onOptionChange("showTotals",
|
|
2959
|
+
(r) => {
|
|
2960
|
+
n.onOptionChange("showTotals", r);
|
|
2825
2961
|
},
|
|
2826
2962
|
o
|
|
2827
2963
|
)
|
|
2828
2964
|
), i.appendChild(
|
|
2829
|
-
|
|
2965
|
+
U(
|
|
2830
2966
|
"Show Grand Total",
|
|
2831
2967
|
t.showGrandTotal ?? !0,
|
|
2832
|
-
(
|
|
2833
|
-
n.onOptionChange("showGrandTotal",
|
|
2968
|
+
(r) => {
|
|
2969
|
+
n.onOptionChange("showGrandTotal", r);
|
|
2834
2970
|
},
|
|
2835
2971
|
o
|
|
2836
2972
|
)
|
|
2837
2973
|
), i;
|
|
2838
2974
|
}
|
|
2839
|
-
function
|
|
2975
|
+
function U(s, e, t, n) {
|
|
2840
2976
|
const o = document.createElement("label");
|
|
2841
2977
|
o.className = "tbw-pivot-checkbox";
|
|
2842
2978
|
const i = document.createElement("input");
|
|
2843
2979
|
i.type = "checkbox", i.checked = e, i.addEventListener("change", () => t(i.checked), { signal: n });
|
|
2844
|
-
const
|
|
2845
|
-
return
|
|
2980
|
+
const r = document.createElement("span");
|
|
2981
|
+
return r.textContent = s, o.appendChild(i), o.appendChild(r), o;
|
|
2846
2982
|
}
|
|
2847
|
-
function
|
|
2848
|
-
return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(
|
|
2983
|
+
function Wt(s, e, t) {
|
|
2984
|
+
return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(s.__pivotRowKey ?? "")), e.setAttribute("role", "row"), e.innerHTML = "", t.columns.forEach((n, o) => {
|
|
2849
2985
|
const i = document.createElement("div");
|
|
2850
2986
|
if (i.className = "cell", i.setAttribute("data-col", String(o)), i.setAttribute("role", "gridcell"), o === 0) {
|
|
2851
|
-
const
|
|
2852
|
-
i.style.paddingLeft = `${
|
|
2853
|
-
const l = String(
|
|
2854
|
-
a.type = "button", a.className = "pivot-toggle", a.setAttribute("aria-label",
|
|
2987
|
+
const r = Number(s.__pivotIndent) || 0;
|
|
2988
|
+
i.style.paddingLeft = `${r}px`;
|
|
2989
|
+
const l = String(s.__pivotRowKey), a = document.createElement("button");
|
|
2990
|
+
a.type = "button", a.className = "pivot-toggle", a.setAttribute("aria-label", s.__pivotExpanded ? "Collapse group" : "Expand group"), t.setIcon(a, t.resolveIcon(s.__pivotExpanded ? "collapse" : "expand")), a.addEventListener("click", (u) => {
|
|
2855
2991
|
u.stopPropagation(), t.onToggle(l);
|
|
2856
2992
|
}), i.appendChild(a);
|
|
2857
2993
|
const d = document.createElement("span");
|
|
2858
|
-
d.className = "pivot-label", d.textContent = String(
|
|
2994
|
+
d.className = "pivot-label", d.textContent = String(s.__pivotLabel ?? ""), i.appendChild(d);
|
|
2859
2995
|
const c = document.createElement("span");
|
|
2860
|
-
c.className = "pivot-count", c.textContent = ` (${Number(
|
|
2996
|
+
c.className = "pivot-count", c.textContent = ` (${Number(s.__pivotRowCount) || 0})`, i.appendChild(c);
|
|
2861
2997
|
} else {
|
|
2862
|
-
const
|
|
2863
|
-
i.textContent =
|
|
2998
|
+
const r = s[n.field];
|
|
2999
|
+
i.textContent = r != null ? String(r) : "";
|
|
2864
3000
|
}
|
|
2865
3001
|
e.appendChild(i);
|
|
2866
3002
|
}), !0;
|
|
2867
3003
|
}
|
|
2868
|
-
function
|
|
2869
|
-
return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(
|
|
3004
|
+
function $t(s, e, t) {
|
|
3005
|
+
return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(s.__pivotRowKey ?? "")), e.innerHTML = "", t.forEach((n, o) => {
|
|
2870
3006
|
const i = document.createElement("div");
|
|
2871
3007
|
if (i.className = "cell", i.setAttribute("data-col", String(o)), i.setAttribute("role", "gridcell"), o === 0) {
|
|
2872
|
-
const
|
|
2873
|
-
i.style.paddingLeft = `${
|
|
3008
|
+
const r = Number(s.__pivotIndent) || 0;
|
|
3009
|
+
i.style.paddingLeft = `${r + 20}px`;
|
|
2874
3010
|
const l = document.createElement("span");
|
|
2875
|
-
l.className = "pivot-label", l.textContent = String(
|
|
3011
|
+
l.className = "pivot-label", l.textContent = String(s.__pivotLabel ?? ""), i.appendChild(l);
|
|
2876
3012
|
} else {
|
|
2877
|
-
const
|
|
2878
|
-
i.textContent =
|
|
3013
|
+
const r = s[n.field];
|
|
3014
|
+
i.textContent = r != null ? String(r) : "";
|
|
2879
3015
|
}
|
|
2880
3016
|
e.appendChild(i);
|
|
2881
3017
|
}), !0;
|
|
2882
3018
|
}
|
|
2883
|
-
function
|
|
3019
|
+
function jt(s, e, t) {
|
|
2884
3020
|
return e.className = "pivot-grand-total-row", e.setAttribute("role", "presentation"), e.innerHTML = "", t.forEach((n, o) => {
|
|
2885
3021
|
const i = document.createElement("div");
|
|
2886
3022
|
if (i.className = "cell", i.setAttribute("data-col", String(o)), o === 0) {
|
|
2887
|
-
const
|
|
2888
|
-
|
|
3023
|
+
const r = document.createElement("span");
|
|
3024
|
+
r.className = "pivot-label", r.textContent = "Grand Total", i.appendChild(r);
|
|
2889
3025
|
} else {
|
|
2890
|
-
const
|
|
2891
|
-
i.textContent =
|
|
3026
|
+
const r = s[n.field];
|
|
3027
|
+
i.textContent = r != null ? String(r) : "";
|
|
2892
3028
|
}
|
|
2893
3029
|
e.appendChild(i);
|
|
2894
3030
|
}), !0;
|
|
2895
3031
|
}
|
|
2896
|
-
const
|
|
2897
|
-
class
|
|
3032
|
+
const Ut = '.pivot-group-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:600;background:var(--tbw-pivot-group-bg, var(--tbw-color-row-alt));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-group-row:hover{background:var(--tbw-pivot-group-hover, var(--tbw-color-row-hover))}.pivot-leaf-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-pivot-leaf-bg, var(--tbw-color-bg));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-grand-total-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:700;background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-height:var(--tbw-row-height);border-top:2px solid var(--tbw-color-border-strong)}.pivot-grand-total-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-grand-total-row>.cell:last-child{border-right:0}.pivot-grand-total-footer{position:sticky;bottom:0;z-index:var(--tbw-z-layer-pinned-rows, 20);background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-width:fit-content}.pivot-group-row>.cell,.pivot-leaf-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-group-row>.cell:last-child,.pivot-leaf-row>.cell:last-child{border-right:0}.pivot-toggle{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-right:6px;border:none;background:transparent;cursor:pointer;color:var(--tbw-pivot-toggle-color, var(--tbw-color-fg-muted));border-radius:var(--tbw-border-radius);transition:background .15s,color .15s}.pivot-toggle:hover{background:var(--tbw-pivot-toggle-hover-bg, var(--tbw-color-row-hover));color:var(--tbw-pivot-toggle-hover-color, var(--tbw-color-fg))}.pivot-toggle:focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}.pivot-label{font-weight:inherit}.pivot-count{color:var(--tbw-pivot-count-color, var(--tbw-color-fg-muted));font-size:.9em;font-weight:400}.pivot-total-row{font-weight:700;border-top:2px solid var(--tbw-pivot-border, var(--tbw-color-border-strong))}[data-pivot-depth="1"]{--tbw-pivot-depth: 1}[data-pivot-depth="2"]{--tbw-pivot-depth: 2}[data-pivot-depth="3"]{--tbw-pivot-depth: 3}[data-pivot-depth="4"]{--tbw-pivot-depth: 4}.tbw-pivot-panel{display:flex;flex-direction:column;gap:12px;padding:12px;height:100%;overflow-y:auto;font-size:13px}.tbw-pivot-section{border:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-section-bg, var(--tbw-color-bg))}.tbw-pivot-section-header{padding:8px 12px;font-weight:600;background:var(--tbw-pivot-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius) var(--tbw-border-radius) 0 0}.tbw-pivot-section-content{padding:8px}.tbw-pivot-toggle-wrapper{display:flex;align-items:center}.tbw-pivot-toggle-label{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-toggle-label input{width:16px;height:16px;cursor:pointer}.tbw-pivot-drop-zone{min-height:60px;padding:8px;border:2px dashed var(--tbw-pivot-drop-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-drop-bg, var(--tbw-color-row-alt));display:flex;flex-wrap:wrap;gap:6px;align-content:flex-start;transition:all .15s ease}.tbw-pivot-drop-zone.drag-over{border-color:var(--tbw-color-accent);background:var(--tbw-pivot-drop-active, var(--tbw-focus-background))}.tbw-pivot-placeholder{color:var(--tbw-color-fg-muted);font-style:italic;padding:8px;text-align:center;width:100%}.tbw-pivot-field-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;background:var(--tbw-pivot-chip-bg, var(--tbw-color-header-bg));border:1px solid var(--tbw-pivot-chip-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);cursor:grab;font-size:12px;transition:all .15s ease}.tbw-pivot-field-chip:hover{background:var(--tbw-pivot-chip-hover, var(--tbw-color-row-hover));border-color:var(--tbw-color-accent)}.tbw-pivot-field-chip.available{background:var(--tbw-color-bg)}.tbw-pivot-field-chip.dragging{opacity:.5;cursor:grabbing}.tbw-pivot-chip-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:120px}.tbw-pivot-chip-remove{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:var(--tbw-color-fg-muted);font-size:14px;font-weight:700;cursor:pointer;border-radius:50%;transition:all .15s ease}.tbw-pivot-chip-remove:hover{background:var(--tbw-pivot-chip-remove-hover-bg, var(--tbw-color-accent));color:var(--tbw-pivot-chip-remove-hover-fg, var(--tbw-color-accent-fg))}.tbw-pivot-value-chip{padding:4px 8px}.tbw-pivot-value-label-wrapper{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.tbw-pivot-agg-select{padding:2px 4px;font-size:11px;border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);cursor:pointer}.tbw-pivot-available-fields{display:flex;flex-wrap:wrap;gap:6px;min-height:40px}.tbw-pivot-options{display:flex;flex-direction:column;gap:8px}.tbw-pivot-checkbox{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-checkbox input{width:14px;height:14px;cursor:pointer}.pivot-group-row.tbw-pivot-slide-in,.pivot-leaf-row.tbw-pivot-slide-in{animation:tbw-pivot-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-pivot-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.pivot-group-row.tbw-pivot-fade-in,.pivot-leaf-row.tbw-pivot-fade-in{animation:tbw-pivot-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-pivot-fade-in{0%{opacity:0}to{opacity:1}}';
|
|
3033
|
+
class T extends v {
|
|
2898
3034
|
name = "pivot";
|
|
2899
3035
|
version = "1.0.0";
|
|
2900
3036
|
/** Tool panel ID for shell integration */
|
|
@@ -2903,7 +3039,9 @@ class F extends x {
|
|
|
2903
3039
|
return {
|
|
2904
3040
|
active: !0,
|
|
2905
3041
|
showTotals: !0,
|
|
2906
|
-
showGrandTotal: !0
|
|
3042
|
+
showGrandTotal: !0,
|
|
3043
|
+
showToolPanel: !0,
|
|
3044
|
+
animation: "slide"
|
|
2907
3045
|
};
|
|
2908
3046
|
}
|
|
2909
3047
|
// #region Internal State
|
|
@@ -2916,64 +3054,86 @@ class F extends x {
|
|
|
2916
3054
|
originalColumns = [];
|
|
2917
3055
|
panelContainer = null;
|
|
2918
3056
|
grandTotalFooter = null;
|
|
3057
|
+
previousVisibleKeys = /* @__PURE__ */ new Set();
|
|
3058
|
+
keysToAnimate = /* @__PURE__ */ new Set();
|
|
2919
3059
|
/**
|
|
2920
3060
|
* Check if the plugin has valid pivot configuration (at least value fields).
|
|
2921
3061
|
*/
|
|
2922
3062
|
hasValidPivotConfig() {
|
|
2923
3063
|
return (this.config.valueFields?.length ?? 0) > 0;
|
|
2924
3064
|
}
|
|
3065
|
+
/**
|
|
3066
|
+
* Get animation style respecting grid-level animation mode.
|
|
3067
|
+
*/
|
|
3068
|
+
get animationStyle() {
|
|
3069
|
+
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
3070
|
+
if (t === !1 || t === "off") return !1;
|
|
3071
|
+
if (t !== !0 && t !== "on") {
|
|
3072
|
+
const n = this.shadowRoot?.host;
|
|
3073
|
+
if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
3074
|
+
return !1;
|
|
3075
|
+
}
|
|
3076
|
+
return this.config.animation ?? "slide";
|
|
3077
|
+
}
|
|
2925
3078
|
// #endregion
|
|
2926
3079
|
// #region Lifecycle
|
|
2927
3080
|
detach() {
|
|
2928
|
-
this.isActive = !1, this.hasInitialized = !1, this.pivotResult = null, this.fieldHeaderMap.clear(), this.originalColumns = [], this.panelContainer = null, this.cleanupGrandTotalFooter();
|
|
3081
|
+
this.isActive = !1, this.hasInitialized = !1, this.pivotResult = null, this.fieldHeaderMap.clear(), this.originalColumns = [], this.panelContainer = null, this.cleanupGrandTotalFooter(), this.previousVisibleKeys.clear(), this.keysToAnimate.clear();
|
|
2929
3082
|
}
|
|
2930
3083
|
// #endregion
|
|
2931
3084
|
// #region Shell Integration
|
|
2932
3085
|
getToolPanel() {
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
3086
|
+
if ((this.config?.showToolPanel ?? this.userConfig?.showToolPanel ?? !0) !== !1)
|
|
3087
|
+
return {
|
|
3088
|
+
id: T.PANEL_ID,
|
|
3089
|
+
title: "Pivot",
|
|
3090
|
+
icon: "⊞",
|
|
3091
|
+
tooltip: "Configure pivot table",
|
|
3092
|
+
order: 90,
|
|
3093
|
+
render: (t) => this.renderPanel(t)
|
|
3094
|
+
};
|
|
2941
3095
|
}
|
|
2942
3096
|
// #endregion
|
|
2943
3097
|
// #region Hooks
|
|
2944
3098
|
processRows(e) {
|
|
2945
3099
|
if (!this.hasInitialized && this.config.active !== !1 && this.hasValidPivotConfig() && (this.hasInitialized = !0, this.isActive = !0), !this.isActive)
|
|
2946
3100
|
return [...e];
|
|
2947
|
-
const t =
|
|
3101
|
+
const t = Ft(this.config);
|
|
2948
3102
|
if (t.length > 0)
|
|
2949
3103
|
return this.warn(`Config errors: ${t.join(", ")}`), [...e];
|
|
2950
3104
|
if (this.buildFieldHeaderMap(), this.defaultExpanded = this.config.defaultExpanded ?? !0, this.expandedKeys.size === 0 && this.defaultExpanded && this.pivotResult) {
|
|
2951
|
-
const
|
|
2952
|
-
for (const
|
|
2953
|
-
this.expandedKeys.add(
|
|
3105
|
+
const r = j(this.pivotResult.rows);
|
|
3106
|
+
for (const l of r)
|
|
3107
|
+
this.expandedKeys.add(l);
|
|
2954
3108
|
}
|
|
2955
|
-
if (this.pivotResult =
|
|
2956
|
-
const
|
|
2957
|
-
for (const
|
|
2958
|
-
this.expandedKeys.add(
|
|
3109
|
+
if (this.pivotResult = Pt(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded) {
|
|
3110
|
+
const r = j(this.pivotResult.rows);
|
|
3111
|
+
for (const l of r)
|
|
3112
|
+
this.expandedKeys.add(l);
|
|
2959
3113
|
}
|
|
2960
|
-
const n = this.config.indentWidth ?? 20
|
|
2961
|
-
return Pt(
|
|
3114
|
+
const n = this.config.indentWidth ?? 20, o = qt(
|
|
2962
3115
|
this.pivotResult.rows,
|
|
2963
3116
|
this.expandedKeys,
|
|
2964
3117
|
this.defaultExpanded
|
|
2965
|
-
).map((
|
|
2966
|
-
__pivotRowKey:
|
|
2967
|
-
__pivotLabel:
|
|
2968
|
-
__pivotDepth:
|
|
2969
|
-
__pivotIsGroup:
|
|
2970
|
-
__pivotHasChildren: !!
|
|
2971
|
-
__pivotExpanded: this.expandedKeys.has(
|
|
2972
|
-
__pivotRowCount:
|
|
2973
|
-
__pivotIndent:
|
|
2974
|
-
__pivotTotal:
|
|
2975
|
-
...
|
|
3118
|
+
).map((r) => ({
|
|
3119
|
+
__pivotRowKey: r.rowKey,
|
|
3120
|
+
__pivotLabel: r.rowLabel,
|
|
3121
|
+
__pivotDepth: r.depth,
|
|
3122
|
+
__pivotIsGroup: r.isGroup,
|
|
3123
|
+
__pivotHasChildren: !!r.children?.length,
|
|
3124
|
+
__pivotExpanded: this.expandedKeys.has(r.rowKey),
|
|
3125
|
+
__pivotRowCount: r.rowCount ?? 0,
|
|
3126
|
+
__pivotIndent: r.depth * n,
|
|
3127
|
+
__pivotTotal: r.total,
|
|
3128
|
+
...r.values
|
|
2976
3129
|
}));
|
|
3130
|
+
this.keysToAnimate.clear();
|
|
3131
|
+
const i = /* @__PURE__ */ new Set();
|
|
3132
|
+
for (const r of o) {
|
|
3133
|
+
const l = r.__pivotRowKey;
|
|
3134
|
+
i.add(l), !this.previousVisibleKeys.has(l) && r.__pivotDepth > 0 && this.keysToAnimate.add(l);
|
|
3135
|
+
}
|
|
3136
|
+
return this.previousVisibleKeys = i, o;
|
|
2977
3137
|
}
|
|
2978
3138
|
processColumns(e) {
|
|
2979
3139
|
if (!this.isActive || !this.pivotResult)
|
|
@@ -2986,9 +3146,9 @@ class F extends x {
|
|
|
2986
3146
|
});
|
|
2987
3147
|
for (const o of this.pivotResult.columnKeys)
|
|
2988
3148
|
for (const i of this.config.valueFields ?? []) {
|
|
2989
|
-
const
|
|
3149
|
+
const r = ne([o], i.field), l = i.header || this.fieldHeaderMap.get(i.field) || i.field;
|
|
2990
3150
|
t.push({
|
|
2991
|
-
field:
|
|
3151
|
+
field: r,
|
|
2992
3152
|
header: `${o} - ${l} (${i.aggFunc})`,
|
|
2993
3153
|
width: 120,
|
|
2994
3154
|
type: "number"
|
|
@@ -3003,12 +3163,12 @@ class F extends x {
|
|
|
3003
3163
|
}
|
|
3004
3164
|
renderRow(e, t) {
|
|
3005
3165
|
const n = e;
|
|
3006
|
-
return n.__pivotRowKey && n.__pivotHasChildren ?
|
|
3166
|
+
return n.__pivotRowKey && n.__pivotHasChildren ? Wt(n, t, {
|
|
3007
3167
|
columns: this.gridColumns,
|
|
3008
3168
|
onToggle: (o) => this.toggle(o),
|
|
3009
3169
|
resolveIcon: (o) => this.resolveIcon(o),
|
|
3010
3170
|
setIcon: (o, i) => this.setIcon(o, i)
|
|
3011
|
-
}) : n.__pivotRowKey !== void 0 && this.isActive ?
|
|
3171
|
+
}) : n.__pivotRowKey !== void 0 && this.isActive ? $t(n, t, this.gridColumns) : (this.cleanupPivotStyling(t), !1);
|
|
3012
3172
|
}
|
|
3013
3173
|
/**
|
|
3014
3174
|
* Remove pivot-specific classes, attributes, and inline styles from a row element.
|
|
@@ -3020,6 +3180,16 @@ class F extends x {
|
|
|
3020
3180
|
}
|
|
3021
3181
|
afterRender() {
|
|
3022
3182
|
this.isActive && this.config.showGrandTotal && this.pivotResult ? this.renderGrandTotalFooter() : this.cleanupGrandTotalFooter();
|
|
3183
|
+
const e = this.animationStyle;
|
|
3184
|
+
if (e === !1 || this.keysToAnimate.size === 0) return;
|
|
3185
|
+
const t = this.shadowRoot?.querySelector(".rows");
|
|
3186
|
+
if (!t) return;
|
|
3187
|
+
const n = e === "fade" ? "tbw-pivot-fade-in" : "tbw-pivot-slide-in";
|
|
3188
|
+
for (const o of t.querySelectorAll(".pivot-group-row, .pivot-leaf-row")) {
|
|
3189
|
+
const i = o.dataset.pivotKey;
|
|
3190
|
+
i && this.keysToAnimate.has(i) && (o.classList.add(n), o.addEventListener("animationend", () => o.classList.remove(n), { once: !0 }));
|
|
3191
|
+
}
|
|
3192
|
+
this.keysToAnimate.clear();
|
|
3023
3193
|
}
|
|
3024
3194
|
/**
|
|
3025
3195
|
* Render the grand total row as a sticky footer pinned to the bottom.
|
|
@@ -3038,7 +3208,7 @@ class F extends x {
|
|
|
3038
3208
|
__pivotTotal: this.pivotResult.grandTotal,
|
|
3039
3209
|
...this.pivotResult.totals
|
|
3040
3210
|
};
|
|
3041
|
-
|
|
3211
|
+
jt(n, this.grandTotalFooter, this.gridColumns);
|
|
3042
3212
|
}
|
|
3043
3213
|
/**
|
|
3044
3214
|
* Remove the grand total footer element.
|
|
@@ -3059,7 +3229,7 @@ class F extends x {
|
|
|
3059
3229
|
}
|
|
3060
3230
|
expandAll() {
|
|
3061
3231
|
if (this.pivotResult) {
|
|
3062
|
-
const e =
|
|
3232
|
+
const e = j(this.pivotResult.rows);
|
|
3063
3233
|
for (const t of e)
|
|
3064
3234
|
this.expandedKeys.add(t);
|
|
3065
3235
|
this.requestRender();
|
|
@@ -3100,16 +3270,16 @@ class F extends x {
|
|
|
3100
3270
|
// #endregion
|
|
3101
3271
|
// #region Tool Panel API
|
|
3102
3272
|
showPanel() {
|
|
3103
|
-
this.grid.openToolPanel(
|
|
3273
|
+
this.grid.openToolPanel(T.PANEL_ID);
|
|
3104
3274
|
}
|
|
3105
3275
|
hidePanel() {
|
|
3106
3276
|
this.grid.closeToolPanel();
|
|
3107
3277
|
}
|
|
3108
3278
|
togglePanel() {
|
|
3109
|
-
this.grid.toggleToolPanel(
|
|
3279
|
+
this.grid.toggleToolPanel(T.PANEL_ID);
|
|
3110
3280
|
}
|
|
3111
3281
|
isPanelVisible() {
|
|
3112
|
-
return this.grid.activeToolPanel ===
|
|
3282
|
+
return this.grid.activeToolPanel === T.PANEL_ID;
|
|
3113
3283
|
}
|
|
3114
3284
|
// #endregion
|
|
3115
3285
|
// #region Private Helpers
|
|
@@ -3153,7 +3323,7 @@ class F extends x {
|
|
|
3153
3323
|
},
|
|
3154
3324
|
getAvailableFields: () => this.getAvailableFields()
|
|
3155
3325
|
};
|
|
3156
|
-
return
|
|
3326
|
+
return Ht(e, this.config, this.isActive, t);
|
|
3157
3327
|
}
|
|
3158
3328
|
refreshPanel() {
|
|
3159
3329
|
this.panelContainer && (this.panelContainer.innerHTML = "", this.renderPanel(this.panelContainer));
|
|
@@ -3187,28 +3357,59 @@ class F extends x {
|
|
|
3187
3357
|
}
|
|
3188
3358
|
// #endregion
|
|
3189
3359
|
// #region Styles
|
|
3190
|
-
styles =
|
|
3360
|
+
styles = Ut;
|
|
3191
3361
|
// #endregion
|
|
3192
3362
|
}
|
|
3193
|
-
function
|
|
3194
|
-
const e =
|
|
3363
|
+
function _e(s) {
|
|
3364
|
+
const e = s.meta ?? {};
|
|
3195
3365
|
return e.lockPosition !== !0 && e.suppressMovable !== !0;
|
|
3196
3366
|
}
|
|
3197
|
-
function
|
|
3198
|
-
if (e === t || e < 0 || e >=
|
|
3199
|
-
const n = [...
|
|
3367
|
+
function Ie(s, e, t) {
|
|
3368
|
+
if (e === t || e < 0 || e >= s.length || t < 0 || t > s.length) return s;
|
|
3369
|
+
const n = [...s], [o] = n.splice(e, 1);
|
|
3200
3370
|
return n.splice(t, 0, o), n;
|
|
3201
3371
|
}
|
|
3202
|
-
const
|
|
3203
|
-
class
|
|
3372
|
+
const Yt = '.header-row>.cell[draggable=true]{cursor:grab;position:relative}.header-row>.cell.dragging{opacity:.5;cursor:grabbing}.header-row>.cell.drop-before:before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent));z-index:1}.header-row>.cell.drop-after:after{content:"";position:absolute;right:0;top:0;bottom:0;width:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent));z-index:1}.cell.flip-animating{transition:transform var(--tbw-animation-duration, .2s) ease-out;will-change:transform;z-index:1}@keyframes reorder-fade-in{0%{opacity:0}to{opacity:1}}.cell.fade-animating{animation:reorder-fade-in var(--tbw-animation-duration, .2s) ease-out backwards}';
|
|
3373
|
+
class _n extends v {
|
|
3204
3374
|
name = "reorder";
|
|
3205
3375
|
version = "1.0.0";
|
|
3206
3376
|
get defaultConfig() {
|
|
3207
3377
|
return {
|
|
3208
|
-
animation:
|
|
3209
|
-
|
|
3378
|
+
animation: "flip"
|
|
3379
|
+
// Plugin's own default
|
|
3210
3380
|
};
|
|
3211
3381
|
}
|
|
3382
|
+
/**
|
|
3383
|
+
* Resolve animation type from plugin config.
|
|
3384
|
+
* Respects grid-level animation.mode (disabled = no animation).
|
|
3385
|
+
*/
|
|
3386
|
+
get animationType() {
|
|
3387
|
+
return this.isAnimationEnabled ? this.config.animation !== void 0 ? this.config.animation : this.config.viewTransition === !1 ? !1 : (this.config.viewTransition === !0, "flip") : !1;
|
|
3388
|
+
}
|
|
3389
|
+
/**
|
|
3390
|
+
* Check if animations are enabled at the grid level.
|
|
3391
|
+
* Respects gridConfig.animation.mode and CSS variable.
|
|
3392
|
+
*/
|
|
3393
|
+
get isAnimationEnabled() {
|
|
3394
|
+
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
3395
|
+
if (t === !1 || t === "off") return !1;
|
|
3396
|
+
if (t === !0 || t === "on") return !0;
|
|
3397
|
+
const n = this.shadowRoot?.host;
|
|
3398
|
+
return n ? getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
3399
|
+
}
|
|
3400
|
+
/**
|
|
3401
|
+
* Get animation duration from CSS variable (set by grid config).
|
|
3402
|
+
*/
|
|
3403
|
+
get animationDuration() {
|
|
3404
|
+
if (this.config.animationDuration !== void 0)
|
|
3405
|
+
return this.config.animationDuration;
|
|
3406
|
+
const e = this.shadowRoot?.host;
|
|
3407
|
+
if (e) {
|
|
3408
|
+
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
|
|
3409
|
+
if (!isNaN(n)) return n;
|
|
3410
|
+
}
|
|
3411
|
+
return 200;
|
|
3412
|
+
}
|
|
3212
3413
|
// #region Internal State
|
|
3213
3414
|
isDragging = !1;
|
|
3214
3415
|
draggedField = null;
|
|
@@ -3231,18 +3432,17 @@ class An extends x {
|
|
|
3231
3432
|
}
|
|
3232
3433
|
// #endregion
|
|
3233
3434
|
// #region Hooks
|
|
3234
|
-
// Note: No processColumns hook needed - we directly update the grid's column order
|
|
3235
3435
|
afterRender() {
|
|
3236
3436
|
const e = this.shadowRoot;
|
|
3237
3437
|
if (!e) return;
|
|
3238
3438
|
e.querySelectorAll(".header-row > .cell").forEach((n) => {
|
|
3239
3439
|
const o = n, i = o.getAttribute("data-field");
|
|
3240
3440
|
if (!i) return;
|
|
3241
|
-
const
|
|
3242
|
-
type:
|
|
3243
|
-
context:
|
|
3441
|
+
const r = this.columns.find((c) => c.field === i), d = !this.grid.queryPlugins({
|
|
3442
|
+
type: N.CAN_MOVE_COLUMN,
|
|
3443
|
+
context: r
|
|
3244
3444
|
}).includes(!1);
|
|
3245
|
-
if (!
|
|
3445
|
+
if (!r || !_e(r) || !d) {
|
|
3246
3446
|
o.draggable = !1;
|
|
3247
3447
|
return;
|
|
3248
3448
|
}
|
|
@@ -3255,8 +3455,8 @@ class An extends x {
|
|
|
3255
3455
|
});
|
|
3256
3456
|
}), o.addEventListener("dragover", (c) => {
|
|
3257
3457
|
if (c.preventDefault(), !this.isDragging || this.draggedField === i) return;
|
|
3258
|
-
const u = o.getBoundingClientRect(), h = u.left + u.width / 2,
|
|
3259
|
-
this.dropIndex = c.clientX < h ?
|
|
3458
|
+
const u = o.getBoundingClientRect(), h = u.left + u.width / 2, f = this.getColumnOrder().indexOf(i);
|
|
3459
|
+
this.dropIndex = c.clientX < h ? f : f + 1, o.classList.add("drop-target"), o.classList.toggle("drop-before", c.clientX < h), o.classList.toggle("drop-after", c.clientX >= h);
|
|
3260
3460
|
}), o.addEventListener("dragleave", () => {
|
|
3261
3461
|
o.classList.remove("drop-target", "drop-before", "drop-after");
|
|
3262
3462
|
}), o.addEventListener("drop", (c) => {
|
|
@@ -3264,16 +3464,42 @@ class An extends x {
|
|
|
3264
3464
|
const u = this.draggedField, h = this.draggedIndex, g = this.dropIndex;
|
|
3265
3465
|
if (!this.isDragging || u === null || h === null || g === null)
|
|
3266
3466
|
return;
|
|
3267
|
-
const
|
|
3467
|
+
const f = g > h ? g - 1 : g, m = this.getColumnOrder(), p = Ie(m, h, f), R = {
|
|
3268
3468
|
field: u,
|
|
3269
3469
|
fromIndex: h,
|
|
3270
|
-
toIndex:
|
|
3271
|
-
columnOrder:
|
|
3470
|
+
toIndex: f,
|
|
3471
|
+
columnOrder: p
|
|
3272
3472
|
};
|
|
3273
|
-
this.
|
|
3473
|
+
this.updateColumnOrder(p), this.emit("column-move", R);
|
|
3274
3474
|
}));
|
|
3275
3475
|
});
|
|
3276
3476
|
}
|
|
3477
|
+
/**
|
|
3478
|
+
* Handle Alt+Arrow keyboard shortcuts for column reordering.
|
|
3479
|
+
*/
|
|
3480
|
+
onKeyDown(e) {
|
|
3481
|
+
if (!e.altKey || e.key !== "ArrowLeft" && e.key !== "ArrowRight")
|
|
3482
|
+
return;
|
|
3483
|
+
const t = this.grid, n = t._focusCol, o = t._visibleColumns;
|
|
3484
|
+
if (n < 0 || n >= o.length) return;
|
|
3485
|
+
const i = o[n];
|
|
3486
|
+
if (!i || !_e(i)) return;
|
|
3487
|
+
const r = this.grid;
|
|
3488
|
+
if (r.queryPlugins({
|
|
3489
|
+
type: N.CAN_MOVE_COLUMN,
|
|
3490
|
+
context: i
|
|
3491
|
+
}).includes(!1)) return;
|
|
3492
|
+
const a = this.getColumnOrder(), d = a.indexOf(i.field);
|
|
3493
|
+
if (d === -1) return;
|
|
3494
|
+
const c = e.key === "ArrowLeft" ? d - 1 : d + 1;
|
|
3495
|
+
if (c < 0 || c >= a.length) return;
|
|
3496
|
+
const u = o.find((h) => h.field === a[c]);
|
|
3497
|
+
if (!(u && r.queryPlugins({
|
|
3498
|
+
type: N.CAN_MOVE_COLUMN,
|
|
3499
|
+
context: u
|
|
3500
|
+
}).includes(!1)))
|
|
3501
|
+
return this.moveColumn(i.field, c), t._focusCol = c, Ge(this.grid), e.preventDefault(), e.stopPropagation(), !0;
|
|
3502
|
+
}
|
|
3277
3503
|
// #endregion
|
|
3278
3504
|
// #region Public API
|
|
3279
3505
|
/**
|
|
@@ -3291,85 +3517,179 @@ class An extends x {
|
|
|
3291
3517
|
moveColumn(e, t) {
|
|
3292
3518
|
const n = this.getColumnOrder(), o = n.indexOf(e);
|
|
3293
3519
|
if (o === -1) return;
|
|
3294
|
-
const i =
|
|
3295
|
-
this.
|
|
3520
|
+
const i = Ie(n, o, t);
|
|
3521
|
+
this.updateColumnOrder(i), this.emit("column-move", {
|
|
3296
3522
|
field: e,
|
|
3297
3523
|
fromIndex: o,
|
|
3298
3524
|
toIndex: t,
|
|
3299
3525
|
columnOrder: i
|
|
3300
|
-
})
|
|
3526
|
+
});
|
|
3301
3527
|
}
|
|
3302
3528
|
/**
|
|
3303
3529
|
* Set a specific column order.
|
|
3304
3530
|
* @param order - Array of field names in desired order
|
|
3305
3531
|
*/
|
|
3306
3532
|
setColumnOrder(e) {
|
|
3307
|
-
this.
|
|
3533
|
+
this.updateColumnOrder(e);
|
|
3308
3534
|
}
|
|
3309
3535
|
/**
|
|
3310
3536
|
* Reset column order to the original configuration order.
|
|
3311
3537
|
*/
|
|
3312
3538
|
resetColumnOrder() {
|
|
3313
3539
|
const e = this.columns.map((t) => t.field);
|
|
3314
|
-
this.
|
|
3540
|
+
this.updateColumnOrder(e);
|
|
3541
|
+
}
|
|
3542
|
+
// #endregion
|
|
3543
|
+
// #region View Transition
|
|
3544
|
+
/**
|
|
3545
|
+
* Capture header cell positions before reorder.
|
|
3546
|
+
*/
|
|
3547
|
+
captureHeaderPositions() {
|
|
3548
|
+
const e = /* @__PURE__ */ new Map();
|
|
3549
|
+
return this.shadowRoot?.querySelectorAll(".header-row > .cell[data-field]").forEach((t) => {
|
|
3550
|
+
const n = t.getAttribute("data-field");
|
|
3551
|
+
n && e.set(n, t.getBoundingClientRect().left);
|
|
3552
|
+
}), e;
|
|
3553
|
+
}
|
|
3554
|
+
/**
|
|
3555
|
+
* Apply FLIP animation for column reorder.
|
|
3556
|
+
* Uses CSS transitions - JS sets initial transform and toggles class.
|
|
3557
|
+
* @param oldPositions - Header positions captured before DOM change
|
|
3558
|
+
*/
|
|
3559
|
+
animateFLIP(e) {
|
|
3560
|
+
const t = this.shadowRoot;
|
|
3561
|
+
if (!t || e.size === 0) return;
|
|
3562
|
+
const n = /* @__PURE__ */ new Map();
|
|
3563
|
+
if (t.querySelectorAll(".header-row > .cell[data-field]").forEach((r) => {
|
|
3564
|
+
const l = r.getAttribute("data-field");
|
|
3565
|
+
if (!l) return;
|
|
3566
|
+
const a = e.get(l);
|
|
3567
|
+
if (a === void 0) return;
|
|
3568
|
+
const d = a - r.getBoundingClientRect().left;
|
|
3569
|
+
Math.abs(d) > 1 && n.set(l, d);
|
|
3570
|
+
}), n.size === 0) return;
|
|
3571
|
+
const o = [];
|
|
3572
|
+
if (t.querySelectorAll(".cell[data-field]").forEach((r) => {
|
|
3573
|
+
const l = n.get(r.getAttribute("data-field") ?? "");
|
|
3574
|
+
if (l !== void 0) {
|
|
3575
|
+
const a = r;
|
|
3576
|
+
a.style.transform = `translateX(${l}px)`, o.push(a);
|
|
3577
|
+
}
|
|
3578
|
+
}), o.length === 0) return;
|
|
3579
|
+
t.host.offsetHeight;
|
|
3580
|
+
const i = this.animationDuration;
|
|
3581
|
+
requestAnimationFrame(() => {
|
|
3582
|
+
o.forEach((r) => {
|
|
3583
|
+
r.classList.add("flip-animating"), r.style.transform = "";
|
|
3584
|
+
}), setTimeout(() => {
|
|
3585
|
+
o.forEach((r) => {
|
|
3586
|
+
r.style.transform = "", r.classList.remove("flip-animating");
|
|
3587
|
+
});
|
|
3588
|
+
}, i + 50);
|
|
3589
|
+
});
|
|
3590
|
+
}
|
|
3591
|
+
/**
|
|
3592
|
+
* Apply crossfade animation for moved columns.
|
|
3593
|
+
* Uses CSS keyframes - JS just toggles classes.
|
|
3594
|
+
*/
|
|
3595
|
+
animateFade(e) {
|
|
3596
|
+
const t = this.shadowRoot;
|
|
3597
|
+
if (!t) {
|
|
3598
|
+
e();
|
|
3599
|
+
return;
|
|
3600
|
+
}
|
|
3601
|
+
const n = this.captureHeaderPositions();
|
|
3602
|
+
e();
|
|
3603
|
+
const o = /* @__PURE__ */ new Set();
|
|
3604
|
+
if (t.querySelectorAll(".header-row > .cell[data-field]").forEach((l) => {
|
|
3605
|
+
const a = l.getAttribute("data-field");
|
|
3606
|
+
if (!a) return;
|
|
3607
|
+
const d = n.get(a);
|
|
3608
|
+
if (d === void 0) return;
|
|
3609
|
+
const c = l.getBoundingClientRect().left;
|
|
3610
|
+
Math.abs(d - c) > 1 && o.add(a);
|
|
3611
|
+
}), o.size === 0) return;
|
|
3612
|
+
const i = [];
|
|
3613
|
+
if (t.querySelectorAll(".cell[data-field]").forEach((l) => {
|
|
3614
|
+
const a = l.getAttribute("data-field");
|
|
3615
|
+
if (a && o.has(a)) {
|
|
3616
|
+
const d = l;
|
|
3617
|
+
d.classList.add("fade-animating"), i.push(d);
|
|
3618
|
+
}
|
|
3619
|
+
}), i.length === 0) return;
|
|
3620
|
+
const r = this.animationDuration;
|
|
3621
|
+
setTimeout(() => {
|
|
3622
|
+
i.forEach((l) => l.classList.remove("fade-animating"));
|
|
3623
|
+
}, r + 50);
|
|
3624
|
+
}
|
|
3625
|
+
/**
|
|
3626
|
+
* Update column order with configured animation.
|
|
3627
|
+
*/
|
|
3628
|
+
updateColumnOrder(e) {
|
|
3629
|
+
const t = this.grid, n = this.animationType;
|
|
3630
|
+
if (n === "flip" && this.shadowRoot) {
|
|
3631
|
+
const o = this.captureHeaderPositions();
|
|
3632
|
+
t.setColumnOrder(e), this.shadowRoot.host.offsetHeight, this.animateFLIP(o);
|
|
3633
|
+
} else n === "fade" ? this.animateFade(() => t.setColumnOrder(e)) : t.setColumnOrder(e);
|
|
3634
|
+
t.requestStateChange?.();
|
|
3315
3635
|
}
|
|
3316
3636
|
// #endregion
|
|
3317
3637
|
// #region Styles
|
|
3318
|
-
styles =
|
|
3638
|
+
styles = Yt;
|
|
3319
3639
|
// #endregion
|
|
3320
3640
|
}
|
|
3321
|
-
function D(
|
|
3641
|
+
function D(s) {
|
|
3322
3642
|
return {
|
|
3323
|
-
startRow: Math.min(
|
|
3324
|
-
startCol: Math.min(
|
|
3325
|
-
endRow: Math.max(
|
|
3326
|
-
endCol: Math.max(
|
|
3643
|
+
startRow: Math.min(s.startRow, s.endRow),
|
|
3644
|
+
startCol: Math.min(s.startCol, s.endCol),
|
|
3645
|
+
endRow: Math.max(s.startRow, s.endRow),
|
|
3646
|
+
endCol: Math.max(s.startCol, s.endCol)
|
|
3327
3647
|
};
|
|
3328
3648
|
}
|
|
3329
|
-
function
|
|
3330
|
-
const e = D(
|
|
3649
|
+
function Zt(s) {
|
|
3650
|
+
const e = D(s);
|
|
3331
3651
|
return {
|
|
3332
3652
|
from: { row: e.startRow, col: e.startCol },
|
|
3333
3653
|
to: { row: e.endRow, col: e.endCol }
|
|
3334
3654
|
};
|
|
3335
3655
|
}
|
|
3336
|
-
function
|
|
3337
|
-
return
|
|
3656
|
+
function J(s) {
|
|
3657
|
+
return s.map(Zt);
|
|
3338
3658
|
}
|
|
3339
|
-
function
|
|
3659
|
+
function Xt(s, e, t) {
|
|
3340
3660
|
const n = D(t);
|
|
3341
|
-
return
|
|
3661
|
+
return s >= n.startRow && s <= n.endRow && e >= n.startCol && e <= n.endCol;
|
|
3342
3662
|
}
|
|
3343
|
-
function
|
|
3344
|
-
return t.some((n) =>
|
|
3663
|
+
function Le(s, e, t) {
|
|
3664
|
+
return t.some((n) => Xt(s, e, n));
|
|
3345
3665
|
}
|
|
3346
|
-
function
|
|
3347
|
-
const e = [], t = D(
|
|
3666
|
+
function Jt(s) {
|
|
3667
|
+
const e = [], t = D(s);
|
|
3348
3668
|
for (let n = t.startRow; n <= t.endRow; n++)
|
|
3349
3669
|
for (let o = t.startCol; o <= t.endCol; o++)
|
|
3350
3670
|
e.push({ row: n, col: o });
|
|
3351
3671
|
return e;
|
|
3352
3672
|
}
|
|
3353
|
-
function
|
|
3673
|
+
function Qt(s) {
|
|
3354
3674
|
const e = /* @__PURE__ */ new Map();
|
|
3355
|
-
for (const t of
|
|
3356
|
-
for (const n of
|
|
3675
|
+
for (const t of s)
|
|
3676
|
+
for (const n of Jt(t))
|
|
3357
3677
|
e.set(`${n.row},${n.col}`, n);
|
|
3358
3678
|
return [...e.values()];
|
|
3359
3679
|
}
|
|
3360
|
-
function
|
|
3680
|
+
function Y(s, e) {
|
|
3361
3681
|
return {
|
|
3362
|
-
startRow:
|
|
3363
|
-
startCol:
|
|
3682
|
+
startRow: s.row,
|
|
3683
|
+
startCol: s.col,
|
|
3364
3684
|
endRow: e.row,
|
|
3365
3685
|
endCol: e.col
|
|
3366
3686
|
};
|
|
3367
3687
|
}
|
|
3368
|
-
const
|
|
3369
|
-
function
|
|
3370
|
-
if (
|
|
3688
|
+
const en = ':host .selecting .data-grid-row>.cell{user-select:none}:host .data-grid-row.row-focus{background-color:var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%))}:host([data-selection-mode="row"]) .cell-focus{outline:none}:host .data-grid-row>.cell.selected{background-color:var(--tbw-range-selection-bg)}:host .data-grid-row>.cell.selected.top{border-top:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.bottom{border-bottom:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.first{border-left:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.last{border-right:2px solid var(--tbw-range-border-color)}';
|
|
3689
|
+
function tn(s, e, t) {
|
|
3690
|
+
if (s === "cell" && e.selectedCell)
|
|
3371
3691
|
return {
|
|
3372
|
-
mode:
|
|
3692
|
+
mode: s,
|
|
3373
3693
|
ranges: [
|
|
3374
3694
|
{
|
|
3375
3695
|
from: { row: e.selectedCell.row, col: e.selectedCell.col },
|
|
@@ -3377,16 +3697,16 @@ function en(r, e, t) {
|
|
|
3377
3697
|
}
|
|
3378
3698
|
]
|
|
3379
3699
|
};
|
|
3380
|
-
if (
|
|
3700
|
+
if (s === "row" && e.selected.size > 0) {
|
|
3381
3701
|
const n = [...e.selected].map((o) => ({
|
|
3382
3702
|
from: { row: o, col: 0 },
|
|
3383
3703
|
to: { row: o, col: t - 1 }
|
|
3384
3704
|
}));
|
|
3385
|
-
return { mode:
|
|
3705
|
+
return { mode: s, ranges: n };
|
|
3386
3706
|
}
|
|
3387
|
-
return
|
|
3707
|
+
return s === "range" && e.ranges.length > 0 ? { mode: s, ranges: J(e.ranges) } : { mode: s, ranges: [] };
|
|
3388
3708
|
}
|
|
3389
|
-
class
|
|
3709
|
+
class In extends v {
|
|
3390
3710
|
name = "selection";
|
|
3391
3711
|
version = "1.0.0";
|
|
3392
3712
|
get defaultConfig() {
|
|
@@ -3404,12 +3724,14 @@ class _n extends x {
|
|
|
3404
3724
|
activeRange = null;
|
|
3405
3725
|
cellAnchor = null;
|
|
3406
3726
|
isDragging = !1;
|
|
3727
|
+
/** Pending keyboard navigation update (processed in afterRender) */
|
|
3728
|
+
pendingKeyboardUpdate = null;
|
|
3407
3729
|
/** Cell selection state (cell mode) */
|
|
3408
3730
|
selectedCell = null;
|
|
3409
3731
|
// #endregion
|
|
3410
3732
|
// #region Lifecycle
|
|
3411
3733
|
detach() {
|
|
3412
|
-
this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.isDragging = !1, this.selectedCell = null;
|
|
3734
|
+
this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.isDragging = !1, this.selectedCell = null, this.pendingKeyboardUpdate = null;
|
|
3413
3735
|
}
|
|
3414
3736
|
// #endregion
|
|
3415
3737
|
// #region Event Handlers
|
|
@@ -3420,9 +3742,9 @@ class _n extends x {
|
|
|
3420
3742
|
if (i === "row")
|
|
3421
3743
|
return this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
|
|
3422
3744
|
if (i === "range") {
|
|
3423
|
-
const
|
|
3424
|
-
if (
|
|
3425
|
-
const a =
|
|
3745
|
+
const r = o.shiftKey, l = o.ctrlKey || o.metaKey;
|
|
3746
|
+
if (r && this.cellAnchor) {
|
|
3747
|
+
const a = Y(this.cellAnchor, { row: t, col: n });
|
|
3426
3748
|
l ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = a : this.ranges.push(a) : this.ranges = [a], this.activeRange = a;
|
|
3427
3749
|
} else if (l) {
|
|
3428
3750
|
const a = {
|
|
@@ -3451,33 +3773,22 @@ class _n extends x {
|
|
|
3451
3773
|
return t === "cell" ? this.selectedCell = null : t === "row" ? (this.selected.clear(), this.anchor = null) : t === "range" && (this.ranges = [], this.activeRange = null, this.cellAnchor = null), this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
3452
3774
|
if (t === "cell" && o)
|
|
3453
3775
|
return queueMicrotask(() => {
|
|
3454
|
-
this.selectedCell = { row: this.grid.
|
|
3776
|
+
this.selectedCell = { row: this.grid._focusRow, col: this.grid._focusCol }, this.emit("selection-change", this.#e()), this.requestAfterRender();
|
|
3455
3777
|
}), !1;
|
|
3456
3778
|
if (t === "row" && (e.key === "ArrowUp" || e.key === "ArrowDown"))
|
|
3457
3779
|
return queueMicrotask(() => {
|
|
3458
|
-
this.selected.clear(), this.selected.add(this.grid.
|
|
3780
|
+
this.selected.clear(), this.selected.add(this.grid._focusRow), this.lastSelected = this.grid._focusRow, this.emit("selection-change", this.#e()), this.requestAfterRender();
|
|
3459
3781
|
}), !1;
|
|
3460
|
-
if (t === "range" && o)
|
|
3461
|
-
|
|
3462
|
-
return queueMicrotask(() => {
|
|
3463
|
-
const s = this.grid.focusRow, l = this.grid.focusCol;
|
|
3464
|
-
if (i) {
|
|
3465
|
-
this.cellAnchor || (this.cellAnchor = { row: s, col: l });
|
|
3466
|
-
const a = U(this.cellAnchor, { row: s, col: l });
|
|
3467
|
-
this.ranges = [a], this.activeRange = a;
|
|
3468
|
-
} else
|
|
3469
|
-
this.ranges = [], this.activeRange = null, this.cellAnchor = { row: s, col: l };
|
|
3470
|
-
this.emit("selection-change", this.#e()), this.requestAfterRender();
|
|
3471
|
-
}), !1;
|
|
3472
|
-
}
|
|
3782
|
+
if (t === "range" && o)
|
|
3783
|
+
return e.shiftKey && !this.cellAnchor && (this.cellAnchor = { row: this.grid._focusRow, col: this.grid._focusCol }), this.pendingKeyboardUpdate = { shiftKey: e.shiftKey }, queueMicrotask(() => this.requestAfterRender()), !1;
|
|
3473
3784
|
if (t === "range" && e.key === "a" && (e.ctrlKey || e.metaKey)) {
|
|
3474
|
-
const i = this.rows.length,
|
|
3475
|
-
if (i > 0 &&
|
|
3785
|
+
const i = this.rows.length, r = this.columns.length;
|
|
3786
|
+
if (i > 0 && r > 0) {
|
|
3476
3787
|
const l = {
|
|
3477
3788
|
startRow: 0,
|
|
3478
3789
|
startCol: 0,
|
|
3479
3790
|
endRow: i - 1,
|
|
3480
|
-
endCol:
|
|
3791
|
+
endCol: r - 1
|
|
3481
3792
|
};
|
|
3482
3793
|
return this.ranges = [l], this.activeRange = l, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
3483
3794
|
}
|
|
@@ -3500,7 +3811,7 @@ class _n extends x {
|
|
|
3500
3811
|
}
|
|
3501
3812
|
onCellMouseMove(e) {
|
|
3502
3813
|
if (this.config.mode !== "range" || !this.isDragging || !this.cellAnchor || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
|
|
3503
|
-
const t =
|
|
3814
|
+
const t = Y(this.cellAnchor, { row: e.rowIndex, col: e.colIndex });
|
|
3504
3815
|
return this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = t : this.ranges.push(t), this.activeRange = t, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
3505
3816
|
}
|
|
3506
3817
|
onCellMouseUp(e) {
|
|
@@ -3522,13 +3833,13 @@ class _n extends x {
|
|
|
3522
3833
|
if (o.forEach((i) => {
|
|
3523
3834
|
i.classList.remove("selected", "row-focus");
|
|
3524
3835
|
}), t === "row" && (e.querySelectorAll(".cell-focus").forEach((i) => i.classList.remove("cell-focus")), o.forEach((i) => {
|
|
3525
|
-
const
|
|
3836
|
+
const r = i.querySelector(".cell[data-row]"), l = parseInt(r?.getAttribute("data-row") ?? "-1", 10);
|
|
3526
3837
|
l >= 0 && this.selected.has(l) && i.classList.add("selected", "row-focus");
|
|
3527
3838
|
})), t === "range" && this.ranges.length > 0) {
|
|
3528
3839
|
const i = this.activeRange ? D(this.activeRange) : null;
|
|
3529
3840
|
e.querySelectorAll(".cell[data-row][data-col]").forEach((l) => {
|
|
3530
3841
|
const a = parseInt(l.getAttribute("data-row") ?? "-1", 10), d = parseInt(l.getAttribute("data-col") ?? "-1", 10);
|
|
3531
|
-
a >= 0 && d >= 0 &&
|
|
3842
|
+
a >= 0 && d >= 0 && Le(a, d, this.ranges) && (l.classList.add("selected"), l.classList.remove("cell-focus"), i && (a === i.startRow && l.classList.add("top"), a === i.endRow && l.classList.add("bottom"), d === i.startCol && l.classList.add("first"), d === i.endCol && l.classList.add("last")));
|
|
3532
3843
|
});
|
|
3533
3844
|
}
|
|
3534
3845
|
t === "cell" && this.selectedCell && e.querySelectorAll(".cell-focus").forEach((i) => i.classList.remove("cell-focus"));
|
|
@@ -3537,6 +3848,16 @@ class _n extends x {
|
|
|
3537
3848
|
const e = this.shadowRoot;
|
|
3538
3849
|
if (!e) return;
|
|
3539
3850
|
const t = e.children[0], { mode: n } = this.config;
|
|
3851
|
+
if (this.pendingKeyboardUpdate && n === "range") {
|
|
3852
|
+
const { shiftKey: o } = this.pendingKeyboardUpdate;
|
|
3853
|
+
this.pendingKeyboardUpdate = null;
|
|
3854
|
+
const i = this.grid._focusRow, r = this.grid._focusCol;
|
|
3855
|
+
if (o && this.cellAnchor) {
|
|
3856
|
+
const l = Y(this.cellAnchor, { row: i, col: r });
|
|
3857
|
+
this.ranges = [l], this.activeRange = l;
|
|
3858
|
+
} else o || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: i, col: r });
|
|
3859
|
+
this.emit("selection-change", this.#e());
|
|
3860
|
+
}
|
|
3540
3861
|
this.grid.setAttribute("data-selection-mode", n), t && t.classList.toggle("selecting", this.isDragging), this.#t();
|
|
3541
3862
|
}
|
|
3542
3863
|
/**
|
|
@@ -3564,19 +3885,19 @@ class _n extends x {
|
|
|
3564
3885
|
* Get all selected cell ranges in public format.
|
|
3565
3886
|
*/
|
|
3566
3887
|
getRanges() {
|
|
3567
|
-
return
|
|
3888
|
+
return J(this.ranges);
|
|
3568
3889
|
}
|
|
3569
3890
|
/**
|
|
3570
3891
|
* Get all selected cells across all ranges.
|
|
3571
3892
|
*/
|
|
3572
3893
|
getSelectedCells() {
|
|
3573
|
-
return
|
|
3894
|
+
return Qt(this.ranges);
|
|
3574
3895
|
}
|
|
3575
3896
|
/**
|
|
3576
3897
|
* Check if a specific cell is in range selection.
|
|
3577
3898
|
*/
|
|
3578
3899
|
isCellSelected(e, t) {
|
|
3579
|
-
return
|
|
3900
|
+
return Le(e, t, this.ranges);
|
|
3580
3901
|
}
|
|
3581
3902
|
/**
|
|
3582
3903
|
* Clear all selection.
|
|
@@ -3595,13 +3916,13 @@ class _n extends x {
|
|
|
3595
3916
|
endCol: t.to.col
|
|
3596
3917
|
})), this.activeRange = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null, this.emit("selection-change", {
|
|
3597
3918
|
mode: this.config.mode,
|
|
3598
|
-
ranges:
|
|
3919
|
+
ranges: J(this.ranges)
|
|
3599
3920
|
}), this.requestAfterRender();
|
|
3600
3921
|
}
|
|
3601
3922
|
// #endregion
|
|
3602
3923
|
// #region Private Helpers
|
|
3603
3924
|
#e() {
|
|
3604
|
-
return
|
|
3925
|
+
return tn(
|
|
3605
3926
|
this.config.mode,
|
|
3606
3927
|
{
|
|
3607
3928
|
selectedCell: this.selectedCell,
|
|
@@ -3613,41 +3934,41 @@ class _n extends x {
|
|
|
3613
3934
|
}
|
|
3614
3935
|
// #endregion
|
|
3615
3936
|
// #region Styles
|
|
3616
|
-
styles =
|
|
3937
|
+
styles = en;
|
|
3617
3938
|
// #endregion
|
|
3618
3939
|
}
|
|
3619
|
-
function q(
|
|
3620
|
-
return Math.floor(
|
|
3940
|
+
function q(s, e) {
|
|
3941
|
+
return Math.floor(s / e);
|
|
3621
3942
|
}
|
|
3622
|
-
function
|
|
3943
|
+
function nn(s, e) {
|
|
3623
3944
|
return {
|
|
3624
|
-
start:
|
|
3625
|
-
end: (
|
|
3945
|
+
start: s * e,
|
|
3946
|
+
end: (s + 1) * e
|
|
3626
3947
|
};
|
|
3627
3948
|
}
|
|
3628
|
-
function
|
|
3629
|
-
const n = q(
|
|
3630
|
-
for (let
|
|
3631
|
-
i.push(
|
|
3949
|
+
function on(s, e, t) {
|
|
3950
|
+
const n = q(s, t), o = q(e - 1, t), i = [];
|
|
3951
|
+
for (let r = n; r <= o; r++)
|
|
3952
|
+
i.push(r);
|
|
3632
3953
|
return i;
|
|
3633
3954
|
}
|
|
3634
|
-
async function
|
|
3635
|
-
const o =
|
|
3636
|
-
return
|
|
3955
|
+
async function Te(s, e, t, n) {
|
|
3956
|
+
const o = nn(e, t);
|
|
3957
|
+
return s.getRows({
|
|
3637
3958
|
startRow: o.start,
|
|
3638
3959
|
endRow: o.end,
|
|
3639
3960
|
sortModel: n.sortModel,
|
|
3640
3961
|
filterModel: n.filterModel
|
|
3641
3962
|
});
|
|
3642
3963
|
}
|
|
3643
|
-
function
|
|
3644
|
-
const n = q(
|
|
3964
|
+
function rn(s, e, t) {
|
|
3965
|
+
const n = q(s, e), o = t.get(n);
|
|
3645
3966
|
if (!o) return;
|
|
3646
|
-
const i =
|
|
3967
|
+
const i = s % e;
|
|
3647
3968
|
return o[i];
|
|
3648
3969
|
}
|
|
3649
|
-
const
|
|
3650
|
-
class
|
|
3970
|
+
const sn = 100;
|
|
3971
|
+
class Ln extends v {
|
|
3651
3972
|
name = "serverSide";
|
|
3652
3973
|
version = "1.0.0";
|
|
3653
3974
|
get defaultConfig() {
|
|
@@ -3676,13 +3997,13 @@ class In extends x {
|
|
|
3676
3997
|
*/
|
|
3677
3998
|
loadRequiredBlocks() {
|
|
3678
3999
|
if (!this.dataSource) return;
|
|
3679
|
-
const e = this.grid, t = this.config.cacheBlockSize ?? 100, n = { startRow: e.
|
|
4000
|
+
const e = this.grid, t = this.config.cacheBlockSize ?? 100, n = { startRow: e._virtualization.start, endRow: e._virtualization.end }, o = on(n.startRow, n.endRow, t);
|
|
3680
4001
|
for (const i of o)
|
|
3681
4002
|
if (!(this.loadedBlocks.has(i) || this.loadingBlocks.has(i))) {
|
|
3682
4003
|
if (this.loadingBlocks.size >= (this.config.maxConcurrentRequests ?? 2))
|
|
3683
4004
|
break;
|
|
3684
|
-
this.loadingBlocks.add(i),
|
|
3685
|
-
this.loadedBlocks.set(i,
|
|
4005
|
+
this.loadingBlocks.add(i), Te(this.dataSource, i, t, {}).then((r) => {
|
|
4006
|
+
this.loadedBlocks.set(i, r.rows), this.totalRowCount = r.totalRowCount, this.loadingBlocks.delete(i), this.requestRender(), this.loadRequiredBlocks();
|
|
3686
4007
|
}).catch(() => {
|
|
3687
4008
|
this.loadingBlocks.delete(i);
|
|
3688
4009
|
});
|
|
@@ -3694,7 +4015,7 @@ class In extends x {
|
|
|
3694
4015
|
if (!this.dataSource) return [...e];
|
|
3695
4016
|
const t = [];
|
|
3696
4017
|
for (let n = 0; n < this.totalRowCount; n++) {
|
|
3697
|
-
const o =
|
|
4018
|
+
const o = rn(n, this.config.cacheBlockSize ?? 100, this.loadedBlocks);
|
|
3698
4019
|
t.push(o ?? { __loading: !0, __index: n });
|
|
3699
4020
|
}
|
|
3700
4021
|
return t;
|
|
@@ -3702,7 +4023,7 @@ class In extends x {
|
|
|
3702
4023
|
onScroll(e) {
|
|
3703
4024
|
this.dataSource && (this.loadRequiredBlocks(), this.scrollDebounceTimer && clearTimeout(this.scrollDebounceTimer), this.scrollDebounceTimer = setTimeout(() => {
|
|
3704
4025
|
this.loadRequiredBlocks();
|
|
3705
|
-
},
|
|
4026
|
+
}, sn));
|
|
3706
4027
|
}
|
|
3707
4028
|
// #endregion
|
|
3708
4029
|
// #region Public API
|
|
@@ -3713,7 +4034,7 @@ class In extends x {
|
|
|
3713
4034
|
setDataSource(e) {
|
|
3714
4035
|
this.dataSource = e, this.loadedBlocks.clear(), this.loadingBlocks.clear();
|
|
3715
4036
|
const t = this.config.cacheBlockSize ?? 100;
|
|
3716
|
-
|
|
4037
|
+
Te(e, 0, t, {}).then((n) => {
|
|
3717
4038
|
this.loadedBlocks.set(0, n.rows), this.totalRowCount = n.totalRowCount, this.requestRender();
|
|
3718
4039
|
});
|
|
3719
4040
|
}
|
|
@@ -3751,80 +4072,62 @@ class In extends x {
|
|
|
3751
4072
|
}
|
|
3752
4073
|
// #endregion
|
|
3753
4074
|
}
|
|
3754
|
-
function
|
|
3755
|
-
return
|
|
3756
|
-
}
|
|
3757
|
-
function De(r, e, t, n = null, o = 0) {
|
|
3758
|
-
const i = e.childrenField ?? "children", s = [];
|
|
3759
|
-
for (let l = 0; l < r.length; l++) {
|
|
3760
|
-
const a = r[l], d = ne(a, l, n), c = a[i], u = Array.isArray(c) && c.length > 0, h = t.has(d);
|
|
3761
|
-
if (s.push({
|
|
3762
|
-
key: d,
|
|
3763
|
-
data: a,
|
|
3764
|
-
depth: o,
|
|
3765
|
-
hasChildren: u,
|
|
3766
|
-
isExpanded: h,
|
|
3767
|
-
parentKey: n
|
|
3768
|
-
}), u && h) {
|
|
3769
|
-
const g = De(c, e, t, d, o + 1);
|
|
3770
|
-
s.push(...g);
|
|
3771
|
-
}
|
|
3772
|
-
}
|
|
3773
|
-
return s;
|
|
4075
|
+
function De(s, e, t) {
|
|
4076
|
+
return s.id !== void 0 ? String(s.id) : t ? `${t}-${e}` : String(e);
|
|
3774
4077
|
}
|
|
3775
|
-
function
|
|
3776
|
-
const t = new Set(
|
|
4078
|
+
function Fe(s, e) {
|
|
4079
|
+
const t = new Set(s);
|
|
3777
4080
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
3778
4081
|
}
|
|
3779
|
-
function
|
|
4082
|
+
function Q(s, e, t = null, n = 0) {
|
|
3780
4083
|
const o = e.childrenField ?? "children", i = /* @__PURE__ */ new Set();
|
|
3781
|
-
for (let
|
|
3782
|
-
const l = r
|
|
4084
|
+
for (let r = 0; r < s.length; r++) {
|
|
4085
|
+
const l = s[r], a = De(l, r, t), d = l[o];
|
|
3783
4086
|
if (Array.isArray(d) && d.length > 0) {
|
|
3784
4087
|
i.add(a);
|
|
3785
|
-
const c =
|
|
4088
|
+
const c = Q(d, e, a, n + 1);
|
|
3786
4089
|
for (const u of c) i.add(u);
|
|
3787
4090
|
}
|
|
3788
4091
|
}
|
|
3789
4092
|
return i;
|
|
3790
4093
|
}
|
|
3791
|
-
function
|
|
4094
|
+
function ln() {
|
|
3792
4095
|
return /* @__PURE__ */ new Set();
|
|
3793
4096
|
}
|
|
3794
|
-
function
|
|
4097
|
+
function He(s, e, t, n = null, o = 0) {
|
|
3795
4098
|
const i = t.childrenField ?? "children";
|
|
3796
|
-
for (let
|
|
3797
|
-
const l = r
|
|
4099
|
+
for (let r = 0; r < s.length; r++) {
|
|
4100
|
+
const l = s[r], a = De(l, r, n);
|
|
3798
4101
|
if (a === e)
|
|
3799
4102
|
return [a];
|
|
3800
4103
|
const d = l[i];
|
|
3801
4104
|
if (Array.isArray(d) && d.length > 0) {
|
|
3802
|
-
const c =
|
|
4105
|
+
const c = He(d, e, t, a, o + 1);
|
|
3803
4106
|
if (c)
|
|
3804
4107
|
return [a, ...c];
|
|
3805
4108
|
}
|
|
3806
4109
|
}
|
|
3807
4110
|
return null;
|
|
3808
4111
|
}
|
|
3809
|
-
function
|
|
3810
|
-
const o =
|
|
4112
|
+
function an(s, e, t, n) {
|
|
4113
|
+
const o = He(s, e, t);
|
|
3811
4114
|
if (!o) return n;
|
|
3812
4115
|
const i = new Set(n);
|
|
3813
|
-
for (let
|
|
3814
|
-
i.add(o[
|
|
4116
|
+
for (let r = 0; r < o.length - 1; r++)
|
|
4117
|
+
i.add(o[r]);
|
|
3815
4118
|
return i;
|
|
3816
4119
|
}
|
|
3817
|
-
function
|
|
3818
|
-
if (!Array.isArray(
|
|
3819
|
-
for (const t of
|
|
4120
|
+
function Pe(s, e = "children") {
|
|
4121
|
+
if (!Array.isArray(s) || s.length === 0) return !1;
|
|
4122
|
+
for (const t of s)
|
|
3820
4123
|
if (t && Array.isArray(t[e]) && t[e].length > 0)
|
|
3821
4124
|
return !0;
|
|
3822
4125
|
return !1;
|
|
3823
4126
|
}
|
|
3824
|
-
function
|
|
3825
|
-
if (!Array.isArray(
|
|
4127
|
+
function dn(s) {
|
|
4128
|
+
if (!Array.isArray(s) || s.length === 0) return null;
|
|
3826
4129
|
const e = ["children", "items", "nodes", "subRows", "nested"];
|
|
3827
|
-
for (const t of
|
|
4130
|
+
for (const t of s)
|
|
3828
4131
|
if (!(!t || typeof t != "object")) {
|
|
3829
4132
|
for (const n of e)
|
|
3830
4133
|
if (Array.isArray(t[n]) && t[n].length > 0)
|
|
@@ -3832,173 +4135,202 @@ function an(r) {
|
|
|
3832
4135
|
}
|
|
3833
4136
|
return null;
|
|
3834
4137
|
}
|
|
3835
|
-
const
|
|
3836
|
-
class
|
|
4138
|
+
const cn = ".tree-cell{display:flex;align-items:center;padding-left:calc(var(--tree-depth, 0) * var(--tbw-tree-indent, 20px))}.tree-toggle{cursor:pointer;user-select:none;display:inline-flex;align-items:center;justify-content:center;margin-right:4px}.tree-toggle:hover{color:var(--tbw-tree-accent, var(--tbw-color-accent))}.tree-spacer{width:14px;display:inline-block}.data-grid-row.tbw-tree-slide-in{animation:tbw-tree-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-tree-fade-in{animation:tbw-tree-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-fade-in{0%{opacity:0}to{opacity:1}}";
|
|
4139
|
+
class Tn extends v {
|
|
3837
4140
|
name = "tree";
|
|
3838
4141
|
version = "1.0.0";
|
|
4142
|
+
styles = cn;
|
|
3839
4143
|
get defaultConfig() {
|
|
3840
4144
|
return {
|
|
3841
4145
|
childrenField: "children",
|
|
3842
4146
|
autoDetect: !0,
|
|
3843
4147
|
defaultExpanded: !1,
|
|
3844
4148
|
indentWidth: 20,
|
|
3845
|
-
showExpandIcons: !0
|
|
4149
|
+
showExpandIcons: !0,
|
|
4150
|
+
animation: "slide"
|
|
3846
4151
|
};
|
|
3847
4152
|
}
|
|
3848
|
-
// #region
|
|
3849
|
-
/** Set of expanded row keys */
|
|
4153
|
+
// #region State
|
|
3850
4154
|
expandedKeys = /* @__PURE__ */ new Set();
|
|
3851
|
-
/** Whether initial expansion (based on defaultExpanded config) has been applied */
|
|
3852
4155
|
initialExpansionDone = !1;
|
|
3853
|
-
/** Flattened tree rows for rendering */
|
|
3854
4156
|
flattenedRows = [];
|
|
3855
|
-
/** Map from key to flattened row for quick lookup */
|
|
3856
4157
|
rowKeyMap = /* @__PURE__ */ new Map();
|
|
3857
|
-
|
|
3858
|
-
|
|
4158
|
+
previousVisibleKeys = /* @__PURE__ */ new Set();
|
|
4159
|
+
keysToAnimate = /* @__PURE__ */ new Set();
|
|
4160
|
+
sortState = null;
|
|
3859
4161
|
detach() {
|
|
3860
|
-
this.expandedKeys.clear(), this.initialExpansionDone = !1, this.flattenedRows = [], this.rowKeyMap.clear();
|
|
4162
|
+
this.expandedKeys.clear(), this.initialExpansionDone = !1, this.flattenedRows = [], this.rowKeyMap.clear(), this.previousVisibleKeys.clear(), this.keysToAnimate.clear(), this.sortState = null;
|
|
4163
|
+
}
|
|
4164
|
+
// #endregion
|
|
4165
|
+
// #region Animation
|
|
4166
|
+
get animationStyle() {
|
|
4167
|
+
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
4168
|
+
if (t === !1 || t === "off") return !1;
|
|
4169
|
+
if (t !== !0 && t !== "on") {
|
|
4170
|
+
const n = this.shadowRoot?.host;
|
|
4171
|
+
if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
4172
|
+
return !1;
|
|
4173
|
+
}
|
|
4174
|
+
return this.config.animation ?? "slide";
|
|
3861
4175
|
}
|
|
3862
4176
|
// #endregion
|
|
3863
4177
|
// #region Auto-Detection
|
|
3864
|
-
/**
|
|
3865
|
-
* Detects if tree functionality should be enabled based on data structure.
|
|
3866
|
-
* Called by the grid during plugin initialization.
|
|
3867
|
-
*/
|
|
3868
4178
|
detect(e) {
|
|
3869
4179
|
if (!this.config.autoDetect) return !1;
|
|
3870
|
-
const t = this.config.childrenField ??
|
|
3871
|
-
return
|
|
4180
|
+
const t = this.config.childrenField ?? dn(e) ?? "children";
|
|
4181
|
+
return Pe(e, t);
|
|
3872
4182
|
}
|
|
3873
4183
|
// #endregion
|
|
3874
4184
|
// #region Data Processing
|
|
3875
4185
|
processRows(e) {
|
|
3876
4186
|
const t = this.config.childrenField ?? "children";
|
|
3877
|
-
if (!
|
|
3878
|
-
return this.flattenedRows = [], this.rowKeyMap.clear(), [...e];
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
4187
|
+
if (!Pe(e, t))
|
|
4188
|
+
return this.flattenedRows = [], this.rowKeyMap.clear(), this.previousVisibleKeys.clear(), [...e];
|
|
4189
|
+
let n = this.withStableKeys(e);
|
|
4190
|
+
this.sortState && (n = this.sortTree(n, this.sortState.field, this.sortState.direction)), this.config.defaultExpanded && !this.initialExpansionDone && (this.expandedKeys = Q(n, this.config), this.initialExpansionDone = !0), this.flattenedRows = this.flattenTree(n, this.expandedKeys), this.rowKeyMap.clear(), this.keysToAnimate.clear();
|
|
4191
|
+
const o = /* @__PURE__ */ new Set();
|
|
4192
|
+
for (const i of this.flattenedRows)
|
|
4193
|
+
this.rowKeyMap.set(i.key, i), o.add(i.key), !this.previousVisibleKeys.has(i.key) && i.depth > 0 && this.keysToAnimate.add(i.key);
|
|
4194
|
+
return this.previousVisibleKeys = o, this.flattenedRows.map((i) => ({
|
|
4195
|
+
...i.data,
|
|
4196
|
+
__treeKey: i.key,
|
|
4197
|
+
__treeDepth: i.depth,
|
|
4198
|
+
__treeHasChildren: i.hasChildren,
|
|
4199
|
+
__treeExpanded: i.isExpanded
|
|
3888
4200
|
}));
|
|
3889
4201
|
}
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
const
|
|
3893
|
-
|
|
3894
|
-
const
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
if (f.style.display = "flex", f.style.alignItems = "center", f.style.paddingLeft = `${h * t}px`, g && n) {
|
|
3900
|
-
const w = document.createElement("span");
|
|
3901
|
-
w.className = "tree-toggle", this.setIcon(w, this.resolveIcon(p ? "collapse" : "expand")), w.style.cursor = "pointer", w.style.marginRight = "4px", w.style.fontSize = "10px", w.setAttribute("data-tree-key", c.__treeKey), f.appendChild(w);
|
|
3902
|
-
} else if (n) {
|
|
3903
|
-
const w = document.createElement("span");
|
|
3904
|
-
w.style.width = "14px", w.style.display = "inline-block", f.appendChild(w);
|
|
3905
|
-
}
|
|
3906
|
-
const m = document.createElement("span");
|
|
3907
|
-
if (s) {
|
|
3908
|
-
const w = s(a);
|
|
3909
|
-
w instanceof Node ? m.appendChild(w) : m.textContent = String(w ?? d ?? "");
|
|
3910
|
-
} else
|
|
3911
|
-
m.textContent = String(d ?? "");
|
|
3912
|
-
return f.appendChild(m), f;
|
|
4202
|
+
/** Assign stable keys to rows (preserves key across sort operations) */
|
|
4203
|
+
withStableKeys(e, t = null) {
|
|
4204
|
+
const n = this.config.childrenField ?? "children";
|
|
4205
|
+
return e.map((o, i) => {
|
|
4206
|
+
const r = o.id !== void 0 ? String(o.id) : o.__stableKey ?? (t ? `${t}-${i}` : String(i)), l = o[n], a = Array.isArray(l) && l.length > 0;
|
|
4207
|
+
return {
|
|
4208
|
+
...o,
|
|
4209
|
+
__stableKey: r,
|
|
4210
|
+
...a ? { [n]: this.withStableKeys(l, r) } : {}
|
|
3913
4211
|
};
|
|
3914
|
-
|
|
4212
|
+
});
|
|
4213
|
+
}
|
|
4214
|
+
/** Flatten tree using stable keys */
|
|
4215
|
+
flattenTree(e, t, n = 0) {
|
|
4216
|
+
const o = this.config.childrenField ?? "children", i = [];
|
|
4217
|
+
for (const r of e) {
|
|
4218
|
+
const l = r.__stableKey ?? r.id ?? "?", a = r[o], d = Array.isArray(a) && a.length > 0, c = t.has(l);
|
|
4219
|
+
i.push({
|
|
4220
|
+
key: l,
|
|
4221
|
+
data: r,
|
|
4222
|
+
depth: n,
|
|
4223
|
+
hasChildren: d,
|
|
4224
|
+
isExpanded: c,
|
|
4225
|
+
parentKey: n > 0 && l.substring(0, l.lastIndexOf("-")) || null
|
|
4226
|
+
}), d && c && i.push(...this.flattenTree(a, t, n + 1));
|
|
3915
4227
|
}
|
|
3916
|
-
return
|
|
4228
|
+
return i;
|
|
4229
|
+
}
|
|
4230
|
+
/** Sort tree recursively, keeping children with parents */
|
|
4231
|
+
sortTree(e, t, n) {
|
|
4232
|
+
const o = this.config.childrenField ?? "children";
|
|
4233
|
+
return [...e].sort((r, l) => {
|
|
4234
|
+
const a = r[t], d = l[t];
|
|
4235
|
+
return a == null && d == null ? 0 : a == null ? -1 : d == null ? 1 : a > d ? n : a < d ? -n : 0;
|
|
4236
|
+
}).map((r) => {
|
|
4237
|
+
const l = r[o];
|
|
4238
|
+
return Array.isArray(l) && l.length > 0 ? { ...r, [o]: this.sortTree(l, t, n) } : r;
|
|
4239
|
+
});
|
|
4240
|
+
}
|
|
4241
|
+
processColumns(e) {
|
|
4242
|
+
if (this.flattenedRows.length === 0) return [...e];
|
|
4243
|
+
const t = [...e];
|
|
4244
|
+
if (t.length === 0) return t;
|
|
4245
|
+
const n = { ...t[0] }, o = n.viewRenderer;
|
|
4246
|
+
if (o?.__treeWrapped) return t;
|
|
4247
|
+
const i = () => this.config, r = this.setIcon.bind(this), l = this.resolveIcon.bind(this), a = (d) => {
|
|
4248
|
+
const { value: c, row: u } = d, { indentWidth: h = 20, showExpandIcons: g = !0 } = i(), f = document.createElement("span");
|
|
4249
|
+
if (f.className = "tree-cell", f.style.setProperty("--tree-depth", String(u.__treeDepth ?? 0)), f.style.setProperty("--tbw-tree-indent", `${h}px`), u.__treeHasChildren && g) {
|
|
4250
|
+
const p = document.createElement("span");
|
|
4251
|
+
p.className = `tree-toggle${u.__treeExpanded ? " expanded" : ""}`, r(p, l(u.__treeExpanded ? "collapse" : "expand")), p.setAttribute("data-tree-key", u.__treeKey), f.appendChild(p);
|
|
4252
|
+
} else if (g) {
|
|
4253
|
+
const p = document.createElement("span");
|
|
4254
|
+
p.className = "tree-spacer", f.appendChild(p);
|
|
4255
|
+
}
|
|
4256
|
+
const m = document.createElement("span");
|
|
4257
|
+
if (o) {
|
|
4258
|
+
const p = o(d);
|
|
4259
|
+
p instanceof Node ? m.appendChild(p) : m.textContent = String(p ?? c ?? "");
|
|
4260
|
+
} else
|
|
4261
|
+
m.textContent = String(c ?? "");
|
|
4262
|
+
return f.appendChild(m), f;
|
|
4263
|
+
};
|
|
4264
|
+
return a.__treeWrapped = !0, n.viewRenderer = a, t[0] = n, t;
|
|
3917
4265
|
}
|
|
3918
4266
|
// #endregion
|
|
3919
4267
|
// #region Event Handlers
|
|
3920
4268
|
onCellClick(e) {
|
|
3921
4269
|
const t = e.originalEvent?.target;
|
|
3922
4270
|
if (!t?.classList.contains("tree-toggle")) return !1;
|
|
3923
|
-
const n = t.getAttribute("data-tree-key");
|
|
3924
|
-
|
|
3925
|
-
const o = this.rowKeyMap.get(n);
|
|
3926
|
-
return o ? (this.expandedKeys = Le(this.expandedKeys, n), this.emit("tree-expand", {
|
|
4271
|
+
const n = t.getAttribute("data-tree-key"), o = n ? this.rowKeyMap.get(n) : null;
|
|
4272
|
+
return o ? (this.expandedKeys = Fe(this.expandedKeys, n), this.emit("tree-expand", {
|
|
3927
4273
|
key: n,
|
|
3928
4274
|
row: o.data,
|
|
3929
4275
|
expanded: this.expandedKeys.has(n),
|
|
3930
4276
|
depth: o.depth
|
|
3931
4277
|
}), this.requestRender(), !0) : !1;
|
|
3932
4278
|
}
|
|
4279
|
+
onHeaderClick(e) {
|
|
4280
|
+
if (this.flattenedRows.length === 0 || !e.column.sortable) return !1;
|
|
4281
|
+
const { field: t } = e.column;
|
|
4282
|
+
!this.sortState || this.sortState.field !== t ? this.sortState = { field: t, direction: 1 } : this.sortState.direction === 1 ? this.sortState = { field: t, direction: -1 } : this.sortState = null;
|
|
4283
|
+
const n = this.grid;
|
|
4284
|
+
return n._sortState !== void 0 && (n._sortState = this.sortState ? { ...this.sortState } : null), this.emit("sort-change", { field: t, direction: this.sortState?.direction ?? 0 }), this.requestRender(), !0;
|
|
4285
|
+
}
|
|
4286
|
+
afterRender() {
|
|
4287
|
+
const e = this.animationStyle;
|
|
4288
|
+
if (e === !1 || this.keysToAnimate.size === 0) return;
|
|
4289
|
+
const t = this.shadowRoot?.querySelector(".rows");
|
|
4290
|
+
if (!t) return;
|
|
4291
|
+
const n = e === "fade" ? "tbw-tree-fade-in" : "tbw-tree-slide-in";
|
|
4292
|
+
for (const o of t.querySelectorAll(".data-grid-row")) {
|
|
4293
|
+
const i = o.querySelector(".cell[data-row]"), r = i ? parseInt(i.getAttribute("data-row") ?? "-1", 10) : -1, l = this.flattenedRows[r]?.key;
|
|
4294
|
+
l && this.keysToAnimate.has(l) && (o.classList.add(n), o.addEventListener("animationend", () => o.classList.remove(n), { once: !0 }));
|
|
4295
|
+
}
|
|
4296
|
+
this.keysToAnimate.clear();
|
|
4297
|
+
}
|
|
3933
4298
|
// #endregion
|
|
3934
4299
|
// #region Public API
|
|
3935
|
-
/**
|
|
3936
|
-
* Expand a specific node by key.
|
|
3937
|
-
*/
|
|
3938
4300
|
expand(e) {
|
|
3939
4301
|
this.expandedKeys.add(e), this.requestRender();
|
|
3940
4302
|
}
|
|
3941
|
-
/**
|
|
3942
|
-
* Collapse a specific node by key.
|
|
3943
|
-
*/
|
|
3944
4303
|
collapse(e) {
|
|
3945
4304
|
this.expandedKeys.delete(e), this.requestRender();
|
|
3946
4305
|
}
|
|
3947
|
-
/**
|
|
3948
|
-
* Toggle the expansion state of a node.
|
|
3949
|
-
*/
|
|
3950
4306
|
toggle(e) {
|
|
3951
|
-
this.expandedKeys =
|
|
4307
|
+
this.expandedKeys = Fe(this.expandedKeys, e), this.requestRender();
|
|
3952
4308
|
}
|
|
3953
|
-
/**
|
|
3954
|
-
* Expand all nodes in the tree.
|
|
3955
|
-
*/
|
|
3956
4309
|
expandAll() {
|
|
3957
|
-
this.expandedKeys =
|
|
4310
|
+
this.expandedKeys = Q(this.rows, this.config), this.requestRender();
|
|
3958
4311
|
}
|
|
3959
|
-
/**
|
|
3960
|
-
* Collapse all nodes in the tree.
|
|
3961
|
-
*/
|
|
3962
4312
|
collapseAll() {
|
|
3963
|
-
this.expandedKeys =
|
|
4313
|
+
this.expandedKeys = ln(), this.requestRender();
|
|
3964
4314
|
}
|
|
3965
|
-
/**
|
|
3966
|
-
* Check if a node is currently expanded.
|
|
3967
|
-
*/
|
|
3968
4315
|
isExpanded(e) {
|
|
3969
4316
|
return this.expandedKeys.has(e);
|
|
3970
4317
|
}
|
|
3971
|
-
/**
|
|
3972
|
-
* Get all currently expanded keys.
|
|
3973
|
-
*/
|
|
3974
4318
|
getExpandedKeys() {
|
|
3975
4319
|
return [...this.expandedKeys];
|
|
3976
4320
|
}
|
|
3977
|
-
/**
|
|
3978
|
-
* Get the flattened tree rows with metadata.
|
|
3979
|
-
*/
|
|
3980
4321
|
getFlattenedRows() {
|
|
3981
4322
|
return [...this.flattenedRows];
|
|
3982
4323
|
}
|
|
3983
|
-
/**
|
|
3984
|
-
* Get a row's original data by its key.
|
|
3985
|
-
*/
|
|
3986
4324
|
getRowByKey(e) {
|
|
3987
4325
|
return this.rowKeyMap.get(e)?.data;
|
|
3988
4326
|
}
|
|
3989
|
-
/**
|
|
3990
|
-
* Expand all ancestors of a node to make it visible.
|
|
3991
|
-
*/
|
|
3992
4327
|
expandToKey(e) {
|
|
3993
|
-
this.expandedKeys =
|
|
4328
|
+
this.expandedKeys = an(this.rows, e, this.config, this.expandedKeys), this.requestRender();
|
|
3994
4329
|
}
|
|
3995
4330
|
// #endregion
|
|
3996
|
-
// #region Styles
|
|
3997
|
-
styles = dn;
|
|
3998
|
-
// #endregion
|
|
3999
4331
|
}
|
|
4000
|
-
function
|
|
4001
|
-
const n = [...
|
|
4332
|
+
function un(s, e, t) {
|
|
4333
|
+
const n = [...s.undoStack, e];
|
|
4002
4334
|
for (; n.length > t; )
|
|
4003
4335
|
n.shift();
|
|
4004
4336
|
return {
|
|
@@ -4007,50 +4339,50 @@ function cn(r, e, t) {
|
|
|
4007
4339
|
// Clear redo on new action
|
|
4008
4340
|
};
|
|
4009
4341
|
}
|
|
4010
|
-
function
|
|
4011
|
-
if (
|
|
4012
|
-
return { newState:
|
|
4013
|
-
const e = [...
|
|
4342
|
+
function Me(s) {
|
|
4343
|
+
if (s.undoStack.length === 0)
|
|
4344
|
+
return { newState: s, action: null };
|
|
4345
|
+
const e = [...s.undoStack], t = e.pop();
|
|
4014
4346
|
return t ? {
|
|
4015
4347
|
newState: {
|
|
4016
4348
|
undoStack: e,
|
|
4017
|
-
redoStack: [...
|
|
4349
|
+
redoStack: [...s.redoStack, t]
|
|
4018
4350
|
},
|
|
4019
4351
|
action: t
|
|
4020
|
-
} : { newState:
|
|
4352
|
+
} : { newState: s, action: null };
|
|
4021
4353
|
}
|
|
4022
|
-
function
|
|
4023
|
-
if (
|
|
4024
|
-
return { newState:
|
|
4025
|
-
const e = [...
|
|
4354
|
+
function Ke(s) {
|
|
4355
|
+
if (s.redoStack.length === 0)
|
|
4356
|
+
return { newState: s, action: null };
|
|
4357
|
+
const e = [...s.redoStack], t = e.pop();
|
|
4026
4358
|
return t ? {
|
|
4027
4359
|
newState: {
|
|
4028
|
-
undoStack: [...
|
|
4360
|
+
undoStack: [...s.undoStack, t],
|
|
4029
4361
|
redoStack: e
|
|
4030
4362
|
},
|
|
4031
4363
|
action: t
|
|
4032
|
-
} : { newState:
|
|
4364
|
+
} : { newState: s, action: null };
|
|
4033
4365
|
}
|
|
4034
|
-
function
|
|
4035
|
-
return
|
|
4366
|
+
function hn(s) {
|
|
4367
|
+
return s.undoStack.length > 0;
|
|
4036
4368
|
}
|
|
4037
|
-
function
|
|
4038
|
-
return
|
|
4369
|
+
function gn(s) {
|
|
4370
|
+
return s.redoStack.length > 0;
|
|
4039
4371
|
}
|
|
4040
|
-
function
|
|
4372
|
+
function fn() {
|
|
4041
4373
|
return { undoStack: [], redoStack: [] };
|
|
4042
4374
|
}
|
|
4043
|
-
function pn(
|
|
4375
|
+
function pn(s, e, t, n) {
|
|
4044
4376
|
return {
|
|
4045
4377
|
type: "cell-edit",
|
|
4046
|
-
rowIndex:
|
|
4378
|
+
rowIndex: s,
|
|
4047
4379
|
field: e,
|
|
4048
4380
|
oldValue: t,
|
|
4049
4381
|
newValue: n,
|
|
4050
4382
|
timestamp: Date.now()
|
|
4051
4383
|
};
|
|
4052
4384
|
}
|
|
4053
|
-
class Fn extends
|
|
4385
|
+
class Fn extends v {
|
|
4054
4386
|
name = "undoRedo";
|
|
4055
4387
|
version = "1.0.0";
|
|
4056
4388
|
get defaultConfig() {
|
|
@@ -4075,7 +4407,7 @@ class Fn extends x {
|
|
|
4075
4407
|
onKeyDown(e) {
|
|
4076
4408
|
const t = (e.ctrlKey || e.metaKey) && e.key === "z" && !e.shiftKey, n = (e.ctrlKey || e.metaKey) && (e.key === "y" || e.key === "z" && e.shiftKey);
|
|
4077
4409
|
if (t) {
|
|
4078
|
-
const o =
|
|
4410
|
+
const o = Me({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
4079
4411
|
if (o.action) {
|
|
4080
4412
|
const i = this.rows;
|
|
4081
4413
|
i[o.action.rowIndex] && (i[o.action.rowIndex][o.action.field] = o.action.oldValue), this.undoStack = o.newState.undoStack, this.redoStack = o.newState.redoStack, this.emit("undo", {
|
|
@@ -4086,7 +4418,7 @@ class Fn extends x {
|
|
|
4086
4418
|
return !0;
|
|
4087
4419
|
}
|
|
4088
4420
|
if (n) {
|
|
4089
|
-
const o =
|
|
4421
|
+
const o = Ke({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
4090
4422
|
if (o.action) {
|
|
4091
4423
|
const i = this.rows;
|
|
4092
4424
|
i[o.action.rowIndex] && (i[o.action.rowIndex][o.action.field] = o.action.newValue), this.undoStack = o.newState.undoStack, this.redoStack = o.newState.redoStack, this.emit("redo", {
|
|
@@ -4109,12 +4441,12 @@ class Fn extends x {
|
|
|
4109
4441
|
* @param newValue - The value after the edit
|
|
4110
4442
|
*/
|
|
4111
4443
|
recordEdit(e, t, n, o) {
|
|
4112
|
-
const i = pn(e, t, n, o),
|
|
4444
|
+
const i = pn(e, t, n, o), r = un(
|
|
4113
4445
|
{ undoStack: this.undoStack, redoStack: this.redoStack },
|
|
4114
4446
|
i,
|
|
4115
4447
|
this.config.maxHistorySize ?? 100
|
|
4116
4448
|
);
|
|
4117
|
-
this.undoStack =
|
|
4449
|
+
this.undoStack = r.undoStack, this.redoStack = r.redoStack;
|
|
4118
4450
|
}
|
|
4119
4451
|
/**
|
|
4120
4452
|
* Programmatically undo the last action.
|
|
@@ -4122,7 +4454,7 @@ class Fn extends x {
|
|
|
4122
4454
|
* @returns The undone action, or null if nothing to undo
|
|
4123
4455
|
*/
|
|
4124
4456
|
undo() {
|
|
4125
|
-
const e =
|
|
4457
|
+
const e = Me({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
4126
4458
|
if (e.action) {
|
|
4127
4459
|
const t = this.rows;
|
|
4128
4460
|
t[e.action.rowIndex] && (t[e.action.rowIndex][e.action.field] = e.action.oldValue), this.undoStack = e.newState.undoStack, this.redoStack = e.newState.redoStack, this.requestRender();
|
|
@@ -4135,7 +4467,7 @@ class Fn extends x {
|
|
|
4135
4467
|
* @returns The redone action, or null if nothing to redo
|
|
4136
4468
|
*/
|
|
4137
4469
|
redo() {
|
|
4138
|
-
const e =
|
|
4470
|
+
const e = Ke({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
4139
4471
|
if (e.action) {
|
|
4140
4472
|
const t = this.rows;
|
|
4141
4473
|
t[e.action.rowIndex] && (t[e.action.rowIndex][e.action.field] = e.action.newValue), this.undoStack = e.newState.undoStack, this.redoStack = e.newState.redoStack, this.requestRender();
|
|
@@ -4146,19 +4478,19 @@ class Fn extends x {
|
|
|
4146
4478
|
* Check if there are any actions that can be undone.
|
|
4147
4479
|
*/
|
|
4148
4480
|
canUndo() {
|
|
4149
|
-
return
|
|
4481
|
+
return hn({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
4150
4482
|
}
|
|
4151
4483
|
/**
|
|
4152
4484
|
* Check if there are any actions that can be redone.
|
|
4153
4485
|
*/
|
|
4154
4486
|
canRedo() {
|
|
4155
|
-
return
|
|
4487
|
+
return gn({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
4156
4488
|
}
|
|
4157
4489
|
/**
|
|
4158
4490
|
* Clear all undo/redo history.
|
|
4159
4491
|
*/
|
|
4160
4492
|
clearHistory() {
|
|
4161
|
-
const e =
|
|
4493
|
+
const e = fn();
|
|
4162
4494
|
this.undoStack = e.undoStack, this.redoStack = e.redoStack;
|
|
4163
4495
|
}
|
|
4164
4496
|
/**
|
|
@@ -4175,12 +4507,12 @@ class Fn extends x {
|
|
|
4175
4507
|
}
|
|
4176
4508
|
// #endregion
|
|
4177
4509
|
}
|
|
4178
|
-
const
|
|
4179
|
-
function Ne(
|
|
4180
|
-
const e =
|
|
4510
|
+
const mn = '.tbw-visibility-content{display:flex;flex-direction:column;height:100%}.tbw-visibility-list{flex:1;overflow-y:auto;padding:8px}.tbw-visibility-row{display:flex;align-items:center;gap:8px;padding:6px 4px;cursor:pointer;font-size:13px;border-radius:var(--tbw-border-radius, 4px);position:relative}.tbw-visibility-row:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}.tbw-visibility-row input[type=checkbox]{cursor:pointer}.tbw-visibility-row.locked span{color:var(--tbw-color-fg-muted, #888)}.tbw-visibility-handle{cursor:grab;color:var(--tbw-color-fg-muted, #888);font-size:10px;letter-spacing:-2px;user-select:none;flex-shrink:0}.tbw-visibility-row.reorderable:hover .tbw-visibility-handle{color:var(--tbw-color-fg, #1f2937)}.tbw-visibility-label{display:flex;align-items:center;gap:8px;flex:1;cursor:pointer}.tbw-visibility-row.dragging{opacity:.5;cursor:grabbing}.tbw-visibility-row.drop-before:before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-row.drop-after:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-show-all{margin:8px;padding:8px 12px;border:1px solid var(--tbw-visibility-border, var(--tbw-color-border, #e5e7eb));border-radius:var(--tbw-border-radius, 4px);background:var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg, #f9fafb));color:var(--tbw-color-fg, #1f2937);cursor:pointer;font-size:13px}.tbw-visibility-show-all:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}';
|
|
4511
|
+
function Ne(s) {
|
|
4512
|
+
const e = s.meta ?? {};
|
|
4181
4513
|
return e.lockPosition !== !0 && e.suppressMovable !== !0;
|
|
4182
4514
|
}
|
|
4183
|
-
class
|
|
4515
|
+
class F extends v {
|
|
4184
4516
|
name = "visibility";
|
|
4185
4517
|
version = "1.0.0";
|
|
4186
4518
|
/** Tool panel ID for shell integration */
|
|
@@ -4209,7 +4541,7 @@ class T extends x {
|
|
|
4209
4541
|
*/
|
|
4210
4542
|
getToolPanel() {
|
|
4211
4543
|
return {
|
|
4212
|
-
id:
|
|
4544
|
+
id: F.PANEL_ID,
|
|
4213
4545
|
title: "Columns",
|
|
4214
4546
|
icon: "☰",
|
|
4215
4547
|
tooltip: "Column visibility",
|
|
@@ -4224,7 +4556,7 @@ class T extends x {
|
|
|
4224
4556
|
* Show the visibility sidebar panel.
|
|
4225
4557
|
*/
|
|
4226
4558
|
show() {
|
|
4227
|
-
this.grid.openToolPanel(
|
|
4559
|
+
this.grid.openToolPanel(F.PANEL_ID);
|
|
4228
4560
|
}
|
|
4229
4561
|
/**
|
|
4230
4562
|
* Hide the visibility sidebar panel.
|
|
@@ -4236,7 +4568,7 @@ class T extends x {
|
|
|
4236
4568
|
* Toggle the visibility sidebar panel.
|
|
4237
4569
|
*/
|
|
4238
4570
|
toggle() {
|
|
4239
|
-
this.grid.toggleToolPanel(
|
|
4571
|
+
this.grid.toggleToolPanel(F.PANEL_ID);
|
|
4240
4572
|
}
|
|
4241
4573
|
/**
|
|
4242
4574
|
* Check if a specific column is visible.
|
|
@@ -4314,7 +4646,7 @@ class T extends x {
|
|
|
4314
4646
|
* @returns True if the panel is open
|
|
4315
4647
|
*/
|
|
4316
4648
|
isPanelVisible() {
|
|
4317
|
-
return this.grid.activeToolPanel ===
|
|
4649
|
+
return this.grid.activeToolPanel === F.PANEL_ID;
|
|
4318
4650
|
}
|
|
4319
4651
|
// #endregion
|
|
4320
4652
|
// #region Private Methods
|
|
@@ -4350,16 +4682,16 @@ class T extends x {
|
|
|
4350
4682
|
e.innerHTML = "";
|
|
4351
4683
|
const o = t.getAllColumns();
|
|
4352
4684
|
for (let i = 0; i < o.length; i++) {
|
|
4353
|
-
const
|
|
4354
|
-
a.className =
|
|
4685
|
+
const r = o[i], l = r.header || r.field, a = document.createElement("div");
|
|
4686
|
+
a.className = r.lockVisible ? "tbw-visibility-row locked" : "tbw-visibility-row", a.setAttribute("data-field", r.field), a.setAttribute("data-index", String(i)), n && Ne(r) && (a.draggable = !0, a.classList.add("reorderable"), this.setupDragListeners(a, r.field, i, e));
|
|
4355
4687
|
const d = document.createElement("label");
|
|
4356
4688
|
d.className = "tbw-visibility-label";
|
|
4357
4689
|
const c = document.createElement("input");
|
|
4358
|
-
c.type = "checkbox", c.checked =
|
|
4359
|
-
t.toggleColumnVisibility(
|
|
4690
|
+
c.type = "checkbox", c.checked = r.visible, c.disabled = r.lockVisible ?? !1, c.addEventListener("change", () => {
|
|
4691
|
+
t.toggleColumnVisibility(r.field), setTimeout(() => this.rebuildToggles(e), 0);
|
|
4360
4692
|
});
|
|
4361
4693
|
const u = document.createElement("span");
|
|
4362
|
-
if (u.textContent = l, d.appendChild(c), d.appendChild(u), n && Ne(
|
|
4694
|
+
if (u.textContent = l, d.appendChild(c), d.appendChild(u), n && Ne(r)) {
|
|
4363
4695
|
const h = document.createElement("span");
|
|
4364
4696
|
h.className = "tbw-visibility-handle", this.setIcon(h, this.resolveIcon("dragHandle")), h.title = "Drag to reorder", a.appendChild(h);
|
|
4365
4697
|
}
|
|
@@ -4379,7 +4711,7 @@ class T extends x {
|
|
|
4379
4711
|
});
|
|
4380
4712
|
}), e.addEventListener("dragover", (i) => {
|
|
4381
4713
|
if (i.preventDefault(), !this.isDragging || this.draggedField === t) return;
|
|
4382
|
-
const
|
|
4714
|
+
const r = e.getBoundingClientRect(), l = r.top + r.height / 2;
|
|
4383
4715
|
this.dropIndex = i.clientY < l ? n : n + 1, o.querySelectorAll(".tbw-visibility-row").forEach((a) => {
|
|
4384
4716
|
a !== e && a.classList.remove("drop-target", "drop-before", "drop-after");
|
|
4385
4717
|
}), e.classList.add("drop-target"), e.classList.toggle("drop-before", i.clientY < l), e.classList.toggle("drop-after", i.clientY >= l);
|
|
@@ -4387,13 +4719,13 @@ class T extends x {
|
|
|
4387
4719
|
e.classList.remove("drop-target", "drop-before", "drop-after");
|
|
4388
4720
|
}), e.addEventListener("drop", (i) => {
|
|
4389
4721
|
i.preventDefault();
|
|
4390
|
-
const
|
|
4391
|
-
if (!this.isDragging ||
|
|
4722
|
+
const r = this.draggedField, l = this.draggedIndex, a = this.dropIndex;
|
|
4723
|
+
if (!this.isDragging || r === null || l === null || a === null)
|
|
4392
4724
|
return;
|
|
4393
4725
|
const d = a > l ? a - 1 : a;
|
|
4394
4726
|
if (d !== l) {
|
|
4395
4727
|
const c = {
|
|
4396
|
-
field:
|
|
4728
|
+
field: r,
|
|
4397
4729
|
fromIndex: l,
|
|
4398
4730
|
toIndex: d
|
|
4399
4731
|
};
|
|
@@ -4405,48 +4737,51 @@ class T extends x {
|
|
|
4405
4737
|
}
|
|
4406
4738
|
// #endregion
|
|
4407
4739
|
// #region Styles
|
|
4408
|
-
styles =
|
|
4740
|
+
styles = mn;
|
|
4409
4741
|
// #endregion
|
|
4410
4742
|
}
|
|
4411
4743
|
export {
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4744
|
+
v as BaseGridPlugin,
|
|
4745
|
+
bn as ClipboardPlugin,
|
|
4746
|
+
vn as ColumnVirtualizationPlugin,
|
|
4747
|
+
xn as ContextMenuPlugin,
|
|
4748
|
+
Kn as DEFAULT_ANIMATION_CONFIG,
|
|
4749
|
+
Ve as DEFAULT_GRID_ICONS,
|
|
4417
4750
|
Nn as DGEvents,
|
|
4418
|
-
|
|
4419
|
-
|
|
4751
|
+
qn as DataGridElement,
|
|
4752
|
+
yn as ExportPlugin,
|
|
4420
4753
|
A as FilteringPlugin,
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4754
|
+
Dn as FitModeEnum,
|
|
4755
|
+
Hn as GridCSSVars,
|
|
4756
|
+
Vn as GridClasses,
|
|
4757
|
+
On as GridDataAttrs,
|
|
4425
4758
|
Gn as GridElement,
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4759
|
+
Bn as GridSelectors,
|
|
4760
|
+
Cn as GroupingColumnsPlugin,
|
|
4761
|
+
Rn as GroupingRowsPlugin,
|
|
4762
|
+
Sn as MasterDetailPlugin,
|
|
4763
|
+
kn as MultiSortPlugin,
|
|
4764
|
+
N as PLUGIN_QUERIES,
|
|
4432
4765
|
En as PinnedColumnsPlugin,
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4766
|
+
An as PinnedRowsPlugin,
|
|
4767
|
+
T as PivotPlugin,
|
|
4768
|
+
zn as PluginEvents,
|
|
4769
|
+
Wn as PluginManager,
|
|
4770
|
+
_n as ReorderPlugin,
|
|
4771
|
+
In as SelectionPlugin,
|
|
4772
|
+
Ln as ServerSidePlugin,
|
|
4773
|
+
Tn as TreePlugin,
|
|
4441
4774
|
Fn as UndoRedoPlugin,
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4775
|
+
F as VisibilityPlugin,
|
|
4776
|
+
$n as aggregatorRegistry,
|
|
4777
|
+
jn as builtInSort,
|
|
4778
|
+
Un as defaultComparator,
|
|
4779
|
+
le as getAggregator,
|
|
4445
4780
|
Oe as getValueAggregator,
|
|
4446
|
-
|
|
4447
|
-
|
|
4781
|
+
Yn as listAggregators,
|
|
4782
|
+
Zn as registerAggregator,
|
|
4448
4783
|
se as runAggregator,
|
|
4449
|
-
|
|
4450
|
-
|
|
4784
|
+
Xn as runValueAggregator,
|
|
4785
|
+
Jn as unregisterAggregator
|
|
4451
4786
|
};
|
|
4452
4787
|
//# sourceMappingURL=all.js.map
|