@toolbox-web/grid 0.0.7 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/all.d.ts +151 -95
- package/all.js +1554 -1452
- package/all.js.map +1 -1
- package/custom-elements.json +89 -7
- package/index.d.ts +68 -23
- package/index.js +1066 -948
- package/index.js.map +1 -1
- package/lib/plugins/clipboard/index.js +48 -49
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +6 -6
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +32 -34
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/export/index.js +7 -7
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +5 -38
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +4 -32
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js +8 -45
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +6 -30
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +19 -42
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +5 -6
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +6 -80
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +673 -145
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/reorder/index.js +22 -51
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js +53 -83
- 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 +6 -14
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js +2 -3
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +13 -105
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/themes/dg-theme-bootstrap.css +73 -0
- package/themes/dg-theme-material.css +71 -0
- package/umd/grid.all.umd.js +40 -415
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +29 -60
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/clipboard.umd.js +4 -4
- package/umd/plugins/clipboard.umd.js.map +1 -1
- package/umd/plugins/column-virtualization.umd.js +1 -1
- package/umd/plugins/column-virtualization.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +2 -2
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/export.umd.js +1 -1
- package/umd/plugins/export.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +2 -34
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-columns.umd.js +1 -28
- package/umd/plugins/grouping-columns.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +1 -39
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +1 -26
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/multi-sort.umd.js +1 -25
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/pinned-columns.umd.js +1 -1
- package/umd/plugins/pinned-columns.umd.js.map +1 -1
- package/umd/plugins/pinned-rows.umd.js +1 -72
- package/umd/plugins/pinned-rows.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js +1 -7
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -30
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +1 -33
- 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 -10
- package/umd/plugins/tree.umd.js.map +1 -1
- package/umd/plugins/undo-redo.umd.js +1 -1
- package/umd/plugins/undo-redo.umd.js.map +1 -1
- package/umd/plugins/visibility.umd.js +1 -93
- package/umd/plugins/visibility.umd.js.map +1 -1
package/all.js
CHANGED
|
@@ -1,71 +1,70 @@
|
|
|
1
|
-
import { BaseGridPlugin as
|
|
2
|
-
import { DGEvents as
|
|
3
|
-
function
|
|
4
|
-
if (
|
|
5
|
-
return
|
|
6
|
-
if (
|
|
7
|
-
if (
|
|
8
|
-
if (typeof
|
|
9
|
-
const
|
|
1
|
+
import { BaseGridPlugin as C, DEFAULT_GRID_ICONS as Ae, runAggregator as ee, getAggregator as _e, getValueAggregator as Ie } from "./index.js";
|
|
2
|
+
import { DGEvents as co, DataGridElement as uo, FitModeEnum as ho, GridCSSVars as po, GridClasses as go, GridDataAttrs as fo, DataGridElement as mo, GridSelectors as bo, PluginEvents as wo, PluginManager as vo, SelectionPlugin as xo, TreePlugin as Co, aggregatorRegistry as yo, listAggregators as Ro, registerAggregator as So, runValueAggregator as Eo, unregisterAggregator as ko } from "./index.js";
|
|
3
|
+
function Te(s, e, t, o) {
|
|
4
|
+
if (o.processCell)
|
|
5
|
+
return o.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 n = String(s), i = o.delimiter ?? " ", r = o.newline ?? `
|
|
10
10
|
`;
|
|
11
|
-
return
|
|
11
|
+
return o.quoteStrings || n.includes(i) || n.includes(r) || n.includes('"') ? `"${n.replace(/"/g, '""')}"` : n;
|
|
12
12
|
}
|
|
13
|
-
function
|
|
14
|
-
const { rows: e, columns: t, selectedIndices:
|
|
13
|
+
function D(s) {
|
|
14
|
+
const { rows: e, columns: t, selectedIndices: o, config: n } = s, i = n.delimiter ?? " ", r = n.newline ?? `
|
|
15
15
|
`, l = t.filter((u) => !u.hidden && !u.field.startsWith("__")), a = [];
|
|
16
|
-
if (
|
|
16
|
+
if (n.includeHeaders) {
|
|
17
17
|
const u = l.map((h) => {
|
|
18
|
-
const
|
|
19
|
-
return
|
|
18
|
+
const p = h.header || h.field;
|
|
19
|
+
return p.includes(i) || p.includes(r) || p.includes('"') ? `"${p.replace(/"/g, '""')}"` : p;
|
|
20
20
|
});
|
|
21
|
-
a.push(u.join(
|
|
21
|
+
a.push(u.join(i));
|
|
22
22
|
}
|
|
23
|
-
const c = [...
|
|
23
|
+
const c = [...o instanceof Set ? [...o] : o].sort((u, h) => u - h);
|
|
24
24
|
for (const u of c) {
|
|
25
25
|
const h = e[u];
|
|
26
26
|
if (!h) continue;
|
|
27
|
-
const
|
|
28
|
-
(g) =>
|
|
27
|
+
const p = l.map(
|
|
28
|
+
(g) => Te(h[g.field], g.field, h, n)
|
|
29
29
|
);
|
|
30
|
-
a.push(
|
|
30
|
+
a.push(p.join(i));
|
|
31
31
|
}
|
|
32
|
-
return a.join(
|
|
32
|
+
return a.join(r);
|
|
33
33
|
}
|
|
34
|
-
async function
|
|
34
|
+
async function q(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
|
|
45
|
-
const t = e.delimiter ?? " ",
|
|
46
|
-
`,
|
|
44
|
+
function te(s, e) {
|
|
45
|
+
const t = e.delimiter ?? " ", o = e.newline ?? `
|
|
46
|
+
`, n = s.replace(/\r\n/g, `
|
|
47
47
|
`).replace(/\r/g, `
|
|
48
|
-
`),
|
|
49
|
-
let
|
|
50
|
-
for (let d = 0; d <
|
|
51
|
-
const c =
|
|
52
|
-
c === '"' && !a ? a = !0 : c === '"' && a ?
|
|
48
|
+
`), i = [];
|
|
49
|
+
let r = [], l = "", a = !1;
|
|
50
|
+
for (let d = 0; d < n.length; d++) {
|
|
51
|
+
const c = n[d];
|
|
52
|
+
c === '"' && !a ? a = !0 : c === '"' && a ? n[d + 1] === '"' ? (l += '"', d++) : a = !1 : c === t && !a ? (r.push(l), l = "") : c === o && !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 oe() {
|
|
57
57
|
try {
|
|
58
58
|
return await navigator.clipboard.readText();
|
|
59
59
|
} catch {
|
|
60
60
|
return "";
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
class
|
|
63
|
+
class Ut extends C {
|
|
64
64
|
name = "clipboard";
|
|
65
65
|
version = "1.0.0";
|
|
66
66
|
get defaultConfig() {
|
|
67
67
|
return {
|
|
68
|
-
enabled: !0,
|
|
69
68
|
includeHeaders: !1,
|
|
70
69
|
delimiter: " ",
|
|
71
70
|
newline: `
|
|
@@ -82,26 +81,25 @@ class yt extends y {
|
|
|
82
81
|
}
|
|
83
82
|
// ===== Event Handlers =====
|
|
84
83
|
onKeyDown(e) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return t ? (this.#e(e.target), !0) : n ? (this.#n(), !0) : !1;
|
|
84
|
+
const t = (e.ctrlKey || e.metaKey) && e.key === "c", o = (e.ctrlKey || e.metaKey) && e.key === "v";
|
|
85
|
+
return t ? (this.#e(e.target), !0) : o ? (this.#o(), !0) : !1;
|
|
88
86
|
}
|
|
89
87
|
// ===== Private Methods =====
|
|
90
88
|
/**
|
|
91
89
|
* Handle copy operation
|
|
92
90
|
*/
|
|
93
91
|
#e(e) {
|
|
94
|
-
const t = this.#t(),
|
|
92
|
+
const t = this.#t(), o = t?.getSelectedRows() ?? [], n = o.length > 0, i = t?.getRanges() ?? [], r = i.length > 0, l = t?.getSelectedCell() != null;
|
|
95
93
|
let a, d, c;
|
|
96
|
-
if (
|
|
97
|
-
a =
|
|
94
|
+
if (n && t)
|
|
95
|
+
a = D({
|
|
98
96
|
rows: this.rows,
|
|
99
97
|
columns: [...this.columns],
|
|
100
|
-
selectedIndices:
|
|
98
|
+
selectedIndices: o,
|
|
101
99
|
config: this.config
|
|
102
|
-
}), d =
|
|
103
|
-
else if (
|
|
104
|
-
const u =
|
|
100
|
+
}), d = o.length, c = this.columns.filter((u) => !u.hidden && !u.field.startsWith("__")).length;
|
|
101
|
+
else if (r && t) {
|
|
102
|
+
const u = i[i.length - 1], h = this.#i({
|
|
105
103
|
startRow: u.from.row,
|
|
106
104
|
startCol: u.from.col,
|
|
107
105
|
endRow: u.to.row,
|
|
@@ -109,25 +107,25 @@ class yt extends y {
|
|
|
109
107
|
});
|
|
110
108
|
a = h.text, d = h.rowCount, c = h.columnCount;
|
|
111
109
|
} else if (l && t) {
|
|
112
|
-
const u = t.getSelectedCell(), h = this.#
|
|
110
|
+
const u = t.getSelectedCell(), h = this.#n(u.row, u.col);
|
|
113
111
|
if (!h) return;
|
|
114
112
|
a = h.text, d = 1, c = 1;
|
|
115
113
|
} else {
|
|
116
|
-
const u = this.#
|
|
114
|
+
const u = this.#r(e);
|
|
117
115
|
if (!u) return;
|
|
118
116
|
a = u.text, d = 1, c = 1;
|
|
119
117
|
}
|
|
120
|
-
|
|
118
|
+
q(a).then(() => {
|
|
121
119
|
this.lastCopied = { text: a, timestamp: Date.now() }, this.emit("copy", { text: a, rowCount: d, columnCount: c });
|
|
122
120
|
});
|
|
123
121
|
}
|
|
124
122
|
/**
|
|
125
123
|
* Handle paste operation
|
|
126
124
|
*/
|
|
127
|
-
#
|
|
128
|
-
|
|
125
|
+
#o() {
|
|
126
|
+
oe().then((e) => {
|
|
129
127
|
if (!e) return;
|
|
130
|
-
const t =
|
|
128
|
+
const t = te(e, this.config);
|
|
131
129
|
this.emit("paste", { rows: t, text: e });
|
|
132
130
|
});
|
|
133
131
|
}
|
|
@@ -148,42 +146,42 @@ class yt extends y {
|
|
|
148
146
|
/**
|
|
149
147
|
* Build text for a single cell by row/col index.
|
|
150
148
|
*/
|
|
151
|
-
#
|
|
152
|
-
const
|
|
153
|
-
if (!n) return null;
|
|
154
|
-
const o = this.columns[t];
|
|
149
|
+
#n(e, t) {
|
|
150
|
+
const o = this.rows[e];
|
|
155
151
|
if (!o) return null;
|
|
156
|
-
const
|
|
152
|
+
const n = this.columns[t];
|
|
153
|
+
if (!n) return null;
|
|
154
|
+
const i = o[n.field], r = n.header || n.field;
|
|
157
155
|
let l;
|
|
158
156
|
if (this.config.includeHeaders) {
|
|
159
|
-
const a =
|
|
160
|
-
l = `${
|
|
157
|
+
const a = i == null ? "" : String(i);
|
|
158
|
+
l = `${r}: ${a}`;
|
|
161
159
|
} else
|
|
162
|
-
l =
|
|
160
|
+
l = i == null ? "" : String(i);
|
|
163
161
|
return { text: l };
|
|
164
162
|
}
|
|
165
163
|
/**
|
|
166
164
|
* Build text for a rectangular range of cells.
|
|
167
165
|
*/
|
|
168
|
-
#
|
|
169
|
-
const { startRow: t, startCol:
|
|
170
|
-
`, h = [],
|
|
166
|
+
#i(e) {
|
|
167
|
+
const { startRow: t, startCol: o, endRow: n, endCol: i } = e, r = Math.min(t, n), l = Math.max(t, n), a = Math.min(o, i), d = Math.max(o, i), c = this.config.delimiter ?? " ", u = this.config.newline ?? `
|
|
168
|
+
`, h = [], p = this.columns.slice(a, d + 1);
|
|
171
169
|
if (this.config.includeHeaders) {
|
|
172
|
-
const g =
|
|
170
|
+
const g = p.map((m) => m.header || m.field);
|
|
173
171
|
h.push(g.join(c));
|
|
174
172
|
}
|
|
175
|
-
for (let g =
|
|
173
|
+
for (let g = r; g <= l; g++) {
|
|
176
174
|
const m = this.rows[g];
|
|
177
175
|
if (!m) continue;
|
|
178
|
-
const b =
|
|
179
|
-
const
|
|
180
|
-
return
|
|
176
|
+
const b = p.map((R) => {
|
|
177
|
+
const E = m[R.field];
|
|
178
|
+
return E == null ? "" : E instanceof Date ? E.toISOString() : String(E);
|
|
181
179
|
});
|
|
182
180
|
h.push(b.join(c));
|
|
183
181
|
}
|
|
184
182
|
return {
|
|
185
183
|
text: h.join(u),
|
|
186
|
-
rowCount: l -
|
|
184
|
+
rowCount: l - r + 1,
|
|
187
185
|
columnCount: d - a + 1
|
|
188
186
|
};
|
|
189
187
|
}
|
|
@@ -191,25 +189,25 @@ class yt extends y {
|
|
|
191
189
|
* Build text for a single focused cell from DOM.
|
|
192
190
|
* Used when selection plugin is not available or no rows are selected.
|
|
193
191
|
*/
|
|
194
|
-
#
|
|
192
|
+
#r(e) {
|
|
195
193
|
const t = e.closest("[data-field-cache]");
|
|
196
194
|
if (!t) return null;
|
|
197
|
-
const
|
|
198
|
-
if (!n) return null;
|
|
199
|
-
const o = t.dataset.row;
|
|
195
|
+
const o = t.dataset.fieldCache;
|
|
200
196
|
if (!o) return null;
|
|
201
|
-
const
|
|
202
|
-
if (
|
|
203
|
-
const
|
|
204
|
-
if (
|
|
205
|
-
const
|
|
197
|
+
const n = t.dataset.row;
|
|
198
|
+
if (!n) return null;
|
|
199
|
+
const i = parseInt(n, 10);
|
|
200
|
+
if (isNaN(i)) return null;
|
|
201
|
+
const r = this.rows[i];
|
|
202
|
+
if (!r) return null;
|
|
203
|
+
const l = r[o], d = this.columns.find((u) => u.field === o)?.header || o;
|
|
206
204
|
let c;
|
|
207
205
|
if (this.config.includeHeaders) {
|
|
208
206
|
const u = l == null ? "" : String(l);
|
|
209
207
|
c = `${d}: ${u}`;
|
|
210
208
|
} else
|
|
211
209
|
c = l == null ? "" : String(l);
|
|
212
|
-
return { text: c, field:
|
|
210
|
+
return { text: c, field: o, value: l };
|
|
213
211
|
}
|
|
214
212
|
// ===== Public API =====
|
|
215
213
|
/**
|
|
@@ -217,13 +215,13 @@ class yt extends y {
|
|
|
217
215
|
* @returns The copied text
|
|
218
216
|
*/
|
|
219
217
|
async copy() {
|
|
220
|
-
const t = this.#t()?.getSelectedRows() ?? [],
|
|
218
|
+
const t = this.#t()?.getSelectedRows() ?? [], o = D({
|
|
221
219
|
rows: this.rows,
|
|
222
220
|
columns: [...this.columns],
|
|
223
221
|
selectedIndices: t,
|
|
224
222
|
config: this.config
|
|
225
223
|
});
|
|
226
|
-
return await
|
|
224
|
+
return await q(o), this.lastCopied = { text: o, timestamp: Date.now() }, o;
|
|
227
225
|
}
|
|
228
226
|
/**
|
|
229
227
|
* Copy specific rows by index to clipboard.
|
|
@@ -231,21 +229,21 @@ class yt extends y {
|
|
|
231
229
|
* @returns The copied text
|
|
232
230
|
*/
|
|
233
231
|
async copyRows(e) {
|
|
234
|
-
const t =
|
|
232
|
+
const t = D({
|
|
235
233
|
rows: this.rows,
|
|
236
234
|
columns: [...this.columns],
|
|
237
235
|
selectedIndices: e,
|
|
238
236
|
config: this.config
|
|
239
237
|
});
|
|
240
|
-
return await
|
|
238
|
+
return await q(t), this.lastCopied = { text: t, timestamp: Date.now() }, t;
|
|
241
239
|
}
|
|
242
240
|
/**
|
|
243
241
|
* Read and parse clipboard content.
|
|
244
242
|
* @returns Parsed 2D array of cell values, or null if clipboard is empty
|
|
245
243
|
*/
|
|
246
244
|
async paste() {
|
|
247
|
-
const e = await
|
|
248
|
-
return e ?
|
|
245
|
+
const e = await oe();
|
|
246
|
+
return e ? te(e, this.config) : null;
|
|
249
247
|
}
|
|
250
248
|
/**
|
|
251
249
|
* Get the last copied text and timestamp.
|
|
@@ -255,66 +253,65 @@ class yt extends y {
|
|
|
255
253
|
return this.lastCopied;
|
|
256
254
|
}
|
|
257
255
|
}
|
|
258
|
-
const
|
|
259
|
-
function
|
|
260
|
-
if (
|
|
261
|
-
return
|
|
262
|
-
if (typeof
|
|
263
|
-
return
|
|
264
|
-
const e = parseFloat(
|
|
265
|
-
return isNaN(e) ?
|
|
256
|
+
const ne = 100;
|
|
257
|
+
function U(s) {
|
|
258
|
+
if (s == null)
|
|
259
|
+
return ne;
|
|
260
|
+
if (typeof s == "number")
|
|
261
|
+
return s;
|
|
262
|
+
const e = parseFloat(s);
|
|
263
|
+
return isNaN(e) ? ne : e;
|
|
266
264
|
}
|
|
267
|
-
function
|
|
268
|
-
return
|
|
265
|
+
function ie(s) {
|
|
266
|
+
return s.map((e) => U(e.width));
|
|
269
267
|
}
|
|
270
|
-
function
|
|
268
|
+
function re(s) {
|
|
271
269
|
const e = [];
|
|
272
270
|
let t = 0;
|
|
273
|
-
for (const
|
|
274
|
-
e.push(t), t +=
|
|
271
|
+
for (const o of s)
|
|
272
|
+
e.push(t), t += U(o.width);
|
|
275
273
|
return e;
|
|
276
274
|
}
|
|
277
|
-
function
|
|
278
|
-
return
|
|
275
|
+
function se(s) {
|
|
276
|
+
return s.reduce((e, t) => e + U(t.width), 0);
|
|
279
277
|
}
|
|
280
|
-
function
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
278
|
+
function Fe(s, e, t, o, n) {
|
|
279
|
+
const i = t.length;
|
|
280
|
+
if (i === 0)
|
|
283
281
|
return { startCol: 0, endCol: 0, visibleColumns: [] };
|
|
284
|
-
let
|
|
285
|
-
|
|
286
|
-
const l =
|
|
287
|
-
let a =
|
|
288
|
-
for (let c =
|
|
282
|
+
let r = Le(s, t, o);
|
|
283
|
+
r = Math.max(0, r - n);
|
|
284
|
+
const l = s + e;
|
|
285
|
+
let a = r;
|
|
286
|
+
for (let c = r; c < i; c++) {
|
|
289
287
|
if (t[c] >= l) {
|
|
290
288
|
a = c - 1;
|
|
291
289
|
break;
|
|
292
290
|
}
|
|
293
291
|
a = c;
|
|
294
292
|
}
|
|
295
|
-
a = Math.min(
|
|
293
|
+
a = Math.min(i - 1, a + n);
|
|
296
294
|
const d = [];
|
|
297
|
-
for (let c =
|
|
295
|
+
for (let c = r; c <= a; c++)
|
|
298
296
|
d.push(c);
|
|
299
|
-
return { startCol:
|
|
297
|
+
return { startCol: r, endCol: a, visibleColumns: d };
|
|
300
298
|
}
|
|
301
|
-
function
|
|
302
|
-
let
|
|
303
|
-
for (;
|
|
304
|
-
const
|
|
305
|
-
e[
|
|
299
|
+
function Le(s, e, t) {
|
|
300
|
+
let o = 0, n = e.length - 1;
|
|
301
|
+
for (; o < n; ) {
|
|
302
|
+
const i = Math.floor((o + n) / 2);
|
|
303
|
+
e[i] + t[i] <= s ? o = i + 1 : n = i;
|
|
306
304
|
}
|
|
307
|
-
return
|
|
305
|
+
return o;
|
|
308
306
|
}
|
|
309
|
-
function
|
|
310
|
-
return t ?
|
|
307
|
+
function Ne(s, e, t) {
|
|
308
|
+
return t ? s > e : !1;
|
|
311
309
|
}
|
|
312
|
-
class
|
|
310
|
+
class Yt extends C {
|
|
313
311
|
name = "columnVirtualization";
|
|
314
312
|
version = "1.0.0";
|
|
315
313
|
get defaultConfig() {
|
|
316
314
|
return {
|
|
317
|
-
enabled: !0,
|
|
318
315
|
autoEnable: !0,
|
|
319
316
|
threshold: 30,
|
|
320
317
|
overscan: 3
|
|
@@ -332,35 +329,35 @@ class Ct extends y {
|
|
|
332
329
|
attach(e) {
|
|
333
330
|
super.attach(e);
|
|
334
331
|
const t = this.columns;
|
|
335
|
-
this.columnWidths =
|
|
332
|
+
this.columnWidths = ie(t), this.columnOffsets = re(t), this.totalWidth = se(t), this.endCol = t.length - 1;
|
|
336
333
|
}
|
|
337
334
|
detach() {
|
|
338
335
|
this.columnWidths = [], this.columnOffsets = [], this.isVirtualized = !1, this.startCol = 0, this.endCol = 0, this.scrollLeft = 0, this.totalWidth = 0;
|
|
339
336
|
}
|
|
340
337
|
// ===== Hooks =====
|
|
341
338
|
processColumns(e) {
|
|
342
|
-
const t =
|
|
343
|
-
if (this.isVirtualized = t ?? !1, this.columnWidths =
|
|
339
|
+
const t = Ne(e.length, this.config.threshold ?? 30, this.config.autoEnable ?? !0);
|
|
340
|
+
if (this.isVirtualized = t ?? !1, this.columnWidths = ie(e), this.columnOffsets = re(e), this.totalWidth = se(e), !t)
|
|
344
341
|
return this.startCol = 0, this.endCol = e.length - 1, [...e];
|
|
345
|
-
const
|
|
342
|
+
const o = this.grid.clientWidth || 800, n = Fe(
|
|
346
343
|
this.scrollLeft,
|
|
347
|
-
|
|
344
|
+
o,
|
|
348
345
|
this.columnOffsets,
|
|
349
346
|
this.columnWidths,
|
|
350
347
|
this.config.overscan ?? 3
|
|
351
348
|
);
|
|
352
|
-
return this.startCol =
|
|
349
|
+
return this.startCol = n.startCol, this.endCol = n.endCol, n.visibleColumns.map((i) => e[i]);
|
|
353
350
|
}
|
|
354
351
|
afterRender() {
|
|
355
352
|
if (!this.isVirtualized) return;
|
|
356
353
|
const e = this.shadowRoot;
|
|
357
354
|
if (!e) return;
|
|
358
|
-
const t = this.columnOffsets[this.startCol] ?? 0,
|
|
359
|
-
|
|
360
|
-
|
|
355
|
+
const t = this.columnOffsets[this.startCol] ?? 0, o = e.querySelector(".header-row"), n = e.querySelectorAll(".data-grid-row");
|
|
356
|
+
o && (o.style.paddingLeft = `${t}px`), n.forEach((r) => {
|
|
357
|
+
r.style.paddingLeft = `${t}px`;
|
|
361
358
|
});
|
|
362
|
-
const
|
|
363
|
-
|
|
359
|
+
const i = e.querySelector(".rows-viewport .rows");
|
|
360
|
+
i && (i.style.width = `${this.totalWidth}px`);
|
|
364
361
|
}
|
|
365
362
|
onScroll(e) {
|
|
366
363
|
!this.isVirtualized || Math.abs(e.scrollLeft - this.scrollLeft) < 1 || (this.scrollLeft = e.scrollLeft, this.requestRender());
|
|
@@ -383,8 +380,8 @@ class Ct extends y {
|
|
|
383
380
|
* @param columnIndex - Index of the column to scroll to
|
|
384
381
|
*/
|
|
385
382
|
scrollToColumn(e) {
|
|
386
|
-
const t = this.columnOffsets[e] ?? 0,
|
|
387
|
-
|
|
383
|
+
const t = this.columnOffsets[e] ?? 0, o = this.grid;
|
|
384
|
+
o.scrollLeft = t;
|
|
388
385
|
}
|
|
389
386
|
/**
|
|
390
387
|
* Get the left offset for a specific column.
|
|
@@ -400,58 +397,58 @@ class Ct extends y {
|
|
|
400
397
|
return this.totalWidth;
|
|
401
398
|
}
|
|
402
399
|
}
|
|
403
|
-
function
|
|
404
|
-
return (typeof
|
|
400
|
+
function $(s, e) {
|
|
401
|
+
return (typeof s == "function" ? s(e) : s).filter((o) => !(o.hidden === !0 || typeof o.hidden == "function" && o.hidden(e)));
|
|
405
402
|
}
|
|
406
|
-
function
|
|
407
|
-
return
|
|
403
|
+
function Me(s, e) {
|
|
404
|
+
return s.disabled === !0 ? !0 : typeof s.disabled == "function" ? s.disabled(e) : !1;
|
|
408
405
|
}
|
|
409
|
-
function
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
for (const
|
|
413
|
-
if (
|
|
406
|
+
function j(s, e, t, o = Ae.submenuArrow) {
|
|
407
|
+
const n = document.createElement("div");
|
|
408
|
+
n.className = "tbw-context-menu", n.setAttribute("role", "menu");
|
|
409
|
+
for (const i of s) {
|
|
410
|
+
if (i.separator) {
|
|
414
411
|
const d = document.createElement("div");
|
|
415
|
-
d.className = "tbw-context-menu-separator", d.setAttribute("role", "separator"),
|
|
412
|
+
d.className = "tbw-context-menu-separator", d.setAttribute("role", "separator"), n.appendChild(d);
|
|
416
413
|
continue;
|
|
417
414
|
}
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
const l =
|
|
421
|
-
if (l && (
|
|
415
|
+
const r = document.createElement("div");
|
|
416
|
+
r.className = "tbw-context-menu-item", i.cssClass && r.classList.add(i.cssClass), r.setAttribute("role", "menuitem"), r.setAttribute("data-id", i.id);
|
|
417
|
+
const l = Me(i, e);
|
|
418
|
+
if (l && (r.classList.add("disabled"), r.setAttribute("aria-disabled", "true")), i.icon) {
|
|
422
419
|
const d = document.createElement("span");
|
|
423
|
-
d.className = "tbw-context-menu-icon", d.innerHTML =
|
|
420
|
+
d.className = "tbw-context-menu-icon", d.innerHTML = i.icon, r.appendChild(d);
|
|
424
421
|
}
|
|
425
422
|
const a = document.createElement("span");
|
|
426
|
-
if (a.className = "tbw-context-menu-label", a.textContent =
|
|
423
|
+
if (a.className = "tbw-context-menu-label", a.textContent = i.name, r.appendChild(a), i.shortcut) {
|
|
427
424
|
const d = document.createElement("span");
|
|
428
|
-
d.className = "tbw-context-menu-shortcut", d.textContent =
|
|
425
|
+
d.className = "tbw-context-menu-shortcut", d.textContent = i.shortcut, r.appendChild(d);
|
|
429
426
|
}
|
|
430
|
-
if (
|
|
427
|
+
if (i.subMenu?.length) {
|
|
431
428
|
const d = document.createElement("span");
|
|
432
|
-
d.className = "tbw-context-menu-arrow", typeof
|
|
433
|
-
if (
|
|
434
|
-
const u =
|
|
435
|
-
h.classList.add("tbw-context-submenu"), h.style.position = "absolute", h.style.left = "100%", h.style.top = "0",
|
|
436
|
-
}),
|
|
437
|
-
const c =
|
|
429
|
+
d.className = "tbw-context-menu-arrow", typeof o == "string" ? d.innerHTML = o : o instanceof HTMLElement && d.appendChild(o.cloneNode(!0)), r.appendChild(d), r.addEventListener("mouseenter", () => {
|
|
430
|
+
if (r.querySelector(".tbw-context-menu") || !i.subMenu) return;
|
|
431
|
+
const u = $(i.subMenu, e), h = j(u, e, t, o);
|
|
432
|
+
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);
|
|
433
|
+
}), r.addEventListener("mouseleave", () => {
|
|
434
|
+
const c = r.querySelector(".tbw-context-menu");
|
|
438
435
|
c && c.remove();
|
|
439
436
|
});
|
|
440
437
|
}
|
|
441
|
-
!l &&
|
|
442
|
-
d.stopPropagation(), t(
|
|
443
|
-
}),
|
|
438
|
+
!l && i.action && !i.subMenu && r.addEventListener("click", (d) => {
|
|
439
|
+
d.stopPropagation(), t(i);
|
|
440
|
+
}), n.appendChild(r);
|
|
444
441
|
}
|
|
445
|
-
return
|
|
442
|
+
return n;
|
|
446
443
|
}
|
|
447
|
-
function
|
|
448
|
-
|
|
449
|
-
const
|
|
450
|
-
let
|
|
451
|
-
e +
|
|
444
|
+
function le(s, e, t) {
|
|
445
|
+
s.style.position = "fixed", s.style.left = `${e}px`, s.style.top = `${t}px`, s.style.visibility = "hidden", s.style.zIndex = "10000";
|
|
446
|
+
const o = s.getBoundingClientRect(), n = window.innerWidth, i = window.innerHeight;
|
|
447
|
+
let r = e, l = t;
|
|
448
|
+
e + o.width > n && (r = e - o.width), t + o.height > i && (l = t - o.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";
|
|
452
449
|
}
|
|
453
|
-
let
|
|
454
|
-
const
|
|
450
|
+
let H = null, G = null, A = null;
|
|
451
|
+
const Pe = `
|
|
455
452
|
.tbw-context-menu {
|
|
456
453
|
position: fixed;
|
|
457
454
|
background: light-dark(#f5f5f5, #2a2a2a);
|
|
@@ -502,31 +499,30 @@ const Ee = `
|
|
|
502
499
|
background: light-dark(#d0d0d4, #454545);
|
|
503
500
|
margin: 4px 0;
|
|
504
501
|
}
|
|
505
|
-
`,
|
|
502
|
+
`, O = [
|
|
506
503
|
{
|
|
507
504
|
id: "copy",
|
|
508
505
|
name: "Copy",
|
|
509
506
|
shortcut: "Ctrl+C",
|
|
510
|
-
action: (
|
|
511
|
-
|
|
507
|
+
action: (s) => {
|
|
508
|
+
s.grid?.plugins?.clipboard?.copy?.();
|
|
512
509
|
}
|
|
513
510
|
},
|
|
514
511
|
{ separator: !0, id: "sep1", name: "" },
|
|
515
512
|
{
|
|
516
513
|
id: "export-csv",
|
|
517
514
|
name: "Export CSV",
|
|
518
|
-
action: (
|
|
519
|
-
|
|
515
|
+
action: (s) => {
|
|
516
|
+
s.grid?.plugins?.export?.exportCsv?.();
|
|
520
517
|
}
|
|
521
518
|
}
|
|
522
519
|
];
|
|
523
|
-
class
|
|
520
|
+
class Zt extends C {
|
|
524
521
|
name = "contextMenu";
|
|
525
522
|
version = "1.0.0";
|
|
526
523
|
get defaultConfig() {
|
|
527
524
|
return {
|
|
528
|
-
|
|
529
|
-
items: B
|
|
525
|
+
items: O
|
|
530
526
|
};
|
|
531
527
|
}
|
|
532
528
|
// ===== Internal State =====
|
|
@@ -543,35 +539,33 @@ class St extends y {
|
|
|
543
539
|
}
|
|
544
540
|
// ===== Private Methods =====
|
|
545
541
|
installGlobalHandlers() {
|
|
546
|
-
!A && typeof document < "u" && (A = document.createElement("style"), A.id = "tbw-context-menu-styles", A.textContent =
|
|
542
|
+
!A && typeof document < "u" && (A = document.createElement("style"), A.id = "tbw-context-menu-styles", A.textContent = Pe, document.head.appendChild(A)), H || (H = () => {
|
|
547
543
|
document.querySelectorAll(".tbw-context-menu").forEach((t) => t.remove());
|
|
548
|
-
}, document.addEventListener("click",
|
|
549
|
-
e.key === "Escape" && document.querySelectorAll(".tbw-context-menu").forEach((
|
|
550
|
-
}, document.addEventListener("keydown",
|
|
544
|
+
}, document.addEventListener("click", H)), G || (G = (e) => {
|
|
545
|
+
e.key === "Escape" && document.querySelectorAll(".tbw-context-menu").forEach((o) => o.remove());
|
|
546
|
+
}, document.addEventListener("keydown", G));
|
|
551
547
|
}
|
|
552
548
|
// ===== Hooks =====
|
|
553
549
|
afterRender() {
|
|
554
|
-
if (!this.config.enabled) return;
|
|
555
550
|
const e = this.shadowRoot;
|
|
556
551
|
if (!e) return;
|
|
557
552
|
const t = e.children[0];
|
|
558
|
-
t && t.getAttribute("data-context-menu-bound") !== "true" && (t.setAttribute("data-context-menu-bound", "true"), t.addEventListener("contextmenu", (
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
const r = o.target, s = r.closest("[data-row][data-col]"), l = r.closest(".header-cell");
|
|
553
|
+
t && t.getAttribute("data-context-menu-bound") !== "true" && (t.setAttribute("data-context-menu-bound", "true"), t.addEventListener("contextmenu", (o) => {
|
|
554
|
+
const n = o;
|
|
555
|
+
n.preventDefault();
|
|
556
|
+
const i = n.target, r = i.closest("[data-row][data-col]"), l = i.closest(".header-cell");
|
|
563
557
|
let a;
|
|
564
|
-
if (
|
|
565
|
-
const c = parseInt(
|
|
558
|
+
if (r) {
|
|
559
|
+
const c = parseInt(r.getAttribute("data-row") ?? "-1", 10), u = parseInt(r.getAttribute("data-col") ?? "-1", 10), h = this.columns[u], p = this.rows[c];
|
|
566
560
|
a = {
|
|
567
|
-
row:
|
|
561
|
+
row: p,
|
|
568
562
|
rowIndex: c,
|
|
569
563
|
column: h,
|
|
570
564
|
columnIndex: u,
|
|
571
565
|
field: h?.field ?? "",
|
|
572
|
-
value:
|
|
566
|
+
value: p?.[h?.field] ?? null,
|
|
573
567
|
isHeader: !1,
|
|
574
|
-
event:
|
|
568
|
+
event: n
|
|
575
569
|
};
|
|
576
570
|
} else if (l) {
|
|
577
571
|
const c = parseInt(l.getAttribute("data-col") ?? "-1", 10), u = this.columns[c];
|
|
@@ -583,20 +577,20 @@ class St extends y {
|
|
|
583
577
|
field: u?.field ?? "",
|
|
584
578
|
value: null,
|
|
585
579
|
isHeader: !0,
|
|
586
|
-
event:
|
|
580
|
+
event: n
|
|
587
581
|
};
|
|
588
582
|
} else
|
|
589
583
|
return;
|
|
590
|
-
this.params = a, this.position = { x:
|
|
591
|
-
const d =
|
|
592
|
-
d.length && (this.menuElement && this.menuElement.remove(), this.menuElement =
|
|
584
|
+
this.params = a, this.position = { x: n.clientX, y: n.clientY };
|
|
585
|
+
const d = $(this.config.items ?? O, a);
|
|
586
|
+
d.length && (this.menuElement && this.menuElement.remove(), this.menuElement = j(
|
|
593
587
|
d,
|
|
594
588
|
a,
|
|
595
589
|
(c) => {
|
|
596
590
|
c.action && c.action(a), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
|
|
597
591
|
},
|
|
598
592
|
this.gridIcons.submenuArrow
|
|
599
|
-
), document.body.appendChild(this.menuElement),
|
|
593
|
+
), document.body.appendChild(this.menuElement), le(this.menuElement, n.clientX, n.clientY), this.isOpen = !0, this.emit("context-menu-open", { params: a, items: d }));
|
|
600
594
|
}));
|
|
601
595
|
}
|
|
602
596
|
// ===== Public API =====
|
|
@@ -606,25 +600,25 @@ class St extends y {
|
|
|
606
600
|
* @param y - Y coordinate
|
|
607
601
|
* @param params - Partial context menu parameters
|
|
608
602
|
*/
|
|
609
|
-
showMenu(e, t,
|
|
610
|
-
const
|
|
611
|
-
row:
|
|
612
|
-
rowIndex:
|
|
613
|
-
column:
|
|
614
|
-
columnIndex:
|
|
615
|
-
field:
|
|
616
|
-
value:
|
|
617
|
-
isHeader:
|
|
618
|
-
event:
|
|
619
|
-
},
|
|
620
|
-
this.menuElement && this.menuElement.remove(), this.menuElement =
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
(
|
|
624
|
-
|
|
603
|
+
showMenu(e, t, o) {
|
|
604
|
+
const n = {
|
|
605
|
+
row: o.row ?? null,
|
|
606
|
+
rowIndex: o.rowIndex ?? -1,
|
|
607
|
+
column: o.column ?? null,
|
|
608
|
+
columnIndex: o.columnIndex ?? -1,
|
|
609
|
+
field: o.field ?? "",
|
|
610
|
+
value: o.value ?? null,
|
|
611
|
+
isHeader: o.isHeader ?? !1,
|
|
612
|
+
event: o.event ?? new MouseEvent("contextmenu")
|
|
613
|
+
}, i = $(this.config.items ?? O, n);
|
|
614
|
+
this.menuElement && this.menuElement.remove(), this.menuElement = j(
|
|
615
|
+
i,
|
|
616
|
+
n,
|
|
617
|
+
(r) => {
|
|
618
|
+
r.action && r.action(n), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
|
|
625
619
|
},
|
|
626
620
|
this.gridIcons.submenuArrow
|
|
627
|
-
), document.body.appendChild(this.menuElement),
|
|
621
|
+
), document.body.appendChild(this.menuElement), le(this.menuElement, e, t), this.isOpen = !0;
|
|
628
622
|
}
|
|
629
623
|
/**
|
|
630
624
|
* Hide the context menu.
|
|
@@ -641,88 +635,87 @@ class St extends y {
|
|
|
641
635
|
}
|
|
642
636
|
// Styles are injected globally via installGlobalHandlers() since menu renders in document.body
|
|
643
637
|
}
|
|
644
|
-
function
|
|
645
|
-
if (
|
|
646
|
-
if (
|
|
647
|
-
if (typeof
|
|
648
|
-
const t = String(
|
|
638
|
+
function ae(s, e = !0) {
|
|
639
|
+
if (s == null) return "";
|
|
640
|
+
if (s instanceof Date) return s.toISOString();
|
|
641
|
+
if (typeof s == "object") return JSON.stringify(s);
|
|
642
|
+
const t = String(s);
|
|
649
643
|
return e && (t.includes(",") || t.includes('"') || t.includes(`
|
|
650
644
|
`) || t.includes("\r")) ? `"${t.replace(/"/g, '""')}"` : t;
|
|
651
645
|
}
|
|
652
|
-
function
|
|
653
|
-
const
|
|
654
|
-
`,
|
|
646
|
+
function De(s, e, t, o = {}) {
|
|
647
|
+
const n = o.delimiter ?? ",", i = o.newline ?? `
|
|
648
|
+
`, r = [], l = o.bom ? "\uFEFF" : "";
|
|
655
649
|
if (t.includeHeaders !== !1) {
|
|
656
650
|
const a = e.map((d) => {
|
|
657
651
|
const c = d.header || d.field, u = t.processHeader ? t.processHeader(c, d.field) : c;
|
|
658
|
-
return
|
|
652
|
+
return ae(u);
|
|
659
653
|
});
|
|
660
|
-
|
|
654
|
+
r.push(a.join(n));
|
|
661
655
|
}
|
|
662
|
-
for (const a of
|
|
656
|
+
for (const a of s) {
|
|
663
657
|
const d = e.map((c) => {
|
|
664
658
|
let u = a[c.field];
|
|
665
|
-
return t.processCell && (u = t.processCell(u, c.field, a)),
|
|
659
|
+
return t.processCell && (u = t.processCell(u, c.field, a)), ae(u);
|
|
666
660
|
});
|
|
667
|
-
|
|
661
|
+
r.push(d.join(n));
|
|
668
662
|
}
|
|
669
|
-
return l +
|
|
663
|
+
return l + r.join(i);
|
|
670
664
|
}
|
|
671
|
-
function
|
|
672
|
-
const t = URL.createObjectURL(
|
|
673
|
-
|
|
665
|
+
function Y(s, e) {
|
|
666
|
+
const t = URL.createObjectURL(s), o = document.createElement("a");
|
|
667
|
+
o.href = t, o.download = e, o.style.display = "none", document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(t);
|
|
674
668
|
}
|
|
675
|
-
function
|
|
676
|
-
const t = new Blob([
|
|
677
|
-
|
|
669
|
+
function qe(s, e) {
|
|
670
|
+
const t = new Blob([s], { type: "text/csv;charset=utf-8;" });
|
|
671
|
+
Y(t, e);
|
|
678
672
|
}
|
|
679
|
-
function
|
|
680
|
-
return
|
|
673
|
+
function de(s) {
|
|
674
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
681
675
|
}
|
|
682
|
-
function
|
|
683
|
-
let
|
|
676
|
+
function He(s, e, t) {
|
|
677
|
+
let o = `<?xml version="1.0" encoding="UTF-8"?>
|
|
684
678
|
<?mso-application progid="Excel.Sheet"?>
|
|
685
679
|
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
|
686
680
|
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
|
|
687
681
|
<Worksheet ss:Name="Sheet1">
|
|
688
682
|
<Table>`;
|
|
689
683
|
if (t.includeHeaders !== !1) {
|
|
690
|
-
|
|
684
|
+
o += `
|
|
691
685
|
<Row>`;
|
|
692
|
-
for (const
|
|
693
|
-
const
|
|
694
|
-
|
|
686
|
+
for (const n of e) {
|
|
687
|
+
const i = n.header || n.field, r = t.processHeader ? t.processHeader(i, n.field) : i;
|
|
688
|
+
o += `<Cell><Data ss:Type="String">${de(r)}</Data></Cell>`;
|
|
695
689
|
}
|
|
696
|
-
|
|
690
|
+
o += "</Row>";
|
|
697
691
|
}
|
|
698
|
-
for (const
|
|
699
|
-
|
|
692
|
+
for (const n of s) {
|
|
693
|
+
o += `
|
|
700
694
|
<Row>`;
|
|
701
|
-
for (const
|
|
702
|
-
let
|
|
703
|
-
t.processCell && (
|
|
695
|
+
for (const i of e) {
|
|
696
|
+
let r = n[i.field];
|
|
697
|
+
t.processCell && (r = t.processCell(r, i.field, n));
|
|
704
698
|
let l = "String", a = "";
|
|
705
|
-
|
|
699
|
+
r == null ? a = "" : typeof r == "number" && !isNaN(r) ? (l = "Number", a = String(r)) : r instanceof Date ? (l = "DateTime", a = r.toISOString()) : a = de(String(r)), o += `<Cell><Data ss:Type="${l}">${a}</Data></Cell>`;
|
|
706
700
|
}
|
|
707
|
-
|
|
701
|
+
o += "</Row>";
|
|
708
702
|
}
|
|
709
|
-
return
|
|
703
|
+
return o += `
|
|
710
704
|
</Table>
|
|
711
705
|
</Worksheet>
|
|
712
|
-
</Workbook>`,
|
|
706
|
+
</Workbook>`, o;
|
|
713
707
|
}
|
|
714
|
-
function
|
|
715
|
-
const t = e.endsWith(".xls") ? e : `${e}.xls`,
|
|
708
|
+
function Ge(s, e) {
|
|
709
|
+
const t = e.endsWith(".xls") ? e : `${e}.xls`, o = new Blob([s], {
|
|
716
710
|
type: "application/vnd.ms-excel;charset=utf-8;"
|
|
717
711
|
});
|
|
718
|
-
|
|
712
|
+
Y(o, t);
|
|
719
713
|
}
|
|
720
|
-
class
|
|
714
|
+
class Xt extends C {
|
|
721
715
|
name = "export";
|
|
722
716
|
version = "1.0.0";
|
|
723
717
|
get defaultConfig() {
|
|
724
718
|
return {
|
|
725
|
-
enabled: !0,
|
|
726
719
|
fileName: "export",
|
|
727
720
|
includeHeaders: !0,
|
|
728
721
|
onlyVisible: !0,
|
|
@@ -734,59 +727,59 @@ class Rt extends y {
|
|
|
734
727
|
lastExportInfo = null;
|
|
735
728
|
// ===== Private Methods =====
|
|
736
729
|
performExport(e, t) {
|
|
737
|
-
const
|
|
730
|
+
const o = this.config, n = {
|
|
738
731
|
format: e,
|
|
739
|
-
fileName: t?.fileName ??
|
|
740
|
-
includeHeaders: t?.includeHeaders ??
|
|
732
|
+
fileName: t?.fileName ?? o.fileName ?? "export",
|
|
733
|
+
includeHeaders: t?.includeHeaders ?? o.includeHeaders,
|
|
741
734
|
processCell: t?.processCell,
|
|
742
735
|
processHeader: t?.processHeader,
|
|
743
736
|
columns: t?.columns,
|
|
744
737
|
rowIndices: t?.rowIndices
|
|
745
738
|
};
|
|
746
|
-
let
|
|
747
|
-
if (
|
|
739
|
+
let i = [...this.columns];
|
|
740
|
+
if (o.onlyVisible && (i = i.filter((a) => !a.hidden && !a.field.startsWith("__"))), t?.columns) {
|
|
748
741
|
const a = new Set(t.columns);
|
|
749
|
-
|
|
742
|
+
i = i.filter((d) => a.has(d.field));
|
|
750
743
|
}
|
|
751
|
-
let
|
|
752
|
-
if (
|
|
744
|
+
let r = [...this.rows];
|
|
745
|
+
if (o.onlySelected) {
|
|
753
746
|
const a = this.getSelectionState();
|
|
754
|
-
a?.selected?.size && (
|
|
747
|
+
a?.selected?.size && (r = [...a.selected].sort((c, u) => c - u).map((c) => this.rows[c]).filter(Boolean));
|
|
755
748
|
}
|
|
756
|
-
t?.rowIndices && (
|
|
757
|
-
let l =
|
|
749
|
+
t?.rowIndices && (r = t.rowIndices.map((a) => this.rows[a]).filter(Boolean)), this.isExportingFlag = !0;
|
|
750
|
+
let l = n.fileName;
|
|
758
751
|
try {
|
|
759
752
|
switch (e) {
|
|
760
753
|
case "csv": {
|
|
761
|
-
const a =
|
|
762
|
-
l = l.endsWith(".csv") ? l : `${l}.csv`,
|
|
754
|
+
const a = De(r, i, n, { bom: !0 });
|
|
755
|
+
l = l.endsWith(".csv") ? l : `${l}.csv`, qe(a, l);
|
|
763
756
|
break;
|
|
764
757
|
}
|
|
765
758
|
case "excel": {
|
|
766
|
-
const a =
|
|
767
|
-
l = l.endsWith(".xls") ? l : `${l}.xls`,
|
|
759
|
+
const a = He(r, i, n);
|
|
760
|
+
l = l.endsWith(".xls") ? l : `${l}.xls`, Ge(a, l);
|
|
768
761
|
break;
|
|
769
762
|
}
|
|
770
763
|
case "json": {
|
|
771
|
-
const a =
|
|
764
|
+
const a = r.map((u) => {
|
|
772
765
|
const h = {};
|
|
773
|
-
for (const
|
|
774
|
-
let g = u[
|
|
775
|
-
|
|
766
|
+
for (const p of i) {
|
|
767
|
+
let g = u[p.field];
|
|
768
|
+
n.processCell && (g = n.processCell(g, p.field, u)), h[p.field] = g;
|
|
776
769
|
}
|
|
777
770
|
return h;
|
|
778
771
|
}), d = JSON.stringify(a, null, 2);
|
|
779
772
|
l = l.endsWith(".json") ? l : `${l}.json`;
|
|
780
773
|
const c = new Blob([d], { type: "application/json" });
|
|
781
|
-
|
|
774
|
+
Y(c, l);
|
|
782
775
|
break;
|
|
783
776
|
}
|
|
784
777
|
}
|
|
785
778
|
this.lastExportInfo = { format: e, timestamp: /* @__PURE__ */ new Date() }, this.emit("export-complete", {
|
|
786
779
|
format: e,
|
|
787
780
|
fileName: l,
|
|
788
|
-
rowCount:
|
|
789
|
-
columnCount:
|
|
781
|
+
rowCount: r.length,
|
|
782
|
+
columnCount: i.length
|
|
790
783
|
});
|
|
791
784
|
} finally {
|
|
792
785
|
this.isExportingFlag = !1;
|
|
@@ -836,69 +829,69 @@ class Rt extends y {
|
|
|
836
829
|
return this.lastExportInfo;
|
|
837
830
|
}
|
|
838
831
|
}
|
|
839
|
-
function
|
|
840
|
-
const { totalRows: e, viewportHeight: t, scrollTop:
|
|
841
|
-
let l = Math.floor(
|
|
832
|
+
function Oe(s) {
|
|
833
|
+
const { totalRows: e, viewportHeight: t, scrollTop: o, rowHeight: n, overscan: i } = s, r = Math.ceil(t / n);
|
|
834
|
+
let l = Math.floor(o / n) - i;
|
|
842
835
|
l < 0 && (l = 0);
|
|
843
|
-
let a = l +
|
|
844
|
-
return a > e && (a = e), a === e && l > 0 && (l = Math.max(0, a -
|
|
836
|
+
let a = l + r + i * 2;
|
|
837
|
+
return a > e && (a = e), a === e && l > 0 && (l = Math.max(0, a - r - i * 2)), {
|
|
845
838
|
start: l,
|
|
846
839
|
end: a,
|
|
847
|
-
offsetY: l *
|
|
848
|
-
totalHeight: e *
|
|
840
|
+
offsetY: l * n,
|
|
841
|
+
totalHeight: e * n
|
|
849
842
|
};
|
|
850
843
|
}
|
|
851
|
-
function
|
|
852
|
-
return
|
|
844
|
+
function Be(s, e) {
|
|
845
|
+
return s <= e;
|
|
853
846
|
}
|
|
854
|
-
function
|
|
855
|
-
const
|
|
847
|
+
function Ve(s, e, t = !1) {
|
|
848
|
+
const o = s[e.field];
|
|
856
849
|
if (e.operator === "blank")
|
|
857
|
-
return
|
|
850
|
+
return o == null || o === "";
|
|
858
851
|
if (e.operator === "notBlank")
|
|
859
|
-
return
|
|
860
|
-
if (
|
|
861
|
-
const
|
|
852
|
+
return o != null && o !== "";
|
|
853
|
+
if (o == null) return !1;
|
|
854
|
+
const n = String(o), i = t ? n : n.toLowerCase(), r = t ? String(e.value) : String(e.value).toLowerCase();
|
|
862
855
|
switch (e.operator) {
|
|
863
856
|
// Text operators
|
|
864
857
|
case "contains":
|
|
865
|
-
return
|
|
858
|
+
return i.includes(r);
|
|
866
859
|
case "notContains":
|
|
867
|
-
return !
|
|
860
|
+
return !i.includes(r);
|
|
868
861
|
case "equals":
|
|
869
|
-
return
|
|
862
|
+
return i === r;
|
|
870
863
|
case "notEquals":
|
|
871
|
-
return
|
|
864
|
+
return i !== r;
|
|
872
865
|
case "startsWith":
|
|
873
|
-
return
|
|
866
|
+
return i.startsWith(r);
|
|
874
867
|
case "endsWith":
|
|
875
|
-
return
|
|
868
|
+
return i.endsWith(r);
|
|
876
869
|
// Number/Date operators (use raw numeric values)
|
|
877
870
|
case "lessThan":
|
|
878
|
-
return Number(
|
|
871
|
+
return Number(o) < Number(e.value);
|
|
879
872
|
case "lessThanOrEqual":
|
|
880
|
-
return Number(
|
|
873
|
+
return Number(o) <= Number(e.value);
|
|
881
874
|
case "greaterThan":
|
|
882
|
-
return Number(
|
|
875
|
+
return Number(o) > Number(e.value);
|
|
883
876
|
case "greaterThanOrEqual":
|
|
884
|
-
return Number(
|
|
877
|
+
return Number(o) >= Number(e.value);
|
|
885
878
|
case "between":
|
|
886
|
-
return Number(
|
|
879
|
+
return Number(o) >= Number(e.value) && Number(o) <= Number(e.valueTo);
|
|
887
880
|
// Set operators
|
|
888
881
|
case "in":
|
|
889
|
-
return Array.isArray(e.value) && e.value.includes(
|
|
882
|
+
return Array.isArray(e.value) && e.value.includes(o);
|
|
890
883
|
case "notIn":
|
|
891
|
-
return Array.isArray(e.value) && !e.value.includes(
|
|
884
|
+
return Array.isArray(e.value) && !e.value.includes(o);
|
|
892
885
|
default:
|
|
893
886
|
return !0;
|
|
894
887
|
}
|
|
895
888
|
}
|
|
896
|
-
function
|
|
897
|
-
return e.length ?
|
|
889
|
+
function Ke(s, e, t = !1) {
|
|
890
|
+
return e.length ? s.filter((o) => e.every((n) => Ve(o, n, t))) : s;
|
|
898
891
|
}
|
|
899
|
-
function
|
|
892
|
+
function ze(s) {
|
|
900
893
|
return JSON.stringify(
|
|
901
|
-
|
|
894
|
+
s.map((e) => ({
|
|
902
895
|
field: e.field,
|
|
903
896
|
operator: e.operator,
|
|
904
897
|
value: e.value,
|
|
@@ -906,15 +899,15 @@ function Ne(i) {
|
|
|
906
899
|
}))
|
|
907
900
|
);
|
|
908
901
|
}
|
|
909
|
-
function
|
|
902
|
+
function ce(s, e) {
|
|
910
903
|
const t = /* @__PURE__ */ new Set();
|
|
911
|
-
for (const
|
|
912
|
-
const
|
|
913
|
-
|
|
904
|
+
for (const o of s) {
|
|
905
|
+
const n = o[e];
|
|
906
|
+
n != null && t.add(n);
|
|
914
907
|
}
|
|
915
|
-
return [...t].sort((
|
|
908
|
+
return [...t].sort((o, n) => typeof o == "number" && typeof n == "number" ? o - n : String(o).localeCompare(String(n)));
|
|
916
909
|
}
|
|
917
|
-
const
|
|
910
|
+
const We = '.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))}', $e = `
|
|
918
911
|
.tbw-filter-panel {
|
|
919
912
|
position: fixed;
|
|
920
913
|
background: var(--tbw-filter-panel-bg, var(--tbw-color-panel-bg, light-dark(#eeeeee, #222222)));
|
|
@@ -1056,12 +1049,11 @@ const De = `
|
|
|
1056
1049
|
background: var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)));
|
|
1057
1050
|
}
|
|
1058
1051
|
`;
|
|
1059
|
-
class
|
|
1052
|
+
class k extends C {
|
|
1060
1053
|
name = "filtering";
|
|
1061
1054
|
version = "1.0.0";
|
|
1062
1055
|
get defaultConfig() {
|
|
1063
1056
|
return {
|
|
1064
|
-
enabled: !0,
|
|
1065
1057
|
debounceMs: 300,
|
|
1066
1058
|
caseSensitive: !1,
|
|
1067
1059
|
trimInput: !0,
|
|
@@ -1095,27 +1087,26 @@ class E extends y {
|
|
|
1095
1087
|
processRows(e) {
|
|
1096
1088
|
const t = [...this.filters.values()];
|
|
1097
1089
|
if (!t.length) return [...e];
|
|
1098
|
-
const
|
|
1099
|
-
if (this.cacheKey ===
|
|
1090
|
+
const o = ze(t);
|
|
1091
|
+
if (this.cacheKey === o && this.cachedResult)
|
|
1100
1092
|
return this.cachedResult;
|
|
1101
|
-
const
|
|
1102
|
-
return this.cachedResult =
|
|
1093
|
+
const n = Ke([...e], t, this.config.caseSensitive);
|
|
1094
|
+
return this.cachedResult = n, this.cacheKey = o, n;
|
|
1103
1095
|
}
|
|
1104
1096
|
afterRender() {
|
|
1105
|
-
if (!this.config.enabled) return;
|
|
1106
1097
|
const e = this.shadowRoot;
|
|
1107
1098
|
if (!e) return;
|
|
1108
|
-
e.querySelectorAll('[part~="header-cell"]').forEach((
|
|
1109
|
-
const
|
|
1110
|
-
if (
|
|
1111
|
-
const
|
|
1112
|
-
if (!
|
|
1113
|
-
const
|
|
1114
|
-
if (!
|
|
1099
|
+
e.querySelectorAll('[part~="header-cell"]').forEach((o) => {
|
|
1100
|
+
const n = o.getAttribute("data-col");
|
|
1101
|
+
if (n === null) return;
|
|
1102
|
+
const i = this.columns[parseInt(n, 10)];
|
|
1103
|
+
if (!i || i.filterable === !1 || o.querySelector(".tbw-filter-btn")) return;
|
|
1104
|
+
const r = i.field;
|
|
1105
|
+
if (!r) return;
|
|
1115
1106
|
const l = document.createElement("button");
|
|
1116
|
-
l.className = "tbw-filter-btn", l.setAttribute("aria-label", `Filter ${
|
|
1117
|
-
a.stopPropagation(), this.toggleFilterPanel(
|
|
1118
|
-
}),
|
|
1107
|
+
l.className = "tbw-filter-btn", l.setAttribute("aria-label", `Filter ${i.header ?? r}`), l.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>', this.filters.has(r) && (l.classList.add("active"), o.classList.add("filtered")), l.addEventListener("click", (a) => {
|
|
1108
|
+
a.stopPropagation(), this.toggleFilterPanel(r, i, l);
|
|
1109
|
+
}), o.appendChild(l);
|
|
1119
1110
|
});
|
|
1120
1111
|
}
|
|
1121
1112
|
// ===== Public API =====
|
|
@@ -1201,7 +1192,7 @@ class E extends y {
|
|
|
1201
1192
|
* Uses sourceRows to include all values regardless of current filter.
|
|
1202
1193
|
*/
|
|
1203
1194
|
getUniqueValues(e) {
|
|
1204
|
-
return
|
|
1195
|
+
return ce(this.sourceRows, e);
|
|
1205
1196
|
}
|
|
1206
1197
|
// ===== Private Methods =====
|
|
1207
1198
|
/**
|
|
@@ -1214,27 +1205,27 @@ class E extends y {
|
|
|
1214
1205
|
return;
|
|
1215
1206
|
}
|
|
1216
1207
|
const e = document.createElement("style");
|
|
1217
|
-
e.id = "tbw-filter-panel-styles", e.textContent =
|
|
1208
|
+
e.id = "tbw-filter-panel-styles", e.textContent = $e, document.head.appendChild(e), this.globalStylesInjected = !0;
|
|
1218
1209
|
}
|
|
1219
1210
|
/**
|
|
1220
1211
|
* Toggle the filter panel for a field
|
|
1221
1212
|
*/
|
|
1222
|
-
toggleFilterPanel(e, t,
|
|
1213
|
+
toggleFilterPanel(e, t, o) {
|
|
1223
1214
|
if (this.openPanelField === e) {
|
|
1224
1215
|
this.closeFilterPanel();
|
|
1225
1216
|
return;
|
|
1226
1217
|
}
|
|
1227
1218
|
this.closeFilterPanel();
|
|
1228
|
-
const
|
|
1229
|
-
|
|
1230
|
-
const
|
|
1231
|
-
let
|
|
1232
|
-
|
|
1219
|
+
const n = document.createElement("div");
|
|
1220
|
+
n.className = "tbw-filter-panel", this.panelElement = n, this.openPanelField = e;
|
|
1221
|
+
const i = ce(this.sourceRows, e);
|
|
1222
|
+
let r = this.excludedValues.get(e);
|
|
1223
|
+
r || (r = /* @__PURE__ */ new Set(), this.excludedValues.set(e, r));
|
|
1233
1224
|
const l = this.searchText.get(e) ?? "", a = {
|
|
1234
1225
|
field: e,
|
|
1235
1226
|
column: t,
|
|
1236
|
-
uniqueValues:
|
|
1237
|
-
excludedValues:
|
|
1227
|
+
uniqueValues: i,
|
|
1228
|
+
excludedValues: r,
|
|
1238
1229
|
searchText: l,
|
|
1239
1230
|
applySetFilter: (c) => {
|
|
1240
1231
|
this.applySetFilter(e, c), this.closeFilterPanel();
|
|
@@ -1248,11 +1239,11 @@ class E extends y {
|
|
|
1248
1239
|
closePanel: () => this.closeFilterPanel()
|
|
1249
1240
|
};
|
|
1250
1241
|
let d = !1;
|
|
1251
|
-
this.config.filterPanelRenderer && (this.config.filterPanelRenderer(
|
|
1242
|
+
this.config.filterPanelRenderer && (this.config.filterPanelRenderer(n, a), d = n.children.length > 0), d || this.renderDefaultFilterPanel(n, a, i, r), document.body.appendChild(n), this.positionPanel(n, o), this.panelAbortController = new AbortController(), setTimeout(() => {
|
|
1252
1243
|
document.addEventListener(
|
|
1253
1244
|
"click",
|
|
1254
1245
|
(c) => {
|
|
1255
|
-
!
|
|
1246
|
+
!n.contains(c.target) && c.target !== o && this.closeFilterPanel();
|
|
1256
1247
|
},
|
|
1257
1248
|
{ signal: this.panelAbortController?.signal }
|
|
1258
1249
|
);
|
|
@@ -1268,20 +1259,20 @@ class E extends y {
|
|
|
1268
1259
|
* Position the panel below the button
|
|
1269
1260
|
*/
|
|
1270
1261
|
positionPanel(e, t) {
|
|
1271
|
-
const
|
|
1272
|
-
e.style.position = "fixed", e.style.top = `${
|
|
1273
|
-
const
|
|
1274
|
-
|
|
1262
|
+
const o = t.getBoundingClientRect();
|
|
1263
|
+
e.style.position = "fixed", e.style.top = `${o.bottom + 4}px`, e.style.left = `${o.left}px`, requestAnimationFrame(() => {
|
|
1264
|
+
const n = e.getBoundingClientRect();
|
|
1265
|
+
n.right > window.innerWidth - 8 && (e.style.left = `${window.innerWidth - n.width - 8}px`), n.bottom > window.innerHeight - 8 && (e.style.top = `${o.top - n.height - 4}px`);
|
|
1275
1266
|
});
|
|
1276
1267
|
}
|
|
1277
1268
|
/**
|
|
1278
1269
|
* Render the default filter panel content
|
|
1279
1270
|
*/
|
|
1280
|
-
renderDefaultFilterPanel(e, t,
|
|
1281
|
-
const { field:
|
|
1282
|
-
|
|
1271
|
+
renderDefaultFilterPanel(e, t, o, n) {
|
|
1272
|
+
const { field: i } = t, r = document.createElement("div");
|
|
1273
|
+
r.className = "tbw-filter-search";
|
|
1283
1274
|
const l = document.createElement("input");
|
|
1284
|
-
l.type = "text", l.placeholder = "Search...", l.className = "tbw-filter-search-input", l.value = this.searchText.get(
|
|
1275
|
+
l.type = "text", l.placeholder = "Search...", l.className = "tbw-filter-search-input", l.value = this.searchText.get(i) ?? "", r.appendChild(l), e.appendChild(r);
|
|
1285
1276
|
const a = document.createElement("div");
|
|
1286
1277
|
a.className = "tbw-filter-actions";
|
|
1287
1278
|
const d = document.createElement("label");
|
|
@@ -1291,99 +1282,99 @@ class E extends y {
|
|
|
1291
1282
|
const u = document.createElement("span");
|
|
1292
1283
|
u.textContent = "Select All", d.appendChild(c), d.appendChild(u), a.appendChild(d);
|
|
1293
1284
|
const h = () => {
|
|
1294
|
-
const
|
|
1295
|
-
c.checked =
|
|
1285
|
+
const f = [...b.values()], x = f.every((v) => v), y = f.every((v) => !v);
|
|
1286
|
+
c.checked = x, c.indeterminate = !x && !y;
|
|
1296
1287
|
};
|
|
1297
1288
|
c.addEventListener("change", () => {
|
|
1298
|
-
const
|
|
1299
|
-
for (const
|
|
1300
|
-
b.set(
|
|
1301
|
-
h(),
|
|
1289
|
+
const f = c.checked;
|
|
1290
|
+
for (const x of b.keys())
|
|
1291
|
+
b.set(x, f);
|
|
1292
|
+
h(), P();
|
|
1302
1293
|
}), e.appendChild(a);
|
|
1303
|
-
const
|
|
1304
|
-
|
|
1294
|
+
const p = document.createElement("div");
|
|
1295
|
+
p.className = "tbw-filter-values";
|
|
1305
1296
|
const g = document.createElement("div");
|
|
1306
|
-
g.className = "tbw-filter-values-spacer",
|
|
1297
|
+
g.className = "tbw-filter-values-spacer", p.appendChild(g);
|
|
1307
1298
|
const m = document.createElement("div");
|
|
1308
|
-
m.className = "tbw-filter-values-content",
|
|
1299
|
+
m.className = "tbw-filter-values-content", p.appendChild(m);
|
|
1309
1300
|
const b = /* @__PURE__ */ new Map();
|
|
1310
|
-
|
|
1311
|
-
const
|
|
1312
|
-
b.set(
|
|
1301
|
+
o.forEach((f) => {
|
|
1302
|
+
const x = f == null ? "__null__" : String(f);
|
|
1303
|
+
b.set(x, !n.has(f));
|
|
1313
1304
|
}), h();
|
|
1314
|
-
let
|
|
1315
|
-
const
|
|
1316
|
-
const
|
|
1317
|
-
w.className = "tbw-filter-value-item", w.style.position = "absolute", w.style.top = `${
|
|
1318
|
-
const
|
|
1319
|
-
|
|
1320
|
-
b.set(
|
|
1305
|
+
let R = [];
|
|
1306
|
+
const E = (f, x) => {
|
|
1307
|
+
const y = f == null ? "(Blank)" : String(f), v = f == null ? "__null__" : String(f), w = document.createElement("label");
|
|
1308
|
+
w.className = "tbw-filter-value-item", w.style.position = "absolute", w.style.top = `${x * k.LIST_ITEM_HEIGHT}px`, w.style.left = "0", w.style.right = "0", w.style.height = `${k.LIST_ITEM_HEIGHT}px`, w.style.boxSizing = "border-box";
|
|
1309
|
+
const S = document.createElement("input");
|
|
1310
|
+
S.type = "checkbox", S.className = "tbw-filter-checkbox", S.checked = b.get(v) ?? !0, S.dataset.value = v, S.addEventListener("change", () => {
|
|
1311
|
+
b.set(v, S.checked), h();
|
|
1321
1312
|
});
|
|
1322
|
-
const
|
|
1323
|
-
return
|
|
1324
|
-
},
|
|
1325
|
-
const
|
|
1326
|
-
if (g.style.height = `${
|
|
1327
|
-
m.innerHTML = "", m.style.transform = "translateY(0px)",
|
|
1328
|
-
m.appendChild(
|
|
1313
|
+
const Q = document.createElement("span");
|
|
1314
|
+
return Q.textContent = y, w.appendChild(S), w.appendChild(Q), w;
|
|
1315
|
+
}, P = () => {
|
|
1316
|
+
const f = R.length, x = p.clientHeight, y = p.scrollTop;
|
|
1317
|
+
if (g.style.height = `${f * k.LIST_ITEM_HEIGHT}px`, Be(f, k.LIST_BYPASS_THRESHOLD / 3)) {
|
|
1318
|
+
m.innerHTML = "", m.style.transform = "translateY(0px)", R.forEach((w, S) => {
|
|
1319
|
+
m.appendChild(E(w, S));
|
|
1329
1320
|
});
|
|
1330
1321
|
return;
|
|
1331
1322
|
}
|
|
1332
|
-
const
|
|
1333
|
-
totalRows:
|
|
1334
|
-
viewportHeight:
|
|
1335
|
-
scrollTop:
|
|
1336
|
-
rowHeight:
|
|
1337
|
-
overscan:
|
|
1323
|
+
const v = Oe({
|
|
1324
|
+
totalRows: f,
|
|
1325
|
+
viewportHeight: x,
|
|
1326
|
+
scrollTop: y,
|
|
1327
|
+
rowHeight: k.LIST_ITEM_HEIGHT,
|
|
1328
|
+
overscan: k.LIST_OVERSCAN
|
|
1338
1329
|
});
|
|
1339
|
-
m.style.transform = `translateY(${
|
|
1340
|
-
for (let w =
|
|
1341
|
-
m.appendChild(R
|
|
1342
|
-
},
|
|
1343
|
-
const
|
|
1344
|
-
if (
|
|
1345
|
-
const
|
|
1346
|
-
return !
|
|
1347
|
-
}),
|
|
1330
|
+
m.style.transform = `translateY(${v.offsetY}px)`, m.innerHTML = "";
|
|
1331
|
+
for (let w = v.start; w < v.end; w++)
|
|
1332
|
+
m.appendChild(E(R[w], w - v.start));
|
|
1333
|
+
}, X = (f) => {
|
|
1334
|
+
const x = f.toLowerCase();
|
|
1335
|
+
if (R = o.filter((y) => {
|
|
1336
|
+
const v = y == null ? "(Blank)" : String(y);
|
|
1337
|
+
return !f || v.toLowerCase().includes(x);
|
|
1338
|
+
}), R.length === 0) {
|
|
1348
1339
|
g.style.height = "0px", m.innerHTML = "";
|
|
1349
|
-
const
|
|
1350
|
-
|
|
1340
|
+
const y = document.createElement("div");
|
|
1341
|
+
y.className = "tbw-filter-no-match", y.textContent = "No matching values", m.appendChild(y);
|
|
1351
1342
|
return;
|
|
1352
1343
|
}
|
|
1353
|
-
|
|
1344
|
+
P();
|
|
1354
1345
|
};
|
|
1355
|
-
|
|
1346
|
+
p.addEventListener(
|
|
1356
1347
|
"scroll",
|
|
1357
1348
|
() => {
|
|
1358
|
-
|
|
1349
|
+
R.length > 0 && P();
|
|
1359
1350
|
},
|
|
1360
1351
|
{ passive: !0 }
|
|
1361
|
-
),
|
|
1362
|
-
let
|
|
1352
|
+
), X(l.value), e.appendChild(p);
|
|
1353
|
+
let J;
|
|
1363
1354
|
l.addEventListener("input", () => {
|
|
1364
|
-
clearTimeout(
|
|
1365
|
-
this.searchText.set(
|
|
1355
|
+
clearTimeout(J), J = setTimeout(() => {
|
|
1356
|
+
this.searchText.set(i, l.value), X(l.value);
|
|
1366
1357
|
}, this.config.debounceMs ?? 150);
|
|
1367
1358
|
});
|
|
1368
|
-
const
|
|
1369
|
-
|
|
1370
|
-
const
|
|
1371
|
-
|
|
1372
|
-
const
|
|
1373
|
-
for (const [
|
|
1374
|
-
if (!
|
|
1375
|
-
if (
|
|
1376
|
-
|
|
1359
|
+
const F = document.createElement("div");
|
|
1360
|
+
F.className = "tbw-filter-buttons";
|
|
1361
|
+
const L = document.createElement("button");
|
|
1362
|
+
L.className = "tbw-filter-apply-btn", L.textContent = "Apply", L.addEventListener("click", () => {
|
|
1363
|
+
const f = [];
|
|
1364
|
+
for (const [x, y] of b)
|
|
1365
|
+
if (!y)
|
|
1366
|
+
if (x === "__null__")
|
|
1367
|
+
f.push(null);
|
|
1377
1368
|
else {
|
|
1378
|
-
const
|
|
1379
|
-
|
|
1369
|
+
const v = o.find((w) => String(w) === x);
|
|
1370
|
+
f.push(v !== void 0 ? v : x);
|
|
1380
1371
|
}
|
|
1381
|
-
t.applySetFilter(
|
|
1382
|
-
}),
|
|
1383
|
-
const
|
|
1384
|
-
|
|
1372
|
+
t.applySetFilter(f);
|
|
1373
|
+
}), F.appendChild(L);
|
|
1374
|
+
const N = document.createElement("button");
|
|
1375
|
+
N.className = "tbw-filter-clear-btn", N.textContent = "Clear Filter", N.addEventListener("click", () => {
|
|
1385
1376
|
t.clearFilter();
|
|
1386
|
-
}),
|
|
1377
|
+
}), F.appendChild(N), e.appendChild(F);
|
|
1387
1378
|
}
|
|
1388
1379
|
/**
|
|
1389
1380
|
* Apply a set filter (exclude values)
|
|
@@ -1402,13 +1393,13 @@ class E extends y {
|
|
|
1402
1393
|
/**
|
|
1403
1394
|
* Apply a text filter
|
|
1404
1395
|
*/
|
|
1405
|
-
applyTextFilter(e, t,
|
|
1396
|
+
applyTextFilter(e, t, o, n) {
|
|
1406
1397
|
this.filters.set(e, {
|
|
1407
1398
|
field: e,
|
|
1408
1399
|
type: "text",
|
|
1409
1400
|
operator: t,
|
|
1410
|
-
value:
|
|
1411
|
-
valueTo:
|
|
1401
|
+
value: o,
|
|
1402
|
+
valueTo: n
|
|
1412
1403
|
}), this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
|
|
1413
1404
|
filters: [...this.filters.values()],
|
|
1414
1405
|
filteredRowCount: 0
|
|
@@ -1438,75 +1429,43 @@ class E extends y {
|
|
|
1438
1429
|
this.filters.delete(e);
|
|
1439
1430
|
return;
|
|
1440
1431
|
}
|
|
1441
|
-
const
|
|
1432
|
+
const o = {
|
|
1442
1433
|
field: e,
|
|
1443
1434
|
type: t.filter.type,
|
|
1444
1435
|
operator: t.filter.operator,
|
|
1445
1436
|
value: t.filter.value,
|
|
1446
1437
|
valueTo: t.filter.valueTo
|
|
1447
1438
|
};
|
|
1448
|
-
this.filters.set(e,
|
|
1439
|
+
this.filters.set(e, o), this.cachedResult = null, this.cacheKey = null;
|
|
1449
1440
|
}
|
|
1450
1441
|
// ===== Styles =====
|
|
1451
|
-
styles =
|
|
1452
|
-
.header-cell.filtered::before {
|
|
1453
|
-
content: '';
|
|
1454
|
-
position: absolute;
|
|
1455
|
-
top: 4px;
|
|
1456
|
-
right: 4px;
|
|
1457
|
-
width: 6px;
|
|
1458
|
-
height: 6px;
|
|
1459
|
-
background: var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));
|
|
1460
|
-
border-radius: 50%;
|
|
1461
|
-
}
|
|
1462
|
-
.tbw-filter-btn {
|
|
1463
|
-
display: inline-flex;
|
|
1464
|
-
align-items: center;
|
|
1465
|
-
justify-content: center;
|
|
1466
|
-
background: transparent;
|
|
1467
|
-
border: none;
|
|
1468
|
-
cursor: pointer;
|
|
1469
|
-
padding: 2px;
|
|
1470
|
-
margin-left: 4px;
|
|
1471
|
-
opacity: 0.4;
|
|
1472
|
-
transition: opacity 0.15s;
|
|
1473
|
-
color: inherit;
|
|
1474
|
-
vertical-align: middle;
|
|
1475
|
-
}
|
|
1476
|
-
.tbw-filter-btn:hover,
|
|
1477
|
-
.tbw-filter-btn.active {
|
|
1478
|
-
opacity: 1;
|
|
1479
|
-
}
|
|
1480
|
-
.tbw-filter-btn.active {
|
|
1481
|
-
color: var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));
|
|
1482
|
-
}
|
|
1483
|
-
`;
|
|
1442
|
+
styles = We;
|
|
1484
1443
|
}
|
|
1485
|
-
function
|
|
1486
|
-
if (!
|
|
1487
|
-
const e = /* @__PURE__ */ new Map(), t = [],
|
|
1444
|
+
function je(s) {
|
|
1445
|
+
if (!s.length) return [];
|
|
1446
|
+
const e = /* @__PURE__ */ new Map(), t = [], o = (r, l) => {
|
|
1488
1447
|
if (!l.length) return;
|
|
1489
1448
|
const a = t[t.length - 1];
|
|
1490
|
-
if (a && a.implicit && a.firstIndex + a.columns.length ===
|
|
1449
|
+
if (a && a.implicit && a.firstIndex + a.columns.length === r) {
|
|
1491
1450
|
a.columns.push(...l);
|
|
1492
1451
|
return;
|
|
1493
1452
|
}
|
|
1494
1453
|
t.push({
|
|
1495
|
-
id: "__implicit__" +
|
|
1454
|
+
id: "__implicit__" + r,
|
|
1496
1455
|
label: void 0,
|
|
1497
1456
|
columns: l,
|
|
1498
|
-
firstIndex:
|
|
1457
|
+
firstIndex: r,
|
|
1499
1458
|
implicit: !0
|
|
1500
1459
|
});
|
|
1501
1460
|
};
|
|
1502
|
-
let
|
|
1503
|
-
return
|
|
1504
|
-
const a =
|
|
1461
|
+
let n = [], i = 0;
|
|
1462
|
+
return s.forEach((r, l) => {
|
|
1463
|
+
const a = r.group;
|
|
1505
1464
|
if (!a) {
|
|
1506
|
-
|
|
1465
|
+
n.length === 0 && (i = l), n.push(r);
|
|
1507
1466
|
return;
|
|
1508
1467
|
}
|
|
1509
|
-
|
|
1468
|
+
n.length && (o(i, n.slice()), n = []);
|
|
1510
1469
|
const d = typeof a == "string" ? a : a.id;
|
|
1511
1470
|
let c = e.get(d);
|
|
1512
1471
|
c || (c = {
|
|
@@ -1514,44 +1473,44 @@ function Pe(i) {
|
|
|
1514
1473
|
label: typeof a == "string" ? void 0 : a.label,
|
|
1515
1474
|
columns: [],
|
|
1516
1475
|
firstIndex: l
|
|
1517
|
-
}, e.set(d, c), t.push(c)), c.columns.push(
|
|
1518
|
-
}),
|
|
1476
|
+
}, e.set(d, c), t.push(c)), c.columns.push(r);
|
|
1477
|
+
}), n.length && o(i, n), t.length === 1 && t[0].implicit && t[0].columns.length === s.length ? [] : t;
|
|
1519
1478
|
}
|
|
1520
|
-
function
|
|
1521
|
-
if (!e.length || !
|
|
1522
|
-
const
|
|
1523
|
-
for (const
|
|
1524
|
-
for (const
|
|
1525
|
-
|
|
1526
|
-
const
|
|
1527
|
-
|
|
1528
|
-
const
|
|
1529
|
-
l && (
|
|
1479
|
+
function Ue(s, e, t) {
|
|
1480
|
+
if (!e.length || !s) return;
|
|
1481
|
+
const o = /* @__PURE__ */ new Map();
|
|
1482
|
+
for (const i of e)
|
|
1483
|
+
for (const r of i.columns)
|
|
1484
|
+
r?.field && o.set(r.field, i.id);
|
|
1485
|
+
const n = Array.from(s.querySelectorAll(".cell[data-field]"));
|
|
1486
|
+
n.forEach((i) => {
|
|
1487
|
+
const r = i.getAttribute("data-field") || "", l = o.get(r);
|
|
1488
|
+
l && (i.classList.add("grouped"), i.getAttribute("data-group") || i.setAttribute("data-group", l));
|
|
1530
1489
|
});
|
|
1531
|
-
for (const
|
|
1532
|
-
const
|
|
1490
|
+
for (const i of e) {
|
|
1491
|
+
const r = i.columns[i.columns.length - 1], l = n.find((a) => a.getAttribute("data-field") === r.field);
|
|
1533
1492
|
l && l.classList.add("group-end");
|
|
1534
1493
|
}
|
|
1535
1494
|
}
|
|
1536
|
-
function
|
|
1537
|
-
if (
|
|
1495
|
+
function Ye(s, e) {
|
|
1496
|
+
if (s.length === 0) return null;
|
|
1538
1497
|
const t = document.createElement("div");
|
|
1539
1498
|
t.className = "header-group-row", t.setAttribute("role", "row");
|
|
1540
|
-
for (const
|
|
1541
|
-
const
|
|
1542
|
-
l.className = "cell header-group-cell",
|
|
1499
|
+
for (const o of s) {
|
|
1500
|
+
const n = o.firstIndex != null ? o.firstIndex : e.findIndex((a) => o.columns.includes(a)), i = String(o.id).startsWith("__implicit__"), r = i ? "" : o.label || o.id, l = document.createElement("div");
|
|
1501
|
+
l.className = "cell header-group-cell", i && l.classList.add("implicit-group"), l.setAttribute("data-group", String(o.id)), l.style.gridColumn = `${n + 1} / span ${o.columns.length}`, l.textContent = r, t.appendChild(l);
|
|
1543
1502
|
}
|
|
1544
1503
|
return t;
|
|
1545
1504
|
}
|
|
1546
|
-
function
|
|
1547
|
-
return
|
|
1505
|
+
function Ze(s) {
|
|
1506
|
+
return s.some((e) => e.group != null);
|
|
1548
1507
|
}
|
|
1549
|
-
|
|
1508
|
+
const Xe = ".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))}";
|
|
1509
|
+
class Jt extends C {
|
|
1550
1510
|
name = "groupingColumns";
|
|
1551
1511
|
version = "1.0.0";
|
|
1552
1512
|
get defaultConfig() {
|
|
1553
1513
|
return {
|
|
1554
|
-
enabled: !0,
|
|
1555
1514
|
showGroupBorders: !0
|
|
1556
1515
|
};
|
|
1557
1516
|
}
|
|
@@ -1567,33 +1526,31 @@ class kt extends y {
|
|
|
1567
1526
|
* Auto-detect column groups from column configuration.
|
|
1568
1527
|
*/
|
|
1569
1528
|
static detect(e, t) {
|
|
1570
|
-
const
|
|
1571
|
-
return Array.isArray(
|
|
1529
|
+
const o = t?.columns;
|
|
1530
|
+
return Array.isArray(o) ? Ze(o) : !1;
|
|
1572
1531
|
}
|
|
1573
1532
|
// ===== Hooks =====
|
|
1574
1533
|
processColumns(e) {
|
|
1575
|
-
|
|
1576
|
-
return this.isActive = !1, this.groups = [], [...e];
|
|
1577
|
-
const t = Pe(e);
|
|
1534
|
+
const t = je(e);
|
|
1578
1535
|
return t.length === 0 ? (this.isActive = !1, this.groups = [], [...e]) : (this.isActive = !0, this.groups = t, [...e]);
|
|
1579
1536
|
}
|
|
1580
1537
|
afterRender() {
|
|
1581
1538
|
if (!this.isActive || this.groups.length === 0) {
|
|
1582
|
-
const
|
|
1583
|
-
|
|
1539
|
+
const r = this.shadowRoot?.querySelector(".header")?.querySelector(".header-group-row");
|
|
1540
|
+
r && r.remove();
|
|
1584
1541
|
return;
|
|
1585
1542
|
}
|
|
1586
1543
|
const e = this.shadowRoot?.querySelector(".header");
|
|
1587
1544
|
if (!e) return;
|
|
1588
1545
|
const t = e.querySelector(".header-group-row");
|
|
1589
1546
|
t && t.remove();
|
|
1590
|
-
const
|
|
1591
|
-
if (
|
|
1592
|
-
const
|
|
1593
|
-
|
|
1547
|
+
const o = Ye(this.groups, this.columns);
|
|
1548
|
+
if (o) {
|
|
1549
|
+
const i = e.querySelector(".header-row");
|
|
1550
|
+
i ? e.insertBefore(o, i) : e.appendChild(o);
|
|
1594
1551
|
}
|
|
1595
|
-
const
|
|
1596
|
-
|
|
1552
|
+
const n = e.querySelector(".header-row");
|
|
1553
|
+
n && Ue(n, this.groups, this.columns);
|
|
1597
1554
|
}
|
|
1598
1555
|
// ===== Public API =====
|
|
1599
1556
|
/**
|
|
@@ -1616,7 +1573,7 @@ class kt extends y {
|
|
|
1616
1573
|
* @returns Array of columns in the group
|
|
1617
1574
|
*/
|
|
1618
1575
|
getGroupColumns(e) {
|
|
1619
|
-
const t = this.groups.find((
|
|
1576
|
+
const t = this.groups.find((o) => o.id === e);
|
|
1620
1577
|
return t ? t.columns : [];
|
|
1621
1578
|
}
|
|
1622
1579
|
/**
|
|
@@ -1626,90 +1583,63 @@ class kt extends y {
|
|
|
1626
1583
|
this.requestRender();
|
|
1627
1584
|
}
|
|
1628
1585
|
// ===== Styles =====
|
|
1629
|
-
styles =
|
|
1630
|
-
.header-group-row {
|
|
1631
|
-
display: grid;
|
|
1632
|
-
grid-auto-flow: column;
|
|
1633
|
-
background: var(--tbw-grouping-columns-header-bg, var(--tbw-color-header-bg));
|
|
1634
|
-
border-bottom: 1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border));
|
|
1635
|
-
}
|
|
1636
|
-
.header-group-cell {
|
|
1637
|
-
display: flex;
|
|
1638
|
-
align-items: center;
|
|
1639
|
-
justify-content: center;
|
|
1640
|
-
padding: 4px 8px;
|
|
1641
|
-
font-weight: 600;
|
|
1642
|
-
font-size: 0.9em;
|
|
1643
|
-
text-transform: uppercase;
|
|
1644
|
-
letter-spacing: 0.5px;
|
|
1645
|
-
border-right: 1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border));
|
|
1646
|
-
}
|
|
1647
|
-
.header-group-cell:last-child {
|
|
1648
|
-
border-right: none;
|
|
1649
|
-
}
|
|
1650
|
-
.header-row .cell.grouped {
|
|
1651
|
-
border-top: none;
|
|
1652
|
-
}
|
|
1653
|
-
.header-row .cell.group-end {
|
|
1654
|
-
border-right: 2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong));
|
|
1655
|
-
}
|
|
1656
|
-
`;
|
|
1586
|
+
styles = Xe;
|
|
1657
1587
|
}
|
|
1658
|
-
function
|
|
1659
|
-
const
|
|
1660
|
-
if (
|
|
1588
|
+
function Je({ rows: s, config: e, expanded: t }) {
|
|
1589
|
+
const o = e.groupOn;
|
|
1590
|
+
if (typeof o != "function")
|
|
1661
1591
|
return [];
|
|
1662
|
-
const
|
|
1663
|
-
if (
|
|
1664
|
-
let a =
|
|
1592
|
+
const n = { key: "__root__", value: null, depth: -1, rows: [], children: /* @__PURE__ */ new Map() };
|
|
1593
|
+
if (s.forEach((l) => {
|
|
1594
|
+
let a = o(l);
|
|
1665
1595
|
a == null || a === !1 ? a = ["__ungrouped__"] : Array.isArray(a) || (a = [a]);
|
|
1666
|
-
let d =
|
|
1596
|
+
let d = n;
|
|
1667
1597
|
a.forEach((c, u) => {
|
|
1668
|
-
const h = c == null ? "∅" : String(c),
|
|
1598
|
+
const h = c == null ? "∅" : String(c), p = d.key === "__root__" ? h : d.key + "||" + h;
|
|
1669
1599
|
let g = d.children.get(h);
|
|
1670
|
-
g || (g = { key:
|
|
1600
|
+
g || (g = { key: p, value: c, depth: u, rows: [], children: /* @__PURE__ */ new Map(), parent: d }, d.children.set(h, g)), d = g;
|
|
1671
1601
|
}), d.rows.push(l);
|
|
1672
|
-
}),
|
|
1602
|
+
}), n.children.size === 1 && n.children.has("__ungrouped__") && n.children.get("__ungrouped__").rows.length === s.length)
|
|
1673
1603
|
return [];
|
|
1674
|
-
const
|
|
1675
|
-
if (l ===
|
|
1676
|
-
l.children.forEach((d) =>
|
|
1604
|
+
const i = [], r = (l) => {
|
|
1605
|
+
if (l === n) {
|
|
1606
|
+
l.children.forEach((d) => r(d));
|
|
1677
1607
|
return;
|
|
1678
1608
|
}
|
|
1679
1609
|
const a = t.has(l.key);
|
|
1680
|
-
|
|
1610
|
+
i.push({
|
|
1681
1611
|
kind: "group",
|
|
1682
1612
|
key: l.key,
|
|
1683
1613
|
value: l.value,
|
|
1684
1614
|
depth: l.depth,
|
|
1685
1615
|
rows: l.rows,
|
|
1686
1616
|
expanded: a
|
|
1687
|
-
}), a && (l.children.size ? l.children.forEach((d) =>
|
|
1617
|
+
}), a && (l.children.size ? l.children.forEach((d) => r(d)) : l.rows.forEach((d) => i.push({ kind: "data", row: d, rowIndex: s.indexOf(d) })));
|
|
1688
1618
|
};
|
|
1689
|
-
return
|
|
1619
|
+
return r(n), i;
|
|
1690
1620
|
}
|
|
1691
|
-
function
|
|
1692
|
-
const t = new Set(
|
|
1621
|
+
function Qe(s, e) {
|
|
1622
|
+
const t = new Set(s);
|
|
1693
1623
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
1694
1624
|
}
|
|
1695
|
-
function
|
|
1625
|
+
function et(s) {
|
|
1696
1626
|
const e = /* @__PURE__ */ new Set();
|
|
1697
|
-
for (const t of
|
|
1627
|
+
for (const t of s)
|
|
1698
1628
|
t.kind === "group" && e.add(t.key);
|
|
1699
1629
|
return e;
|
|
1700
1630
|
}
|
|
1701
|
-
function
|
|
1631
|
+
function tt() {
|
|
1702
1632
|
return /* @__PURE__ */ new Set();
|
|
1703
1633
|
}
|
|
1704
|
-
function
|
|
1705
|
-
return
|
|
1634
|
+
function ot(s) {
|
|
1635
|
+
return s.kind !== "group" ? 0 : s.rows.length;
|
|
1706
1636
|
}
|
|
1707
|
-
|
|
1637
|
+
const nt = '.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;font-size:10px}.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}';
|
|
1638
|
+
class Qt extends C {
|
|
1708
1639
|
name = "groupingRows";
|
|
1709
1640
|
version = "1.0.0";
|
|
1710
1641
|
get defaultConfig() {
|
|
1711
1642
|
return {
|
|
1712
|
-
enabled: !0,
|
|
1713
1643
|
defaultExpanded: !1,
|
|
1714
1644
|
showRowCount: !0,
|
|
1715
1645
|
indentWidth: 20,
|
|
@@ -1734,22 +1664,22 @@ class Et extends y {
|
|
|
1734
1664
|
}
|
|
1735
1665
|
processRows(e) {
|
|
1736
1666
|
const t = this.config;
|
|
1737
|
-
if (
|
|
1667
|
+
if (typeof t.groupOn != "function")
|
|
1738
1668
|
return this.isActive = !1, this.flattenedRows = [], [...e];
|
|
1739
|
-
const
|
|
1669
|
+
const o = Je({
|
|
1740
1670
|
rows: e,
|
|
1741
1671
|
config: t,
|
|
1742
1672
|
expanded: this.expandedKeys
|
|
1743
1673
|
});
|
|
1744
|
-
return
|
|
1674
|
+
return o.length === 0 ? (this.isActive = !1, this.flattenedRows = [], [...e]) : (this.isActive = !0, this.flattenedRows = o, o.map((n) => n.kind === "group" ? {
|
|
1745
1675
|
__isGroupRow: !0,
|
|
1746
|
-
__groupKey:
|
|
1747
|
-
__groupValue:
|
|
1748
|
-
__groupDepth:
|
|
1749
|
-
__groupRows:
|
|
1750
|
-
__groupExpanded:
|
|
1751
|
-
__groupRowCount:
|
|
1752
|
-
} :
|
|
1676
|
+
__groupKey: n.key,
|
|
1677
|
+
__groupValue: n.value,
|
|
1678
|
+
__groupDepth: n.depth,
|
|
1679
|
+
__groupRows: n.rows,
|
|
1680
|
+
__groupExpanded: n.expanded,
|
|
1681
|
+
__groupRowCount: ot(n)
|
|
1682
|
+
} : n.row));
|
|
1753
1683
|
}
|
|
1754
1684
|
onCellClick(e) {
|
|
1755
1685
|
const t = e.row;
|
|
@@ -1759,14 +1689,14 @@ class Et extends y {
|
|
|
1759
1689
|
/**
|
|
1760
1690
|
* Render a row. Returns true if we handled the row (group row), false otherwise.
|
|
1761
1691
|
*/
|
|
1762
|
-
renderRow(e, t,
|
|
1692
|
+
renderRow(e, t, o) {
|
|
1763
1693
|
if (!e?.__isGroupRow)
|
|
1764
1694
|
return !1;
|
|
1765
|
-
const
|
|
1766
|
-
if (
|
|
1695
|
+
const n = this.config;
|
|
1696
|
+
if (n.groupRowRenderer) {
|
|
1767
1697
|
const l = () => {
|
|
1768
1698
|
this.toggle(e.__groupKey);
|
|
1769
|
-
}, a =
|
|
1699
|
+
}, a = n.groupRowRenderer({
|
|
1770
1700
|
key: e.__groupKey,
|
|
1771
1701
|
value: e.__groupValue,
|
|
1772
1702
|
depth: e.__groupDepth,
|
|
@@ -1777,55 +1707,55 @@ class Et extends y {
|
|
|
1777
1707
|
if (a)
|
|
1778
1708
|
return t.className = "group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), typeof a == "string" ? t.innerHTML = a : (t.innerHTML = "", t.appendChild(a)), !0;
|
|
1779
1709
|
}
|
|
1780
|
-
const
|
|
1710
|
+
const i = () => {
|
|
1781
1711
|
this.toggle(e.__groupKey);
|
|
1782
1712
|
};
|
|
1783
|
-
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) * (
|
|
1713
|
+
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) * (n.indentWidth ?? 20)}px`, t.innerHTML = "", n.fullWidth !== !1 ? this.renderFullWidthGroupRow(e, t, i) : this.renderPerColumnGroupRow(e, t, i), !0;
|
|
1784
1714
|
}
|
|
1785
1715
|
afterRender() {
|
|
1786
1716
|
}
|
|
1787
1717
|
// ===== Private Rendering Helpers =====
|
|
1788
|
-
renderFullWidthGroupRow(e, t,
|
|
1789
|
-
const
|
|
1790
|
-
|
|
1791
|
-
const
|
|
1792
|
-
|
|
1793
|
-
d.stopPropagation(),
|
|
1794
|
-
}),
|
|
1718
|
+
renderFullWidthGroupRow(e, t, o) {
|
|
1719
|
+
const n = this.config, i = document.createElement("div");
|
|
1720
|
+
i.className = "cell group-full", i.style.gridColumn = "1 / -1", i.setAttribute("role", "gridcell");
|
|
1721
|
+
const r = document.createElement("button");
|
|
1722
|
+
r.type = "button", r.className = "group-toggle", r.setAttribute("aria-label", e.__groupExpanded ? "Collapse group" : "Expand group"), this.setIcon(r, this.resolveIcon(e.__groupExpanded ? "collapse" : "expand")), r.addEventListener("click", (d) => {
|
|
1723
|
+
d.stopPropagation(), o();
|
|
1724
|
+
}), i.appendChild(r);
|
|
1795
1725
|
const l = document.createElement("span");
|
|
1796
1726
|
l.className = "group-label";
|
|
1797
|
-
const a =
|
|
1798
|
-
if (l.textContent = a,
|
|
1727
|
+
const a = n.formatLabel ? n.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
|
|
1728
|
+
if (l.textContent = a, i.appendChild(l), n.showRowCount !== !1) {
|
|
1799
1729
|
const d = document.createElement("span");
|
|
1800
|
-
d.className = "group-count", d.textContent = `(${e.__groupRowCount ?? e.__groupRows?.length ?? 0})`,
|
|
1730
|
+
d.className = "group-count", d.textContent = `(${e.__groupRowCount ?? e.__groupRows?.length ?? 0})`, i.appendChild(d);
|
|
1801
1731
|
}
|
|
1802
|
-
t.appendChild(
|
|
1732
|
+
t.appendChild(i);
|
|
1803
1733
|
}
|
|
1804
|
-
renderPerColumnGroupRow(e, t,
|
|
1805
|
-
const
|
|
1806
|
-
d && (t.style.display = "grid", t.style.gridTemplateColumns = d),
|
|
1734
|
+
renderPerColumnGroupRow(e, t, o) {
|
|
1735
|
+
const n = this.config, i = n.aggregators ?? {}, r = this.columns, l = e.__groupRows ?? [], d = this.shadowRoot?.querySelector(".body")?.style.gridTemplateColumns || "";
|
|
1736
|
+
d && (t.style.display = "grid", t.style.gridTemplateColumns = d), r.forEach((c, u) => {
|
|
1807
1737
|
const h = document.createElement("div");
|
|
1808
1738
|
if (h.className = "cell group-cell", h.setAttribute("data-col", String(u)), h.setAttribute("role", "gridcell"), u === 0) {
|
|
1809
|
-
const
|
|
1810
|
-
|
|
1811
|
-
b.stopPropagation(),
|
|
1812
|
-
}), h.appendChild(
|
|
1813
|
-
const g = document.createElement("span"), m =
|
|
1739
|
+
const p = document.createElement("button");
|
|
1740
|
+
p.type = "button", p.className = "group-toggle", p.setAttribute("aria-label", e.__groupExpanded ? "Collapse group" : "Expand group"), this.setIcon(p, this.resolveIcon(e.__groupExpanded ? "collapse" : "expand")), p.addEventListener("click", (b) => {
|
|
1741
|
+
b.stopPropagation(), o();
|
|
1742
|
+
}), h.appendChild(p);
|
|
1743
|
+
const g = document.createElement("span"), m = i[c.field];
|
|
1814
1744
|
if (m) {
|
|
1815
|
-
const b =
|
|
1745
|
+
const b = ee(m, l, c.field, c);
|
|
1816
1746
|
g.textContent = b != null ? String(b) : String(e.__groupValue);
|
|
1817
1747
|
} else {
|
|
1818
|
-
const b =
|
|
1748
|
+
const b = n.formatLabel ? n.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
|
|
1819
1749
|
g.textContent = b;
|
|
1820
1750
|
}
|
|
1821
|
-
if (h.appendChild(g),
|
|
1751
|
+
if (h.appendChild(g), n.showRowCount !== !1) {
|
|
1822
1752
|
const b = document.createElement("span");
|
|
1823
1753
|
b.className = "group-count", b.textContent = ` (${l.length})`, h.appendChild(b);
|
|
1824
1754
|
}
|
|
1825
1755
|
} else {
|
|
1826
|
-
const
|
|
1827
|
-
if (
|
|
1828
|
-
const g =
|
|
1756
|
+
const p = i[c.field];
|
|
1757
|
+
if (p) {
|
|
1758
|
+
const g = ee(p, l, c.field, c);
|
|
1829
1759
|
h.textContent = g != null ? String(g) : "";
|
|
1830
1760
|
} else
|
|
1831
1761
|
h.textContent = "";
|
|
@@ -1838,21 +1768,21 @@ class Et extends y {
|
|
|
1838
1768
|
* Expand all groups.
|
|
1839
1769
|
*/
|
|
1840
1770
|
expandAll() {
|
|
1841
|
-
this.expandedKeys =
|
|
1771
|
+
this.expandedKeys = et(this.flattenedRows), this.requestRender();
|
|
1842
1772
|
}
|
|
1843
1773
|
/**
|
|
1844
1774
|
* Collapse all groups.
|
|
1845
1775
|
*/
|
|
1846
1776
|
collapseAll() {
|
|
1847
|
-
this.expandedKeys =
|
|
1777
|
+
this.expandedKeys = tt(), this.requestRender();
|
|
1848
1778
|
}
|
|
1849
1779
|
/**
|
|
1850
1780
|
* Toggle expansion of a specific group.
|
|
1851
1781
|
* @param key - The group key to toggle
|
|
1852
1782
|
*/
|
|
1853
1783
|
toggle(e) {
|
|
1854
|
-
this.expandedKeys =
|
|
1855
|
-
const t = this.flattenedRows.find((
|
|
1784
|
+
this.expandedKeys = Qe(this.expandedKeys, e);
|
|
1785
|
+
const t = this.flattenedRows.find((o) => o.kind === "group" && o.key === e);
|
|
1856
1786
|
this.emit("group-toggle", {
|
|
1857
1787
|
key: e,
|
|
1858
1788
|
expanded: this.expandedKeys.has(e),
|
|
@@ -1941,75 +1871,37 @@ class Et extends y {
|
|
|
1941
1871
|
this.config.groupOn = e, this.requestRender();
|
|
1942
1872
|
}
|
|
1943
1873
|
// ===== Styles =====
|
|
1944
|
-
styles =
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
}
|
|
1949
|
-
.group-row:hover {
|
|
1950
|
-
background: var(--tbw-grouping-rows-bg-hover, var(--tbw-color-row-hover));
|
|
1951
|
-
}
|
|
1952
|
-
.group-toggle {
|
|
1953
|
-
cursor: pointer;
|
|
1954
|
-
user-select: none;
|
|
1955
|
-
display: inline-flex;
|
|
1956
|
-
align-items: center;
|
|
1957
|
-
justify-content: center;
|
|
1958
|
-
width: 20px;
|
|
1959
|
-
height: 20px;
|
|
1960
|
-
margin-right: 4px;
|
|
1961
|
-
font-size: 10px;
|
|
1962
|
-
}
|
|
1963
|
-
.group-toggle:hover {
|
|
1964
|
-
background: var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));
|
|
1965
|
-
border-radius: 2px;
|
|
1966
|
-
}
|
|
1967
|
-
.group-label {
|
|
1968
|
-
display: inline-flex;
|
|
1969
|
-
align-items: center;
|
|
1970
|
-
gap: 8px;
|
|
1971
|
-
}
|
|
1972
|
-
.group-count {
|
|
1973
|
-
color: var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));
|
|
1974
|
-
font-size: 0.85em;
|
|
1975
|
-
font-weight: normal;
|
|
1976
|
-
}
|
|
1977
|
-
[data-group-depth="0"] .group-label { padding-left: 0; }
|
|
1978
|
-
[data-group-depth="1"] .group-label { padding-left: 20px; }
|
|
1979
|
-
[data-group-depth="2"] .group-label { padding-left: 40px; }
|
|
1980
|
-
[data-group-depth="3"] .group-label { padding-left: 60px; }
|
|
1981
|
-
[data-group-depth="4"] .group-label { padding-left: 80px; }
|
|
1982
|
-
`;
|
|
1983
|
-
}
|
|
1984
|
-
function H(i, e) {
|
|
1985
|
-
const t = new Set(i);
|
|
1874
|
+
styles = nt;
|
|
1875
|
+
}
|
|
1876
|
+
function B(s, e) {
|
|
1877
|
+
const t = new Set(s);
|
|
1986
1878
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
1987
1879
|
}
|
|
1988
|
-
function
|
|
1989
|
-
const t = new Set(
|
|
1880
|
+
function it(s, e) {
|
|
1881
|
+
const t = new Set(s);
|
|
1990
1882
|
return t.add(e), t;
|
|
1991
1883
|
}
|
|
1992
|
-
function
|
|
1993
|
-
const t = new Set(
|
|
1884
|
+
function rt(s, e) {
|
|
1885
|
+
const t = new Set(s);
|
|
1994
1886
|
return t.delete(e), t;
|
|
1995
1887
|
}
|
|
1996
|
-
function
|
|
1997
|
-
return
|
|
1998
|
-
}
|
|
1999
|
-
function Ye(i, e, t, n) {
|
|
2000
|
-
const o = document.createElement("div");
|
|
2001
|
-
o.className = "master-detail-row", o.setAttribute("data-detail-for", String(e)), o.setAttribute("role", "row");
|
|
2002
|
-
const r = document.createElement("div");
|
|
2003
|
-
r.className = "master-detail-cell", r.setAttribute("role", "cell"), r.style.gridColumn = `1 / ${n + 1}`;
|
|
2004
|
-
const s = t(i, e);
|
|
2005
|
-
return typeof s == "string" ? r.innerHTML = s : s instanceof HTMLElement && r.appendChild(s), o.appendChild(r), o;
|
|
1888
|
+
function st(s, e) {
|
|
1889
|
+
return s.has(e);
|
|
2006
1890
|
}
|
|
2007
|
-
|
|
1891
|
+
function lt(s, e, t, o) {
|
|
1892
|
+
const n = document.createElement("div");
|
|
1893
|
+
n.className = "master-detail-row", n.setAttribute("data-detail-for", String(e)), n.setAttribute("role", "row");
|
|
1894
|
+
const i = document.createElement("div");
|
|
1895
|
+
i.className = "master-detail-cell", i.setAttribute("role", "cell"), i.style.gridColumn = `1 / ${o + 1}`;
|
|
1896
|
+
const r = t(s, e);
|
|
1897
|
+
return typeof r == "string" ? i.innerHTML = r : r instanceof HTMLElement && i.appendChild(r), n.appendChild(i), n;
|
|
1898
|
+
}
|
|
1899
|
+
const at = ".master-detail-cell-wrapper{display:flex;align-items:center;gap:4px}.master-detail-toggle{cursor:pointer;font-size:10px;opacity:.7;user-select:none}.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))}.master-detail-cell{padding:16px;overflow:auto}";
|
|
1900
|
+
class eo extends C {
|
|
2008
1901
|
name = "masterDetail";
|
|
2009
1902
|
version = "1.0.0";
|
|
2010
1903
|
get defaultConfig() {
|
|
2011
1904
|
return {
|
|
2012
|
-
enabled: !0,
|
|
2013
1905
|
detailHeight: "auto",
|
|
2014
1906
|
expandOnRowClick: !1,
|
|
2015
1907
|
collapseOnClickOutside: !1,
|
|
@@ -2029,37 +1921,37 @@ class At extends y {
|
|
|
2029
1921
|
return [...e];
|
|
2030
1922
|
const t = [...e];
|
|
2031
1923
|
if (t.length > 0) {
|
|
2032
|
-
const
|
|
2033
|
-
if (
|
|
1924
|
+
const o = { ...t[0] }, n = o.viewRenderer;
|
|
1925
|
+
if (n?.__masterDetailWrapped)
|
|
2034
1926
|
return t;
|
|
2035
|
-
const
|
|
2036
|
-
const { value: l, row: a } =
|
|
1927
|
+
const i = (r) => {
|
|
1928
|
+
const { value: l, row: a } = r, d = this.expandedRows.has(a), c = document.createElement("span");
|
|
2037
1929
|
c.className = "master-detail-cell-wrapper";
|
|
2038
1930
|
const u = document.createElement("span");
|
|
2039
|
-
u.className = "master-detail-toggle", this.setIcon(u, this.resolveIcon(d ? "collapse" : "expand")), u.setAttribute("aria-expanded", String(d)), u.setAttribute("aria-label", d ? "Collapse details" : "Expand details"), u.addEventListener("click", (
|
|
2040
|
-
|
|
1931
|
+
u.className = "master-detail-toggle", this.setIcon(u, this.resolveIcon(d ? "collapse" : "expand")), u.setAttribute("aria-expanded", String(d)), u.setAttribute("aria-label", d ? "Collapse details" : "Expand details"), u.addEventListener("click", (p) => {
|
|
1932
|
+
p.stopPropagation();
|
|
2041
1933
|
const g = this.rows.indexOf(a);
|
|
2042
|
-
this.expandedRows =
|
|
1934
|
+
this.expandedRows = B(this.expandedRows, a), this.emit("detail-expand", {
|
|
2043
1935
|
rowIndex: g,
|
|
2044
1936
|
row: a,
|
|
2045
1937
|
expanded: this.expandedRows.has(a)
|
|
2046
1938
|
}), this.requestRender();
|
|
2047
1939
|
}), c.appendChild(u);
|
|
2048
1940
|
const h = document.createElement("span");
|
|
2049
|
-
if (
|
|
2050
|
-
const
|
|
2051
|
-
|
|
1941
|
+
if (n) {
|
|
1942
|
+
const p = n(r);
|
|
1943
|
+
p instanceof Node ? h.appendChild(p) : h.textContent = String(p ?? l ?? "");
|
|
2052
1944
|
} else
|
|
2053
1945
|
h.textContent = String(l ?? "");
|
|
2054
1946
|
return c.appendChild(h), c;
|
|
2055
1947
|
};
|
|
2056
|
-
|
|
1948
|
+
i.__masterDetailWrapped = !0, o.viewRenderer = i, t[0] = o;
|
|
2057
1949
|
}
|
|
2058
1950
|
return t;
|
|
2059
1951
|
}
|
|
2060
1952
|
onRowClick(e) {
|
|
2061
1953
|
if (!(!this.config.expandOnRowClick || !this.config.detailRenderer))
|
|
2062
|
-
return this.expandedRows =
|
|
1954
|
+
return this.expandedRows = B(this.expandedRows, e.row), this.emit("detail-expand", {
|
|
2063
1955
|
rowIndex: e.rowIndex,
|
|
2064
1956
|
row: e.row,
|
|
2065
1957
|
expanded: this.expandedRows.has(e.row)
|
|
@@ -2086,25 +1978,25 @@ class At extends y {
|
|
|
2086
1978
|
if (!this.config.detailRenderer) return;
|
|
2087
1979
|
const e = this.shadowRoot?.querySelector(".rows");
|
|
2088
1980
|
if (!e) return;
|
|
2089
|
-
const t = /* @__PURE__ */ new Map(),
|
|
2090
|
-
for (const
|
|
2091
|
-
const l =
|
|
2092
|
-
a >= 0 && t.set(a,
|
|
2093
|
-
}
|
|
2094
|
-
const
|
|
2095
|
-
for (const
|
|
2096
|
-
const l = parseInt(
|
|
2097
|
-
(!d || !c) && (
|
|
2098
|
-
}
|
|
2099
|
-
for (const [
|
|
2100
|
-
const a = this.rows[
|
|
1981
|
+
const t = /* @__PURE__ */ new Map(), o = e.querySelectorAll(".data-grid-row"), n = this.columns.length;
|
|
1982
|
+
for (const r of o) {
|
|
1983
|
+
const l = r.querySelector(".cell[data-row]"), a = l ? parseInt(l.getAttribute("data-row") ?? "-1", 10) : -1;
|
|
1984
|
+
a >= 0 && t.set(a, r);
|
|
1985
|
+
}
|
|
1986
|
+
const i = e.querySelectorAll(".master-detail-row");
|
|
1987
|
+
for (const r of i) {
|
|
1988
|
+
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);
|
|
1989
|
+
(!d || !c) && (r.remove(), a && this.detailElements.delete(a));
|
|
1990
|
+
}
|
|
1991
|
+
for (const [r, l] of t) {
|
|
1992
|
+
const a = this.rows[r];
|
|
2101
1993
|
if (!a || !this.expandedRows.has(a)) continue;
|
|
2102
1994
|
const d = this.detailElements.get(a);
|
|
2103
1995
|
if (d) {
|
|
2104
1996
|
d.previousElementSibling !== l && l.after(d);
|
|
2105
1997
|
continue;
|
|
2106
1998
|
}
|
|
2107
|
-
const c =
|
|
1999
|
+
const c = lt(a, r, this.config.detailRenderer, n);
|
|
2108
2000
|
typeof this.config.detailHeight == "number" && (c.style.height = `${this.config.detailHeight}px`), l.after(c), this.detailElements.set(a, c);
|
|
2109
2001
|
}
|
|
2110
2002
|
}
|
|
@@ -2115,12 +2007,12 @@ class At extends y {
|
|
|
2115
2007
|
getExtraHeight() {
|
|
2116
2008
|
let e = 0;
|
|
2117
2009
|
for (const t of this.expandedRows) {
|
|
2118
|
-
const
|
|
2119
|
-
if (
|
|
2120
|
-
e +=
|
|
2010
|
+
const o = this.detailElements.get(t);
|
|
2011
|
+
if (o)
|
|
2012
|
+
e += o.offsetHeight;
|
|
2121
2013
|
else {
|
|
2122
|
-
const
|
|
2123
|
-
e += typeof
|
|
2014
|
+
const n = this.config?.detailHeight;
|
|
2015
|
+
e += typeof n == "number" ? n : 150;
|
|
2124
2016
|
}
|
|
2125
2017
|
}
|
|
2126
2018
|
return e;
|
|
@@ -2131,15 +2023,15 @@ class At extends y {
|
|
|
2131
2023
|
*/
|
|
2132
2024
|
getExtraHeightBefore(e) {
|
|
2133
2025
|
let t = 0;
|
|
2134
|
-
for (const
|
|
2135
|
-
const
|
|
2136
|
-
if (
|
|
2137
|
-
const
|
|
2138
|
-
if (
|
|
2139
|
-
t +=
|
|
2026
|
+
for (const o of this.expandedRows) {
|
|
2027
|
+
const n = this.rows.indexOf(o);
|
|
2028
|
+
if (n >= 0 && n < e) {
|
|
2029
|
+
const i = this.detailElements.get(o);
|
|
2030
|
+
if (i)
|
|
2031
|
+
t += i.offsetHeight;
|
|
2140
2032
|
else {
|
|
2141
|
-
const
|
|
2142
|
-
t += typeof
|
|
2033
|
+
const r = this.config?.detailHeight;
|
|
2034
|
+
t += typeof r == "number" ? r : 150;
|
|
2143
2035
|
}
|
|
2144
2036
|
}
|
|
2145
2037
|
}
|
|
@@ -2149,20 +2041,20 @@ class At extends y {
|
|
|
2149
2041
|
* Adjust the virtualization start index to keep expanded row visible while its detail is visible.
|
|
2150
2042
|
* This ensures the detail scrolls smoothly out of view instead of disappearing abruptly.
|
|
2151
2043
|
*/
|
|
2152
|
-
adjustVirtualStart(e, t,
|
|
2044
|
+
adjustVirtualStart(e, t, o) {
|
|
2153
2045
|
if (this.expandedRows.size === 0) return e;
|
|
2154
|
-
const
|
|
2046
|
+
const n = [];
|
|
2155
2047
|
for (const l of this.expandedRows) {
|
|
2156
2048
|
const a = this.rows.indexOf(l);
|
|
2157
|
-
a >= 0 &&
|
|
2049
|
+
a >= 0 && n.push({ index: a, row: l });
|
|
2158
2050
|
}
|
|
2159
|
-
|
|
2160
|
-
let
|
|
2161
|
-
for (const { index: l, row: a } of
|
|
2162
|
-
const d = l *
|
|
2163
|
-
|
|
2051
|
+
n.sort((l, a) => l.index - a.index);
|
|
2052
|
+
let i = e, r = 0;
|
|
2053
|
+
for (const { index: l, row: a } of n) {
|
|
2054
|
+
const d = l * o + r, u = this.detailElements.get(a)?.offsetHeight ?? (typeof this.config?.detailHeight == "number" ? this.config.detailHeight : 150), h = d + o + u;
|
|
2055
|
+
r += u, !(l >= e) && h > t && l < i && (i = l);
|
|
2164
2056
|
}
|
|
2165
|
-
return
|
|
2057
|
+
return i;
|
|
2166
2058
|
}
|
|
2167
2059
|
// ===== Public API =====
|
|
2168
2060
|
/**
|
|
@@ -2171,7 +2063,7 @@ class At extends y {
|
|
|
2171
2063
|
*/
|
|
2172
2064
|
expand(e) {
|
|
2173
2065
|
const t = this.rows[e];
|
|
2174
|
-
t && (this.expandedRows =
|
|
2066
|
+
t && (this.expandedRows = it(this.expandedRows, t), this.requestRender());
|
|
2175
2067
|
}
|
|
2176
2068
|
/**
|
|
2177
2069
|
* Collapse the detail row at the given index.
|
|
@@ -2179,7 +2071,7 @@ class At extends y {
|
|
|
2179
2071
|
*/
|
|
2180
2072
|
collapse(e) {
|
|
2181
2073
|
const t = this.rows[e];
|
|
2182
|
-
t && (this.expandedRows =
|
|
2074
|
+
t && (this.expandedRows = rt(this.expandedRows, t), this.requestRender());
|
|
2183
2075
|
}
|
|
2184
2076
|
/**
|
|
2185
2077
|
* Toggle the detail row at the given index.
|
|
@@ -2187,7 +2079,7 @@ class At extends y {
|
|
|
2187
2079
|
*/
|
|
2188
2080
|
toggle(e) {
|
|
2189
2081
|
const t = this.rows[e];
|
|
2190
|
-
t && (this.expandedRows =
|
|
2082
|
+
t && (this.expandedRows = B(this.expandedRows, t), this.requestRender());
|
|
2191
2083
|
}
|
|
2192
2084
|
/**
|
|
2193
2085
|
* Check if the detail row at the given index is expanded.
|
|
@@ -2196,7 +2088,7 @@ class At extends y {
|
|
|
2196
2088
|
*/
|
|
2197
2089
|
isExpanded(e) {
|
|
2198
2090
|
const t = this.rows[e];
|
|
2199
|
-
return t ?
|
|
2091
|
+
return t ? st(this.expandedRows, t) : !1;
|
|
2200
2092
|
}
|
|
2201
2093
|
/**
|
|
2202
2094
|
* Expand all detail rows.
|
|
@@ -2219,8 +2111,8 @@ class At extends y {
|
|
|
2219
2111
|
getExpandedRows() {
|
|
2220
2112
|
const e = [];
|
|
2221
2113
|
for (const t of this.expandedRows) {
|
|
2222
|
-
const
|
|
2223
|
-
|
|
2114
|
+
const o = this.rows.indexOf(t);
|
|
2115
|
+
o >= 0 && e.push(o);
|
|
2224
2116
|
}
|
|
2225
2117
|
return e;
|
|
2226
2118
|
}
|
|
@@ -2234,63 +2126,38 @@ class At extends y {
|
|
|
2234
2126
|
return t ? this.detailElements.get(t) : void 0;
|
|
2235
2127
|
}
|
|
2236
2128
|
// ===== Styles =====
|
|
2237
|
-
styles =
|
|
2238
|
-
.master-detail-cell-wrapper {
|
|
2239
|
-
display: flex;
|
|
2240
|
-
align-items: center;
|
|
2241
|
-
gap: 4px;
|
|
2242
|
-
}
|
|
2243
|
-
.master-detail-toggle {
|
|
2244
|
-
cursor: pointer;
|
|
2245
|
-
font-size: 10px;
|
|
2246
|
-
opacity: 0.7;
|
|
2247
|
-
user-select: none;
|
|
2248
|
-
}
|
|
2249
|
-
.master-detail-toggle:hover {
|
|
2250
|
-
opacity: 1;
|
|
2251
|
-
}
|
|
2252
|
-
.master-detail-row {
|
|
2253
|
-
grid-column: 1 / -1;
|
|
2254
|
-
display: grid;
|
|
2255
|
-
background: var(--tbw-master-detail-bg, var(--tbw-color-row-alt));
|
|
2256
|
-
border-bottom: 1px solid var(--tbw-master-detail-border, var(--tbw-color-border));
|
|
2257
|
-
}
|
|
2258
|
-
.master-detail-cell {
|
|
2259
|
-
padding: 16px;
|
|
2260
|
-
overflow: auto;
|
|
2261
|
-
}
|
|
2262
|
-
`;
|
|
2129
|
+
styles = at;
|
|
2263
2130
|
}
|
|
2264
|
-
function
|
|
2265
|
-
return e.length ? [...
|
|
2266
|
-
for (const
|
|
2267
|
-
const l = t.find((u) => u.field ===
|
|
2131
|
+
function dt(s, e, t) {
|
|
2132
|
+
return e.length ? [...s].sort((o, n) => {
|
|
2133
|
+
for (const i of e) {
|
|
2134
|
+
const l = t.find((u) => u.field === i.field)?.sortComparator ?? ct, a = o[i.field], d = n[i.field], c = l(a, d, o, n);
|
|
2268
2135
|
if (c !== 0)
|
|
2269
|
-
return
|
|
2136
|
+
return i.direction === "asc" ? c : -c;
|
|
2270
2137
|
}
|
|
2271
2138
|
return 0;
|
|
2272
|
-
}) : [...
|
|
2139
|
+
}) : [...s];
|
|
2273
2140
|
}
|
|
2274
|
-
function
|
|
2275
|
-
return
|
|
2141
|
+
function ct(s, e) {
|
|
2142
|
+
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));
|
|
2276
2143
|
}
|
|
2277
|
-
function
|
|
2278
|
-
const
|
|
2279
|
-
return t ?
|
|
2144
|
+
function ut(s, e, t, o) {
|
|
2145
|
+
const n = s.find((i) => i.field === e);
|
|
2146
|
+
return t ? n ? n.direction === "asc" ? s.map((i) => i.field === e ? { ...i, direction: "desc" } : i) : s.filter((i) => i.field !== e) : s.length < o ? [...s, { field: e, direction: "asc" }] : s : n?.direction === "asc" ? [{ field: e, direction: "desc" }] : n?.direction === "desc" ? [] : [{ field: e, direction: "asc" }];
|
|
2280
2147
|
}
|
|
2281
|
-
function
|
|
2282
|
-
const t =
|
|
2148
|
+
function ue(s, e) {
|
|
2149
|
+
const t = s.findIndex((o) => o.field === e);
|
|
2283
2150
|
return t >= 0 ? t + 1 : void 0;
|
|
2284
2151
|
}
|
|
2285
|
-
function
|
|
2286
|
-
return
|
|
2152
|
+
function he(s, e) {
|
|
2153
|
+
return s.find((t) => t.field === e)?.direction;
|
|
2287
2154
|
}
|
|
2288
|
-
|
|
2155
|
+
const ht = '.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-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}';
|
|
2156
|
+
class to extends C {
|
|
2289
2157
|
name = "multiSort";
|
|
2290
2158
|
version = "1.0.0";
|
|
2291
2159
|
get defaultConfig() {
|
|
2292
2160
|
return {
|
|
2293
|
-
enabled: !0,
|
|
2294
2161
|
maxSortColumns: 3,
|
|
2295
2162
|
showSortIndex: !0
|
|
2296
2163
|
};
|
|
@@ -2303,30 +2170,30 @@ class It extends y {
|
|
|
2303
2170
|
}
|
|
2304
2171
|
// ===== Hooks =====
|
|
2305
2172
|
processRows(e) {
|
|
2306
|
-
return this.sortModel.length === 0 ? [...e] :
|
|
2173
|
+
return this.sortModel.length === 0 ? [...e] : dt([...e], this.sortModel, [...this.columns]);
|
|
2307
2174
|
}
|
|
2308
2175
|
onHeaderClick(e) {
|
|
2309
|
-
if (!this.columns.find((
|
|
2310
|
-
const
|
|
2311
|
-
return this.sortModel =
|
|
2176
|
+
if (!this.columns.find((i) => i.field === e.field)?.sortable) return !1;
|
|
2177
|
+
const o = e.originalEvent.shiftKey, n = this.config.maxSortColumns ?? 3;
|
|
2178
|
+
return this.sortModel = ut(this.sortModel, e.field, o, n), this.emit("sort-change", { sortModel: [...this.sortModel] }), this.requestRender(), !0;
|
|
2312
2179
|
}
|
|
2313
2180
|
afterRender() {
|
|
2314
2181
|
const e = this.shadowRoot;
|
|
2315
2182
|
if (!e) return;
|
|
2316
2183
|
const t = this.config.showSortIndex !== !1;
|
|
2317
|
-
e.querySelectorAll(".header-row .cell[data-field]").forEach((
|
|
2318
|
-
const
|
|
2319
|
-
if (!
|
|
2320
|
-
const
|
|
2321
|
-
if (
|
|
2322
|
-
|
|
2184
|
+
e.querySelectorAll(".header-row .cell[data-field]").forEach((n) => {
|
|
2185
|
+
const i = n.getAttribute("data-field");
|
|
2186
|
+
if (!i) return;
|
|
2187
|
+
const r = ue(this.sortModel, i), l = he(this.sortModel, i);
|
|
2188
|
+
if (n.querySelector(".sort-index")?.remove(), l) {
|
|
2189
|
+
n.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove(), n.setAttribute("data-sort", l);
|
|
2323
2190
|
const c = document.createElement("span");
|
|
2324
|
-
if (c.className = "sort-indicator", c.style.marginLeft = "4px", c.style.opacity = "0.8", this.setIcon(c, this.resolveIcon(l === "asc" ? "sortAsc" : "sortDesc")),
|
|
2191
|
+
if (c.className = "sort-indicator", c.style.marginLeft = "4px", c.style.opacity = "0.8", this.setIcon(c, this.resolveIcon(l === "asc" ? "sortAsc" : "sortDesc")), n.appendChild(c), t && this.sortModel.length > 1 && r !== void 0) {
|
|
2325
2192
|
const u = document.createElement("span");
|
|
2326
|
-
u.className = "sort-index", u.textContent = String(
|
|
2193
|
+
u.className = "sort-index", u.textContent = String(r), n.appendChild(u);
|
|
2327
2194
|
}
|
|
2328
2195
|
} else
|
|
2329
|
-
|
|
2196
|
+
n.removeAttribute("data-sort");
|
|
2330
2197
|
});
|
|
2331
2198
|
}
|
|
2332
2199
|
// ===== Public API =====
|
|
@@ -2356,7 +2223,7 @@ class It extends y {
|
|
|
2356
2223
|
* @returns 1-based index or undefined if not sorted
|
|
2357
2224
|
*/
|
|
2358
2225
|
getSortIndex(e) {
|
|
2359
|
-
return
|
|
2226
|
+
return ue(this.sortModel, e);
|
|
2360
2227
|
}
|
|
2361
2228
|
/**
|
|
2362
2229
|
* Get the sort direction for a specific field.
|
|
@@ -2364,14 +2231,14 @@ class It extends y {
|
|
|
2364
2231
|
* @returns Sort direction or undefined if not sorted
|
|
2365
2232
|
*/
|
|
2366
2233
|
getSortDirection(e) {
|
|
2367
|
-
return
|
|
2234
|
+
return he(this.sortModel, e);
|
|
2368
2235
|
}
|
|
2369
2236
|
// ===== Column State Hooks =====
|
|
2370
2237
|
/**
|
|
2371
2238
|
* Return sort state for a column if it's in the sort model.
|
|
2372
2239
|
*/
|
|
2373
2240
|
getColumnState(e) {
|
|
2374
|
-
const t = this.sortModel.findIndex((
|
|
2241
|
+
const t = this.sortModel.findIndex((n) => n.field === e);
|
|
2375
2242
|
return t === -1 ? void 0 : {
|
|
2376
2243
|
sort: {
|
|
2377
2244
|
direction: this.sortModel[t].direction,
|
|
@@ -2385,91 +2252,65 @@ class It extends y {
|
|
|
2385
2252
|
*/
|
|
2386
2253
|
applyColumnState(e, t) {
|
|
2387
2254
|
if (!t.sort) {
|
|
2388
|
-
this.sortModel = this.sortModel.filter((
|
|
2255
|
+
this.sortModel = this.sortModel.filter((i) => i.field !== e);
|
|
2389
2256
|
return;
|
|
2390
2257
|
}
|
|
2391
|
-
const
|
|
2258
|
+
const o = this.sortModel.findIndex((i) => i.field === e), n = {
|
|
2392
2259
|
field: e,
|
|
2393
2260
|
direction: t.sort.direction
|
|
2394
2261
|
};
|
|
2395
|
-
|
|
2262
|
+
o !== -1 ? this.sortModel[o] = n : this.sortModel.splice(t.sort.priority, 0, n);
|
|
2396
2263
|
}
|
|
2397
2264
|
// ===== Styles =====
|
|
2398
|
-
styles =
|
|
2399
|
-
.header-cell[data-sort="asc"]::after {
|
|
2400
|
-
content: '↑';
|
|
2401
|
-
margin-left: 4px;
|
|
2402
|
-
opacity: 0.8;
|
|
2403
|
-
}
|
|
2404
|
-
.header-cell[data-sort="desc"]::after {
|
|
2405
|
-
content: '↓';
|
|
2406
|
-
margin-left: 4px;
|
|
2407
|
-
opacity: 0.8;
|
|
2408
|
-
}
|
|
2409
|
-
.sort-index {
|
|
2410
|
-
font-size: 10px;
|
|
2411
|
-
background: var(--tbw-multi-sort-badge-bg, var(--tbw-color-panel-bg));
|
|
2412
|
-
color: var(--tbw-multi-sort-badge-color, var(--tbw-color-fg));
|
|
2413
|
-
border-radius: 50%;
|
|
2414
|
-
width: 14px;
|
|
2415
|
-
height: 14px;
|
|
2416
|
-
display: inline-flex;
|
|
2417
|
-
align-items: center;
|
|
2418
|
-
justify-content: center;
|
|
2419
|
-
margin-left: 2px;
|
|
2420
|
-
font-weight: 600;
|
|
2421
|
-
}
|
|
2422
|
-
`;
|
|
2265
|
+
styles = ht;
|
|
2423
2266
|
}
|
|
2424
|
-
function
|
|
2425
|
-
return
|
|
2267
|
+
function pt(s) {
|
|
2268
|
+
return s.filter((e) => e.sticky === "left");
|
|
2426
2269
|
}
|
|
2427
|
-
function
|
|
2428
|
-
return
|
|
2270
|
+
function gt(s) {
|
|
2271
|
+
return s.filter((e) => e.sticky === "right");
|
|
2429
2272
|
}
|
|
2430
|
-
function
|
|
2431
|
-
return
|
|
2273
|
+
function V(s) {
|
|
2274
|
+
return s.some((e) => e.sticky === "left" || e.sticky === "right");
|
|
2432
2275
|
}
|
|
2433
|
-
function
|
|
2434
|
-
const t =
|
|
2276
|
+
function pe(s, e) {
|
|
2277
|
+
const t = s.shadowRoot;
|
|
2435
2278
|
if (!t) return;
|
|
2436
|
-
const
|
|
2437
|
-
if (!
|
|
2438
|
-
const
|
|
2279
|
+
const o = Array.from(t.querySelectorAll(".header-row .cell"));
|
|
2280
|
+
if (!o.length) return;
|
|
2281
|
+
const n = /* @__PURE__ */ new Map();
|
|
2439
2282
|
e.forEach((l, a) => {
|
|
2440
|
-
l.field &&
|
|
2283
|
+
l.field && n.set(l.field, a);
|
|
2441
2284
|
});
|
|
2442
|
-
let
|
|
2285
|
+
let i = 0;
|
|
2443
2286
|
for (const l of e)
|
|
2444
2287
|
if (l.sticky === "left") {
|
|
2445
|
-
const a =
|
|
2446
|
-
d && (d.classList.add("sticky-left"), d.style.left =
|
|
2447
|
-
c.classList.add("sticky-left"), c.style.left =
|
|
2448
|
-
}),
|
|
2288
|
+
const a = n.get(l.field), d = o.find((c) => c.getAttribute("data-field") === l.field);
|
|
2289
|
+
d && (d.classList.add("sticky-left"), d.style.left = i + "px", a !== void 0 && t.querySelectorAll(`.data-grid-row .cell[data-col="${a}"]`).forEach((c) => {
|
|
2290
|
+
c.classList.add("sticky-left"), c.style.left = i + "px";
|
|
2291
|
+
}), i += d.offsetWidth);
|
|
2449
2292
|
}
|
|
2450
|
-
let
|
|
2293
|
+
let r = 0;
|
|
2451
2294
|
for (const l of [...e].reverse())
|
|
2452
2295
|
if (l.sticky === "right") {
|
|
2453
|
-
const a =
|
|
2454
|
-
d && (d.classList.add("sticky-right"), d.style.right =
|
|
2455
|
-
c.classList.add("sticky-right"), c.style.right =
|
|
2456
|
-
}),
|
|
2296
|
+
const a = n.get(l.field), d = o.find((c) => c.getAttribute("data-field") === l.field);
|
|
2297
|
+
d && (d.classList.add("sticky-right"), d.style.right = r + "px", a !== void 0 && t.querySelectorAll(`.data-grid-row .cell[data-col="${a}"]`).forEach((c) => {
|
|
2298
|
+
c.classList.add("sticky-right"), c.style.right = r + "px";
|
|
2299
|
+
}), r += d.offsetWidth);
|
|
2457
2300
|
}
|
|
2458
2301
|
}
|
|
2459
|
-
function
|
|
2460
|
-
const e =
|
|
2302
|
+
function ge(s) {
|
|
2303
|
+
const e = s.shadowRoot;
|
|
2461
2304
|
if (!e) return;
|
|
2462
|
-
e.querySelectorAll(".sticky-left, .sticky-right").forEach((
|
|
2463
|
-
|
|
2305
|
+
e.querySelectorAll(".sticky-left, .sticky-right").forEach((o) => {
|
|
2306
|
+
o.classList.remove("sticky-left", "sticky-right"), o.style.left = "", o.style.right = "";
|
|
2464
2307
|
});
|
|
2465
2308
|
}
|
|
2466
|
-
class
|
|
2309
|
+
class oo extends C {
|
|
2467
2310
|
name = "pinnedColumns";
|
|
2468
2311
|
version = "1.0.0";
|
|
2469
2312
|
get defaultConfig() {
|
|
2470
|
-
return {
|
|
2471
|
-
enabled: !0
|
|
2472
|
-
};
|
|
2313
|
+
return {};
|
|
2473
2314
|
}
|
|
2474
2315
|
// ===== Internal State =====
|
|
2475
2316
|
isApplied = !1;
|
|
@@ -2484,23 +2325,23 @@ class _t extends y {
|
|
|
2484
2325
|
* Auto-detect sticky columns from column configuration.
|
|
2485
2326
|
*/
|
|
2486
2327
|
static detect(e, t) {
|
|
2487
|
-
const
|
|
2488
|
-
return Array.isArray(
|
|
2328
|
+
const o = t?.columns;
|
|
2329
|
+
return Array.isArray(o) ? V(o) : !1;
|
|
2489
2330
|
}
|
|
2490
2331
|
// ===== Hooks =====
|
|
2491
2332
|
processColumns(e) {
|
|
2492
|
-
return this.
|
|
2333
|
+
return this.isApplied = V([...e]), [...e];
|
|
2493
2334
|
}
|
|
2494
2335
|
afterRender() {
|
|
2495
|
-
if (!this.
|
|
2336
|
+
if (!this.isApplied)
|
|
2496
2337
|
return;
|
|
2497
2338
|
const e = this.grid, t = [...this.columns];
|
|
2498
|
-
if (!
|
|
2499
|
-
|
|
2339
|
+
if (!V(t)) {
|
|
2340
|
+
ge(e), this.isApplied = !1;
|
|
2500
2341
|
return;
|
|
2501
2342
|
}
|
|
2502
2343
|
queueMicrotask(() => {
|
|
2503
|
-
|
|
2344
|
+
pe(e, t);
|
|
2504
2345
|
});
|
|
2505
2346
|
}
|
|
2506
2347
|
// ===== Public API =====
|
|
@@ -2509,117 +2350,117 @@ class _t extends y {
|
|
|
2509
2350
|
*/
|
|
2510
2351
|
refreshStickyOffsets() {
|
|
2511
2352
|
const e = [...this.columns];
|
|
2512
|
-
|
|
2353
|
+
pe(this.grid, e);
|
|
2513
2354
|
}
|
|
2514
2355
|
/**
|
|
2515
2356
|
* Get columns pinned to the left.
|
|
2516
2357
|
*/
|
|
2517
2358
|
getLeftPinnedColumns() {
|
|
2518
2359
|
const e = [...this.columns];
|
|
2519
|
-
return
|
|
2360
|
+
return pt(e);
|
|
2520
2361
|
}
|
|
2521
2362
|
/**
|
|
2522
2363
|
* Get columns pinned to the right.
|
|
2523
2364
|
*/
|
|
2524
2365
|
getRightPinnedColumns() {
|
|
2525
2366
|
const e = [...this.columns];
|
|
2526
|
-
return
|
|
2367
|
+
return gt(e);
|
|
2527
2368
|
}
|
|
2528
2369
|
/**
|
|
2529
2370
|
* Clear all sticky positioning.
|
|
2530
2371
|
*/
|
|
2531
2372
|
clearStickyPositions() {
|
|
2532
|
-
|
|
2373
|
+
ge(this.grid);
|
|
2533
2374
|
}
|
|
2534
2375
|
}
|
|
2535
|
-
function
|
|
2376
|
+
function K(s, e) {
|
|
2536
2377
|
const t = document.createElement("div");
|
|
2537
2378
|
t.className = "tbw-pinned-rows", t.setAttribute("role", "status"), t.setAttribute("aria-live", "polite");
|
|
2538
|
-
const n = document.createElement("div");
|
|
2539
|
-
n.className = "tbw-pinned-rows-left";
|
|
2540
2379
|
const o = document.createElement("div");
|
|
2541
|
-
o.className = "tbw-pinned-rows-
|
|
2542
|
-
const
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2380
|
+
o.className = "tbw-pinned-rows-left";
|
|
2381
|
+
const n = document.createElement("div");
|
|
2382
|
+
n.className = "tbw-pinned-rows-center";
|
|
2383
|
+
const i = document.createElement("div");
|
|
2384
|
+
if (i.className = "tbw-pinned-rows-right", s.showRowCount !== !1) {
|
|
2385
|
+
const r = document.createElement("span");
|
|
2386
|
+
r.className = "tbw-status-panel tbw-status-panel-row-count", r.textContent = `Total: ${e.totalRows} rows`, o.appendChild(r);
|
|
2387
|
+
}
|
|
2388
|
+
if (s.showFilteredCount && e.filteredRows !== e.totalRows) {
|
|
2389
|
+
const r = document.createElement("span");
|
|
2390
|
+
r.className = "tbw-status-panel tbw-status-panel-filtered-count", r.textContent = `Filtered: ${e.filteredRows}`, o.appendChild(r);
|
|
2391
|
+
}
|
|
2392
|
+
if (s.showSelectedCount && e.selectedRows > 0) {
|
|
2393
|
+
const r = document.createElement("span");
|
|
2394
|
+
r.className = "tbw-status-panel tbw-status-panel-selected-count", r.textContent = `Selected: ${e.selectedRows}`, i.appendChild(r);
|
|
2395
|
+
}
|
|
2396
|
+
if (s.customPanels)
|
|
2397
|
+
for (const r of s.customPanels) {
|
|
2398
|
+
const l = ft(r, e);
|
|
2399
|
+
switch (r.position) {
|
|
2559
2400
|
case "left":
|
|
2560
|
-
|
|
2401
|
+
o.appendChild(l);
|
|
2561
2402
|
break;
|
|
2562
2403
|
case "center":
|
|
2563
|
-
|
|
2404
|
+
n.appendChild(l);
|
|
2564
2405
|
break;
|
|
2565
2406
|
case "right":
|
|
2566
|
-
|
|
2407
|
+
i.appendChild(l);
|
|
2567
2408
|
break;
|
|
2568
2409
|
}
|
|
2569
2410
|
}
|
|
2570
|
-
return t.appendChild(
|
|
2411
|
+
return t.appendChild(o), t.appendChild(n), t.appendChild(i), t;
|
|
2571
2412
|
}
|
|
2572
|
-
function
|
|
2413
|
+
function fe(s) {
|
|
2573
2414
|
const e = document.createElement("div");
|
|
2574
|
-
return e.className = `tbw-aggregation-rows tbw-aggregation-rows-${
|
|
2575
|
-
}
|
|
2576
|
-
function
|
|
2577
|
-
|
|
2578
|
-
for (const
|
|
2579
|
-
const
|
|
2580
|
-
if (
|
|
2581
|
-
const
|
|
2582
|
-
|
|
2415
|
+
return e.className = `tbw-aggregation-rows tbw-aggregation-rows-${s}`, e.setAttribute("role", "rowgroup"), e;
|
|
2416
|
+
}
|
|
2417
|
+
function me(s, e, t, o) {
|
|
2418
|
+
s.innerHTML = "";
|
|
2419
|
+
for (const n of e) {
|
|
2420
|
+
const i = document.createElement("div");
|
|
2421
|
+
if (i.className = "tbw-aggregation-row", i.setAttribute("role", "row"), n.id && i.setAttribute("data-aggregation-id", n.id), n.fullWidth) {
|
|
2422
|
+
const r = document.createElement("div");
|
|
2423
|
+
r.className = "tbw-aggregation-cell tbw-aggregation-cell-full", r.style.gridColumn = "1 / -1", r.textContent = n.label || "", i.appendChild(r);
|
|
2583
2424
|
} else
|
|
2584
|
-
for (const
|
|
2425
|
+
for (const r of t) {
|
|
2585
2426
|
const l = document.createElement("div");
|
|
2586
|
-
l.className = "tbw-aggregation-cell", l.setAttribute("data-field",
|
|
2427
|
+
l.className = "tbw-aggregation-cell", l.setAttribute("data-field", r.field);
|
|
2587
2428
|
let a;
|
|
2588
|
-
const d =
|
|
2429
|
+
const d = n.aggregators?.[r.field];
|
|
2589
2430
|
if (d) {
|
|
2590
|
-
const c =
|
|
2591
|
-
c && (a = c(
|
|
2592
|
-
} else if (
|
|
2593
|
-
const c =
|
|
2594
|
-
typeof c == "function" ? a = c(
|
|
2431
|
+
const c = _e(d);
|
|
2432
|
+
c && (a = c(o, r.field, r));
|
|
2433
|
+
} else if (n.cells && Object.prototype.hasOwnProperty.call(n.cells, r.field)) {
|
|
2434
|
+
const c = n.cells[r.field];
|
|
2435
|
+
typeof c == "function" ? a = c(o, r.field, r) : a = c;
|
|
2595
2436
|
}
|
|
2596
|
-
l.textContent = a != null ? String(a) : "",
|
|
2437
|
+
l.textContent = a != null ? String(a) : "", i.appendChild(l);
|
|
2597
2438
|
}
|
|
2598
|
-
|
|
2439
|
+
s.appendChild(i);
|
|
2599
2440
|
}
|
|
2600
2441
|
}
|
|
2601
|
-
function
|
|
2442
|
+
function ft(s, e) {
|
|
2602
2443
|
const t = document.createElement("div");
|
|
2603
|
-
t.className = "tbw-status-panel tbw-status-panel-custom", t.id = `status-panel-${
|
|
2604
|
-
const
|
|
2605
|
-
return typeof
|
|
2444
|
+
t.className = "tbw-status-panel tbw-status-panel-custom", t.id = `status-panel-${s.id}`;
|
|
2445
|
+
const o = s.render(e);
|
|
2446
|
+
return typeof o == "string" ? t.innerHTML = o : t.appendChild(o), t;
|
|
2606
2447
|
}
|
|
2607
|
-
function
|
|
2448
|
+
function be(s, e, t, o, n) {
|
|
2608
2449
|
return {
|
|
2609
|
-
totalRows:
|
|
2610
|
-
filteredRows:
|
|
2611
|
-
selectedRows:
|
|
2450
|
+
totalRows: s.length,
|
|
2451
|
+
filteredRows: n?.cachedResult?.length ?? s.length,
|
|
2452
|
+
selectedRows: o?.selected?.size ?? 0,
|
|
2612
2453
|
columns: e,
|
|
2613
|
-
rows:
|
|
2454
|
+
rows: s,
|
|
2614
2455
|
grid: t
|
|
2615
2456
|
};
|
|
2616
2457
|
}
|
|
2617
|
-
|
|
2458
|
+
const mt = ".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-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}";
|
|
2459
|
+
class no extends C {
|
|
2618
2460
|
name = "pinnedRows";
|
|
2619
2461
|
version = "1.0.0";
|
|
2620
2462
|
get defaultConfig() {
|
|
2621
2463
|
return {
|
|
2622
|
-
enabled: !0,
|
|
2623
2464
|
position: "bottom",
|
|
2624
2465
|
showRowCount: !0,
|
|
2625
2466
|
showSelectedCount: !0,
|
|
@@ -2637,49 +2478,45 @@ class Tt extends y {
|
|
|
2637
2478
|
}
|
|
2638
2479
|
// ===== Hooks =====
|
|
2639
2480
|
afterRender() {
|
|
2640
|
-
if (!this.config.enabled) {
|
|
2641
|
-
this.cleanup();
|
|
2642
|
-
return;
|
|
2643
|
-
}
|
|
2644
2481
|
const e = this.shadowRoot;
|
|
2645
2482
|
if (!e) return;
|
|
2646
2483
|
const t = e.querySelector(".tbw-scroll-area") ?? e.querySelector(".tbw-grid-content") ?? e.children[0];
|
|
2647
2484
|
if (!t) return;
|
|
2648
|
-
const
|
|
2485
|
+
const o = this.getSelectionState(), n = this.getFilterState(), i = be(
|
|
2649
2486
|
this.rows,
|
|
2650
2487
|
this.columns,
|
|
2651
2488
|
this.grid,
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
),
|
|
2489
|
+
o,
|
|
2490
|
+
n
|
|
2491
|
+
), r = this.config.aggregationRows || [], l = r.filter((h) => h.position === "top"), a = r.filter((h) => h.position !== "top");
|
|
2655
2492
|
if (l.length > 0) {
|
|
2656
2493
|
if (!this.topAggregationContainer) {
|
|
2657
|
-
this.topAggregationContainer =
|
|
2494
|
+
this.topAggregationContainer = fe("top");
|
|
2658
2495
|
const h = e.querySelector(".header");
|
|
2659
2496
|
h && h.nextSibling ? t.insertBefore(this.topAggregationContainer, h.nextSibling) : t.appendChild(this.topAggregationContainer);
|
|
2660
2497
|
}
|
|
2661
|
-
|
|
2498
|
+
me(
|
|
2662
2499
|
this.topAggregationContainer,
|
|
2663
2500
|
l,
|
|
2664
2501
|
this.visibleColumns,
|
|
2665
2502
|
this.rows
|
|
2666
2503
|
);
|
|
2667
2504
|
} else this.topAggregationContainer && (this.topAggregationContainer.remove(), this.topAggregationContainer = null);
|
|
2668
|
-
const d = this.config.showRowCount !== !1 || this.config.showSelectedCount &&
|
|
2505
|
+
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;
|
|
2669
2506
|
if (d && this.config.position === "top")
|
|
2670
2507
|
if (!this.infoBarElement)
|
|
2671
|
-
this.infoBarElement =
|
|
2508
|
+
this.infoBarElement = K(this.config, i), t.insertBefore(this.infoBarElement, t.firstChild);
|
|
2672
2509
|
else {
|
|
2673
|
-
const h =
|
|
2510
|
+
const h = K(this.config, i);
|
|
2674
2511
|
this.infoBarElement.replaceWith(h), this.infoBarElement = h;
|
|
2675
2512
|
}
|
|
2676
2513
|
else this.config.position === "top" && this.infoBarElement && (this.infoBarElement.remove(), this.infoBarElement = null);
|
|
2677
|
-
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 =
|
|
2514
|
+
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 = fe("bottom")), this.footerWrapper.appendChild(this.bottomAggregationContainer), me(
|
|
2678
2515
|
this.bottomAggregationContainer,
|
|
2679
2516
|
a,
|
|
2680
2517
|
this.visibleColumns,
|
|
2681
2518
|
this.rows
|
|
2682
|
-
)), c && (this.infoBarElement =
|
|
2519
|
+
)), c && (this.infoBarElement = K(this.config, i), this.footerWrapper.appendChild(this.infoBarElement))) : this.cleanupFooter();
|
|
2683
2520
|
}
|
|
2684
2521
|
// ===== Private Methods =====
|
|
2685
2522
|
cleanup() {
|
|
@@ -2715,7 +2552,7 @@ class Tt extends y {
|
|
|
2715
2552
|
*/
|
|
2716
2553
|
getContext() {
|
|
2717
2554
|
const e = this.getSelectionState(), t = this.getFilterState();
|
|
2718
|
-
return
|
|
2555
|
+
return be(
|
|
2719
2556
|
this.rows,
|
|
2720
2557
|
this.columns,
|
|
2721
2558
|
this.grid,
|
|
@@ -2752,223 +2589,490 @@ class Tt extends y {
|
|
|
2752
2589
|
this.config.aggregationRows && (this.config.aggregationRows = this.config.aggregationRows.filter((t) => t.id !== e), this.requestRender());
|
|
2753
2590
|
}
|
|
2754
2591
|
// ===== Styles =====
|
|
2755
|
-
styles =
|
|
2756
|
-
.tbw-footer {
|
|
2757
|
-
position: sticky;
|
|
2758
|
-
bottom: 0;
|
|
2759
|
-
z-index: var(--tbw-z-layer-pinned-rows, 20);
|
|
2760
|
-
background: var(--tbw-color-panel-bg);
|
|
2761
|
-
}
|
|
2762
|
-
|
|
2763
|
-
.tbw-pinned-rows {
|
|
2764
|
-
display: flex;
|
|
2765
|
-
align-items: center;
|
|
2766
|
-
justify-content: space-between;
|
|
2767
|
-
padding: 8px 12px;
|
|
2768
|
-
background: var(--tbw-pinned-rows-bg, var(--tbw-color-panel-bg));
|
|
2769
|
-
border-top: 1px solid var(--tbw-pinned-rows-border, var(--tbw-color-border));
|
|
2770
|
-
font-size: 12px;
|
|
2771
|
-
color: var(--tbw-pinned-rows-color, var(--tbw-color-fg-muted));
|
|
2772
|
-
min-height: 32px;
|
|
2773
|
-
box-sizing: border-box;
|
|
2774
|
-
min-width: fit-content;
|
|
2775
|
-
}
|
|
2776
|
-
.tbw-pinned-rows-left,
|
|
2777
|
-
.tbw-pinned-rows-center,
|
|
2778
|
-
.tbw-pinned-rows-right {
|
|
2779
|
-
display: flex;
|
|
2780
|
-
align-items: center;
|
|
2781
|
-
gap: 16px;
|
|
2782
|
-
}
|
|
2783
|
-
.tbw-pinned-rows-left {
|
|
2784
|
-
justify-content: flex-start;
|
|
2785
|
-
}
|
|
2786
|
-
.tbw-pinned-rows-center {
|
|
2787
|
-
justify-content: center;
|
|
2788
|
-
flex: 1;
|
|
2789
|
-
}
|
|
2790
|
-
.tbw-pinned-rows-right {
|
|
2791
|
-
justify-content: flex-end;
|
|
2792
|
-
}
|
|
2793
|
-
.tbw-status-panel {
|
|
2794
|
-
white-space: nowrap;
|
|
2795
|
-
}
|
|
2796
|
-
|
|
2797
|
-
.tbw-aggregation-rows {
|
|
2798
|
-
min-width: fit-content;
|
|
2799
|
-
background: var(--tbw-aggregation-bg, var(--tbw-color-header-bg));
|
|
2800
|
-
}
|
|
2801
|
-
.tbw-aggregation-rows-top {
|
|
2802
|
-
border-bottom: 1px solid var(--tbw-aggregation-border, var(--tbw-color-border));
|
|
2803
|
-
}
|
|
2804
|
-
.tbw-aggregation-rows-bottom {
|
|
2805
|
-
border-top: 1px solid var(--tbw-aggregation-border, var(--tbw-color-border));
|
|
2806
|
-
}
|
|
2807
|
-
.tbw-aggregation-row {
|
|
2808
|
-
display: grid;
|
|
2809
|
-
grid-template-columns: var(--tbw-column-template);
|
|
2810
|
-
font-weight: var(--tbw-aggregation-font-weight, 600);
|
|
2811
|
-
}
|
|
2812
|
-
.tbw-aggregation-cell {
|
|
2813
|
-
padding: var(--tbw-cell-padding, 2px 8px);
|
|
2814
|
-
min-height: var(--tbw-row-height, 28px);
|
|
2815
|
-
display: flex;
|
|
2816
|
-
align-items: center;
|
|
2817
|
-
border-right: 1px solid var(--tbw-color-border-cell);
|
|
2818
|
-
}
|
|
2819
|
-
.tbw-aggregation-cell:last-child {
|
|
2820
|
-
border-right: 0;
|
|
2821
|
-
}
|
|
2822
|
-
.tbw-aggregation-cell-full {
|
|
2823
|
-
grid-column: 1 / -1;
|
|
2824
|
-
border-right: 0;
|
|
2825
|
-
}
|
|
2826
|
-
`;
|
|
2592
|
+
styles = mt;
|
|
2827
2593
|
}
|
|
2828
|
-
|
|
2594
|
+
const bt = Ie;
|
|
2595
|
+
function wt(s) {
|
|
2829
2596
|
const e = [];
|
|
2830
|
-
return !
|
|
2831
|
-
}
|
|
2832
|
-
function
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
return (e) => e[e.length - 1] ?? 0;
|
|
2848
|
-
default:
|
|
2849
|
-
return (e) => e.reduce((t, n) => t + n, 0);
|
|
2850
|
-
}
|
|
2851
|
-
}
|
|
2852
|
-
function $(i, e) {
|
|
2853
|
-
return [...i, e].join("|");
|
|
2854
|
-
}
|
|
2855
|
-
function rt(i, e) {
|
|
2856
|
-
const t = e.rowGroupFields ?? [], n = e.columnGroupFields ?? [], o = e.valueFields ?? [], r = it(i, n), s = st(i, t), l = lt(s, n, r, o, 0), a = at(l, r, o), d = Object.values(a).reduce((c, u) => c + u, 0);
|
|
2597
|
+
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;
|
|
2598
|
+
}
|
|
2599
|
+
function Z(s, e) {
|
|
2600
|
+
return [...s, e].join("|");
|
|
2601
|
+
}
|
|
2602
|
+
function vt(s, e) {
|
|
2603
|
+
const t = e.rowGroupFields ?? [], o = e.columnGroupFields ?? [], n = e.valueFields ?? [], i = xt(s, o), r = ke(
|
|
2604
|
+
s,
|
|
2605
|
+
t,
|
|
2606
|
+
o,
|
|
2607
|
+
i,
|
|
2608
|
+
n,
|
|
2609
|
+
0,
|
|
2610
|
+
// starting depth
|
|
2611
|
+
""
|
|
2612
|
+
// parent key prefix
|
|
2613
|
+
), l = yt(r, i, n), a = Object.values(l).reduce((d, c) => d + c, 0);
|
|
2857
2614
|
return {
|
|
2858
|
-
rows:
|
|
2859
|
-
columnKeys:
|
|
2860
|
-
totals:
|
|
2861
|
-
grandTotal:
|
|
2615
|
+
rows: r,
|
|
2616
|
+
columnKeys: i,
|
|
2617
|
+
totals: l,
|
|
2618
|
+
grandTotal: a
|
|
2862
2619
|
};
|
|
2863
2620
|
}
|
|
2864
|
-
function
|
|
2621
|
+
function xt(s, e) {
|
|
2865
2622
|
if (e.length === 0) return ["value"];
|
|
2866
2623
|
const t = /* @__PURE__ */ new Set();
|
|
2867
|
-
for (const
|
|
2868
|
-
const
|
|
2869
|
-
t.add(
|
|
2624
|
+
for (const o of s) {
|
|
2625
|
+
const n = e.map((i) => String(o[i] ?? "")).join("|");
|
|
2626
|
+
t.add(n);
|
|
2870
2627
|
}
|
|
2871
2628
|
return [...t].sort();
|
|
2872
2629
|
}
|
|
2873
|
-
function
|
|
2630
|
+
function Ct(s, e) {
|
|
2874
2631
|
const t = /* @__PURE__ */ new Map();
|
|
2875
|
-
for (const
|
|
2876
|
-
const
|
|
2877
|
-
|
|
2878
|
-
const r = t.get(o);
|
|
2879
|
-
r && r.push(n);
|
|
2632
|
+
for (const o of s) {
|
|
2633
|
+
const n = String(o[e] ?? ""), i = t.get(n);
|
|
2634
|
+
i ? i.push(o) : t.set(n, [o]);
|
|
2880
2635
|
}
|
|
2881
2636
|
return t;
|
|
2882
2637
|
}
|
|
2883
|
-
function
|
|
2884
|
-
const
|
|
2885
|
-
|
|
2886
|
-
const
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2638
|
+
function ke(s, e, t, o, n, i, r) {
|
|
2639
|
+
const l = [];
|
|
2640
|
+
if (e.length === 0) {
|
|
2641
|
+
const h = we(s, t, o, n), p = ve(h);
|
|
2642
|
+
return l.push({
|
|
2643
|
+
rowKey: r || "all",
|
|
2644
|
+
rowLabel: r || "All",
|
|
2645
|
+
depth: i,
|
|
2646
|
+
values: h,
|
|
2647
|
+
total: p,
|
|
2648
|
+
isGroup: !1,
|
|
2649
|
+
rowCount: s.length
|
|
2650
|
+
}), l;
|
|
2651
|
+
}
|
|
2652
|
+
const a = e[0], d = e.slice(1), c = d.length > 0, u = Ct(s, a);
|
|
2653
|
+
for (const [h, p] of u) {
|
|
2654
|
+
const g = r ? `${r}|${h}` : h, m = we(p, t, o, n), b = ve(m);
|
|
2655
|
+
let R;
|
|
2656
|
+
c && (R = ke(
|
|
2657
|
+
p,
|
|
2658
|
+
d,
|
|
2659
|
+
t,
|
|
2660
|
+
o,
|
|
2661
|
+
n,
|
|
2662
|
+
i + 1,
|
|
2663
|
+
g
|
|
2664
|
+
)), l.push({
|
|
2665
|
+
rowKey: g,
|
|
2666
|
+
rowLabel: h || "(blank)",
|
|
2667
|
+
depth: i,
|
|
2668
|
+
values: m,
|
|
2669
|
+
total: b,
|
|
2670
|
+
isGroup: c,
|
|
2671
|
+
children: R,
|
|
2672
|
+
rowCount: p.length
|
|
2900
2673
|
});
|
|
2901
2674
|
}
|
|
2902
|
-
return
|
|
2675
|
+
return l;
|
|
2903
2676
|
}
|
|
2904
|
-
function
|
|
2677
|
+
function we(s, e, t, o) {
|
|
2905
2678
|
const n = {};
|
|
2906
|
-
for (const
|
|
2907
|
-
for (const r of
|
|
2908
|
-
const s =
|
|
2909
|
-
n[
|
|
2679
|
+
for (const i of t)
|
|
2680
|
+
for (const r of o) {
|
|
2681
|
+
const a = (e.length > 0 ? s.filter((h) => e.map((p) => String(h[p] ?? "")).join("|") === i) : s).map((h) => Number(h[r.field]) || 0), d = bt(r.aggFunc), c = a.length > 0 ? d(a) : null, u = Z([i], r.field);
|
|
2682
|
+
n[u] = c;
|
|
2910
2683
|
}
|
|
2911
2684
|
return n;
|
|
2912
2685
|
}
|
|
2913
|
-
function
|
|
2686
|
+
function ve(s) {
|
|
2687
|
+
let e = 0;
|
|
2688
|
+
for (const t of Object.values(s))
|
|
2689
|
+
e += t ?? 0;
|
|
2690
|
+
return e;
|
|
2691
|
+
}
|
|
2692
|
+
function yt(s, e, t) {
|
|
2693
|
+
const o = {};
|
|
2694
|
+
function n(i) {
|
|
2695
|
+
for (const r of i)
|
|
2696
|
+
if (!r.isGroup || !r.children?.length)
|
|
2697
|
+
for (const l of e)
|
|
2698
|
+
for (const a of t) {
|
|
2699
|
+
const d = Z([l], a.field);
|
|
2700
|
+
o[d] = (o[d] ?? 0) + (r.values[d] ?? 0);
|
|
2701
|
+
}
|
|
2702
|
+
else r.children && n(r.children);
|
|
2703
|
+
}
|
|
2704
|
+
return n(s), o;
|
|
2705
|
+
}
|
|
2706
|
+
function Rt(s, e, t = !0) {
|
|
2707
|
+
const o = [];
|
|
2708
|
+
function n(i) {
|
|
2709
|
+
o.push(i);
|
|
2710
|
+
const r = e ? e.has(i.rowKey) : t;
|
|
2711
|
+
if (i.children && r)
|
|
2712
|
+
for (const l of i.children)
|
|
2713
|
+
n(l);
|
|
2714
|
+
}
|
|
2715
|
+
for (const i of s)
|
|
2716
|
+
n(i);
|
|
2717
|
+
return o;
|
|
2718
|
+
}
|
|
2719
|
+
function z(s) {
|
|
2914
2720
|
const e = [];
|
|
2915
|
-
function t(
|
|
2916
|
-
if (e.push(
|
|
2917
|
-
for (const
|
|
2918
|
-
t(
|
|
2721
|
+
function t(o) {
|
|
2722
|
+
if (o.isGroup && e.push(o.rowKey), o.children)
|
|
2723
|
+
for (const n of o.children)
|
|
2724
|
+
t(n);
|
|
2919
2725
|
}
|
|
2920
|
-
for (const
|
|
2921
|
-
t(
|
|
2726
|
+
for (const o of s)
|
|
2727
|
+
t(o);
|
|
2922
2728
|
return e;
|
|
2923
2729
|
}
|
|
2924
|
-
|
|
2730
|
+
const St = ["sum", "avg", "count", "min", "max", "first", "last"];
|
|
2731
|
+
function Et(s, e, t, o) {
|
|
2732
|
+
const n = new AbortController(), i = { config: e, callbacks: o, signal: n.signal }, r = document.createElement("div");
|
|
2733
|
+
return r.className = "tbw-pivot-panel", r.appendChild(_("Options", () => Tt(t, i))), r.appendChild(_("Row Groups", () => xe("rowGroups", i))), r.appendChild(_("Column Groups", () => xe("columnGroups", i))), r.appendChild(_("Values", () => At(i))), r.appendChild(_("Available Fields", () => It(i))), s.appendChild(r), () => {
|
|
2734
|
+
n.abort(), r.remove();
|
|
2735
|
+
};
|
|
2736
|
+
}
|
|
2737
|
+
function _(s, e) {
|
|
2738
|
+
const t = document.createElement("div");
|
|
2739
|
+
t.className = "tbw-pivot-section";
|
|
2740
|
+
const o = document.createElement("div");
|
|
2741
|
+
o.className = "tbw-pivot-section-header", o.textContent = s;
|
|
2742
|
+
const n = document.createElement("div");
|
|
2743
|
+
return n.className = "tbw-pivot-section-content", n.appendChild(e()), t.appendChild(o), t.appendChild(n), t;
|
|
2744
|
+
}
|
|
2745
|
+
function xe(s, e) {
|
|
2746
|
+
const { config: t, callbacks: o, signal: n } = e, i = document.createElement("div");
|
|
2747
|
+
i.className = "tbw-pivot-drop-zone", i.setAttribute("data-zone", s);
|
|
2748
|
+
const r = s === "rowGroups" ? t.rowGroupFields ?? [] : t.columnGroupFields ?? [];
|
|
2749
|
+
if (r.length === 0) {
|
|
2750
|
+
const l = document.createElement("div");
|
|
2751
|
+
l.className = "tbw-pivot-placeholder", l.textContent = "Drag fields here or click to add", i.appendChild(l);
|
|
2752
|
+
} else
|
|
2753
|
+
for (const l of r)
|
|
2754
|
+
i.appendChild(kt(l, s, e));
|
|
2755
|
+
return i.addEventListener(
|
|
2756
|
+
"dragover",
|
|
2757
|
+
(l) => {
|
|
2758
|
+
l.preventDefault(), i.classList.add("drag-over");
|
|
2759
|
+
},
|
|
2760
|
+
{ signal: n }
|
|
2761
|
+
), i.addEventListener(
|
|
2762
|
+
"dragleave",
|
|
2763
|
+
() => {
|
|
2764
|
+
i.classList.remove("drag-over");
|
|
2765
|
+
},
|
|
2766
|
+
{ signal: n }
|
|
2767
|
+
), i.addEventListener(
|
|
2768
|
+
"drop",
|
|
2769
|
+
(l) => {
|
|
2770
|
+
l.preventDefault(), i.classList.remove("drag-over");
|
|
2771
|
+
const a = l.dataTransfer?.getData("text/plain");
|
|
2772
|
+
a && o.onAddFieldToZone(a, s);
|
|
2773
|
+
},
|
|
2774
|
+
{ signal: n }
|
|
2775
|
+
), i;
|
|
2776
|
+
}
|
|
2777
|
+
function kt(s, e, t) {
|
|
2778
|
+
const { callbacks: o, signal: n } = t, i = document.createElement("div");
|
|
2779
|
+
i.className = "tbw-pivot-field-chip", i.draggable = !0;
|
|
2780
|
+
const r = o.getAvailableFields().find((d) => d.field === s), l = document.createElement("span");
|
|
2781
|
+
l.className = "tbw-pivot-chip-label", l.textContent = r?.header ?? s;
|
|
2782
|
+
const a = document.createElement("button");
|
|
2783
|
+
return a.className = "tbw-pivot-chip-remove", a.innerHTML = "×", a.title = "Remove field", a.addEventListener(
|
|
2784
|
+
"click",
|
|
2785
|
+
(d) => {
|
|
2786
|
+
d.stopPropagation(), o.onRemoveFieldFromZone(s, e);
|
|
2787
|
+
},
|
|
2788
|
+
{ signal: n }
|
|
2789
|
+
), i.appendChild(l), i.appendChild(a), i.addEventListener(
|
|
2790
|
+
"dragstart",
|
|
2791
|
+
(d) => {
|
|
2792
|
+
d.dataTransfer?.setData("text/plain", s), d.dataTransfer?.setData("source-zone", e), i.classList.add("dragging");
|
|
2793
|
+
},
|
|
2794
|
+
{ signal: n }
|
|
2795
|
+
), i.addEventListener(
|
|
2796
|
+
"dragend",
|
|
2797
|
+
() => {
|
|
2798
|
+
i.classList.remove("dragging");
|
|
2799
|
+
},
|
|
2800
|
+
{ signal: n }
|
|
2801
|
+
), i;
|
|
2802
|
+
}
|
|
2803
|
+
function At(s) {
|
|
2804
|
+
const { config: e, callbacks: t, signal: o } = s, n = document.createElement("div");
|
|
2805
|
+
n.className = "tbw-pivot-drop-zone tbw-pivot-values-zone", n.setAttribute("data-zone", "values");
|
|
2806
|
+
const i = e.valueFields ?? [];
|
|
2807
|
+
if (i.length === 0) {
|
|
2808
|
+
const r = document.createElement("div");
|
|
2809
|
+
r.className = "tbw-pivot-placeholder", r.textContent = "Drag numeric fields here for aggregation", n.appendChild(r);
|
|
2810
|
+
} else
|
|
2811
|
+
for (const r of i)
|
|
2812
|
+
n.appendChild(_t(r, s));
|
|
2813
|
+
return n.addEventListener(
|
|
2814
|
+
"dragover",
|
|
2815
|
+
(r) => {
|
|
2816
|
+
r.preventDefault(), n.classList.add("drag-over");
|
|
2817
|
+
},
|
|
2818
|
+
{ signal: o }
|
|
2819
|
+
), n.addEventListener(
|
|
2820
|
+
"dragleave",
|
|
2821
|
+
() => {
|
|
2822
|
+
n.classList.remove("drag-over");
|
|
2823
|
+
},
|
|
2824
|
+
{ signal: o }
|
|
2825
|
+
), n.addEventListener(
|
|
2826
|
+
"drop",
|
|
2827
|
+
(r) => {
|
|
2828
|
+
r.preventDefault(), n.classList.remove("drag-over");
|
|
2829
|
+
const l = r.dataTransfer?.getData("text/plain");
|
|
2830
|
+
l && t.onAddValueField(l, "sum");
|
|
2831
|
+
},
|
|
2832
|
+
{ signal: o }
|
|
2833
|
+
), n;
|
|
2834
|
+
}
|
|
2835
|
+
function _t(s, e) {
|
|
2836
|
+
const { callbacks: t, signal: o } = e, n = document.createElement("div");
|
|
2837
|
+
n.className = "tbw-pivot-field-chip tbw-pivot-value-chip";
|
|
2838
|
+
const i = t.getAvailableFields().find((c) => c.field === s.field), r = document.createElement("div");
|
|
2839
|
+
r.className = "tbw-pivot-value-label-wrapper";
|
|
2840
|
+
const l = document.createElement("span");
|
|
2841
|
+
l.className = "tbw-pivot-chip-label", l.textContent = i?.header ?? s.field;
|
|
2842
|
+
const a = document.createElement("select");
|
|
2843
|
+
a.className = "tbw-pivot-agg-select", a.title = "Aggregation function";
|
|
2844
|
+
for (const c of St) {
|
|
2845
|
+
const u = document.createElement("option");
|
|
2846
|
+
u.value = c, u.textContent = c.toUpperCase(), u.selected = c === s.aggFunc, a.appendChild(u);
|
|
2847
|
+
}
|
|
2848
|
+
a.addEventListener(
|
|
2849
|
+
"change",
|
|
2850
|
+
() => {
|
|
2851
|
+
t.onUpdateValueAggFunc(s.field, a.value);
|
|
2852
|
+
},
|
|
2853
|
+
{ signal: o }
|
|
2854
|
+
);
|
|
2855
|
+
const d = document.createElement("button");
|
|
2856
|
+
return d.className = "tbw-pivot-chip-remove", d.innerHTML = "×", d.title = "Remove value field", d.addEventListener(
|
|
2857
|
+
"click",
|
|
2858
|
+
(c) => {
|
|
2859
|
+
c.stopPropagation(), t.onRemoveValueField(s.field);
|
|
2860
|
+
},
|
|
2861
|
+
{ signal: o }
|
|
2862
|
+
), r.appendChild(l), r.appendChild(a), n.appendChild(r), n.appendChild(d), n;
|
|
2863
|
+
}
|
|
2864
|
+
function It(s) {
|
|
2865
|
+
const { config: e, callbacks: t, signal: o } = s, n = document.createElement("div");
|
|
2866
|
+
n.className = "tbw-pivot-available-fields";
|
|
2867
|
+
const i = t.getAvailableFields(), r = /* @__PURE__ */ new Set([
|
|
2868
|
+
...e.rowGroupFields ?? [],
|
|
2869
|
+
...e.columnGroupFields ?? [],
|
|
2870
|
+
...e.valueFields?.map((a) => a.field) ?? []
|
|
2871
|
+
]), l = i.filter((a) => !r.has(a.field));
|
|
2872
|
+
if (l.length === 0) {
|
|
2873
|
+
const a = document.createElement("div");
|
|
2874
|
+
a.className = "tbw-pivot-placeholder", a.textContent = "All fields are in use", n.appendChild(a);
|
|
2875
|
+
} else
|
|
2876
|
+
for (const a of l) {
|
|
2877
|
+
const d = document.createElement("div");
|
|
2878
|
+
d.className = "tbw-pivot-field-chip available", d.textContent = a.header, d.draggable = !0, d.title = `Drag to add "${a.field}" to a zone`, d.addEventListener(
|
|
2879
|
+
"dragstart",
|
|
2880
|
+
(c) => {
|
|
2881
|
+
c.dataTransfer?.setData("text/plain", a.field), d.classList.add("dragging");
|
|
2882
|
+
},
|
|
2883
|
+
{ signal: o }
|
|
2884
|
+
), d.addEventListener(
|
|
2885
|
+
"dragend",
|
|
2886
|
+
() => {
|
|
2887
|
+
d.classList.remove("dragging");
|
|
2888
|
+
},
|
|
2889
|
+
{ signal: o }
|
|
2890
|
+
), n.appendChild(d);
|
|
2891
|
+
}
|
|
2892
|
+
return n;
|
|
2893
|
+
}
|
|
2894
|
+
function Tt(s, e) {
|
|
2895
|
+
const { config: t, callbacks: o, signal: n } = e, i = document.createElement("div");
|
|
2896
|
+
return i.className = "tbw-pivot-options", i.appendChild(
|
|
2897
|
+
W(
|
|
2898
|
+
"Enable Pivot View",
|
|
2899
|
+
s,
|
|
2900
|
+
(r) => {
|
|
2901
|
+
o.onTogglePivot(r);
|
|
2902
|
+
},
|
|
2903
|
+
n
|
|
2904
|
+
)
|
|
2905
|
+
), i.appendChild(
|
|
2906
|
+
W(
|
|
2907
|
+
"Show Row Totals",
|
|
2908
|
+
t.showTotals ?? !0,
|
|
2909
|
+
(r) => {
|
|
2910
|
+
o.onOptionChange("showTotals", r);
|
|
2911
|
+
},
|
|
2912
|
+
n
|
|
2913
|
+
)
|
|
2914
|
+
), i.appendChild(
|
|
2915
|
+
W(
|
|
2916
|
+
"Show Grand Total",
|
|
2917
|
+
t.showGrandTotal ?? !0,
|
|
2918
|
+
(r) => {
|
|
2919
|
+
o.onOptionChange("showGrandTotal", r);
|
|
2920
|
+
},
|
|
2921
|
+
n
|
|
2922
|
+
)
|
|
2923
|
+
), i;
|
|
2924
|
+
}
|
|
2925
|
+
function W(s, e, t, o) {
|
|
2926
|
+
const n = document.createElement("label");
|
|
2927
|
+
n.className = "tbw-pivot-checkbox";
|
|
2928
|
+
const i = document.createElement("input");
|
|
2929
|
+
i.type = "checkbox", i.checked = e, i.addEventListener("change", () => t(i.checked), { signal: o });
|
|
2930
|
+
const r = document.createElement("span");
|
|
2931
|
+
return r.textContent = s, n.appendChild(i), n.appendChild(r), n;
|
|
2932
|
+
}
|
|
2933
|
+
function Ft(s, e, t) {
|
|
2934
|
+
return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.setAttribute("role", "row"), e.setAttribute("aria-expanded", String(s.__pivotExpanded)), e.innerHTML = "", t.columns.forEach((o, n) => {
|
|
2935
|
+
const i = document.createElement("div");
|
|
2936
|
+
if (i.className = "cell", i.setAttribute("data-col", String(n)), i.setAttribute("role", "gridcell"), n === 0) {
|
|
2937
|
+
const r = Number(s.__pivotIndent) || 0;
|
|
2938
|
+
i.style.paddingLeft = `${r}px`;
|
|
2939
|
+
const l = String(s.__pivotRowKey), a = document.createElement("button");
|
|
2940
|
+
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) => {
|
|
2941
|
+
u.stopPropagation(), t.onToggle(l);
|
|
2942
|
+
}), i.appendChild(a);
|
|
2943
|
+
const d = document.createElement("span");
|
|
2944
|
+
d.className = "pivot-label", d.textContent = String(s.__pivotLabel ?? ""), i.appendChild(d);
|
|
2945
|
+
const c = document.createElement("span");
|
|
2946
|
+
c.className = "pivot-count", c.textContent = ` (${Number(s.__pivotRowCount) || 0})`, i.appendChild(c);
|
|
2947
|
+
} else {
|
|
2948
|
+
const r = s[o.field];
|
|
2949
|
+
i.textContent = r != null ? String(r) : "";
|
|
2950
|
+
}
|
|
2951
|
+
e.appendChild(i);
|
|
2952
|
+
}), !0;
|
|
2953
|
+
}
|
|
2954
|
+
function Lt(s, e, t) {
|
|
2955
|
+
return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.innerHTML = "", t.forEach((o, n) => {
|
|
2956
|
+
const i = document.createElement("div");
|
|
2957
|
+
if (i.className = "cell", i.setAttribute("data-col", String(n)), i.setAttribute("role", "gridcell"), n === 0) {
|
|
2958
|
+
const r = Number(s.__pivotIndent) || 0;
|
|
2959
|
+
i.style.paddingLeft = `${r + 20}px`;
|
|
2960
|
+
const l = document.createElement("span");
|
|
2961
|
+
l.className = "pivot-label", l.textContent = String(s.__pivotLabel ?? ""), i.appendChild(l);
|
|
2962
|
+
} else {
|
|
2963
|
+
const r = s[o.field];
|
|
2964
|
+
i.textContent = r != null ? String(r) : "";
|
|
2965
|
+
}
|
|
2966
|
+
e.appendChild(i);
|
|
2967
|
+
}), !0;
|
|
2968
|
+
}
|
|
2969
|
+
function Nt(s, e, t) {
|
|
2970
|
+
return e.className = "pivot-grand-total-row", e.setAttribute("role", "row"), e.innerHTML = "", t.forEach((o, n) => {
|
|
2971
|
+
const i = document.createElement("div");
|
|
2972
|
+
if (i.className = "cell", i.setAttribute("data-col", String(n)), i.setAttribute("role", "gridcell"), n === 0) {
|
|
2973
|
+
const r = document.createElement("span");
|
|
2974
|
+
r.className = "pivot-label", r.textContent = "Grand Total", i.appendChild(r);
|
|
2975
|
+
} else {
|
|
2976
|
+
const r = s[o.field];
|
|
2977
|
+
i.textContent = r != null ? String(r) : "";
|
|
2978
|
+
}
|
|
2979
|
+
e.appendChild(i);
|
|
2980
|
+
}), !0;
|
|
2981
|
+
}
|
|
2982
|
+
const Mt = '.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;font-size:10px;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}';
|
|
2983
|
+
class I extends C {
|
|
2925
2984
|
name = "pivot";
|
|
2926
2985
|
version = "1.0.0";
|
|
2986
|
+
/** Tool panel ID for shell integration */
|
|
2987
|
+
static PANEL_ID = "pivot";
|
|
2927
2988
|
get defaultConfig() {
|
|
2928
2989
|
return {
|
|
2929
|
-
|
|
2990
|
+
active: !0,
|
|
2930
2991
|
showTotals: !0,
|
|
2931
2992
|
showGrandTotal: !0
|
|
2932
2993
|
};
|
|
2933
2994
|
}
|
|
2934
2995
|
// ===== Internal State =====
|
|
2935
2996
|
isActive = !1;
|
|
2997
|
+
hasInitialized = !1;
|
|
2936
2998
|
pivotResult = null;
|
|
2937
|
-
|
|
2938
|
-
|
|
2999
|
+
fieldHeaderMap = /* @__PURE__ */ new Map();
|
|
3000
|
+
expandedKeys = /* @__PURE__ */ new Set();
|
|
3001
|
+
defaultExpanded = !0;
|
|
3002
|
+
originalColumns = [];
|
|
3003
|
+
panelContainer = null;
|
|
3004
|
+
grandTotalFooter = null;
|
|
3005
|
+
/**
|
|
3006
|
+
* Check if the plugin has valid pivot configuration (at least value fields).
|
|
3007
|
+
*/
|
|
3008
|
+
hasValidPivotConfig() {
|
|
3009
|
+
return (this.config.valueFields?.length ?? 0) > 0;
|
|
3010
|
+
}
|
|
2939
3011
|
// ===== Lifecycle =====
|
|
2940
3012
|
detach() {
|
|
2941
|
-
this.isActive = !1, this.pivotResult = null, this.
|
|
3013
|
+
this.isActive = !1, this.hasInitialized = !1, this.pivotResult = null, this.fieldHeaderMap.clear(), this.originalColumns = [], this.panelContainer = null, this.cleanupGrandTotalFooter();
|
|
3014
|
+
}
|
|
3015
|
+
// ===== Shell Integration =====
|
|
3016
|
+
getToolPanel() {
|
|
3017
|
+
return {
|
|
3018
|
+
id: I.PANEL_ID,
|
|
3019
|
+
title: "Pivot",
|
|
3020
|
+
icon: "⊞",
|
|
3021
|
+
tooltip: "Configure pivot table",
|
|
3022
|
+
order: 90,
|
|
3023
|
+
render: (e) => this.renderPanel(e)
|
|
3024
|
+
};
|
|
2942
3025
|
}
|
|
2943
3026
|
// ===== Hooks =====
|
|
2944
3027
|
processRows(e) {
|
|
2945
|
-
if (!this.config.
|
|
3028
|
+
if (!this.hasInitialized && this.config.active !== !1 && this.hasValidPivotConfig() && (this.hasInitialized = !0, this.isActive = !0), !this.isActive)
|
|
2946
3029
|
return [...e];
|
|
2947
|
-
const t =
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
3030
|
+
const t = wt(this.config);
|
|
3031
|
+
if (t.length > 0)
|
|
3032
|
+
return this.warn(`Config errors: ${t.join(", ")}`), [...e];
|
|
3033
|
+
if (this.buildFieldHeaderMap(), this.defaultExpanded = this.config.defaultExpanded ?? !0, this.expandedKeys.size === 0 && this.defaultExpanded && this.pivotResult) {
|
|
3034
|
+
const i = z(this.pivotResult.rows);
|
|
3035
|
+
for (const r of i)
|
|
3036
|
+
this.expandedKeys.add(r);
|
|
3037
|
+
}
|
|
3038
|
+
if (this.pivotResult = vt(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded) {
|
|
3039
|
+
const i = z(this.pivotResult.rows);
|
|
3040
|
+
for (const r of i)
|
|
3041
|
+
this.expandedKeys.add(r);
|
|
3042
|
+
}
|
|
3043
|
+
const o = this.config.indentWidth ?? 20;
|
|
3044
|
+
return Rt(
|
|
3045
|
+
this.pivotResult.rows,
|
|
3046
|
+
this.expandedKeys,
|
|
3047
|
+
this.defaultExpanded
|
|
3048
|
+
).map((i) => ({
|
|
3049
|
+
__pivotRowKey: i.rowKey,
|
|
3050
|
+
__pivotLabel: i.rowLabel,
|
|
3051
|
+
__pivotDepth: i.depth,
|
|
3052
|
+
__pivotIsGroup: i.isGroup,
|
|
3053
|
+
__pivotHasChildren: !!i.children?.length,
|
|
3054
|
+
__pivotExpanded: this.expandedKeys.has(i.rowKey),
|
|
3055
|
+
__pivotRowCount: i.rowCount ?? 0,
|
|
3056
|
+
__pivotIndent: i.depth * o,
|
|
3057
|
+
__pivotTotal: i.total,
|
|
3058
|
+
...i.values
|
|
3059
|
+
}));
|
|
2956
3060
|
}
|
|
2957
3061
|
processColumns(e) {
|
|
2958
|
-
if (!this.
|
|
3062
|
+
if (!this.isActive || !this.pivotResult)
|
|
2959
3063
|
return [...e];
|
|
2960
|
-
const t = [];
|
|
3064
|
+
const t = [], o = (this.config.rowGroupFields ?? []).map((n) => this.fieldHeaderMap.get(n) ?? n).join(" / ");
|
|
2961
3065
|
t.push({
|
|
2962
3066
|
field: "__pivotLabel",
|
|
2963
|
-
header:
|
|
3067
|
+
header: o || "Group",
|
|
2964
3068
|
width: 200
|
|
2965
3069
|
});
|
|
2966
3070
|
for (const n of this.pivotResult.columnKeys)
|
|
2967
|
-
for (const
|
|
2968
|
-
const r =
|
|
3071
|
+
for (const i of this.config.valueFields ?? []) {
|
|
3072
|
+
const r = Z([n], i.field), l = i.header || this.fieldHeaderMap.get(i.field) || i.field;
|
|
2969
3073
|
t.push({
|
|
2970
3074
|
field: r,
|
|
2971
|
-
header: `${n} - ${
|
|
3075
|
+
header: `${n} - ${l} (${i.aggFunc})`,
|
|
2972
3076
|
width: 120,
|
|
2973
3077
|
type: "number"
|
|
2974
3078
|
});
|
|
@@ -2980,85 +3084,207 @@ class Lt extends y {
|
|
|
2980
3084
|
type: "number"
|
|
2981
3085
|
}), t;
|
|
2982
3086
|
}
|
|
2983
|
-
|
|
3087
|
+
renderRow(e, t) {
|
|
3088
|
+
const o = e;
|
|
3089
|
+
return o.__pivotRowKey && o.__pivotHasChildren ? Ft(o, t, {
|
|
3090
|
+
columns: this.gridColumns,
|
|
3091
|
+
onToggle: (n) => this.toggle(n),
|
|
3092
|
+
resolveIcon: (n) => this.resolveIcon(n),
|
|
3093
|
+
setIcon: (n, i) => this.setIcon(n, i)
|
|
3094
|
+
}) : o.__pivotRowKey !== void 0 && this.isActive ? Lt(o, t, this.gridColumns) : (this.cleanupPivotStyling(t), !1);
|
|
3095
|
+
}
|
|
2984
3096
|
/**
|
|
2985
|
-
*
|
|
3097
|
+
* Remove pivot-specific classes, attributes, and inline styles from a row element.
|
|
3098
|
+
* Called when pivot mode is disabled to clean up reused DOM elements.
|
|
3099
|
+
* Clears innerHTML so the grid's default renderer can rebuild the row.
|
|
2986
3100
|
*/
|
|
2987
|
-
|
|
2988
|
-
|
|
3101
|
+
cleanupPivotStyling(e) {
|
|
3102
|
+
(e.classList.contains("pivot-group-row") || e.classList.contains("pivot-leaf-row") || e.classList.contains("pivot-grand-total-row")) && (e.classList.remove("pivot-group-row", "pivot-leaf-row", "pivot-grand-total-row"), e.classList.add("data-grid-row"), e.removeAttribute("data-pivot-depth"), e.innerHTML = "");
|
|
3103
|
+
}
|
|
3104
|
+
afterRender() {
|
|
3105
|
+
this.isActive && this.config.showGrandTotal && this.pivotResult ? this.renderGrandTotalFooter() : this.cleanupGrandTotalFooter();
|
|
2989
3106
|
}
|
|
2990
3107
|
/**
|
|
2991
|
-
*
|
|
3108
|
+
* Render the grand total row as a sticky footer pinned to the bottom.
|
|
2992
3109
|
*/
|
|
2993
|
-
|
|
2994
|
-
|
|
3110
|
+
renderGrandTotalFooter() {
|
|
3111
|
+
if (!this.pivotResult) return;
|
|
3112
|
+
const e = this.shadowRoot;
|
|
3113
|
+
if (!e) return;
|
|
3114
|
+
const t = e.querySelector(".tbw-scroll-area") ?? e.querySelector(".tbw-grid-content") ?? e.children[0];
|
|
3115
|
+
if (!t) return;
|
|
3116
|
+
this.grandTotalFooter || (this.grandTotalFooter = document.createElement("div"), this.grandTotalFooter.className = "pivot-grand-total-footer", t.appendChild(this.grandTotalFooter));
|
|
3117
|
+
const o = {
|
|
3118
|
+
__pivotRowKey: "__grandTotal",
|
|
3119
|
+
__pivotLabel: "Grand Total",
|
|
3120
|
+
__pivotIsGrandTotal: !0,
|
|
3121
|
+
__pivotTotal: this.pivotResult.grandTotal,
|
|
3122
|
+
...this.pivotResult.totals
|
|
3123
|
+
};
|
|
3124
|
+
Nt(o, this.grandTotalFooter, this.gridColumns);
|
|
2995
3125
|
}
|
|
2996
3126
|
/**
|
|
2997
|
-
*
|
|
3127
|
+
* Remove the grand total footer element.
|
|
2998
3128
|
*/
|
|
3129
|
+
cleanupGrandTotalFooter() {
|
|
3130
|
+
this.grandTotalFooter && (this.grandTotalFooter.remove(), this.grandTotalFooter = null);
|
|
3131
|
+
}
|
|
3132
|
+
// ===== Expand/Collapse API =====
|
|
3133
|
+
toggle(e) {
|
|
3134
|
+
this.expandedKeys.has(e) ? this.expandedKeys.delete(e) : this.expandedKeys.add(e), this.requestRender();
|
|
3135
|
+
}
|
|
3136
|
+
expand(e) {
|
|
3137
|
+
this.expandedKeys.add(e), this.requestRender();
|
|
3138
|
+
}
|
|
3139
|
+
collapse(e) {
|
|
3140
|
+
this.expandedKeys.delete(e), this.requestRender();
|
|
3141
|
+
}
|
|
3142
|
+
expandAll() {
|
|
3143
|
+
if (this.pivotResult) {
|
|
3144
|
+
const e = z(this.pivotResult.rows);
|
|
3145
|
+
for (const t of e)
|
|
3146
|
+
this.expandedKeys.add(t);
|
|
3147
|
+
this.requestRender();
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
collapseAll() {
|
|
3151
|
+
this.expandedKeys.clear(), this.requestRender();
|
|
3152
|
+
}
|
|
3153
|
+
isExpanded(e) {
|
|
3154
|
+
return this.expandedKeys.has(e);
|
|
3155
|
+
}
|
|
3156
|
+
// ===== Public API =====
|
|
3157
|
+
enablePivot() {
|
|
3158
|
+
this.originalColumns.length === 0 && this.captureOriginalColumns(), this.isActive = !0, this.requestRender();
|
|
3159
|
+
}
|
|
3160
|
+
disablePivot() {
|
|
3161
|
+
this.isActive = !1, this.pivotResult = null, this.requestRender();
|
|
3162
|
+
}
|
|
2999
3163
|
isPivotActive() {
|
|
3000
3164
|
return this.isActive;
|
|
3001
3165
|
}
|
|
3002
|
-
/**
|
|
3003
|
-
* Get the current pivot result.
|
|
3004
|
-
*/
|
|
3005
3166
|
getPivotResult() {
|
|
3006
3167
|
return this.pivotResult;
|
|
3007
3168
|
}
|
|
3008
|
-
/**
|
|
3009
|
-
* Set the row group fields for pivoting.
|
|
3010
|
-
* @param fields - Array of field names to group rows by
|
|
3011
|
-
*/
|
|
3012
3169
|
setRowGroupFields(e) {
|
|
3013
3170
|
this.config.rowGroupFields = e, this.requestRender();
|
|
3014
3171
|
}
|
|
3015
|
-
/**
|
|
3016
|
-
* Set the column group fields for pivoting.
|
|
3017
|
-
* @param fields - Array of field names to create columns from
|
|
3018
|
-
*/
|
|
3019
3172
|
setColumnGroupFields(e) {
|
|
3020
3173
|
this.config.columnGroupFields = e, this.requestRender();
|
|
3021
3174
|
}
|
|
3022
|
-
/**
|
|
3023
|
-
* Set the value fields with aggregation functions.
|
|
3024
|
-
* @param fields - Array of value field configurations
|
|
3025
|
-
*/
|
|
3026
3175
|
setValueFields(e) {
|
|
3027
3176
|
this.config.valueFields = e, this.requestRender();
|
|
3028
3177
|
}
|
|
3029
|
-
/**
|
|
3030
|
-
* Refresh the pivot by clearing cached results.
|
|
3031
|
-
*/
|
|
3032
3178
|
refresh() {
|
|
3033
3179
|
this.pivotResult = null, this.requestRender();
|
|
3034
3180
|
}
|
|
3181
|
+
// ===== Tool Panel API =====
|
|
3182
|
+
showPanel() {
|
|
3183
|
+
this.grid.openToolPanel(I.PANEL_ID);
|
|
3184
|
+
}
|
|
3185
|
+
hidePanel() {
|
|
3186
|
+
this.grid.closeToolPanel();
|
|
3187
|
+
}
|
|
3188
|
+
togglePanel() {
|
|
3189
|
+
this.grid.toggleToolPanel(I.PANEL_ID);
|
|
3190
|
+
}
|
|
3191
|
+
isPanelVisible() {
|
|
3192
|
+
return this.grid.activeToolPanel === I.PANEL_ID;
|
|
3193
|
+
}
|
|
3194
|
+
// ===== Private Helpers =====
|
|
3195
|
+
get gridColumns() {
|
|
3196
|
+
return this.grid.columns ?? [];
|
|
3197
|
+
}
|
|
3198
|
+
buildFieldHeaderMap() {
|
|
3199
|
+
const e = this.getAvailableFields();
|
|
3200
|
+
this.fieldHeaderMap.clear();
|
|
3201
|
+
for (const t of e)
|
|
3202
|
+
this.fieldHeaderMap.set(t.field, t.header);
|
|
3203
|
+
}
|
|
3204
|
+
getAvailableFields() {
|
|
3205
|
+
return this.originalColumns.length > 0 ? this.originalColumns : this.captureOriginalColumns();
|
|
3206
|
+
}
|
|
3207
|
+
captureOriginalColumns() {
|
|
3208
|
+
const e = this.grid;
|
|
3209
|
+
try {
|
|
3210
|
+
const t = e.getAllColumns?.() ?? e.columns ?? [];
|
|
3211
|
+
return this.originalColumns = t.filter((o) => !o.field.startsWith("__pivot")).map((o) => ({
|
|
3212
|
+
field: o.field,
|
|
3213
|
+
header: o.header ?? o.field
|
|
3214
|
+
})), this.originalColumns;
|
|
3215
|
+
} catch {
|
|
3216
|
+
return [];
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
renderPanel(e) {
|
|
3220
|
+
this.panelContainer = e, this.originalColumns.length === 0 && this.captureOriginalColumns();
|
|
3221
|
+
const t = {
|
|
3222
|
+
onTogglePivot: (o) => {
|
|
3223
|
+
o ? this.enablePivot() : this.disablePivot(), this.refreshPanel();
|
|
3224
|
+
},
|
|
3225
|
+
onAddFieldToZone: (o, n) => this.addFieldToZone(o, n),
|
|
3226
|
+
onRemoveFieldFromZone: (o, n) => this.removeFieldFromZone(o, n),
|
|
3227
|
+
onAddValueField: (o, n) => this.addValueField(o, n),
|
|
3228
|
+
onRemoveValueField: (o) => this.removeValueField(o),
|
|
3229
|
+
onUpdateValueAggFunc: (o, n) => this.updateValueAggFunc(o, n),
|
|
3230
|
+
onOptionChange: (o, n) => {
|
|
3231
|
+
this.config[o] = n, this.isActive && this.refresh();
|
|
3232
|
+
},
|
|
3233
|
+
getAvailableFields: () => this.getAvailableFields()
|
|
3234
|
+
};
|
|
3235
|
+
return Et(e, this.config, this.isActive, t);
|
|
3236
|
+
}
|
|
3237
|
+
refreshPanel() {
|
|
3238
|
+
this.panelContainer && (this.panelContainer.innerHTML = "", this.renderPanel(this.panelContainer));
|
|
3239
|
+
}
|
|
3240
|
+
addFieldToZone(e, t) {
|
|
3241
|
+
if (t === "rowGroups") {
|
|
3242
|
+
const o = this.config.rowGroupFields ?? [];
|
|
3243
|
+
o.includes(e) || (this.config.rowGroupFields = [...o, e]);
|
|
3244
|
+
} else {
|
|
3245
|
+
const o = this.config.columnGroupFields ?? [];
|
|
3246
|
+
o.includes(e) || (this.config.columnGroupFields = [...o, e]);
|
|
3247
|
+
}
|
|
3248
|
+
this.removeFromOtherZones(e, t), this.isActive && this.refresh(), this.refreshPanel();
|
|
3249
|
+
}
|
|
3250
|
+
removeFieldFromZone(e, t) {
|
|
3251
|
+
t === "rowGroups" ? this.config.rowGroupFields = (this.config.rowGroupFields ?? []).filter((o) => o !== e) : this.config.columnGroupFields = (this.config.columnGroupFields ?? []).filter((o) => o !== e), this.isActive && this.refresh(), this.refreshPanel();
|
|
3252
|
+
}
|
|
3253
|
+
removeFromOtherZones(e, t) {
|
|
3254
|
+
t !== "rowGroups" && (this.config.rowGroupFields = (this.config.rowGroupFields ?? []).filter((o) => o !== e)), t !== "columnGroups" && (this.config.columnGroupFields = (this.config.columnGroupFields ?? []).filter((o) => o !== e)), t !== "values" && (this.config.valueFields = (this.config.valueFields ?? []).filter((o) => o.field !== e));
|
|
3255
|
+
}
|
|
3256
|
+
addValueField(e, t) {
|
|
3257
|
+
const o = this.config.valueFields ?? [];
|
|
3258
|
+
o.some((n) => n.field === e) || (this.config.valueFields = [...o, { field: e, aggFunc: t }]), this.removeFromOtherZones(e, "values"), this.isActive && this.refresh(), this.refreshPanel();
|
|
3259
|
+
}
|
|
3260
|
+
removeValueField(e) {
|
|
3261
|
+
this.config.valueFields = (this.config.valueFields ?? []).filter((t) => t.field !== e), this.isActive && this.refresh(), this.refreshPanel();
|
|
3262
|
+
}
|
|
3263
|
+
updateValueAggFunc(e, t) {
|
|
3264
|
+
const o = this.config.valueFields ?? [], n = o.findIndex((i) => i.field === e);
|
|
3265
|
+
n >= 0 && (o[n] = { ...o[n], aggFunc: t }, this.config.valueFields = [...o]), this.isActive && this.refresh();
|
|
3266
|
+
}
|
|
3035
3267
|
// ===== Styles =====
|
|
3036
|
-
styles =
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
.pivot-group-row { font-weight: bold; background: var(--tbw-pivot-group-bg, var(--tbw-color-panel-bg)); }
|
|
3041
|
-
.pivot-total-row { font-weight: bold; border-top: 2px solid var(--tbw-pivot-border, var(--tbw-color-border-strong)); }
|
|
3042
|
-
`;
|
|
3043
|
-
}
|
|
3044
|
-
function ct(i) {
|
|
3045
|
-
const e = i.sticky;
|
|
3268
|
+
styles = Mt;
|
|
3269
|
+
}
|
|
3270
|
+
function Pt(s) {
|
|
3271
|
+
const e = s.sticky;
|
|
3046
3272
|
if (e === "left" || e === "right")
|
|
3047
3273
|
return !1;
|
|
3048
|
-
const t =
|
|
3049
|
-
return
|
|
3274
|
+
const t = s.meta ?? {}, o = t.sticky;
|
|
3275
|
+
return o === "left" || o === "right" ? !1 : t.lockPosition !== !0 && t.suppressMovable !== !0;
|
|
3050
3276
|
}
|
|
3051
|
-
function
|
|
3052
|
-
if (e === t || e < 0 || e >=
|
|
3053
|
-
const
|
|
3054
|
-
return
|
|
3277
|
+
function Ce(s, e, t) {
|
|
3278
|
+
if (e === t || e < 0 || e >= s.length || t < 0 || t > s.length) return s;
|
|
3279
|
+
const o = [...s], [n] = o.splice(e, 1);
|
|
3280
|
+
return o.splice(t, 0, n), o;
|
|
3055
3281
|
}
|
|
3056
|
-
|
|
3282
|
+
const Dt = '.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}';
|
|
3283
|
+
class io extends C {
|
|
3057
3284
|
name = "reorder";
|
|
3058
3285
|
version = "1.0.0";
|
|
3059
3286
|
get defaultConfig() {
|
|
3060
3287
|
return {
|
|
3061
|
-
enabled: !0,
|
|
3062
3288
|
animation: !0,
|
|
3063
3289
|
animationDuration: 200
|
|
3064
3290
|
};
|
|
@@ -3073,8 +3299,8 @@ class Mt extends y {
|
|
|
3073
3299
|
super.attach(e), e.addEventListener(
|
|
3074
3300
|
"column-reorder-request",
|
|
3075
3301
|
(t) => {
|
|
3076
|
-
const
|
|
3077
|
-
|
|
3302
|
+
const o = t.detail;
|
|
3303
|
+
o?.field && typeof o.toIndex == "number" && this.moveColumn(o.field, o.toIndex);
|
|
3078
3304
|
},
|
|
3079
3305
|
{ signal: this.disconnectSignal }
|
|
3080
3306
|
);
|
|
@@ -3085,42 +3311,41 @@ class Mt extends y {
|
|
|
3085
3311
|
// ===== Hooks =====
|
|
3086
3312
|
// Note: No processColumns hook needed - we directly update the grid's column order
|
|
3087
3313
|
afterRender() {
|
|
3088
|
-
if (!this.config.enabled) return;
|
|
3089
3314
|
const e = this.shadowRoot;
|
|
3090
3315
|
if (!e) return;
|
|
3091
|
-
e.querySelectorAll(".header-row > .cell").forEach((
|
|
3092
|
-
const
|
|
3093
|
-
if (!
|
|
3094
|
-
const
|
|
3095
|
-
if (!
|
|
3096
|
-
|
|
3316
|
+
e.querySelectorAll(".header-row > .cell").forEach((o) => {
|
|
3317
|
+
const n = o, i = n.getAttribute("data-field");
|
|
3318
|
+
if (!i) return;
|
|
3319
|
+
const r = this.columns.find((l) => l.field === i);
|
|
3320
|
+
if (!r || !Pt(r)) {
|
|
3321
|
+
n.draggable = !1;
|
|
3097
3322
|
return;
|
|
3098
3323
|
}
|
|
3099
|
-
|
|
3100
|
-
const d = this.getColumnOrder().indexOf(
|
|
3101
|
-
this.isDragging = !0, this.draggedField =
|
|
3102
|
-
}),
|
|
3324
|
+
n.draggable = !0, !n.getAttribute("data-dragstart-bound") && (n.setAttribute("data-dragstart-bound", "true"), n.addEventListener("dragstart", (l) => {
|
|
3325
|
+
const d = this.getColumnOrder().indexOf(i);
|
|
3326
|
+
this.isDragging = !0, this.draggedField = i, this.draggedIndex = d, l.dataTransfer && (l.dataTransfer.effectAllowed = "move", l.dataTransfer.setData("text/plain", i)), n.classList.add("dragging");
|
|
3327
|
+
}), n.addEventListener("dragend", () => {
|
|
3103
3328
|
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null, e.querySelectorAll(".header-row > .cell").forEach((l) => {
|
|
3104
3329
|
l.classList.remove("dragging", "drop-target", "drop-before", "drop-after");
|
|
3105
3330
|
});
|
|
3106
|
-
}),
|
|
3107
|
-
if (l.preventDefault(), !this.isDragging || this.draggedField ===
|
|
3108
|
-
const a =
|
|
3109
|
-
this.dropIndex = l.clientX < d ? u : u + 1,
|
|
3110
|
-
}),
|
|
3111
|
-
|
|
3112
|
-
}),
|
|
3331
|
+
}), n.addEventListener("dragover", (l) => {
|
|
3332
|
+
if (l.preventDefault(), !this.isDragging || this.draggedField === i) return;
|
|
3333
|
+
const a = n.getBoundingClientRect(), d = a.left + a.width / 2, u = this.getColumnOrder().indexOf(i);
|
|
3334
|
+
this.dropIndex = l.clientX < d ? u : u + 1, n.classList.add("drop-target"), n.classList.toggle("drop-before", l.clientX < d), n.classList.toggle("drop-after", l.clientX >= d);
|
|
3335
|
+
}), n.addEventListener("dragleave", () => {
|
|
3336
|
+
n.classList.remove("drop-target", "drop-before", "drop-after");
|
|
3337
|
+
}), n.addEventListener("drop", (l) => {
|
|
3113
3338
|
l.preventDefault();
|
|
3114
3339
|
const a = this.draggedField, d = this.draggedIndex, c = this.dropIndex;
|
|
3115
3340
|
if (!this.isDragging || a === null || d === null || c === null)
|
|
3116
3341
|
return;
|
|
3117
|
-
const u = c > d ? c - 1 : c, h = this.getColumnOrder(),
|
|
3342
|
+
const u = c > d ? c - 1 : c, h = this.getColumnOrder(), p = Ce(h, d, u), g = {
|
|
3118
3343
|
field: a,
|
|
3119
3344
|
fromIndex: d,
|
|
3120
3345
|
toIndex: u,
|
|
3121
|
-
columnOrder:
|
|
3346
|
+
columnOrder: p
|
|
3122
3347
|
};
|
|
3123
|
-
this.grid.setColumnOrder(
|
|
3348
|
+
this.grid.setColumnOrder(p), this.emit("column-move", g), this.grid.requestStateChange?.();
|
|
3124
3349
|
}));
|
|
3125
3350
|
});
|
|
3126
3351
|
}
|
|
@@ -3138,14 +3363,14 @@ class Mt extends y {
|
|
|
3138
3363
|
* @param toIndex - The target index
|
|
3139
3364
|
*/
|
|
3140
3365
|
moveColumn(e, t) {
|
|
3141
|
-
const
|
|
3142
|
-
if (
|
|
3143
|
-
const
|
|
3144
|
-
this.grid.setColumnOrder(
|
|
3366
|
+
const o = this.getColumnOrder(), n = o.indexOf(e);
|
|
3367
|
+
if (n === -1) return;
|
|
3368
|
+
const i = Ce(o, n, t);
|
|
3369
|
+
this.grid.setColumnOrder(i), this.emit("column-move", {
|
|
3145
3370
|
field: e,
|
|
3146
|
-
fromIndex:
|
|
3371
|
+
fromIndex: n,
|
|
3147
3372
|
toIndex: t,
|
|
3148
|
-
columnOrder:
|
|
3373
|
+
columnOrder: i
|
|
3149
3374
|
}), this.grid.requestStateChange?.();
|
|
3150
3375
|
}
|
|
3151
3376
|
/**
|
|
@@ -3163,74 +3388,44 @@ class Mt extends y {
|
|
|
3163
3388
|
this.grid.setColumnOrder(e), this.grid.requestStateChange?.();
|
|
3164
3389
|
}
|
|
3165
3390
|
// ===== Styles =====
|
|
3166
|
-
styles =
|
|
3167
|
-
.header-row > .cell[draggable="true"] {
|
|
3168
|
-
cursor: grab;
|
|
3169
|
-
position: relative;
|
|
3170
|
-
}
|
|
3171
|
-
.header-row > .cell.dragging {
|
|
3172
|
-
opacity: 0.5;
|
|
3173
|
-
cursor: grabbing;
|
|
3174
|
-
}
|
|
3175
|
-
.header-row > .cell.drop-before::before {
|
|
3176
|
-
content: '';
|
|
3177
|
-
position: absolute;
|
|
3178
|
-
left: 0;
|
|
3179
|
-
top: 0;
|
|
3180
|
-
bottom: 0;
|
|
3181
|
-
width: 2px;
|
|
3182
|
-
background: var(--tbw-reorder-indicator, var(--tbw-color-accent));
|
|
3183
|
-
z-index: 1;
|
|
3184
|
-
}
|
|
3185
|
-
.header-row > .cell.drop-after::after {
|
|
3186
|
-
content: '';
|
|
3187
|
-
position: absolute;
|
|
3188
|
-
right: 0;
|
|
3189
|
-
top: 0;
|
|
3190
|
-
bottom: 0;
|
|
3191
|
-
width: 2px;
|
|
3192
|
-
background: var(--tbw-reorder-indicator, var(--tbw-color-accent));
|
|
3193
|
-
z-index: 1;
|
|
3194
|
-
}
|
|
3195
|
-
`;
|
|
3391
|
+
styles = Dt;
|
|
3196
3392
|
}
|
|
3197
|
-
function M(
|
|
3198
|
-
return Math.floor(
|
|
3393
|
+
function M(s, e) {
|
|
3394
|
+
return Math.floor(s / e);
|
|
3199
3395
|
}
|
|
3200
|
-
function
|
|
3396
|
+
function qt(s, e) {
|
|
3201
3397
|
return {
|
|
3202
|
-
start:
|
|
3203
|
-
end: (
|
|
3398
|
+
start: s * e,
|
|
3399
|
+
end: (s + 1) * e
|
|
3204
3400
|
};
|
|
3205
3401
|
}
|
|
3206
|
-
function
|
|
3207
|
-
const
|
|
3208
|
-
for (let
|
|
3209
|
-
|
|
3210
|
-
return
|
|
3211
|
-
}
|
|
3212
|
-
async function
|
|
3213
|
-
const
|
|
3214
|
-
return
|
|
3215
|
-
startRow:
|
|
3216
|
-
endRow:
|
|
3217
|
-
sortModel:
|
|
3218
|
-
filterModel:
|
|
3402
|
+
function Ht(s, e, t) {
|
|
3403
|
+
const o = M(s, t), n = M(e - 1, t), i = [];
|
|
3404
|
+
for (let r = o; r <= n; r++)
|
|
3405
|
+
i.push(r);
|
|
3406
|
+
return i;
|
|
3407
|
+
}
|
|
3408
|
+
async function ye(s, e, t, o) {
|
|
3409
|
+
const n = qt(e, t);
|
|
3410
|
+
return s.getRows({
|
|
3411
|
+
startRow: n.start,
|
|
3412
|
+
endRow: n.end,
|
|
3413
|
+
sortModel: o.sortModel,
|
|
3414
|
+
filterModel: o.filterModel
|
|
3219
3415
|
});
|
|
3220
3416
|
}
|
|
3221
|
-
function
|
|
3222
|
-
const
|
|
3223
|
-
if (!
|
|
3224
|
-
const
|
|
3225
|
-
return
|
|
3417
|
+
function Gt(s, e, t) {
|
|
3418
|
+
const o = M(s, e), n = t.get(o);
|
|
3419
|
+
if (!n) return;
|
|
3420
|
+
const i = s % e;
|
|
3421
|
+
return n[i];
|
|
3226
3422
|
}
|
|
3227
|
-
const
|
|
3228
|
-
class
|
|
3423
|
+
const Ot = 100;
|
|
3424
|
+
class ro extends C {
|
|
3229
3425
|
name = "serverSide";
|
|
3230
3426
|
version = "1.0.0";
|
|
3231
3427
|
get defaultConfig() {
|
|
3232
3428
|
return {
|
|
3233
|
-
enabled: !0,
|
|
3234
3429
|
pageSize: 100,
|
|
3235
3430
|
cacheBlockSize: 100,
|
|
3236
3431
|
maxConcurrentRequests: 2
|
|
@@ -3253,15 +3448,15 @@ class qt extends y {
|
|
|
3253
3448
|
*/
|
|
3254
3449
|
loadRequiredBlocks() {
|
|
3255
3450
|
if (!this.dataSource) return;
|
|
3256
|
-
const e = this.grid, t = this.config.cacheBlockSize ?? 100,
|
|
3257
|
-
for (const
|
|
3258
|
-
if (!(this.loadedBlocks.has(
|
|
3451
|
+
const e = this.grid, t = this.config.cacheBlockSize ?? 100, o = { startRow: e.virtualization.start, endRow: e.virtualization.end }, n = Ht(o.startRow, o.endRow, t);
|
|
3452
|
+
for (const i of n)
|
|
3453
|
+
if (!(this.loadedBlocks.has(i) || this.loadingBlocks.has(i))) {
|
|
3259
3454
|
if (this.loadingBlocks.size >= (this.config.maxConcurrentRequests ?? 2))
|
|
3260
3455
|
break;
|
|
3261
|
-
this.loadingBlocks.add(
|
|
3262
|
-
this.loadedBlocks.set(
|
|
3456
|
+
this.loadingBlocks.add(i), ye(this.dataSource, i, t, {}).then((r) => {
|
|
3457
|
+
this.loadedBlocks.set(i, r.rows), this.totalRowCount = r.totalRowCount, this.loadingBlocks.delete(i), this.requestRender(), this.loadRequiredBlocks();
|
|
3263
3458
|
}).catch(() => {
|
|
3264
|
-
this.loadingBlocks.delete(
|
|
3459
|
+
this.loadingBlocks.delete(i);
|
|
3265
3460
|
});
|
|
3266
3461
|
}
|
|
3267
3462
|
}
|
|
@@ -3269,16 +3464,16 @@ class qt extends y {
|
|
|
3269
3464
|
processRows(e) {
|
|
3270
3465
|
if (!this.dataSource) return [...e];
|
|
3271
3466
|
const t = [];
|
|
3272
|
-
for (let
|
|
3273
|
-
const
|
|
3274
|
-
t.push(
|
|
3467
|
+
for (let o = 0; o < this.totalRowCount; o++) {
|
|
3468
|
+
const n = Gt(o, this.config.cacheBlockSize ?? 100, this.loadedBlocks);
|
|
3469
|
+
t.push(n ?? { __loading: !0, __index: o });
|
|
3275
3470
|
}
|
|
3276
3471
|
return t;
|
|
3277
3472
|
}
|
|
3278
3473
|
onScroll(e) {
|
|
3279
3474
|
this.dataSource && (this.loadRequiredBlocks(), this.scrollDebounceTimer && clearTimeout(this.scrollDebounceTimer), this.scrollDebounceTimer = setTimeout(() => {
|
|
3280
3475
|
this.loadRequiredBlocks();
|
|
3281
|
-
},
|
|
3476
|
+
}, Ot));
|
|
3282
3477
|
}
|
|
3283
3478
|
// ===== Public API =====
|
|
3284
3479
|
/**
|
|
@@ -3288,8 +3483,8 @@ class qt extends y {
|
|
|
3288
3483
|
setDataSource(e) {
|
|
3289
3484
|
this.dataSource = e, this.loadedBlocks.clear(), this.loadingBlocks.clear();
|
|
3290
3485
|
const t = this.config.cacheBlockSize ?? 100;
|
|
3291
|
-
|
|
3292
|
-
this.loadedBlocks.set(0,
|
|
3486
|
+
ye(e, 0, t, {}).then((o) => {
|
|
3487
|
+
this.loadedBlocks.set(0, o.rows), this.totalRowCount = o.totalRowCount, this.requestRender();
|
|
3293
3488
|
});
|
|
3294
3489
|
}
|
|
3295
3490
|
/**
|
|
@@ -3315,8 +3510,8 @@ class qt extends y {
|
|
|
3315
3510
|
* @param rowIndex - Row index to check
|
|
3316
3511
|
*/
|
|
3317
3512
|
isRowLoaded(e) {
|
|
3318
|
-
const t = this.config.cacheBlockSize ?? 100,
|
|
3319
|
-
return this.loadedBlocks.has(
|
|
3513
|
+
const t = this.config.cacheBlockSize ?? 100, o = M(e, t);
|
|
3514
|
+
return this.loadedBlocks.has(o);
|
|
3320
3515
|
}
|
|
3321
3516
|
/**
|
|
3322
3517
|
* Get the number of loaded cache blocks.
|
|
@@ -3325,65 +3520,64 @@ class qt extends y {
|
|
|
3325
3520
|
return this.loadedBlocks.size;
|
|
3326
3521
|
}
|
|
3327
3522
|
}
|
|
3328
|
-
function
|
|
3329
|
-
const
|
|
3330
|
-
for (;
|
|
3331
|
-
|
|
3523
|
+
function Bt(s, e, t) {
|
|
3524
|
+
const o = [...s.undoStack, e];
|
|
3525
|
+
for (; o.length > t; )
|
|
3526
|
+
o.shift();
|
|
3332
3527
|
return {
|
|
3333
|
-
undoStack:
|
|
3528
|
+
undoStack: o,
|
|
3334
3529
|
redoStack: []
|
|
3335
3530
|
// Clear redo on new action
|
|
3336
3531
|
};
|
|
3337
3532
|
}
|
|
3338
|
-
function
|
|
3339
|
-
if (
|
|
3340
|
-
return { newState:
|
|
3341
|
-
const e = [...
|
|
3533
|
+
function Re(s) {
|
|
3534
|
+
if (s.undoStack.length === 0)
|
|
3535
|
+
return { newState: s, action: null };
|
|
3536
|
+
const e = [...s.undoStack], t = e.pop();
|
|
3342
3537
|
return t ? {
|
|
3343
3538
|
newState: {
|
|
3344
3539
|
undoStack: e,
|
|
3345
|
-
redoStack: [...
|
|
3540
|
+
redoStack: [...s.redoStack, t]
|
|
3346
3541
|
},
|
|
3347
3542
|
action: t
|
|
3348
|
-
} : { newState:
|
|
3543
|
+
} : { newState: s, action: null };
|
|
3349
3544
|
}
|
|
3350
|
-
function
|
|
3351
|
-
if (
|
|
3352
|
-
return { newState:
|
|
3353
|
-
const e = [...
|
|
3545
|
+
function Se(s) {
|
|
3546
|
+
if (s.redoStack.length === 0)
|
|
3547
|
+
return { newState: s, action: null };
|
|
3548
|
+
const e = [...s.redoStack], t = e.pop();
|
|
3354
3549
|
return t ? {
|
|
3355
3550
|
newState: {
|
|
3356
|
-
undoStack: [...
|
|
3551
|
+
undoStack: [...s.undoStack, t],
|
|
3357
3552
|
redoStack: e
|
|
3358
3553
|
},
|
|
3359
3554
|
action: t
|
|
3360
|
-
} : { newState:
|
|
3555
|
+
} : { newState: s, action: null };
|
|
3361
3556
|
}
|
|
3362
|
-
function
|
|
3363
|
-
return
|
|
3557
|
+
function Vt(s) {
|
|
3558
|
+
return s.undoStack.length > 0;
|
|
3364
3559
|
}
|
|
3365
|
-
function
|
|
3366
|
-
return
|
|
3560
|
+
function Kt(s) {
|
|
3561
|
+
return s.redoStack.length > 0;
|
|
3367
3562
|
}
|
|
3368
|
-
function
|
|
3563
|
+
function zt() {
|
|
3369
3564
|
return { undoStack: [], redoStack: [] };
|
|
3370
3565
|
}
|
|
3371
|
-
function
|
|
3566
|
+
function Wt(s, e, t, o) {
|
|
3372
3567
|
return {
|
|
3373
3568
|
type: "cell-edit",
|
|
3374
|
-
rowIndex:
|
|
3569
|
+
rowIndex: s,
|
|
3375
3570
|
field: e,
|
|
3376
3571
|
oldValue: t,
|
|
3377
|
-
newValue:
|
|
3572
|
+
newValue: o,
|
|
3378
3573
|
timestamp: Date.now()
|
|
3379
3574
|
};
|
|
3380
3575
|
}
|
|
3381
|
-
class
|
|
3576
|
+
class so extends C {
|
|
3382
3577
|
name = "undoRedo";
|
|
3383
3578
|
version = "1.0.0";
|
|
3384
3579
|
get defaultConfig() {
|
|
3385
3580
|
return {
|
|
3386
|
-
enabled: !0,
|
|
3387
3581
|
maxHistorySize: 100
|
|
3388
3582
|
};
|
|
3389
3583
|
}
|
|
@@ -3402,25 +3596,24 @@ class Ft extends y {
|
|
|
3402
3596
|
* - Ctrl+Y / Cmd+Y / Ctrl+Shift+Z / Cmd+Shift+Z: Redo
|
|
3403
3597
|
*/
|
|
3404
3598
|
onKeyDown(e) {
|
|
3405
|
-
|
|
3406
|
-
const t = (e.ctrlKey || e.metaKey) && e.key === "z" && !e.shiftKey, n = (e.ctrlKey || e.metaKey) && (e.key === "y" || e.key === "z" && e.shiftKey);
|
|
3599
|
+
const t = (e.ctrlKey || e.metaKey) && e.key === "z" && !e.shiftKey, o = (e.ctrlKey || e.metaKey) && (e.key === "y" || e.key === "z" && e.shiftKey);
|
|
3407
3600
|
if (t) {
|
|
3408
|
-
const
|
|
3409
|
-
if (
|
|
3410
|
-
const
|
|
3411
|
-
|
|
3412
|
-
action:
|
|
3601
|
+
const n = Re({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
3602
|
+
if (n.action) {
|
|
3603
|
+
const i = this.rows;
|
|
3604
|
+
i[n.action.rowIndex] && (i[n.action.rowIndex][n.action.field] = n.action.oldValue), this.undoStack = n.newState.undoStack, this.redoStack = n.newState.redoStack, this.emit("undo", {
|
|
3605
|
+
action: n.action,
|
|
3413
3606
|
type: "undo"
|
|
3414
3607
|
}), this.requestRender();
|
|
3415
3608
|
}
|
|
3416
3609
|
return !0;
|
|
3417
3610
|
}
|
|
3418
|
-
if (
|
|
3419
|
-
const
|
|
3420
|
-
if (
|
|
3421
|
-
const
|
|
3422
|
-
|
|
3423
|
-
action:
|
|
3611
|
+
if (o) {
|
|
3612
|
+
const n = Se({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
3613
|
+
if (n.action) {
|
|
3614
|
+
const i = this.rows;
|
|
3615
|
+
i[n.action.rowIndex] && (i[n.action.rowIndex][n.action.field] = n.action.newValue), this.undoStack = n.newState.undoStack, this.redoStack = n.newState.redoStack, this.emit("redo", {
|
|
3616
|
+
action: n.action,
|
|
3424
3617
|
type: "redo"
|
|
3425
3618
|
}), this.requestRender();
|
|
3426
3619
|
}
|
|
@@ -3438,13 +3631,13 @@ class Ft extends y {
|
|
|
3438
3631
|
* @param oldValue - The value before the edit
|
|
3439
3632
|
* @param newValue - The value after the edit
|
|
3440
3633
|
*/
|
|
3441
|
-
recordEdit(e, t,
|
|
3442
|
-
const
|
|
3634
|
+
recordEdit(e, t, o, n) {
|
|
3635
|
+
const i = Wt(e, t, o, n), r = Bt(
|
|
3443
3636
|
{ undoStack: this.undoStack, redoStack: this.redoStack },
|
|
3444
|
-
|
|
3637
|
+
i,
|
|
3445
3638
|
this.config.maxHistorySize ?? 100
|
|
3446
3639
|
);
|
|
3447
|
-
this.undoStack =
|
|
3640
|
+
this.undoStack = r.undoStack, this.redoStack = r.redoStack;
|
|
3448
3641
|
}
|
|
3449
3642
|
/**
|
|
3450
3643
|
* Programmatically undo the last action.
|
|
@@ -3452,7 +3645,7 @@ class Ft extends y {
|
|
|
3452
3645
|
* @returns The undone action, or null if nothing to undo
|
|
3453
3646
|
*/
|
|
3454
3647
|
undo() {
|
|
3455
|
-
const e =
|
|
3648
|
+
const e = Re({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
3456
3649
|
if (e.action) {
|
|
3457
3650
|
const t = this.rows;
|
|
3458
3651
|
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();
|
|
@@ -3465,7 +3658,7 @@ class Ft extends y {
|
|
|
3465
3658
|
* @returns The redone action, or null if nothing to redo
|
|
3466
3659
|
*/
|
|
3467
3660
|
redo() {
|
|
3468
|
-
const e =
|
|
3661
|
+
const e = Se({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
3469
3662
|
if (e.action) {
|
|
3470
3663
|
const t = this.rows;
|
|
3471
3664
|
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();
|
|
@@ -3476,19 +3669,19 @@ class Ft extends y {
|
|
|
3476
3669
|
* Check if there are any actions that can be undone.
|
|
3477
3670
|
*/
|
|
3478
3671
|
canUndo() {
|
|
3479
|
-
return
|
|
3672
|
+
return Vt({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
3480
3673
|
}
|
|
3481
3674
|
/**
|
|
3482
3675
|
* Check if there are any actions that can be redone.
|
|
3483
3676
|
*/
|
|
3484
3677
|
canRedo() {
|
|
3485
|
-
return
|
|
3678
|
+
return Kt({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
3486
3679
|
}
|
|
3487
3680
|
/**
|
|
3488
3681
|
* Clear all undo/redo history.
|
|
3489
3682
|
*/
|
|
3490
3683
|
clearHistory() {
|
|
3491
|
-
const e =
|
|
3684
|
+
const e = zt();
|
|
3492
3685
|
this.undoStack = e.undoStack, this.redoStack = e.redoStack;
|
|
3493
3686
|
}
|
|
3494
3687
|
/**
|
|
@@ -3504,18 +3697,18 @@ class Ft extends y {
|
|
|
3504
3697
|
return [...this.redoStack];
|
|
3505
3698
|
}
|
|
3506
3699
|
}
|
|
3507
|
-
|
|
3508
|
-
|
|
3700
|
+
const $t = '.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))}';
|
|
3701
|
+
function Ee(s) {
|
|
3702
|
+
const e = s.meta ?? {};
|
|
3509
3703
|
return e.lockPosition !== !0 && e.suppressMovable !== !0;
|
|
3510
3704
|
}
|
|
3511
|
-
class
|
|
3705
|
+
class T extends C {
|
|
3512
3706
|
name = "visibility";
|
|
3513
3707
|
version = "1.0.0";
|
|
3514
3708
|
/** Tool panel ID for shell integration */
|
|
3515
3709
|
static PANEL_ID = "columns";
|
|
3516
3710
|
get defaultConfig() {
|
|
3517
3711
|
return {
|
|
3518
|
-
enabled: !0,
|
|
3519
3712
|
allowHideAll: !1
|
|
3520
3713
|
};
|
|
3521
3714
|
}
|
|
@@ -3535,23 +3728,22 @@ class I extends y {
|
|
|
3535
3728
|
* Register the column visibility tool panel with the shell.
|
|
3536
3729
|
*/
|
|
3537
3730
|
getToolPanel() {
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
};
|
|
3731
|
+
return {
|
|
3732
|
+
id: T.PANEL_ID,
|
|
3733
|
+
title: "Columns",
|
|
3734
|
+
icon: "☰",
|
|
3735
|
+
tooltip: "Column visibility",
|
|
3736
|
+
order: 100,
|
|
3737
|
+
// High order so it appears last
|
|
3738
|
+
render: (e) => this.renderPanelContent(e)
|
|
3739
|
+
};
|
|
3548
3740
|
}
|
|
3549
3741
|
// ===== Public API =====
|
|
3550
3742
|
/**
|
|
3551
3743
|
* Show the visibility sidebar panel.
|
|
3552
3744
|
*/
|
|
3553
3745
|
show() {
|
|
3554
|
-
this.grid.openToolPanel(
|
|
3746
|
+
this.grid.openToolPanel(T.PANEL_ID);
|
|
3555
3747
|
}
|
|
3556
3748
|
/**
|
|
3557
3749
|
* Hide the visibility sidebar panel.
|
|
@@ -3563,7 +3755,7 @@ class I extends y {
|
|
|
3563
3755
|
* Toggle the visibility sidebar panel.
|
|
3564
3756
|
*/
|
|
3565
3757
|
toggle() {
|
|
3566
|
-
this.grid.toggleToolPanel(
|
|
3758
|
+
this.grid.toggleToolPanel(T.PANEL_ID);
|
|
3567
3759
|
}
|
|
3568
3760
|
/**
|
|
3569
3761
|
* Check if a specific column is visible.
|
|
@@ -3641,7 +3833,7 @@ class I extends y {
|
|
|
3641
3833
|
* @returns True if the panel is open
|
|
3642
3834
|
*/
|
|
3643
3835
|
isPanelVisible() {
|
|
3644
|
-
return this.grid.activeToolPanel ===
|
|
3836
|
+
return this.grid.activeToolPanel === T.PANEL_ID;
|
|
3645
3837
|
}
|
|
3646
3838
|
// ===== Private Methods =====
|
|
3647
3839
|
/**
|
|
@@ -3649,15 +3841,15 @@ class I extends y {
|
|
|
3649
3841
|
* Returns a cleanup function.
|
|
3650
3842
|
*/
|
|
3651
3843
|
renderPanelContent(e) {
|
|
3652
|
-
const t = this.grid,
|
|
3653
|
-
|
|
3654
|
-
const
|
|
3655
|
-
|
|
3656
|
-
const
|
|
3657
|
-
return
|
|
3658
|
-
t.showAllColumns(), this.rebuildToggles(
|
|
3659
|
-
}),
|
|
3660
|
-
this.columnListElement = null,
|
|
3844
|
+
const t = this.grid, o = document.createElement("div");
|
|
3845
|
+
o.className = "tbw-visibility-content";
|
|
3846
|
+
const n = document.createElement("div");
|
|
3847
|
+
n.className = "tbw-visibility-list", o.appendChild(n);
|
|
3848
|
+
const i = document.createElement("button");
|
|
3849
|
+
return i.className = "tbw-visibility-show-all", i.textContent = "Show All", i.addEventListener("click", () => {
|
|
3850
|
+
t.showAllColumns(), this.rebuildToggles(n);
|
|
3851
|
+
}), o.appendChild(i), this.columnListElement = n, this.rebuildToggles(n), e.appendChild(o), () => {
|
|
3852
|
+
this.columnListElement = null, o.remove();
|
|
3661
3853
|
};
|
|
3662
3854
|
}
|
|
3663
3855
|
/**
|
|
@@ -3672,20 +3864,20 @@ class I extends y {
|
|
|
3672
3864
|
* When a reorder plugin is present, adds drag handles for reordering.
|
|
3673
3865
|
*/
|
|
3674
3866
|
rebuildToggles(e) {
|
|
3675
|
-
const t = this.grid,
|
|
3867
|
+
const t = this.grid, o = this.hasReorderPlugin();
|
|
3676
3868
|
e.innerHTML = "";
|
|
3677
|
-
const
|
|
3678
|
-
for (let
|
|
3679
|
-
const
|
|
3680
|
-
a.className =
|
|
3869
|
+
const n = t.getAllColumns();
|
|
3870
|
+
for (let i = 0; i < n.length; i++) {
|
|
3871
|
+
const r = n[i], l = r.header || r.field, a = document.createElement("div");
|
|
3872
|
+
a.className = r.lockVisible ? "tbw-visibility-row locked" : "tbw-visibility-row", a.setAttribute("data-field", r.field), a.setAttribute("data-index", String(i)), o && Ee(r) && (a.draggable = !0, a.classList.add("reorderable"), this.setupDragListeners(a, r.field, i, e));
|
|
3681
3873
|
const d = document.createElement("label");
|
|
3682
3874
|
d.className = "tbw-visibility-label";
|
|
3683
3875
|
const c = document.createElement("input");
|
|
3684
|
-
c.type = "checkbox", c.checked =
|
|
3685
|
-
t.toggleColumnVisibility(
|
|
3876
|
+
c.type = "checkbox", c.checked = r.visible, c.disabled = r.lockVisible ?? !1, c.addEventListener("change", () => {
|
|
3877
|
+
t.toggleColumnVisibility(r.field), setTimeout(() => this.rebuildToggles(e), 0);
|
|
3686
3878
|
});
|
|
3687
3879
|
const u = document.createElement("span");
|
|
3688
|
-
if (u.textContent = l, d.appendChild(c), d.appendChild(u),
|
|
3880
|
+
if (u.textContent = l, d.appendChild(c), d.appendChild(u), o && Ee(r)) {
|
|
3689
3881
|
const h = document.createElement("span");
|
|
3690
3882
|
h.className = "tbw-visibility-handle", this.setIcon(h, this.resolveIcon("dragHandle")), h.title = "Drag to reorder", a.appendChild(h);
|
|
3691
3883
|
}
|
|
@@ -3696,170 +3888,80 @@ class I extends y {
|
|
|
3696
3888
|
* Set up drag-and-drop event listeners for a row.
|
|
3697
3889
|
* On drop, emits a 'column-reorder-request' event for other plugins to handle.
|
|
3698
3890
|
*/
|
|
3699
|
-
setupDragListeners(e, t,
|
|
3700
|
-
e.addEventListener("dragstart", (
|
|
3701
|
-
this.isDragging = !0, this.draggedField = t, this.draggedIndex =
|
|
3891
|
+
setupDragListeners(e, t, o, n) {
|
|
3892
|
+
e.addEventListener("dragstart", (i) => {
|
|
3893
|
+
this.isDragging = !0, this.draggedField = t, this.draggedIndex = o, i.dataTransfer && (i.dataTransfer.effectAllowed = "move", i.dataTransfer.setData("text/plain", t)), e.classList.add("dragging");
|
|
3702
3894
|
}), e.addEventListener("dragend", () => {
|
|
3703
|
-
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null,
|
|
3704
|
-
|
|
3895
|
+
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null, n.querySelectorAll(".tbw-visibility-row").forEach((i) => {
|
|
3896
|
+
i.classList.remove("dragging", "drop-target", "drop-before", "drop-after");
|
|
3705
3897
|
});
|
|
3706
|
-
}), e.addEventListener("dragover", (
|
|
3707
|
-
if (
|
|
3708
|
-
const
|
|
3709
|
-
this.dropIndex =
|
|
3898
|
+
}), e.addEventListener("dragover", (i) => {
|
|
3899
|
+
if (i.preventDefault(), !this.isDragging || this.draggedField === t) return;
|
|
3900
|
+
const r = e.getBoundingClientRect(), l = r.top + r.height / 2;
|
|
3901
|
+
this.dropIndex = i.clientY < l ? o : o + 1, n.querySelectorAll(".tbw-visibility-row").forEach((a) => {
|
|
3710
3902
|
a !== e && a.classList.remove("drop-target", "drop-before", "drop-after");
|
|
3711
|
-
}), e.classList.add("drop-target"), e.classList.toggle("drop-before",
|
|
3903
|
+
}), e.classList.add("drop-target"), e.classList.toggle("drop-before", i.clientY < l), e.classList.toggle("drop-after", i.clientY >= l);
|
|
3712
3904
|
}), e.addEventListener("dragleave", () => {
|
|
3713
3905
|
e.classList.remove("drop-target", "drop-before", "drop-after");
|
|
3714
|
-
}), e.addEventListener("drop", (
|
|
3715
|
-
|
|
3716
|
-
const
|
|
3717
|
-
if (!this.isDragging ||
|
|
3906
|
+
}), e.addEventListener("drop", (i) => {
|
|
3907
|
+
i.preventDefault();
|
|
3908
|
+
const r = this.draggedField, l = this.draggedIndex, a = this.dropIndex;
|
|
3909
|
+
if (!this.isDragging || r === null || l === null || a === null)
|
|
3718
3910
|
return;
|
|
3719
3911
|
const d = a > l ? a - 1 : a;
|
|
3720
3912
|
if (d !== l) {
|
|
3721
3913
|
const c = {
|
|
3722
|
-
field:
|
|
3914
|
+
field: r,
|
|
3723
3915
|
fromIndex: l,
|
|
3724
3916
|
toIndex: d
|
|
3725
3917
|
};
|
|
3726
3918
|
this.emit("column-reorder-request", c), setTimeout(() => {
|
|
3727
|
-
this.rebuildToggles(
|
|
3919
|
+
this.rebuildToggles(n);
|
|
3728
3920
|
}, 0);
|
|
3729
3921
|
}
|
|
3730
3922
|
});
|
|
3731
3923
|
}
|
|
3732
3924
|
// ===== Styles =====
|
|
3733
|
-
styles =
|
|
3734
|
-
.tbw-visibility-content {
|
|
3735
|
-
display: flex;
|
|
3736
|
-
flex-direction: column;
|
|
3737
|
-
height: 100%;
|
|
3738
|
-
}
|
|
3739
|
-
|
|
3740
|
-
.tbw-visibility-list {
|
|
3741
|
-
flex: 1;
|
|
3742
|
-
overflow-y: auto;
|
|
3743
|
-
padding: 8px;
|
|
3744
|
-
}
|
|
3745
|
-
|
|
3746
|
-
.tbw-visibility-row {
|
|
3747
|
-
display: flex;
|
|
3748
|
-
align-items: center;
|
|
3749
|
-
gap: 8px;
|
|
3750
|
-
padding: 6px 4px;
|
|
3751
|
-
cursor: pointer;
|
|
3752
|
-
font-size: 13px;
|
|
3753
|
-
border-radius: var(--tbw-border-radius, 4px);
|
|
3754
|
-
position: relative;
|
|
3755
|
-
}
|
|
3756
|
-
.tbw-visibility-row:hover {
|
|
3757
|
-
background: var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6));
|
|
3758
|
-
}
|
|
3759
|
-
.tbw-visibility-row input[type="checkbox"] {
|
|
3760
|
-
cursor: pointer;
|
|
3761
|
-
}
|
|
3762
|
-
.tbw-visibility-row.locked span {
|
|
3763
|
-
color: var(--tbw-color-fg-muted, #888);
|
|
3764
|
-
}
|
|
3765
|
-
|
|
3766
|
-
/* Drag handle */
|
|
3767
|
-
.tbw-visibility-handle {
|
|
3768
|
-
cursor: grab;
|
|
3769
|
-
color: var(--tbw-color-fg-muted, #888);
|
|
3770
|
-
font-size: 10px;
|
|
3771
|
-
letter-spacing: -2px;
|
|
3772
|
-
user-select: none;
|
|
3773
|
-
flex-shrink: 0;
|
|
3774
|
-
}
|
|
3775
|
-
.tbw-visibility-row.reorderable:hover .tbw-visibility-handle {
|
|
3776
|
-
color: var(--tbw-color-fg, #1f2937);
|
|
3777
|
-
}
|
|
3778
|
-
|
|
3779
|
-
/* Label wrapper for checkbox and text */
|
|
3780
|
-
.tbw-visibility-label {
|
|
3781
|
-
display: flex;
|
|
3782
|
-
align-items: center;
|
|
3783
|
-
gap: 8px;
|
|
3784
|
-
flex: 1;
|
|
3785
|
-
cursor: pointer;
|
|
3786
|
-
}
|
|
3787
|
-
|
|
3788
|
-
/* Drag states */
|
|
3789
|
-
.tbw-visibility-row.dragging {
|
|
3790
|
-
opacity: 0.5;
|
|
3791
|
-
cursor: grabbing;
|
|
3792
|
-
}
|
|
3793
|
-
.tbw-visibility-row.drop-before::before {
|
|
3794
|
-
content: '';
|
|
3795
|
-
position: absolute;
|
|
3796
|
-
left: 0;
|
|
3797
|
-
right: 0;
|
|
3798
|
-
top: 0;
|
|
3799
|
-
height: 2px;
|
|
3800
|
-
background: var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6));
|
|
3801
|
-
}
|
|
3802
|
-
.tbw-visibility-row.drop-after::after {
|
|
3803
|
-
content: '';
|
|
3804
|
-
position: absolute;
|
|
3805
|
-
left: 0;
|
|
3806
|
-
right: 0;
|
|
3807
|
-
bottom: 0;
|
|
3808
|
-
height: 2px;
|
|
3809
|
-
background: var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6));
|
|
3810
|
-
}
|
|
3811
|
-
|
|
3812
|
-
.tbw-visibility-show-all {
|
|
3813
|
-
margin: 8px;
|
|
3814
|
-
padding: 8px 12px;
|
|
3815
|
-
border: 1px solid var(--tbw-visibility-border, var(--tbw-color-border, #e5e7eb));
|
|
3816
|
-
border-radius: var(--tbw-border-radius, 4px);
|
|
3817
|
-
background: var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg, #f9fafb));
|
|
3818
|
-
color: var(--tbw-color-fg, #1f2937);
|
|
3819
|
-
cursor: pointer;
|
|
3820
|
-
font-size: 13px;
|
|
3821
|
-
}
|
|
3822
|
-
.tbw-visibility-show-all:hover {
|
|
3823
|
-
background: var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6));
|
|
3824
|
-
}
|
|
3825
|
-
`;
|
|
3925
|
+
styles = $t;
|
|
3826
3926
|
}
|
|
3827
3927
|
export {
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3928
|
+
C as BaseGridPlugin,
|
|
3929
|
+
Ut as ClipboardPlugin,
|
|
3930
|
+
Yt as ColumnVirtualizationPlugin,
|
|
3931
|
+
Zt as ContextMenuPlugin,
|
|
3932
|
+
Ae as DEFAULT_GRID_ICONS,
|
|
3933
|
+
co as DGEvents,
|
|
3934
|
+
uo as DataGridElement,
|
|
3935
|
+
Xt as ExportPlugin,
|
|
3936
|
+
k as FilteringPlugin,
|
|
3937
|
+
ho as FitModeEnum,
|
|
3938
|
+
po as GridCSSVars,
|
|
3939
|
+
go as GridClasses,
|
|
3940
|
+
fo as GridDataAttrs,
|
|
3941
|
+
mo as GridElement,
|
|
3942
|
+
bo as GridSelectors,
|
|
3943
|
+
Jt as GroupingColumnsPlugin,
|
|
3944
|
+
Qt as GroupingRowsPlugin,
|
|
3945
|
+
eo as MasterDetailPlugin,
|
|
3946
|
+
to as MultiSortPlugin,
|
|
3947
|
+
oo as PinnedColumnsPlugin,
|
|
3948
|
+
no as PinnedRowsPlugin,
|
|
3949
|
+
I as PivotPlugin,
|
|
3950
|
+
wo as PluginEvents,
|
|
3951
|
+
vo as PluginManager,
|
|
3952
|
+
io as ReorderPlugin,
|
|
3953
|
+
xo as SelectionPlugin,
|
|
3954
|
+
ro as ServerSidePlugin,
|
|
3955
|
+
Co as TreePlugin,
|
|
3956
|
+
so as UndoRedoPlugin,
|
|
3957
|
+
T as VisibilityPlugin,
|
|
3958
|
+
yo as aggregatorRegistry,
|
|
3959
|
+
_e as getAggregator,
|
|
3960
|
+
Ie as getValueAggregator,
|
|
3961
|
+
Ro as listAggregators,
|
|
3962
|
+
So as registerAggregator,
|
|
3963
|
+
ee as runAggregator,
|
|
3964
|
+
Eo as runValueAggregator,
|
|
3965
|
+
ko as unregisterAggregator
|
|
3864
3966
|
};
|
|
3865
3967
|
//# sourceMappingURL=all.js.map
|