@toolbox-web/grid 0.2.6 → 0.2.8
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 +434 -61
- package/all.js +844 -541
- package/all.js.map +1 -1
- package/index-YjW60MHD.js +3235 -0
- package/index-YjW60MHD.js.map +1 -0
- package/index.d.ts +210 -6
- package/index.js +25 -3194
- package/index.js.map +1 -1
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +183 -148
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js +116 -82
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +139 -81
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +17 -17
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +369 -337
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/reorder/index.js +264 -91
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/index.js +180 -169
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +21 -21
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +12 -12
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +1 -1
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const E = {
|
|
2
2
|
expand: "▶",
|
|
3
3
|
collapse: "▼",
|
|
4
4
|
sortAsc: "▲",
|
|
@@ -8,7 +8,7 @@ const P = {
|
|
|
8
8
|
dragHandle: "⋮⋮",
|
|
9
9
|
toolPanel: "☰"
|
|
10
10
|
};
|
|
11
|
-
class
|
|
11
|
+
class P {
|
|
12
12
|
/** Plugin version - override in subclass if needed */
|
|
13
13
|
version = "1.0.0";
|
|
14
14
|
/** CSS styles to inject into the grid's shadow DOM */
|
|
@@ -59,8 +59,8 @@ class N {
|
|
|
59
59
|
/**
|
|
60
60
|
* Emit a custom event from the grid.
|
|
61
61
|
*/
|
|
62
|
-
emit(e,
|
|
63
|
-
this.grid?.dispatchEvent?.(new CustomEvent(e, { detail:
|
|
62
|
+
emit(e, t) {
|
|
63
|
+
this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: t, bubbles: !0 }));
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
66
|
* Request a re-render of the grid.
|
|
@@ -133,7 +133,7 @@ class N {
|
|
|
133
133
|
*/
|
|
134
134
|
get gridIcons() {
|
|
135
135
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
136
|
-
return { ...
|
|
136
|
+
return { ...E, ...e };
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
139
139
|
* Resolve an icon value to string or HTMLElement.
|
|
@@ -143,8 +143,8 @@ class N {
|
|
|
143
143
|
* @param pluginOverride - Optional plugin-level override
|
|
144
144
|
* @returns The resolved icon value
|
|
145
145
|
*/
|
|
146
|
-
resolveIcon(e,
|
|
147
|
-
return
|
|
146
|
+
resolveIcon(e, t) {
|
|
147
|
+
return t !== void 0 ? t : this.gridIcons[e];
|
|
148
148
|
}
|
|
149
149
|
/**
|
|
150
150
|
* Set an icon value on an element.
|
|
@@ -153,8 +153,8 @@ class N {
|
|
|
153
153
|
* @param element - The element to set the icon on
|
|
154
154
|
* @param icon - The icon value (string or HTMLElement)
|
|
155
155
|
*/
|
|
156
|
-
setIcon(e,
|
|
157
|
-
typeof
|
|
156
|
+
setIcon(e, t) {
|
|
157
|
+
typeof t == "string" ? e.innerHTML = t : t instanceof HTMLElement && (e.innerHTML = "", e.appendChild(t.cloneNode(!0)));
|
|
158
158
|
}
|
|
159
159
|
/**
|
|
160
160
|
* Log a warning message.
|
|
@@ -165,48 +165,48 @@ class N {
|
|
|
165
165
|
// #endregion
|
|
166
166
|
}
|
|
167
167
|
const m = {
|
|
168
|
-
sum: (
|
|
169
|
-
avg: (
|
|
170
|
-
const
|
|
171
|
-
return
|
|
168
|
+
sum: (i, e) => i.reduce((t, o) => t + (Number(o[e]) || 0), 0),
|
|
169
|
+
avg: (i, e) => {
|
|
170
|
+
const t = i.reduce((o, n) => o + (Number(n[e]) || 0), 0);
|
|
171
|
+
return i.length ? t / i.length : 0;
|
|
172
172
|
},
|
|
173
|
-
count: (
|
|
174
|
-
min: (
|
|
175
|
-
max: (
|
|
176
|
-
first: (
|
|
177
|
-
last: (
|
|
173
|
+
count: (i) => i.length,
|
|
174
|
+
min: (i, e) => Math.min(...i.map((t) => Number(t[e]) || 1 / 0)),
|
|
175
|
+
max: (i, e) => Math.max(...i.map((t) => Number(t[e]) || -1 / 0)),
|
|
176
|
+
first: (i, e) => i[0]?.[e],
|
|
177
|
+
last: (i, e) => i[i.length - 1]?.[e]
|
|
178
178
|
}, v = /* @__PURE__ */ new Map(), h = {
|
|
179
179
|
/**
|
|
180
180
|
* Register a custom aggregator function.
|
|
181
181
|
*/
|
|
182
|
-
register(
|
|
183
|
-
v.set(
|
|
182
|
+
register(i, e) {
|
|
183
|
+
v.set(i, e);
|
|
184
184
|
},
|
|
185
185
|
/**
|
|
186
186
|
* Unregister a custom aggregator function.
|
|
187
187
|
*/
|
|
188
|
-
unregister(
|
|
189
|
-
v.delete(
|
|
188
|
+
unregister(i) {
|
|
189
|
+
v.delete(i);
|
|
190
190
|
},
|
|
191
191
|
/**
|
|
192
192
|
* Get an aggregator function by reference.
|
|
193
193
|
*/
|
|
194
|
-
get(
|
|
195
|
-
if (
|
|
196
|
-
return typeof
|
|
194
|
+
get(i) {
|
|
195
|
+
if (i !== void 0)
|
|
196
|
+
return typeof i == "function" ? i : v.get(i) ?? m[i];
|
|
197
197
|
},
|
|
198
198
|
/**
|
|
199
199
|
* Run an aggregator on a set of rows.
|
|
200
200
|
*/
|
|
201
|
-
run(
|
|
202
|
-
const
|
|
203
|
-
return
|
|
201
|
+
run(i, e, t, o) {
|
|
202
|
+
const n = this.get(i);
|
|
203
|
+
return n ? n(e, t, o) : void 0;
|
|
204
204
|
},
|
|
205
205
|
/**
|
|
206
206
|
* Check if an aggregator exists.
|
|
207
207
|
*/
|
|
208
|
-
has(
|
|
209
|
-
return v.has(
|
|
208
|
+
has(i) {
|
|
209
|
+
return v.has(i) || i in m;
|
|
210
210
|
},
|
|
211
211
|
/**
|
|
212
212
|
* List all available aggregator names.
|
|
@@ -215,98 +215,98 @@ const m = {
|
|
|
215
215
|
return [...Object.keys(m), ...v.keys()];
|
|
216
216
|
}
|
|
217
217
|
}, A = {
|
|
218
|
-
sum: (
|
|
219
|
-
avg: (
|
|
220
|
-
count: (
|
|
221
|
-
min: (
|
|
222
|
-
max: (
|
|
223
|
-
first: (
|
|
224
|
-
last: (
|
|
218
|
+
sum: (i) => i.reduce((e, t) => e + t, 0),
|
|
219
|
+
avg: (i) => i.length ? i.reduce((e, t) => e + t, 0) / i.length : 0,
|
|
220
|
+
count: (i) => i.length,
|
|
221
|
+
min: (i) => i.length ? Math.min(...i) : 0,
|
|
222
|
+
max: (i) => i.length ? Math.max(...i) : 0,
|
|
223
|
+
first: (i) => i[0] ?? 0,
|
|
224
|
+
last: (i) => i[i.length - 1] ?? 0
|
|
225
225
|
};
|
|
226
|
-
function
|
|
227
|
-
return A[
|
|
226
|
+
function N(i) {
|
|
227
|
+
return A[i] ?? A.sum;
|
|
228
228
|
}
|
|
229
229
|
h.register.bind(h);
|
|
230
230
|
h.unregister.bind(h);
|
|
231
231
|
h.get.bind(h);
|
|
232
232
|
h.run.bind(h);
|
|
233
233
|
h.list.bind(h);
|
|
234
|
-
const K =
|
|
235
|
-
function
|
|
234
|
+
const K = N;
|
|
235
|
+
function S(i) {
|
|
236
236
|
const e = [];
|
|
237
|
-
return !
|
|
237
|
+
return !i.rowGroupFields?.length && !i.columnGroupFields?.length && e.push("At least one row or column group field is required"), i.valueFields?.length || e.push("At least one value field is required"), e;
|
|
238
238
|
}
|
|
239
|
-
function C(
|
|
240
|
-
return [...
|
|
239
|
+
function C(i, e) {
|
|
240
|
+
return [...i, e].join("|");
|
|
241
241
|
}
|
|
242
|
-
function
|
|
243
|
-
const
|
|
242
|
+
function I(i, e) {
|
|
243
|
+
const t = e.rowGroupFields ?? [], o = e.columnGroupFields ?? [], n = e.valueFields ?? [], r = V(i, o), s = L(
|
|
244
|
+
i,
|
|
244
245
|
t,
|
|
245
246
|
o,
|
|
246
|
-
i,
|
|
247
|
-
n,
|
|
248
247
|
r,
|
|
248
|
+
n,
|
|
249
249
|
0,
|
|
250
250
|
// starting depth
|
|
251
251
|
""
|
|
252
252
|
// parent key prefix
|
|
253
|
-
), a =
|
|
253
|
+
), a = D(s, r, n), l = Object.values(a).reduce((d, c) => d + c, 0);
|
|
254
254
|
return {
|
|
255
255
|
rows: s,
|
|
256
|
-
columnKeys:
|
|
256
|
+
columnKeys: r,
|
|
257
257
|
totals: a,
|
|
258
258
|
grandTotal: l
|
|
259
259
|
};
|
|
260
260
|
}
|
|
261
|
-
function V(
|
|
261
|
+
function V(i, e) {
|
|
262
262
|
if (e.length === 0) return ["value"];
|
|
263
|
-
const
|
|
264
|
-
for (const
|
|
265
|
-
const
|
|
266
|
-
|
|
263
|
+
const t = /* @__PURE__ */ new Set();
|
|
264
|
+
for (const o of i) {
|
|
265
|
+
const n = e.map((r) => String(o[r] ?? "")).join("|");
|
|
266
|
+
t.add(n);
|
|
267
267
|
}
|
|
268
|
-
return [...
|
|
268
|
+
return [...t].sort();
|
|
269
269
|
}
|
|
270
|
-
function M(
|
|
271
|
-
const
|
|
272
|
-
for (const
|
|
273
|
-
const
|
|
274
|
-
|
|
270
|
+
function M(i, e) {
|
|
271
|
+
const t = /* @__PURE__ */ new Map();
|
|
272
|
+
for (const o of i) {
|
|
273
|
+
const n = String(o[e] ?? ""), r = t.get(n);
|
|
274
|
+
r ? r.push(o) : t.set(n, [o]);
|
|
275
275
|
}
|
|
276
|
-
return
|
|
276
|
+
return t;
|
|
277
277
|
}
|
|
278
|
-
function L(
|
|
278
|
+
function L(i, e, t, o, n, r, s) {
|
|
279
279
|
const a = [];
|
|
280
280
|
if (e.length === 0) {
|
|
281
|
-
const u = T(t, o,
|
|
281
|
+
const u = T(i, t, o, n), g = _(u);
|
|
282
282
|
return a.push({
|
|
283
283
|
rowKey: s || "all",
|
|
284
284
|
rowLabel: s || "All",
|
|
285
|
-
depth:
|
|
285
|
+
depth: r,
|
|
286
286
|
values: u,
|
|
287
287
|
total: g,
|
|
288
288
|
isGroup: !1,
|
|
289
|
-
rowCount:
|
|
289
|
+
rowCount: i.length
|
|
290
290
|
}), a;
|
|
291
291
|
}
|
|
292
|
-
const l = e[0], d = e.slice(1), c = d.length > 0, p = M(
|
|
292
|
+
const l = e[0], d = e.slice(1), c = d.length > 0, p = M(i, l);
|
|
293
293
|
for (const [u, g] of p) {
|
|
294
|
-
const
|
|
294
|
+
const y = s ? `${s}|${u}` : u, F = T(g, t, o, n), k = _(F);
|
|
295
295
|
let R;
|
|
296
296
|
c && (R = L(
|
|
297
297
|
g,
|
|
298
298
|
d,
|
|
299
|
+
t,
|
|
299
300
|
o,
|
|
300
|
-
|
|
301
|
-
r,
|
|
302
|
-
|
|
303
|
-
F
|
|
301
|
+
n,
|
|
302
|
+
r + 1,
|
|
303
|
+
y
|
|
304
304
|
)), a.push({
|
|
305
|
-
rowKey:
|
|
305
|
+
rowKey: y,
|
|
306
306
|
rowLabel: u || "(blank)",
|
|
307
|
-
depth:
|
|
308
|
-
values:
|
|
309
|
-
total:
|
|
307
|
+
depth: r,
|
|
308
|
+
values: F,
|
|
309
|
+
total: k,
|
|
310
310
|
isGroup: c,
|
|
311
311
|
children: R,
|
|
312
312
|
rowCount: g.length
|
|
@@ -314,204 +314,204 @@ function L(t, e, o, i, r, n, s) {
|
|
|
314
314
|
}
|
|
315
315
|
return a;
|
|
316
316
|
}
|
|
317
|
-
function T(
|
|
318
|
-
const
|
|
319
|
-
for (const
|
|
320
|
-
for (const s of
|
|
321
|
-
const l = (e.length > 0 ?
|
|
322
|
-
|
|
317
|
+
function T(i, e, t, o) {
|
|
318
|
+
const n = {};
|
|
319
|
+
for (const r of t)
|
|
320
|
+
for (const s of o) {
|
|
321
|
+
const l = (e.length > 0 ? i.filter((u) => e.map((g) => String(u[g] ?? "")).join("|") === r) : i).map((u) => Number(u[s.field]) || 0), d = K(s.aggFunc), c = l.length > 0 ? d(l) : null, p = C([r], s.field);
|
|
322
|
+
n[p] = c;
|
|
323
323
|
}
|
|
324
|
-
return
|
|
324
|
+
return n;
|
|
325
325
|
}
|
|
326
|
-
function _(
|
|
326
|
+
function _(i) {
|
|
327
327
|
let e = 0;
|
|
328
|
-
for (const
|
|
329
|
-
e +=
|
|
328
|
+
for (const t of Object.values(i))
|
|
329
|
+
e += t ?? 0;
|
|
330
330
|
return e;
|
|
331
331
|
}
|
|
332
|
-
function
|
|
333
|
-
const
|
|
334
|
-
function r
|
|
335
|
-
for (const s of
|
|
332
|
+
function D(i, e, t) {
|
|
333
|
+
const o = {};
|
|
334
|
+
function n(r) {
|
|
335
|
+
for (const s of r)
|
|
336
336
|
if (!s.isGroup || !s.children?.length)
|
|
337
337
|
for (const a of e)
|
|
338
|
-
for (const l of
|
|
338
|
+
for (const l of t) {
|
|
339
339
|
const d = C([a], l.field);
|
|
340
|
-
|
|
340
|
+
o[d] = (o[d] ?? 0) + (s.values[d] ?? 0);
|
|
341
341
|
}
|
|
342
|
-
else s.children &&
|
|
342
|
+
else s.children && n(s.children);
|
|
343
343
|
}
|
|
344
|
-
return
|
|
344
|
+
return n(i), o;
|
|
345
345
|
}
|
|
346
|
-
function
|
|
347
|
-
const
|
|
348
|
-
function r
|
|
349
|
-
|
|
350
|
-
const s = e ? e.has(
|
|
351
|
-
if (
|
|
352
|
-
for (const a of
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
for (const
|
|
356
|
-
r
|
|
357
|
-
return
|
|
346
|
+
function H(i, e, t = !0) {
|
|
347
|
+
const o = [];
|
|
348
|
+
function n(r) {
|
|
349
|
+
o.push(r);
|
|
350
|
+
const s = e ? e.has(r.rowKey) : t;
|
|
351
|
+
if (r.children && s)
|
|
352
|
+
for (const a of r.children)
|
|
353
|
+
n(a);
|
|
354
|
+
}
|
|
355
|
+
for (const r of i)
|
|
356
|
+
n(r);
|
|
357
|
+
return o;
|
|
358
358
|
}
|
|
359
|
-
function w(
|
|
359
|
+
function w(i) {
|
|
360
360
|
const e = [];
|
|
361
|
-
function o
|
|
362
|
-
if (
|
|
363
|
-
for (const
|
|
364
|
-
|
|
361
|
+
function t(o) {
|
|
362
|
+
if (o.isGroup && e.push(o.rowKey), o.children)
|
|
363
|
+
for (const n of o.children)
|
|
364
|
+
t(n);
|
|
365
365
|
}
|
|
366
|
-
for (const
|
|
367
|
-
o
|
|
366
|
+
for (const o of i)
|
|
367
|
+
t(o);
|
|
368
368
|
return e;
|
|
369
369
|
}
|
|
370
|
-
const
|
|
371
|
-
function
|
|
372
|
-
const
|
|
373
|
-
return s.className = "tbw-pivot-panel", s.appendChild(f("Options", () => U(
|
|
374
|
-
|
|
370
|
+
const q = ["sum", "avg", "count", "min", "max", "first", "last"];
|
|
371
|
+
function z(i, e, t, o) {
|
|
372
|
+
const n = new AbortController(), r = { config: e, callbacks: o, signal: n.signal }, s = document.createElement("div");
|
|
373
|
+
return s.className = "tbw-pivot-panel", s.appendChild(f("Options", () => U(t, r))), s.appendChild(f("Row Groups", () => G("rowGroups", r))), s.appendChild(f("Column Groups", () => G("columnGroups", r))), s.appendChild(f("Values", () => Z(r))), s.appendChild(f("Available Fields", () => j(r))), i.appendChild(s), () => {
|
|
374
|
+
n.abort(), s.remove();
|
|
375
375
|
};
|
|
376
376
|
}
|
|
377
|
-
function f(
|
|
377
|
+
function f(i, e) {
|
|
378
|
+
const t = document.createElement("div");
|
|
379
|
+
t.className = "tbw-pivot-section";
|
|
378
380
|
const o = document.createElement("div");
|
|
379
|
-
o.className = "tbw-pivot-section";
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
const r = document.createElement("div");
|
|
383
|
-
return r.className = "tbw-pivot-section-content", r.appendChild(e()), o.appendChild(i), o.appendChild(r), o;
|
|
381
|
+
o.className = "tbw-pivot-section-header", o.textContent = i;
|
|
382
|
+
const n = document.createElement("div");
|
|
383
|
+
return n.className = "tbw-pivot-section-content", n.appendChild(e()), t.appendChild(o), t.appendChild(n), t;
|
|
384
384
|
}
|
|
385
|
-
function G(
|
|
386
|
-
const { config:
|
|
387
|
-
|
|
388
|
-
const s =
|
|
385
|
+
function G(i, e) {
|
|
386
|
+
const { config: t, callbacks: o, signal: n } = e, r = document.createElement("div");
|
|
387
|
+
r.className = "tbw-pivot-drop-zone", r.setAttribute("data-zone", i);
|
|
388
|
+
const s = i === "rowGroups" ? t.rowGroupFields ?? [] : t.columnGroupFields ?? [];
|
|
389
389
|
if (s.length === 0) {
|
|
390
390
|
const a = document.createElement("div");
|
|
391
|
-
a.className = "tbw-pivot-placeholder", a.textContent = "Drag fields here or click to add",
|
|
391
|
+
a.className = "tbw-pivot-placeholder", a.textContent = "Drag fields here or click to add", r.appendChild(a);
|
|
392
392
|
} else
|
|
393
393
|
for (const a of s)
|
|
394
|
-
|
|
395
|
-
return
|
|
394
|
+
r.appendChild(O(a, i, e));
|
|
395
|
+
return r.addEventListener(
|
|
396
396
|
"dragover",
|
|
397
397
|
(a) => {
|
|
398
|
-
a.preventDefault(),
|
|
398
|
+
a.preventDefault(), r.classList.add("drag-over");
|
|
399
399
|
},
|
|
400
|
-
{ signal:
|
|
401
|
-
),
|
|
400
|
+
{ signal: n }
|
|
401
|
+
), r.addEventListener(
|
|
402
402
|
"dragleave",
|
|
403
403
|
() => {
|
|
404
|
-
|
|
404
|
+
r.classList.remove("drag-over");
|
|
405
405
|
},
|
|
406
|
-
{ signal:
|
|
407
|
-
),
|
|
406
|
+
{ signal: n }
|
|
407
|
+
), r.addEventListener(
|
|
408
408
|
"drop",
|
|
409
409
|
(a) => {
|
|
410
|
-
a.preventDefault(),
|
|
410
|
+
a.preventDefault(), r.classList.remove("drag-over");
|
|
411
411
|
const l = a.dataTransfer?.getData("text/plain");
|
|
412
|
-
l &&
|
|
412
|
+
l && o.onAddFieldToZone(l, i);
|
|
413
413
|
},
|
|
414
|
-
{ signal:
|
|
415
|
-
),
|
|
414
|
+
{ signal: n }
|
|
415
|
+
), r;
|
|
416
416
|
}
|
|
417
|
-
function O(
|
|
418
|
-
const { callbacks:
|
|
419
|
-
|
|
420
|
-
const s =
|
|
421
|
-
a.className = "tbw-pivot-chip-label", a.textContent = s?.header ??
|
|
417
|
+
function O(i, e, t) {
|
|
418
|
+
const { callbacks: o, signal: n } = t, r = document.createElement("div");
|
|
419
|
+
r.className = "tbw-pivot-field-chip", r.draggable = !0;
|
|
420
|
+
const s = o.getAvailableFields().find((d) => d.field === i), a = document.createElement("span");
|
|
421
|
+
a.className = "tbw-pivot-chip-label", a.textContent = s?.header ?? i;
|
|
422
422
|
const l = document.createElement("button");
|
|
423
423
|
return l.className = "tbw-pivot-chip-remove", l.innerHTML = "×", l.title = "Remove field", l.addEventListener(
|
|
424
424
|
"click",
|
|
425
425
|
(d) => {
|
|
426
|
-
d.stopPropagation(),
|
|
426
|
+
d.stopPropagation(), o.onRemoveFieldFromZone(i, e);
|
|
427
427
|
},
|
|
428
|
-
{ signal:
|
|
429
|
-
),
|
|
428
|
+
{ signal: n }
|
|
429
|
+
), r.appendChild(a), r.appendChild(l), r.addEventListener(
|
|
430
430
|
"dragstart",
|
|
431
431
|
(d) => {
|
|
432
|
-
d.dataTransfer?.setData("text/plain",
|
|
432
|
+
d.dataTransfer?.setData("text/plain", i), d.dataTransfer?.setData("source-zone", e), r.classList.add("dragging");
|
|
433
433
|
},
|
|
434
|
-
{ signal:
|
|
435
|
-
),
|
|
434
|
+
{ signal: n }
|
|
435
|
+
), r.addEventListener(
|
|
436
436
|
"dragend",
|
|
437
437
|
() => {
|
|
438
|
-
|
|
438
|
+
r.classList.remove("dragging");
|
|
439
439
|
},
|
|
440
|
-
{ signal:
|
|
441
|
-
),
|
|
440
|
+
{ signal: n }
|
|
441
|
+
), r;
|
|
442
442
|
}
|
|
443
|
-
function Z(
|
|
444
|
-
const { config: e, callbacks:
|
|
445
|
-
|
|
446
|
-
const
|
|
447
|
-
if (
|
|
443
|
+
function Z(i) {
|
|
444
|
+
const { config: e, callbacks: t, signal: o } = i, n = document.createElement("div");
|
|
445
|
+
n.className = "tbw-pivot-drop-zone tbw-pivot-values-zone", n.setAttribute("data-zone", "values");
|
|
446
|
+
const r = e.valueFields ?? [];
|
|
447
|
+
if (r.length === 0) {
|
|
448
448
|
const s = document.createElement("div");
|
|
449
|
-
s.className = "tbw-pivot-placeholder", s.textContent = "Drag numeric fields here for aggregation",
|
|
449
|
+
s.className = "tbw-pivot-placeholder", s.textContent = "Drag numeric fields here for aggregation", n.appendChild(s);
|
|
450
450
|
} else
|
|
451
|
-
for (const s of
|
|
452
|
-
|
|
453
|
-
return
|
|
451
|
+
for (const s of r)
|
|
452
|
+
n.appendChild($(s, i));
|
|
453
|
+
return n.addEventListener(
|
|
454
454
|
"dragover",
|
|
455
455
|
(s) => {
|
|
456
|
-
s.preventDefault(),
|
|
456
|
+
s.preventDefault(), n.classList.add("drag-over");
|
|
457
457
|
},
|
|
458
|
-
{ signal:
|
|
459
|
-
),
|
|
458
|
+
{ signal: o }
|
|
459
|
+
), n.addEventListener(
|
|
460
460
|
"dragleave",
|
|
461
461
|
() => {
|
|
462
|
-
|
|
462
|
+
n.classList.remove("drag-over");
|
|
463
463
|
},
|
|
464
|
-
{ signal:
|
|
465
|
-
),
|
|
464
|
+
{ signal: o }
|
|
465
|
+
), n.addEventListener(
|
|
466
466
|
"drop",
|
|
467
467
|
(s) => {
|
|
468
|
-
s.preventDefault(),
|
|
468
|
+
s.preventDefault(), n.classList.remove("drag-over");
|
|
469
469
|
const a = s.dataTransfer?.getData("text/plain");
|
|
470
|
-
a &&
|
|
470
|
+
a && t.onAddValueField(a, "sum");
|
|
471
471
|
},
|
|
472
|
-
{ signal:
|
|
473
|
-
),
|
|
472
|
+
{ signal: o }
|
|
473
|
+
), n;
|
|
474
474
|
}
|
|
475
|
-
function $(
|
|
476
|
-
const { callbacks:
|
|
477
|
-
|
|
478
|
-
const
|
|
475
|
+
function $(i, e) {
|
|
476
|
+
const { callbacks: t, signal: o } = e, n = document.createElement("div");
|
|
477
|
+
n.className = "tbw-pivot-field-chip tbw-pivot-value-chip";
|
|
478
|
+
const r = t.getAvailableFields().find((c) => c.field === i.field), s = document.createElement("div");
|
|
479
479
|
s.className = "tbw-pivot-value-label-wrapper";
|
|
480
480
|
const a = document.createElement("span");
|
|
481
|
-
a.className = "tbw-pivot-chip-label", a.textContent =
|
|
481
|
+
a.className = "tbw-pivot-chip-label", a.textContent = r?.header ?? i.field;
|
|
482
482
|
const l = document.createElement("select");
|
|
483
483
|
l.className = "tbw-pivot-agg-select", l.title = "Aggregation function";
|
|
484
|
-
for (const c of
|
|
484
|
+
for (const c of q) {
|
|
485
485
|
const p = document.createElement("option");
|
|
486
|
-
p.value = c, p.textContent = c.toUpperCase(), p.selected = c ===
|
|
486
|
+
p.value = c, p.textContent = c.toUpperCase(), p.selected = c === i.aggFunc, l.appendChild(p);
|
|
487
487
|
}
|
|
488
488
|
l.addEventListener(
|
|
489
489
|
"change",
|
|
490
490
|
() => {
|
|
491
|
-
|
|
491
|
+
t.onUpdateValueAggFunc(i.field, l.value);
|
|
492
492
|
},
|
|
493
|
-
{ signal:
|
|
493
|
+
{ signal: o }
|
|
494
494
|
);
|
|
495
495
|
const d = document.createElement("button");
|
|
496
496
|
return d.className = "tbw-pivot-chip-remove", d.innerHTML = "×", d.title = "Remove value field", d.addEventListener(
|
|
497
497
|
"click",
|
|
498
498
|
(c) => {
|
|
499
|
-
c.stopPropagation(),
|
|
499
|
+
c.stopPropagation(), t.onRemoveValueField(i.field);
|
|
500
500
|
},
|
|
501
|
-
{ signal:
|
|
502
|
-
), s.appendChild(a), s.appendChild(l),
|
|
501
|
+
{ signal: o }
|
|
502
|
+
), s.appendChild(a), s.appendChild(l), n.appendChild(s), n.appendChild(d), n;
|
|
503
503
|
}
|
|
504
|
-
function j(
|
|
505
|
-
const { config: e, callbacks:
|
|
506
|
-
|
|
507
|
-
const
|
|
504
|
+
function j(i) {
|
|
505
|
+
const { config: e, callbacks: t, signal: o } = i, n = document.createElement("div");
|
|
506
|
+
n.className = "tbw-pivot-available-fields";
|
|
507
|
+
const r = t.getAvailableFields(), s = /* @__PURE__ */ new Set([
|
|
508
508
|
...e.rowGroupFields ?? [],
|
|
509
509
|
...e.columnGroupFields ?? [],
|
|
510
510
|
...e.valueFields?.map((l) => l.field) ?? []
|
|
511
|
-
]), a =
|
|
511
|
+
]), a = r.filter((l) => !s.has(l.field));
|
|
512
512
|
if (a.length === 0) {
|
|
513
513
|
const l = document.createElement("div");
|
|
514
|
-
l.className = "tbw-pivot-placeholder", l.textContent = "All fields are in use",
|
|
514
|
+
l.className = "tbw-pivot-placeholder", l.textContent = "All fields are in use", n.appendChild(l);
|
|
515
515
|
} else
|
|
516
516
|
for (const l of a) {
|
|
517
517
|
const d = document.createElement("div");
|
|
@@ -520,107 +520,107 @@ function j(t) {
|
|
|
520
520
|
(c) => {
|
|
521
521
|
c.dataTransfer?.setData("text/plain", l.field), d.classList.add("dragging");
|
|
522
522
|
},
|
|
523
|
-
{ signal:
|
|
523
|
+
{ signal: o }
|
|
524
524
|
), d.addEventListener(
|
|
525
525
|
"dragend",
|
|
526
526
|
() => {
|
|
527
527
|
d.classList.remove("dragging");
|
|
528
528
|
},
|
|
529
|
-
{ signal:
|
|
530
|
-
),
|
|
529
|
+
{ signal: o }
|
|
530
|
+
), n.appendChild(d);
|
|
531
531
|
}
|
|
532
|
-
return
|
|
532
|
+
return n;
|
|
533
533
|
}
|
|
534
|
-
function U(
|
|
535
|
-
const { config:
|
|
536
|
-
return
|
|
534
|
+
function U(i, e) {
|
|
535
|
+
const { config: t, callbacks: o, signal: n } = e, r = document.createElement("div");
|
|
536
|
+
return r.className = "tbw-pivot-options", r.appendChild(
|
|
537
537
|
x(
|
|
538
538
|
"Enable Pivot View",
|
|
539
|
-
|
|
539
|
+
i,
|
|
540
540
|
(s) => {
|
|
541
|
-
|
|
541
|
+
o.onTogglePivot(s);
|
|
542
542
|
},
|
|
543
|
-
|
|
543
|
+
n
|
|
544
544
|
)
|
|
545
|
-
),
|
|
545
|
+
), r.appendChild(
|
|
546
546
|
x(
|
|
547
547
|
"Show Row Totals",
|
|
548
|
-
|
|
548
|
+
t.showTotals ?? !0,
|
|
549
549
|
(s) => {
|
|
550
|
-
|
|
550
|
+
o.onOptionChange("showTotals", s);
|
|
551
551
|
},
|
|
552
|
-
|
|
552
|
+
n
|
|
553
553
|
)
|
|
554
|
-
),
|
|
554
|
+
), r.appendChild(
|
|
555
555
|
x(
|
|
556
556
|
"Show Grand Total",
|
|
557
|
-
|
|
557
|
+
t.showGrandTotal ?? !0,
|
|
558
558
|
(s) => {
|
|
559
|
-
|
|
559
|
+
o.onOptionChange("showGrandTotal", s);
|
|
560
560
|
},
|
|
561
|
-
|
|
561
|
+
n
|
|
562
562
|
)
|
|
563
|
-
),
|
|
563
|
+
), r;
|
|
564
564
|
}
|
|
565
|
-
function x(
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
const
|
|
569
|
-
|
|
565
|
+
function x(i, e, t, o) {
|
|
566
|
+
const n = document.createElement("label");
|
|
567
|
+
n.className = "tbw-pivot-checkbox";
|
|
568
|
+
const r = document.createElement("input");
|
|
569
|
+
r.type = "checkbox", r.checked = e, r.addEventListener("change", () => t(r.checked), { signal: o });
|
|
570
570
|
const s = document.createElement("span");
|
|
571
|
-
return s.textContent =
|
|
571
|
+
return s.textContent = i, n.appendChild(r), n.appendChild(s), n;
|
|
572
572
|
}
|
|
573
|
-
function B(
|
|
574
|
-
return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(
|
|
575
|
-
const
|
|
576
|
-
if (
|
|
577
|
-
const s = Number(
|
|
578
|
-
|
|
579
|
-
const a = String(
|
|
580
|
-
l.type = "button", l.className = "pivot-toggle", l.setAttribute("aria-label",
|
|
581
|
-
p.stopPropagation(),
|
|
582
|
-
}),
|
|
573
|
+
function B(i, e, t) {
|
|
574
|
+
return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(i.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(i.__pivotRowKey ?? "")), e.setAttribute("role", "row"), e.innerHTML = "", t.columns.forEach((o, n) => {
|
|
575
|
+
const r = document.createElement("div");
|
|
576
|
+
if (r.className = "cell", r.setAttribute("data-col", String(n)), r.setAttribute("role", "gridcell"), n === 0) {
|
|
577
|
+
const s = Number(i.__pivotIndent) || 0;
|
|
578
|
+
r.style.paddingLeft = `${s}px`;
|
|
579
|
+
const a = String(i.__pivotRowKey), l = document.createElement("button");
|
|
580
|
+
l.type = "button", l.className = "pivot-toggle", l.setAttribute("aria-label", i.__pivotExpanded ? "Collapse group" : "Expand group"), t.setIcon(l, t.resolveIcon(i.__pivotExpanded ? "collapse" : "expand")), l.addEventListener("click", (p) => {
|
|
581
|
+
p.stopPropagation(), t.onToggle(a);
|
|
582
|
+
}), r.appendChild(l);
|
|
583
583
|
const d = document.createElement("span");
|
|
584
|
-
d.className = "pivot-label", d.textContent = String(
|
|
584
|
+
d.className = "pivot-label", d.textContent = String(i.__pivotLabel ?? ""), r.appendChild(d);
|
|
585
585
|
const c = document.createElement("span");
|
|
586
|
-
c.className = "pivot-count", c.textContent = ` (${Number(
|
|
586
|
+
c.className = "pivot-count", c.textContent = ` (${Number(i.__pivotRowCount) || 0})`, r.appendChild(c);
|
|
587
587
|
} else {
|
|
588
|
-
const s =
|
|
589
|
-
|
|
588
|
+
const s = i[o.field];
|
|
589
|
+
r.textContent = s != null ? String(s) : "";
|
|
590
590
|
}
|
|
591
|
-
e.appendChild(
|
|
591
|
+
e.appendChild(r);
|
|
592
592
|
}), !0;
|
|
593
593
|
}
|
|
594
|
-
function W(
|
|
595
|
-
return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(
|
|
596
|
-
const
|
|
597
|
-
if (
|
|
598
|
-
const s = Number(
|
|
599
|
-
|
|
594
|
+
function W(i, e, t) {
|
|
595
|
+
return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(i.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(i.__pivotRowKey ?? "")), e.innerHTML = "", t.forEach((o, n) => {
|
|
596
|
+
const r = document.createElement("div");
|
|
597
|
+
if (r.className = "cell", r.setAttribute("data-col", String(n)), r.setAttribute("role", "gridcell"), n === 0) {
|
|
598
|
+
const s = Number(i.__pivotIndent) || 0;
|
|
599
|
+
r.style.paddingLeft = `${s + 20}px`;
|
|
600
600
|
const a = document.createElement("span");
|
|
601
|
-
a.className = "pivot-label", a.textContent = String(
|
|
601
|
+
a.className = "pivot-label", a.textContent = String(i.__pivotLabel ?? ""), r.appendChild(a);
|
|
602
602
|
} else {
|
|
603
|
-
const s =
|
|
604
|
-
|
|
603
|
+
const s = i[o.field];
|
|
604
|
+
r.textContent = s != null ? String(s) : "";
|
|
605
605
|
}
|
|
606
|
-
e.appendChild(
|
|
606
|
+
e.appendChild(r);
|
|
607
607
|
}), !0;
|
|
608
608
|
}
|
|
609
|
-
function J(
|
|
610
|
-
return e.className = "pivot-grand-total-row", e.setAttribute("role", "presentation"), e.innerHTML = "",
|
|
611
|
-
const
|
|
612
|
-
if (
|
|
609
|
+
function J(i, e, t) {
|
|
610
|
+
return e.className = "pivot-grand-total-row", e.setAttribute("role", "presentation"), e.innerHTML = "", t.forEach((o, n) => {
|
|
611
|
+
const r = document.createElement("div");
|
|
612
|
+
if (r.className = "cell", r.setAttribute("data-col", String(n)), n === 0) {
|
|
613
613
|
const s = document.createElement("span");
|
|
614
|
-
s.className = "pivot-label", s.textContent = "Grand Total",
|
|
614
|
+
s.className = "pivot-label", s.textContent = "Grand Total", r.appendChild(s);
|
|
615
615
|
} else {
|
|
616
|
-
const s =
|
|
617
|
-
|
|
616
|
+
const s = i[o.field];
|
|
617
|
+
r.textContent = s != null ? String(s) : "";
|
|
618
618
|
}
|
|
619
|
-
e.appendChild(
|
|
619
|
+
e.appendChild(r);
|
|
620
620
|
}), !0;
|
|
621
621
|
}
|
|
622
|
-
const Q = '.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;
|
|
623
|
-
class b extends
|
|
622
|
+
const Q = '.pivot-group-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:600;background:var(--tbw-pivot-group-bg, var(--tbw-color-row-alt));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-group-row:hover{background:var(--tbw-pivot-group-hover, var(--tbw-color-row-hover))}.pivot-leaf-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-pivot-leaf-bg, var(--tbw-color-bg));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-grand-total-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:700;background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-height:var(--tbw-row-height);border-top:2px solid var(--tbw-color-border-strong)}.pivot-grand-total-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-grand-total-row>.cell:last-child{border-right:0}.pivot-grand-total-footer{position:sticky;bottom:0;z-index:var(--tbw-z-layer-pinned-rows, 20);background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-width:fit-content}.pivot-group-row>.cell,.pivot-leaf-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-group-row>.cell:last-child,.pivot-leaf-row>.cell:last-child{border-right:0}.pivot-toggle{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-right:6px;border:none;background:transparent;cursor:pointer;color:var(--tbw-pivot-toggle-color, var(--tbw-color-fg-muted));border-radius:var(--tbw-border-radius);transition:background .15s,color .15s}.pivot-toggle:hover{background:var(--tbw-pivot-toggle-hover-bg, var(--tbw-color-row-hover));color:var(--tbw-pivot-toggle-hover-color, var(--tbw-color-fg))}.pivot-toggle:focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}.pivot-label{font-weight:inherit}.pivot-count{color:var(--tbw-pivot-count-color, var(--tbw-color-fg-muted));font-size:.9em;font-weight:400}.pivot-total-row{font-weight:700;border-top:2px solid var(--tbw-pivot-border, var(--tbw-color-border-strong))}[data-pivot-depth="1"]{--tbw-pivot-depth: 1}[data-pivot-depth="2"]{--tbw-pivot-depth: 2}[data-pivot-depth="3"]{--tbw-pivot-depth: 3}[data-pivot-depth="4"]{--tbw-pivot-depth: 4}.tbw-pivot-panel{display:flex;flex-direction:column;gap:12px;padding:12px;height:100%;overflow-y:auto;font-size:13px}.tbw-pivot-section{border:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-section-bg, var(--tbw-color-bg))}.tbw-pivot-section-header{padding:8px 12px;font-weight:600;background:var(--tbw-pivot-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius) var(--tbw-border-radius) 0 0}.tbw-pivot-section-content{padding:8px}.tbw-pivot-toggle-wrapper{display:flex;align-items:center}.tbw-pivot-toggle-label{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-toggle-label input{width:16px;height:16px;cursor:pointer}.tbw-pivot-drop-zone{min-height:60px;padding:8px;border:2px dashed var(--tbw-pivot-drop-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-drop-bg, var(--tbw-color-row-alt));display:flex;flex-wrap:wrap;gap:6px;align-content:flex-start;transition:all .15s ease}.tbw-pivot-drop-zone.drag-over{border-color:var(--tbw-color-accent);background:var(--tbw-pivot-drop-active, var(--tbw-focus-background))}.tbw-pivot-placeholder{color:var(--tbw-color-fg-muted);font-style:italic;padding:8px;text-align:center;width:100%}.tbw-pivot-field-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;background:var(--tbw-pivot-chip-bg, var(--tbw-color-header-bg));border:1px solid var(--tbw-pivot-chip-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);cursor:grab;font-size:12px;transition:all .15s ease}.tbw-pivot-field-chip:hover{background:var(--tbw-pivot-chip-hover, var(--tbw-color-row-hover));border-color:var(--tbw-color-accent)}.tbw-pivot-field-chip.available{background:var(--tbw-color-bg)}.tbw-pivot-field-chip.dragging{opacity:.5;cursor:grabbing}.tbw-pivot-chip-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:120px}.tbw-pivot-chip-remove{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:var(--tbw-color-fg-muted);font-size:14px;font-weight:700;cursor:pointer;border-radius:50%;transition:all .15s ease}.tbw-pivot-chip-remove:hover{background:var(--tbw-pivot-chip-remove-hover-bg, var(--tbw-color-accent));color:var(--tbw-pivot-chip-remove-hover-fg, var(--tbw-color-accent-fg))}.tbw-pivot-value-chip{padding:4px 8px}.tbw-pivot-value-label-wrapper{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.tbw-pivot-agg-select{padding:2px 4px;font-size:11px;border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);cursor:pointer}.tbw-pivot-available-fields{display:flex;flex-wrap:wrap;gap:6px;min-height:40px}.tbw-pivot-options{display:flex;flex-direction:column;gap:8px}.tbw-pivot-checkbox{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-checkbox input{width:14px;height:14px;cursor:pointer}.pivot-group-row.tbw-pivot-slide-in,.pivot-leaf-row.tbw-pivot-slide-in{animation:tbw-pivot-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-pivot-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.pivot-group-row.tbw-pivot-fade-in,.pivot-leaf-row.tbw-pivot-fade-in{animation:tbw-pivot-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-pivot-fade-in{0%{opacity:0}to{opacity:1}}';
|
|
623
|
+
class b extends P {
|
|
624
624
|
name = "pivot";
|
|
625
625
|
version = "1.0.0";
|
|
626
626
|
/** Tool panel ID for shell integration */
|
|
@@ -630,7 +630,8 @@ class b extends N {
|
|
|
630
630
|
active: !0,
|
|
631
631
|
showTotals: !0,
|
|
632
632
|
showGrandTotal: !0,
|
|
633
|
-
showToolPanel: !0
|
|
633
|
+
showToolPanel: !0,
|
|
634
|
+
animation: "slide"
|
|
634
635
|
};
|
|
635
636
|
}
|
|
636
637
|
// #region Internal State
|
|
@@ -643,16 +644,31 @@ class b extends N {
|
|
|
643
644
|
originalColumns = [];
|
|
644
645
|
panelContainer = null;
|
|
645
646
|
grandTotalFooter = null;
|
|
647
|
+
previousVisibleKeys = /* @__PURE__ */ new Set();
|
|
648
|
+
keysToAnimate = /* @__PURE__ */ new Set();
|
|
646
649
|
/**
|
|
647
650
|
* Check if the plugin has valid pivot configuration (at least value fields).
|
|
648
651
|
*/
|
|
649
652
|
hasValidPivotConfig() {
|
|
650
653
|
return (this.config.valueFields?.length ?? 0) > 0;
|
|
651
654
|
}
|
|
655
|
+
/**
|
|
656
|
+
* Get animation style respecting grid-level animation mode.
|
|
657
|
+
*/
|
|
658
|
+
get animationStyle() {
|
|
659
|
+
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
660
|
+
if (t === !1 || t === "off") return !1;
|
|
661
|
+
if (t !== !0 && t !== "on") {
|
|
662
|
+
const o = this.shadowRoot?.host;
|
|
663
|
+
if (o && getComputedStyle(o).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
664
|
+
return !1;
|
|
665
|
+
}
|
|
666
|
+
return this.config.animation ?? "slide";
|
|
667
|
+
}
|
|
652
668
|
// #endregion
|
|
653
669
|
// #region Lifecycle
|
|
654
670
|
detach() {
|
|
655
|
-
this.isActive = !1, this.hasInitialized = !1, this.pivotResult = null, this.fieldHeaderMap.clear(), this.originalColumns = [], this.panelContainer = null, this.cleanupGrandTotalFooter();
|
|
671
|
+
this.isActive = !1, this.hasInitialized = !1, this.pivotResult = null, this.fieldHeaderMap.clear(), this.originalColumns = [], this.panelContainer = null, this.cleanupGrandTotalFooter(), this.previousVisibleKeys.clear(), this.keysToAnimate.clear();
|
|
656
672
|
}
|
|
657
673
|
// #endregion
|
|
658
674
|
// #region Shell Integration
|
|
@@ -664,7 +680,7 @@ class b extends N {
|
|
|
664
680
|
icon: "⊞",
|
|
665
681
|
tooltip: "Configure pivot table",
|
|
666
682
|
order: 90,
|
|
667
|
-
render: (
|
|
683
|
+
render: (t) => this.renderPanel(t)
|
|
668
684
|
};
|
|
669
685
|
}
|
|
670
686
|
// #endregion
|
|
@@ -672,71 +688,77 @@ class b extends N {
|
|
|
672
688
|
processRows(e) {
|
|
673
689
|
if (!this.hasInitialized && this.config.active !== !1 && this.hasValidPivotConfig() && (this.hasInitialized = !0, this.isActive = !0), !this.isActive)
|
|
674
690
|
return [...e];
|
|
675
|
-
const
|
|
676
|
-
if (
|
|
677
|
-
return this.warn(`Config errors: ${
|
|
691
|
+
const t = S(this.config);
|
|
692
|
+
if (t.length > 0)
|
|
693
|
+
return this.warn(`Config errors: ${t.join(", ")}`), [...e];
|
|
678
694
|
if (this.buildFieldHeaderMap(), this.defaultExpanded = this.config.defaultExpanded ?? !0, this.expandedKeys.size === 0 && this.defaultExpanded && this.pivotResult) {
|
|
679
|
-
const
|
|
680
|
-
for (const
|
|
681
|
-
this.expandedKeys.add(
|
|
695
|
+
const s = w(this.pivotResult.rows);
|
|
696
|
+
for (const a of s)
|
|
697
|
+
this.expandedKeys.add(a);
|
|
682
698
|
}
|
|
683
|
-
if (this.pivotResult =
|
|
684
|
-
const
|
|
685
|
-
for (const
|
|
686
|
-
this.expandedKeys.add(
|
|
699
|
+
if (this.pivotResult = I(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded) {
|
|
700
|
+
const s = w(this.pivotResult.rows);
|
|
701
|
+
for (const a of s)
|
|
702
|
+
this.expandedKeys.add(a);
|
|
687
703
|
}
|
|
688
|
-
const
|
|
689
|
-
return D(
|
|
704
|
+
const o = this.config.indentWidth ?? 20, n = H(
|
|
690
705
|
this.pivotResult.rows,
|
|
691
706
|
this.expandedKeys,
|
|
692
707
|
this.defaultExpanded
|
|
693
|
-
).map((
|
|
694
|
-
__pivotRowKey:
|
|
695
|
-
__pivotLabel:
|
|
696
|
-
__pivotDepth:
|
|
697
|
-
__pivotIsGroup:
|
|
698
|
-
__pivotHasChildren: !!
|
|
699
|
-
__pivotExpanded: this.expandedKeys.has(
|
|
700
|
-
__pivotRowCount:
|
|
701
|
-
__pivotIndent:
|
|
702
|
-
__pivotTotal:
|
|
703
|
-
...
|
|
708
|
+
).map((s) => ({
|
|
709
|
+
__pivotRowKey: s.rowKey,
|
|
710
|
+
__pivotLabel: s.rowLabel,
|
|
711
|
+
__pivotDepth: s.depth,
|
|
712
|
+
__pivotIsGroup: s.isGroup,
|
|
713
|
+
__pivotHasChildren: !!s.children?.length,
|
|
714
|
+
__pivotExpanded: this.expandedKeys.has(s.rowKey),
|
|
715
|
+
__pivotRowCount: s.rowCount ?? 0,
|
|
716
|
+
__pivotIndent: s.depth * o,
|
|
717
|
+
__pivotTotal: s.total,
|
|
718
|
+
...s.values
|
|
704
719
|
}));
|
|
720
|
+
this.keysToAnimate.clear();
|
|
721
|
+
const r = /* @__PURE__ */ new Set();
|
|
722
|
+
for (const s of n) {
|
|
723
|
+
const a = s.__pivotRowKey;
|
|
724
|
+
r.add(a), !this.previousVisibleKeys.has(a) && s.__pivotDepth > 0 && this.keysToAnimate.add(a);
|
|
725
|
+
}
|
|
726
|
+
return this.previousVisibleKeys = r, n;
|
|
705
727
|
}
|
|
706
728
|
processColumns(e) {
|
|
707
729
|
if (!this.isActive || !this.pivotResult)
|
|
708
730
|
return [...e];
|
|
709
|
-
const
|
|
710
|
-
|
|
731
|
+
const t = [], o = (this.config.rowGroupFields ?? []).map((n) => this.fieldHeaderMap.get(n) ?? n).join(" / ");
|
|
732
|
+
t.push({
|
|
711
733
|
field: "__pivotLabel",
|
|
712
|
-
header:
|
|
734
|
+
header: o || "Group",
|
|
713
735
|
width: 200
|
|
714
736
|
});
|
|
715
|
-
for (const
|
|
716
|
-
for (const
|
|
717
|
-
const s = C([
|
|
718
|
-
|
|
737
|
+
for (const n of this.pivotResult.columnKeys)
|
|
738
|
+
for (const r of this.config.valueFields ?? []) {
|
|
739
|
+
const s = C([n], r.field), a = r.header || this.fieldHeaderMap.get(r.field) || r.field;
|
|
740
|
+
t.push({
|
|
719
741
|
field: s,
|
|
720
|
-
header: `${
|
|
742
|
+
header: `${n} - ${a} (${r.aggFunc})`,
|
|
721
743
|
width: 120,
|
|
722
744
|
type: "number"
|
|
723
745
|
});
|
|
724
746
|
}
|
|
725
|
-
return this.config.showTotals &&
|
|
747
|
+
return this.config.showTotals && t.push({
|
|
726
748
|
field: "__pivotTotal",
|
|
727
749
|
header: "Total",
|
|
728
750
|
width: 100,
|
|
729
751
|
type: "number"
|
|
730
|
-
}),
|
|
752
|
+
}), t;
|
|
731
753
|
}
|
|
732
|
-
renderRow(e,
|
|
733
|
-
const
|
|
734
|
-
return
|
|
754
|
+
renderRow(e, t) {
|
|
755
|
+
const o = e;
|
|
756
|
+
return o.__pivotRowKey && o.__pivotHasChildren ? B(o, t, {
|
|
735
757
|
columns: this.gridColumns,
|
|
736
|
-
onToggle: (
|
|
737
|
-
resolveIcon: (
|
|
738
|
-
setIcon: (
|
|
739
|
-
}) :
|
|
758
|
+
onToggle: (n) => this.toggle(n),
|
|
759
|
+
resolveIcon: (n) => this.resolveIcon(n),
|
|
760
|
+
setIcon: (n, r) => this.setIcon(n, r)
|
|
761
|
+
}) : o.__pivotRowKey !== void 0 && this.isActive ? W(o, t, this.gridColumns) : (this.cleanupPivotStyling(t), !1);
|
|
740
762
|
}
|
|
741
763
|
/**
|
|
742
764
|
* Remove pivot-specific classes, attributes, and inline styles from a row element.
|
|
@@ -748,6 +770,16 @@ class b extends N {
|
|
|
748
770
|
}
|
|
749
771
|
afterRender() {
|
|
750
772
|
this.isActive && this.config.showGrandTotal && this.pivotResult ? this.renderGrandTotalFooter() : this.cleanupGrandTotalFooter();
|
|
773
|
+
const e = this.animationStyle;
|
|
774
|
+
if (e === !1 || this.keysToAnimate.size === 0) return;
|
|
775
|
+
const t = this.shadowRoot?.querySelector(".rows");
|
|
776
|
+
if (!t) return;
|
|
777
|
+
const o = e === "fade" ? "tbw-pivot-fade-in" : "tbw-pivot-slide-in";
|
|
778
|
+
for (const n of t.querySelectorAll(".pivot-group-row, .pivot-leaf-row")) {
|
|
779
|
+
const r = n.dataset.pivotKey;
|
|
780
|
+
r && this.keysToAnimate.has(r) && (n.classList.add(o), n.addEventListener("animationend", () => n.classList.remove(o), { once: !0 }));
|
|
781
|
+
}
|
|
782
|
+
this.keysToAnimate.clear();
|
|
751
783
|
}
|
|
752
784
|
/**
|
|
753
785
|
* Render the grand total row as a sticky footer pinned to the bottom.
|
|
@@ -756,17 +788,17 @@ class b extends N {
|
|
|
756
788
|
if (!this.pivotResult) return;
|
|
757
789
|
const e = this.shadowRoot;
|
|
758
790
|
if (!e) return;
|
|
759
|
-
const
|
|
760
|
-
if (!
|
|
761
|
-
this.grandTotalFooter || (this.grandTotalFooter = document.createElement("div"), this.grandTotalFooter.className = "pivot-grand-total-footer",
|
|
762
|
-
const
|
|
791
|
+
const t = e.querySelector(".tbw-scroll-area") ?? e.querySelector(".tbw-grid-content") ?? e.children[0];
|
|
792
|
+
if (!t) return;
|
|
793
|
+
this.grandTotalFooter || (this.grandTotalFooter = document.createElement("div"), this.grandTotalFooter.className = "pivot-grand-total-footer", t.appendChild(this.grandTotalFooter));
|
|
794
|
+
const o = {
|
|
763
795
|
__pivotRowKey: "__grandTotal",
|
|
764
796
|
__pivotLabel: "Grand Total",
|
|
765
797
|
__pivotIsGrandTotal: !0,
|
|
766
798
|
__pivotTotal: this.pivotResult.grandTotal,
|
|
767
799
|
...this.pivotResult.totals
|
|
768
800
|
};
|
|
769
|
-
J(
|
|
801
|
+
J(o, this.grandTotalFooter, this.gridColumns);
|
|
770
802
|
}
|
|
771
803
|
/**
|
|
772
804
|
* Remove the grand total footer element.
|
|
@@ -788,8 +820,8 @@ class b extends N {
|
|
|
788
820
|
expandAll() {
|
|
789
821
|
if (this.pivotResult) {
|
|
790
822
|
const e = w(this.pivotResult.rows);
|
|
791
|
-
for (const
|
|
792
|
-
this.expandedKeys.add(
|
|
823
|
+
for (const t of e)
|
|
824
|
+
this.expandedKeys.add(t);
|
|
793
825
|
this.requestRender();
|
|
794
826
|
}
|
|
795
827
|
}
|
|
@@ -847,8 +879,8 @@ class b extends N {
|
|
|
847
879
|
buildFieldHeaderMap() {
|
|
848
880
|
const e = this.getAvailableFields();
|
|
849
881
|
this.fieldHeaderMap.clear();
|
|
850
|
-
for (const
|
|
851
|
-
this.fieldHeaderMap.set(
|
|
882
|
+
for (const t of e)
|
|
883
|
+
this.fieldHeaderMap.set(t.field, t.header);
|
|
852
884
|
}
|
|
853
885
|
getAvailableFields() {
|
|
854
886
|
return this.originalColumns.length > 0 ? this.originalColumns : this.captureOriginalColumns();
|
|
@@ -856,10 +888,10 @@ class b extends N {
|
|
|
856
888
|
captureOriginalColumns() {
|
|
857
889
|
const e = this.grid;
|
|
858
890
|
try {
|
|
859
|
-
const
|
|
860
|
-
return this.originalColumns =
|
|
861
|
-
field:
|
|
862
|
-
header:
|
|
891
|
+
const t = e.getAllColumns?.() ?? e.columns ?? [];
|
|
892
|
+
return this.originalColumns = t.filter((o) => !o.field.startsWith("__pivot")).map((o) => ({
|
|
893
|
+
field: o.field,
|
|
894
|
+
header: o.header ?? o.field
|
|
863
895
|
})), this.originalColumns;
|
|
864
896
|
} catch {
|
|
865
897
|
return [];
|
|
@@ -867,51 +899,51 @@ class b extends N {
|
|
|
867
899
|
}
|
|
868
900
|
renderPanel(e) {
|
|
869
901
|
this.panelContainer = e, this.originalColumns.length === 0 && this.captureOriginalColumns();
|
|
870
|
-
const
|
|
871
|
-
onTogglePivot: (
|
|
872
|
-
|
|
902
|
+
const t = {
|
|
903
|
+
onTogglePivot: (o) => {
|
|
904
|
+
o ? this.enablePivot() : this.disablePivot(), this.refreshPanel();
|
|
873
905
|
},
|
|
874
|
-
onAddFieldToZone: (
|
|
875
|
-
onRemoveFieldFromZone: (
|
|
876
|
-
onAddValueField: (
|
|
877
|
-
onRemoveValueField: (
|
|
878
|
-
onUpdateValueAggFunc: (
|
|
879
|
-
onOptionChange: (
|
|
880
|
-
this.config[
|
|
906
|
+
onAddFieldToZone: (o, n) => this.addFieldToZone(o, n),
|
|
907
|
+
onRemoveFieldFromZone: (o, n) => this.removeFieldFromZone(o, n),
|
|
908
|
+
onAddValueField: (o, n) => this.addValueField(o, n),
|
|
909
|
+
onRemoveValueField: (o) => this.removeValueField(o),
|
|
910
|
+
onUpdateValueAggFunc: (o, n) => this.updateValueAggFunc(o, n),
|
|
911
|
+
onOptionChange: (o, n) => {
|
|
912
|
+
this.config[o] = n, this.isActive && this.refresh();
|
|
881
913
|
},
|
|
882
914
|
getAvailableFields: () => this.getAvailableFields()
|
|
883
915
|
};
|
|
884
|
-
return
|
|
916
|
+
return z(e, this.config, this.isActive, t);
|
|
885
917
|
}
|
|
886
918
|
refreshPanel() {
|
|
887
919
|
this.panelContainer && (this.panelContainer.innerHTML = "", this.renderPanel(this.panelContainer));
|
|
888
920
|
}
|
|
889
|
-
addFieldToZone(e,
|
|
890
|
-
if (
|
|
891
|
-
const
|
|
892
|
-
|
|
921
|
+
addFieldToZone(e, t) {
|
|
922
|
+
if (t === "rowGroups") {
|
|
923
|
+
const o = this.config.rowGroupFields ?? [];
|
|
924
|
+
o.includes(e) || (this.config.rowGroupFields = [...o, e]);
|
|
893
925
|
} else {
|
|
894
|
-
const
|
|
895
|
-
|
|
926
|
+
const o = this.config.columnGroupFields ?? [];
|
|
927
|
+
o.includes(e) || (this.config.columnGroupFields = [...o, e]);
|
|
896
928
|
}
|
|
897
|
-
this.removeFromOtherZones(e,
|
|
929
|
+
this.removeFromOtherZones(e, t), this.isActive && this.refresh(), this.refreshPanel();
|
|
898
930
|
}
|
|
899
|
-
removeFieldFromZone(e,
|
|
900
|
-
|
|
931
|
+
removeFieldFromZone(e, t) {
|
|
932
|
+
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();
|
|
901
933
|
}
|
|
902
|
-
removeFromOtherZones(e,
|
|
903
|
-
|
|
934
|
+
removeFromOtherZones(e, t) {
|
|
935
|
+
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));
|
|
904
936
|
}
|
|
905
|
-
addValueField(e,
|
|
906
|
-
const
|
|
907
|
-
|
|
937
|
+
addValueField(e, t) {
|
|
938
|
+
const o = this.config.valueFields ?? [];
|
|
939
|
+
o.some((n) => n.field === e) || (this.config.valueFields = [...o, { field: e, aggFunc: t }]), this.removeFromOtherZones(e, "values"), this.isActive && this.refresh(), this.refreshPanel();
|
|
908
940
|
}
|
|
909
941
|
removeValueField(e) {
|
|
910
|
-
this.config.valueFields = (this.config.valueFields ?? []).filter((
|
|
942
|
+
this.config.valueFields = (this.config.valueFields ?? []).filter((t) => t.field !== e), this.isActive && this.refresh(), this.refreshPanel();
|
|
911
943
|
}
|
|
912
|
-
updateValueAggFunc(e,
|
|
913
|
-
const
|
|
914
|
-
|
|
944
|
+
updateValueAggFunc(e, t) {
|
|
945
|
+
const o = this.config.valueFields ?? [], n = o.findIndex((r) => r.field === e);
|
|
946
|
+
n >= 0 && (o[n] = { ...o[n], aggFunc: t }, this.config.valueFields = [...o]), this.isActive && this.refresh();
|
|
915
947
|
}
|
|
916
948
|
// #endregion
|
|
917
949
|
// #region Styles
|