@canvas-components/react-pivot-table 0.2.17 → 0.2.19
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/README.md +6 -0
- package/dist/index.cjs +555 -139
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +557 -141
- package/dist/index.js.map +1 -1
- package/package.json +10 -8
- package/LICENSE +0 -21
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createContext, forwardRef, useMemo, useRef, useState, useEffect, useImperativeHandle, useContext, Fragment as Fragment$1 } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { ReactResizablePanels, ReactFilterPanel, ReactPopup, ReactCheckbox,
|
|
2
|
+
import { createPivotFieldLayout, createPivotFieldCatalog, resolvePivotDimensionKey, resolvePivotFieldLayoutOptions, PivotTable, loadPivotScrollbarConfig, loadPivotFieldLayout, DEFAULT_PIVOT_TABLE_DEBUG_OPTIONS, getValueByDataIndex, resolvePivotDimensionTitle, findPivotFieldArea, removePivotField, movePivotField, savePivotScrollbarConfig, resolvePivotValueFieldTitle, savePivotFieldLayout, createPivotCellKey } from '@canvas-components/pivot-table';
|
|
3
|
+
import { getSharedScrollbarSettings, subscribeSharedScrollbarSettings, ReactResizablePanels, ReactFilterPanel, ReactPopup, ReactCheckbox, ReactScrollbarSettingsDialog, ReactScrollbarPositionDialog, setSharedScrollbarSettings, ReactInput, ReactSelect, ReactButton, ReactInputNumber } from '@canvas-components/react-components';
|
|
4
4
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
5
|
+
import { ReactListTableExportNameDialog, ReactListTable } from '@canvas-components/react-list-table';
|
|
5
6
|
import { createPortal } from 'react-dom';
|
|
6
7
|
import { CanvasChart } from '@canvas-components/chart';
|
|
7
8
|
|
|
@@ -30,89 +31,276 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
// src/features/context-menu/pivot-context-menu.css
|
|
33
|
-
styleInject(".react-pivot-table-menu-action {\n transition: background-color 0.2s ease, color 0.2s ease;\n}\n.react-pivot-table-menu-action:hover {\n background: #f3f4f6 !important;\n}\n.react-pivot-table-menu-chevron {\n width: 7px;\n height: 7px;\n flex: 0 0 auto;\n margin-left: 8px;\n border-top: 1.5px solid #9ca3af;\n border-right: 1.5px solid #9ca3af;\n transform: rotate(45deg);\n transform-origin: center;\n transition: transform 0.18s ease, border-color 0.18s ease;\n}\n.react-pivot-table-menu-action:hover .react-pivot-table-menu-chevron,\n.react-pivot-table-menu-chevron-active {\n border-color: #6b7280;\n transform: rotate(135deg);\n}\n");
|
|
34
|
+
styleInject(".react-pivot-table-menu-action {\n font-size: inherit;\n transition: background-color 0.2s ease, color 0.2s ease;\n}\n.react-pivot-table-menu-action:hover {\n background: #f3f4f6 !important;\n}\n.react-pivot-table-menu-chevron {\n width: 7px;\n height: 7px;\n flex: 0 0 auto;\n margin-left: 8px;\n border-top: 1.5px solid #9ca3af;\n border-right: 1.5px solid #9ca3af;\n transform: rotate(45deg);\n transform-origin: center;\n transition: transform 0.18s ease, border-color 0.18s ease;\n}\n.react-pivot-table-menu-action:hover .react-pivot-table-menu-chevron,\n.react-pivot-table-menu-chevron-active {\n border-color: #6b7280;\n transform: rotate(135deg);\n}\n");
|
|
34
35
|
var CONTEXT_MENU_SURFACE_STYLE = {
|
|
35
36
|
padding: 8,
|
|
36
37
|
background: "#ffffff",
|
|
37
|
-
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.16)"
|
|
38
|
+
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.16)",
|
|
39
|
+
fontSize: 14
|
|
38
40
|
};
|
|
41
|
+
function ScrollbarModeMenu(props) {
|
|
42
|
+
const { request, onOpenSettings } = props;
|
|
43
|
+
return /* @__PURE__ */ jsx(
|
|
44
|
+
MenuSubmenu,
|
|
45
|
+
{
|
|
46
|
+
label: "\u6EDA\u52A8\u6761\u6A21\u5F0F",
|
|
47
|
+
items: [
|
|
48
|
+
["scrollbar", "\u6EDA\u52A8\u6761"],
|
|
49
|
+
["button", "\u6309\u94AE"]
|
|
50
|
+
].map(([mode, label]) => ({
|
|
51
|
+
key: `scrollbar-mode-${mode}`,
|
|
52
|
+
label,
|
|
53
|
+
selected: (request.scrollbar?.mode ?? "scrollbar") === mode,
|
|
54
|
+
onClick: () => {
|
|
55
|
+
request.onChangeScrollbar?.({
|
|
56
|
+
...request.scrollbar,
|
|
57
|
+
mode,
|
|
58
|
+
horizontal: request.scrollbar?.horizontal === false ? false : { ...request.scrollbar?.horizontal, mode },
|
|
59
|
+
vertical: request.scrollbar?.vertical === false ? false : { ...request.scrollbar?.vertical, mode }
|
|
60
|
+
});
|
|
61
|
+
request.onClose();
|
|
62
|
+
}
|
|
63
|
+
})),
|
|
64
|
+
footer: /* @__PURE__ */ jsx(ReactButton, { onClick: onOpenSettings, children: "\u914D\u7F6E\u6EDA\u52A8\u6761\u5C5E\u6027" })
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
function ScrollbarCacheMenu(props) {
|
|
69
|
+
const { request } = props;
|
|
70
|
+
return /* @__PURE__ */ jsx(
|
|
71
|
+
MenuSubmenu,
|
|
72
|
+
{
|
|
73
|
+
label: "\u7F13\u5B58\u5230\u672C\u5730",
|
|
74
|
+
items: [
|
|
75
|
+
{
|
|
76
|
+
key: "cache-scrollbar",
|
|
77
|
+
label: "\u6EDA\u52A8\u6761",
|
|
78
|
+
selected: request.scrollbarCacheAvailable === true && request.cacheScrollbar !== false,
|
|
79
|
+
disabled: request.scrollbarCacheAvailable !== true,
|
|
80
|
+
onClick: () => request.onChangeCacheScrollbar?.(request.cacheScrollbar === false)
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
39
86
|
function PivotContextMenu(props) {
|
|
40
87
|
const { request } = props;
|
|
41
88
|
const [menuOpen, setMenuOpen] = useState(true);
|
|
89
|
+
const [scrollbarSettingsRequest, setScrollbarSettingsRequest] = useState(null);
|
|
90
|
+
const [scrollbarPositionRequest, setScrollbarPositionRequest] = useState(null);
|
|
42
91
|
useEffect(() => {
|
|
43
92
|
if (request) setMenuOpen(true);
|
|
44
93
|
}, [request]);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
ReactPopup,
|
|
94
|
+
const scrollbarDialog = scrollbarSettingsRequest ? /* @__PURE__ */ jsx(
|
|
95
|
+
ReactScrollbarSettingsDialog,
|
|
48
96
|
{
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (!open) request.onClose();
|
|
97
|
+
value: scrollbarSettingsRequest.scrollbar,
|
|
98
|
+
onConfirm: (value) => {
|
|
99
|
+
scrollbarSettingsRequest.onChangeScrollbar?.({
|
|
100
|
+
...scrollbarSettingsRequest.scrollbar,
|
|
101
|
+
...value
|
|
102
|
+
});
|
|
103
|
+
setScrollbarSettingsRequest(null);
|
|
57
104
|
},
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
105
|
+
onClose: () => setScrollbarSettingsRequest(null)
|
|
106
|
+
}
|
|
107
|
+
) : null;
|
|
108
|
+
const scrollbarPositionDialog = scrollbarPositionRequest ? /* @__PURE__ */ jsx(
|
|
109
|
+
ReactScrollbarPositionDialog,
|
|
110
|
+
{
|
|
111
|
+
rowCount: scrollbarPositionRequest.scrollbarRowCount ?? 0,
|
|
112
|
+
columnCount: scrollbarPositionRequest.scrollbarColumnCount ?? 0,
|
|
113
|
+
onConfirm: (row, column) => scrollbarPositionRequest.onScrollToPosition?.(row, column),
|
|
114
|
+
onClose: () => setScrollbarPositionRequest(null)
|
|
115
|
+
}
|
|
116
|
+
) : null;
|
|
117
|
+
if (!request)
|
|
118
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
119
|
+
scrollbarDialog,
|
|
120
|
+
scrollbarPositionDialog
|
|
121
|
+
] });
|
|
122
|
+
const openScrollbarSettings = () => {
|
|
123
|
+
setScrollbarSettingsRequest(request);
|
|
124
|
+
request.onClose();
|
|
125
|
+
};
|
|
126
|
+
const exportAndClose = (action) => action ? () => {
|
|
127
|
+
setMenuOpen(false);
|
|
128
|
+
request.onClose();
|
|
129
|
+
action();
|
|
130
|
+
} : void 0;
|
|
131
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
132
|
+
scrollbarDialog,
|
|
133
|
+
scrollbarPositionDialog,
|
|
134
|
+
/* @__PURE__ */ jsx(
|
|
135
|
+
ReactPopup,
|
|
136
|
+
{
|
|
137
|
+
open: menuOpen,
|
|
138
|
+
anchorRect: { x: request.x, y: request.y, width: 0, height: 0 },
|
|
139
|
+
offset: 4,
|
|
140
|
+
matchAnchorWidth: false,
|
|
141
|
+
minWidth: 260,
|
|
142
|
+
onOpenChange: (open) => {
|
|
143
|
+
setMenuOpen(open);
|
|
144
|
+
if (!open) request.onClose();
|
|
145
|
+
},
|
|
146
|
+
surfaceStyle: { ...CONTEXT_MENU_SURFACE_STYLE, width: 260 },
|
|
147
|
+
children: /* @__PURE__ */ jsx("div", { children: request.target === "scrollbar" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
148
|
+
/* @__PURE__ */ jsx(
|
|
149
|
+
ScrollbarModeMenu,
|
|
150
|
+
{
|
|
151
|
+
request,
|
|
152
|
+
onOpenSettings: openScrollbarSettings
|
|
153
|
+
}
|
|
154
|
+
),
|
|
155
|
+
/* @__PURE__ */ jsx(
|
|
156
|
+
MenuAction,
|
|
157
|
+
{
|
|
158
|
+
label: "\u6EDA\u52A8\u5230\u6307\u5B9A\u884C / \u5217",
|
|
159
|
+
onClick: () => {
|
|
160
|
+
setScrollbarPositionRequest(request);
|
|
161
|
+
request.onClose();
|
|
75
162
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
/* @__PURE__ */
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
label: "\u5BFC\u51FA CSV",
|
|
98
|
-
onClick: request.onExportCsv
|
|
163
|
+
}
|
|
164
|
+
),
|
|
165
|
+
/* @__PURE__ */ jsx(
|
|
166
|
+
MenuAction,
|
|
167
|
+
{
|
|
168
|
+
label: "\u91CD\u7F6E\u6EDA\u52A8\u6761",
|
|
169
|
+
onClick: () => {
|
|
170
|
+
request.onResetScrollbar?.();
|
|
171
|
+
request.onClose();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
/* @__PURE__ */ jsx(ScrollbarCacheMenu, { request })
|
|
176
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
177
|
+
request.title ? /* @__PURE__ */ jsx(
|
|
178
|
+
"div",
|
|
179
|
+
{
|
|
180
|
+
style: {
|
|
181
|
+
padding: "6px 10px",
|
|
182
|
+
color: "#8f959e",
|
|
183
|
+
fontSize: 12
|
|
99
184
|
},
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
185
|
+
children: request.title
|
|
186
|
+
}
|
|
187
|
+
) : null,
|
|
188
|
+
/* @__PURE__ */ jsx(
|
|
189
|
+
MenuSubmenu,
|
|
190
|
+
{
|
|
191
|
+
label: "\u590D\u5236",
|
|
192
|
+
items: [
|
|
193
|
+
{
|
|
194
|
+
key: "copy-cell",
|
|
195
|
+
label: request.target === "header" ? "\u590D\u5236\u8868\u5934" : "\u590D\u5236\u5355\u5143\u683C",
|
|
196
|
+
onClick: request.onCopy
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
key: "copy-selection",
|
|
200
|
+
label: "\u590D\u5236\u9009\u533A",
|
|
201
|
+
onClick: request.target === "header" ? void 0 : request.onCopySelection
|
|
202
|
+
},
|
|
203
|
+
...["all", "selection", "viewport"].map(
|
|
204
|
+
(scope) => ({
|
|
205
|
+
key: `copy-image-${scope}`,
|
|
206
|
+
label: `\u590D\u5236\u4E3A\u56FE\u7247 \xB7 ${{ all: "\u6240\u6709\u533A\u57DF", selection: "\u9009\u4E2D\u533A\u57DF", viewport: "\u89C6\u53E3\u533A\u57DF" }[scope]}`,
|
|
207
|
+
onClick: scope === "selection" && !request.hasImageSelection ? void 0 : request.onCopyImage ? () => request.onCopyImage?.(scope) : void 0
|
|
208
|
+
})
|
|
209
|
+
)
|
|
210
|
+
],
|
|
211
|
+
children: request.target !== "header" ? /* @__PURE__ */ jsx(CustomSelectionMenu, { request }) : null
|
|
212
|
+
}
|
|
213
|
+
),
|
|
214
|
+
request.target === "header" ? /* @__PURE__ */ jsx(HeaderMenu, { request }) : null,
|
|
215
|
+
request.target === "summary" ? /* @__PURE__ */ jsx(
|
|
216
|
+
SummaryMenu,
|
|
217
|
+
{
|
|
218
|
+
request
|
|
219
|
+
},
|
|
220
|
+
`${request.indicatorKey}-${request.x}-${request.y}`
|
|
221
|
+
) : null,
|
|
222
|
+
/* @__PURE__ */ jsx(DataFormatMenu, { request }),
|
|
223
|
+
/* @__PURE__ */ jsx(DensityMenu, { request }),
|
|
224
|
+
/* @__PURE__ */ jsx(
|
|
225
|
+
ScrollbarModeMenu,
|
|
226
|
+
{
|
|
227
|
+
request,
|
|
228
|
+
onOpenSettings: openScrollbarSettings
|
|
229
|
+
}
|
|
230
|
+
),
|
|
231
|
+
/* @__PURE__ */ jsx(
|
|
232
|
+
MenuAction,
|
|
233
|
+
{
|
|
234
|
+
label: "\u6EDA\u52A8\u5230\u6307\u5B9A\u884C / \u5217",
|
|
235
|
+
onClick: () => {
|
|
236
|
+
setScrollbarPositionRequest(request);
|
|
237
|
+
request.onClose();
|
|
104
238
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
239
|
+
}
|
|
240
|
+
),
|
|
241
|
+
/* @__PURE__ */ jsx(ScrollbarCacheMenu, { request }),
|
|
242
|
+
/* @__PURE__ */ jsx(
|
|
243
|
+
MenuSubmenu,
|
|
244
|
+
{
|
|
245
|
+
label: "\u91CD\u7F6E",
|
|
246
|
+
items: [
|
|
247
|
+
{
|
|
248
|
+
key: "reset-scrollbar",
|
|
249
|
+
label: "\u91CD\u7F6E\u6EDA\u52A8\u6761",
|
|
250
|
+
onClick: () => {
|
|
251
|
+
request.onResetScrollbar?.();
|
|
252
|
+
request.onClose();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
),
|
|
258
|
+
/* @__PURE__ */ jsx(
|
|
259
|
+
MenuSubmenu,
|
|
260
|
+
{
|
|
261
|
+
label: "\u5BFC\u51FA",
|
|
262
|
+
items: [
|
|
263
|
+
{
|
|
264
|
+
key: "export-csv",
|
|
265
|
+
label: "\u5BFC\u51FA CSV",
|
|
266
|
+
onClick: exportAndClose(request.onExportCsv)
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
key: "export-xlsx",
|
|
270
|
+
label: "\u5BFC\u51FA XLSX",
|
|
271
|
+
onClick: exportAndClose(request.onExportXlsx)
|
|
272
|
+
},
|
|
273
|
+
...["all", "selection", "viewport"].map(
|
|
274
|
+
(scope) => ({
|
|
275
|
+
key: `export-image-${scope}`,
|
|
276
|
+
label: `\u5BFC\u51FA\u56FE\u7247 \xB7 ${{ all: "\u6240\u6709\u533A\u57DF", selection: "\u9009\u4E2D\u533A\u57DF", viewport: "\u89C6\u53E3\u533A\u57DF" }[scope]}`,
|
|
277
|
+
onClick: exportAndClose(
|
|
278
|
+
scope === "selection" && !request.hasImageSelection ? void 0 : request.onExportImage ? () => request.onExportImage?.(scope) : void 0
|
|
279
|
+
)
|
|
280
|
+
})
|
|
281
|
+
)
|
|
282
|
+
]
|
|
283
|
+
}
|
|
284
|
+
),
|
|
285
|
+
request.recordCount != null ? /* @__PURE__ */ jsxs(
|
|
286
|
+
"div",
|
|
287
|
+
{
|
|
288
|
+
style: {
|
|
289
|
+
padding: "8px 10px",
|
|
290
|
+
color: "#8f959e",
|
|
291
|
+
fontSize: 12
|
|
292
|
+
},
|
|
293
|
+
children: [
|
|
294
|
+
"\u4E0B\u94BB\u8BB0\u5F55 ",
|
|
295
|
+
request.recordCount,
|
|
296
|
+
" \u6761"
|
|
297
|
+
]
|
|
298
|
+
}
|
|
299
|
+
) : null
|
|
300
|
+
] }) })
|
|
301
|
+
}
|
|
302
|
+
)
|
|
303
|
+
] });
|
|
116
304
|
}
|
|
117
305
|
function HeaderMenu(props) {
|
|
118
306
|
const { request } = props;
|
|
@@ -144,7 +332,29 @@ function HeaderMenu(props) {
|
|
|
144
332
|
]
|
|
145
333
|
}
|
|
146
334
|
) : null,
|
|
147
|
-
request.
|
|
335
|
+
request.onAutoFitCurrentColumn || request.onAutoFitAllColumns ? /* @__PURE__ */ jsx(
|
|
336
|
+
MenuSubmenu,
|
|
337
|
+
{
|
|
338
|
+
label: "\u81EA\u52A8\u8C03\u6574\u5217\u5BBD",
|
|
339
|
+
items: [
|
|
340
|
+
{
|
|
341
|
+
key: "auto-fit-current",
|
|
342
|
+
label: "\u5F53\u524D\u5217",
|
|
343
|
+
onClick: request.onAutoFitCurrentColumn
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
key: "auto-fit-all",
|
|
347
|
+
label: "\u5168\u90E8\u5217",
|
|
348
|
+
onClick: request.onAutoFitAllColumns
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
key: "auto-fit-fill-container",
|
|
352
|
+
label: "\u81EA\u52A8\u94FA\u6EE1\u5BB9\u5668",
|
|
353
|
+
onClick: request.onAutoFitFillContainer
|
|
354
|
+
}
|
|
355
|
+
]
|
|
356
|
+
}
|
|
357
|
+
) : null,
|
|
148
358
|
hasExpand ? /* @__PURE__ */ jsx(
|
|
149
359
|
MenuSubmenu,
|
|
150
360
|
{
|
|
@@ -172,14 +382,35 @@ function HeaderMenu(props) {
|
|
|
172
382
|
}
|
|
173
383
|
function SummaryMenu(props) {
|
|
174
384
|
const { request } = props;
|
|
385
|
+
const [title, setTitle] = useState(request.summaryTitle ?? "");
|
|
175
386
|
const [precision, setPrecision] = useState(
|
|
176
387
|
request.summaryPrecision ?? null
|
|
177
388
|
);
|
|
389
|
+
const [roundingMode, setRoundingMode] = useState(
|
|
390
|
+
request.summaryRoundingMode ?? "round"
|
|
391
|
+
);
|
|
392
|
+
const [preserveTrailingZeros, setPreserveTrailingZeros] = useState(
|
|
393
|
+
request.summaryPreserveTrailingZeros ?? false
|
|
394
|
+
);
|
|
395
|
+
useEffect(() => {
|
|
396
|
+
setTitle(request.summaryTitle ?? "");
|
|
397
|
+
setPrecision(request.summaryPrecision ?? null);
|
|
398
|
+
setRoundingMode(request.summaryRoundingMode ?? "round");
|
|
399
|
+
setPreserveTrailingZeros(request.summaryPreserveTrailingZeros ?? false);
|
|
400
|
+
}, [
|
|
401
|
+
request.indicatorKey,
|
|
402
|
+
request.summaryTitle,
|
|
403
|
+
request.summaryPrecision,
|
|
404
|
+
request.summaryRoundingMode,
|
|
405
|
+
request.summaryPreserveTrailingZeros
|
|
406
|
+
]);
|
|
178
407
|
const aggregators = [
|
|
179
408
|
["sum", "\u6C42\u548C"],
|
|
180
409
|
["avg", "\u5E73\u5747\u503C"],
|
|
181
410
|
["count", "\u8BA1\u6570"],
|
|
182
411
|
["distinctCount", "\u53BB\u91CD\u8BA1\u6570"],
|
|
412
|
+
["rowCount", "\u884C\u6570"],
|
|
413
|
+
["mergedRowCount", "\u5408\u5E76\u884C\u6570"],
|
|
183
414
|
["min", "\u6700\u5C0F\u503C"],
|
|
184
415
|
["max", "\u6700\u5927\u503C"]
|
|
185
416
|
];
|
|
@@ -188,15 +419,62 @@ function SummaryMenu(props) {
|
|
|
188
419
|
MenuSubmenu,
|
|
189
420
|
{
|
|
190
421
|
label: "\u6C47\u603B\u65B9\u5F0F",
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
422
|
+
minWidth: 268,
|
|
423
|
+
header: request.onChangeSummaryTitle ? /* @__PURE__ */ jsxs(
|
|
424
|
+
"div",
|
|
425
|
+
{
|
|
426
|
+
style: {
|
|
427
|
+
display: "grid",
|
|
428
|
+
gridTemplateColumns: "56px 1fr",
|
|
429
|
+
gap: 8,
|
|
430
|
+
alignItems: "center",
|
|
431
|
+
padding: "2px 10px 10px",
|
|
432
|
+
marginBottom: 4,
|
|
433
|
+
borderBottom: "1px solid #e5e7eb"
|
|
434
|
+
},
|
|
435
|
+
children: [
|
|
436
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#374151", fontSize: 14 }, children: "\u6807\u9898\uFF1A" }),
|
|
437
|
+
/* @__PURE__ */ jsx(
|
|
438
|
+
ReactInput,
|
|
439
|
+
{
|
|
440
|
+
value: title,
|
|
441
|
+
placeholder: "\u8BF7\u8F93\u5165\u6807\u9898",
|
|
442
|
+
onChange: (event) => {
|
|
443
|
+
setTitle(event.target.value);
|
|
444
|
+
request.onChangeSummaryTitle?.(event.target.value);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
)
|
|
448
|
+
]
|
|
198
449
|
}
|
|
199
|
-
|
|
450
|
+
) : void 0,
|
|
451
|
+
items: [
|
|
452
|
+
...aggregators.map(([value, label]) => ({
|
|
453
|
+
key: `summary-${value}`,
|
|
454
|
+
label,
|
|
455
|
+
selected: !request.summaryDisabled && request.summaryAggregator === value,
|
|
456
|
+
onClick: () => {
|
|
457
|
+
request.onChangeSummaryAggregator?.(value);
|
|
458
|
+
request.onClose();
|
|
459
|
+
}
|
|
460
|
+
})),
|
|
461
|
+
{
|
|
462
|
+
key: "summary-prefix",
|
|
463
|
+
label: "\u5C55\u793A\u6C47\u603B\u65B9\u5F0F\u524D\u7F00",
|
|
464
|
+
separatorBefore: true,
|
|
465
|
+
selected: request.summaryShowTypePrefix !== false,
|
|
466
|
+
disabled: request.summaryDisabled,
|
|
467
|
+
onClick: () => request.onChangeSummaryShowTypePrefix?.(
|
|
468
|
+
request.summaryShowTypePrefix === false
|
|
469
|
+
)
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
key: "summary-clear",
|
|
473
|
+
label: "\u53D6\u6D88\u6C47\u603B",
|
|
474
|
+
separatorBefore: true,
|
|
475
|
+
onClick: request.onClearSummary
|
|
476
|
+
}
|
|
477
|
+
],
|
|
200
478
|
footer: request.onChangeSummaryPrecision ? /* @__PURE__ */ jsxs(
|
|
201
479
|
"div",
|
|
202
480
|
{
|
|
@@ -210,7 +488,7 @@ function SummaryMenu(props) {
|
|
|
210
488
|
borderTop: "1px solid #e5e7eb"
|
|
211
489
|
},
|
|
212
490
|
children: [
|
|
213
|
-
/* @__PURE__ */ jsx("span", { style: { color: "#374151", fontSize:
|
|
491
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#374151", fontSize: 14 }, children: "\u5C0F\u6570\u4F4D\u6570" }),
|
|
214
492
|
/* @__PURE__ */ jsx(
|
|
215
493
|
ReactInputNumber,
|
|
216
494
|
{
|
|
@@ -219,10 +497,42 @@ function SummaryMenu(props) {
|
|
|
219
497
|
max: 20,
|
|
220
498
|
step: 1,
|
|
221
499
|
precision: 0,
|
|
222
|
-
placeholder: "\
|
|
500
|
+
placeholder: "\u9ED8\u8BA4",
|
|
501
|
+
onChange: setPrecision,
|
|
502
|
+
onCommit: (value) => request.onChangeSummaryPrecision?.(value ?? void 0)
|
|
503
|
+
}
|
|
504
|
+
),
|
|
505
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#374151", fontSize: 14 }, children: "\u53D6\u6574\u65B9\u5F0F" }),
|
|
506
|
+
/* @__PURE__ */ jsx(
|
|
507
|
+
ReactSelect,
|
|
508
|
+
{
|
|
509
|
+
value: roundingMode,
|
|
510
|
+
options: [
|
|
511
|
+
{ label: "\u56DB\u820D\u4E94\u5165", value: "round" },
|
|
512
|
+
{ label: "\u5411\u4E0B\u53D6\u6574", value: "floor" },
|
|
513
|
+
{ label: "\u5411\u4E0A\u53D6\u6574", value: "ceil" },
|
|
514
|
+
{ label: "\u820D\u53BB\u4E0D\u5904\u7406", value: "truncate" }
|
|
515
|
+
],
|
|
516
|
+
onChange: (value) => {
|
|
517
|
+
const mode = value;
|
|
518
|
+
setRoundingMode(mode);
|
|
519
|
+
request.onChangeSummaryRoundingMode?.(mode);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
),
|
|
523
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#374151", fontSize: 14 }, children: "\u4FDD\u7559\u65E0\u6548\u96F6" }),
|
|
524
|
+
/* @__PURE__ */ jsx(
|
|
525
|
+
ReactSelect,
|
|
526
|
+
{
|
|
527
|
+
value: preserveTrailingZeros ? "true" : "false",
|
|
528
|
+
options: [
|
|
529
|
+
{ label: "\u4E0D\u4FDD\u7559", value: "false" },
|
|
530
|
+
{ label: "\u4FDD\u7559", value: "true" }
|
|
531
|
+
],
|
|
223
532
|
onChange: (value) => {
|
|
224
|
-
|
|
225
|
-
|
|
533
|
+
const enabled = value === "true";
|
|
534
|
+
setPreserveTrailingZeros(enabled);
|
|
535
|
+
request.onChangeSummaryPreserveTrailingZeros?.(enabled);
|
|
226
536
|
}
|
|
227
537
|
}
|
|
228
538
|
)
|
|
@@ -419,7 +729,7 @@ function MenuAction(props) {
|
|
|
419
729
|
);
|
|
420
730
|
}
|
|
421
731
|
function MenuSubmenu(props) {
|
|
422
|
-
const { label, items, footer, children, minWidth = 220 } = props;
|
|
732
|
+
const { label, items, footer, header, children, minWidth = 220 } = props;
|
|
423
733
|
const menuItems = items.filter((item) => item.onClick || item.disabled);
|
|
424
734
|
const reserveSelectionIcon = menuItems.some(
|
|
425
735
|
(item) => typeof item.selected === "boolean"
|
|
@@ -427,7 +737,7 @@ function MenuSubmenu(props) {
|
|
|
427
737
|
const triggerRef = useRef(null);
|
|
428
738
|
const [open, setOpen] = useState(false);
|
|
429
739
|
const closeTimerRef = useRef(null);
|
|
430
|
-
if (!menuItems.length && !footer && !children) return null;
|
|
740
|
+
if (!menuItems.length && !footer && !header && !children) return null;
|
|
431
741
|
const clearCloseTimer = () => {
|
|
432
742
|
if (closeTimerRef.current != null) {
|
|
433
743
|
window.clearTimeout(closeTimerRef.current);
|
|
@@ -494,6 +804,7 @@ function MenuSubmenu(props) {
|
|
|
494
804
|
onOpenChange: setOpen,
|
|
495
805
|
surfaceStyle: { ...CONTEXT_MENU_SURFACE_STYLE, width: minWidth },
|
|
496
806
|
children: /* @__PURE__ */ jsxs("div", { onMouseEnter: clearCloseTimer, onMouseLeave: scheduleClose, children: [
|
|
807
|
+
header,
|
|
497
808
|
menuItems.map((item) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
498
809
|
item.separatorBefore ? /* @__PURE__ */ jsx(MenuDivider, {}) : null,
|
|
499
810
|
/* @__PURE__ */ jsx(
|
|
@@ -691,54 +1002,15 @@ function DataFormatMenu(props) {
|
|
|
691
1002
|
);
|
|
692
1003
|
}
|
|
693
1004
|
function PivotExportNameDialog({
|
|
694
|
-
request
|
|
1005
|
+
request,
|
|
1006
|
+
onClose
|
|
695
1007
|
}) {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
extension ? request.fileName.slice(0, -extension.length) : request.fileName
|
|
699
|
-
);
|
|
700
|
-
const [invalid, setInvalid] = useState(false);
|
|
701
|
-
const confirm = () => {
|
|
702
|
-
if (!fileName.trim()) {
|
|
703
|
-
setInvalid(true);
|
|
704
|
-
return;
|
|
705
|
-
}
|
|
706
|
-
request.onConfirm(`${fileName.trim()}${extension}`);
|
|
707
|
-
};
|
|
708
|
-
return /* @__PURE__ */ jsxs(
|
|
709
|
-
ReactModal,
|
|
1008
|
+
return /* @__PURE__ */ jsx(
|
|
1009
|
+
ReactListTableExportNameDialog,
|
|
710
1010
|
{
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
fullscreenable: false,
|
|
715
|
-
onCancel: request.onCancel,
|
|
716
|
-
onOk: confirm,
|
|
717
|
-
okText: "\u5BFC\u51FA",
|
|
718
|
-
cancelText: "\u53D6\u6D88",
|
|
719
|
-
children: [
|
|
720
|
-
/* @__PURE__ */ jsxs("label", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
|
|
721
|
-
"\u6587\u4EF6\u540D\u79F0",
|
|
722
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
723
|
-
/* @__PURE__ */ jsx(
|
|
724
|
-
ReactInput,
|
|
725
|
-
{
|
|
726
|
-
autoFocus: true,
|
|
727
|
-
value: fileName,
|
|
728
|
-
placeholder: "\u8BF7\u8F93\u5165\u6587\u4EF6\u540D\u79F0",
|
|
729
|
-
onFocus: (event) => event.target.select(),
|
|
730
|
-
onChange: (event) => {
|
|
731
|
-
setFileName(event.target.value);
|
|
732
|
-
setInvalid(false);
|
|
733
|
-
},
|
|
734
|
-
onPressEnter: confirm
|
|
735
|
-
}
|
|
736
|
-
),
|
|
737
|
-
/* @__PURE__ */ jsx("span", { "aria-label": "\u6587\u4EF6\u540E\u7F00", style: { flexShrink: 0 }, children: extension })
|
|
738
|
-
] })
|
|
739
|
-
] }),
|
|
740
|
-
invalid ? /* @__PURE__ */ jsx("div", { role: "alert", style: { color: "#ff4d4f", marginTop: 8 }, children: "\u8BF7\u8F93\u5165\u6587\u4EF6\u540D\u79F0" }) : null
|
|
741
|
-
]
|
|
1011
|
+
request,
|
|
1012
|
+
onClose,
|
|
1013
|
+
renderTable: (props) => /* @__PURE__ */ jsx(ReactListTable, { ...props })
|
|
742
1014
|
}
|
|
743
1015
|
);
|
|
744
1016
|
}
|
|
@@ -1274,7 +1546,9 @@ var aggregatorOptions = [
|
|
|
1274
1546
|
{ label: "\u5E73\u5747\u503C", value: "avg" },
|
|
1275
1547
|
{ label: "\u6700\u5927\u503C", value: "max" },
|
|
1276
1548
|
{ label: "\u6700\u5C0F\u503C", value: "min" },
|
|
1277
|
-
{ label: "\u53BB\u91CD\u8BA1\u6570", value: "distinctCount" }
|
|
1549
|
+
{ label: "\u53BB\u91CD\u8BA1\u6570", value: "distinctCount" },
|
|
1550
|
+
{ label: "\u884C\u6570", value: "rowCount" },
|
|
1551
|
+
{ label: "\u5408\u5E76\u884C\u6570", value: "mergedRowCount" }
|
|
1278
1552
|
];
|
|
1279
1553
|
var popupStyle = {
|
|
1280
1554
|
padding: 0,
|
|
@@ -1729,7 +2003,14 @@ function resolveReactPivotTableDebugOptions(debug, inheritedEnabled) {
|
|
|
1729
2003
|
};
|
|
1730
2004
|
}
|
|
1731
2005
|
function ReactPivotTableInner(props, ref) {
|
|
1732
|
-
const {
|
|
2006
|
+
const {
|
|
2007
|
+
className,
|
|
2008
|
+
style,
|
|
2009
|
+
customization,
|
|
2010
|
+
pivotAreas,
|
|
2011
|
+
title,
|
|
2012
|
+
...tableOptions
|
|
2013
|
+
} = props;
|
|
1733
2014
|
const inheritedDebugEnabled = useReactPivotTableDebugEnabled();
|
|
1734
2015
|
const resolvedDebug = useMemo(
|
|
1735
2016
|
() => resolveReactPivotTableDebugOptions(
|
|
@@ -1742,6 +2023,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1742
2023
|
const tableRef = useRef(null);
|
|
1743
2024
|
const customizationOptions = customization && typeof customization === "object" ? customization : void 0;
|
|
1744
2025
|
const customizationEnabled = customization === true || customizationOptions != null;
|
|
2026
|
+
const pivotLayoutEnabled = customizationEnabled || pivotAreas != null;
|
|
1745
2027
|
const [internalPanelOpen, setInternalPanelOpen] = useState(
|
|
1746
2028
|
customizationOptions?.defaultOpen ?? false
|
|
1747
2029
|
);
|
|
@@ -1756,13 +2038,35 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1756
2038
|
const chartIdRef = useRef(0);
|
|
1757
2039
|
const layoutRevisionRef = useRef(0);
|
|
1758
2040
|
const [internalLayout, setInternalLayout] = useState(
|
|
1759
|
-
() => customizationOptions?.defaultLayout ??
|
|
2041
|
+
() => pivotAreas ?? customizationOptions?.defaultLayout ?? createPivotFieldLayout({
|
|
2042
|
+
filterDimensions: tableOptions.filterDimensions,
|
|
2043
|
+
columns: tableOptions.columns,
|
|
2044
|
+
rows: tableOptions.rows,
|
|
2045
|
+
indicators: tableOptions.indicators
|
|
2046
|
+
})
|
|
1760
2047
|
);
|
|
1761
2048
|
const [fieldOverrides, setFieldOverrides] = useState({});
|
|
1762
2049
|
const [densityOverride, setDensityOverride] = useState(null);
|
|
2050
|
+
const [scrollbarOverride, setScrollbarOverride] = useState(null);
|
|
2051
|
+
const [sharedScrollbar, setSharedScrollbar] = useState(
|
|
2052
|
+
getSharedScrollbarSettings
|
|
2053
|
+
);
|
|
2054
|
+
useEffect(
|
|
2055
|
+
() => subscribeSharedScrollbarSettings(
|
|
2056
|
+
() => setSharedScrollbar(getSharedScrollbarSettings())
|
|
2057
|
+
),
|
|
2058
|
+
[]
|
|
2059
|
+
);
|
|
2060
|
+
const [scrollbarCacheEnabled, setScrollbarCacheEnabled] = useState(true);
|
|
2061
|
+
const scrollbarRevisionRef = useRef(0);
|
|
2062
|
+
const scrollbarStorageKey = customizationOptions?.storageKey;
|
|
2063
|
+
const effectiveScrollbar = sharedScrollbar.shared ? sharedScrollbar.value : scrollbarOverride ?? tableOptions.scrollbar;
|
|
1763
2064
|
const [filterRequest, setFilterRequest] = useState(null);
|
|
1764
2065
|
const [contextMenuRequest, setContextMenuRequest] = useState(null);
|
|
1765
2066
|
const [exportNameRequest, setExportNameRequest] = useState(null);
|
|
2067
|
+
const [exportLoadingText, setExportLoadingText] = useState(
|
|
2068
|
+
null
|
|
2069
|
+
);
|
|
1766
2070
|
const [tooltipRequest, setTooltipRequest] = useState(null);
|
|
1767
2071
|
const panelOpen = customizationOptions?.open ?? internalPanelOpen;
|
|
1768
2072
|
const fieldLayout = customizationOptions?.layout ?? internalLayout;
|
|
@@ -1803,6 +2107,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1803
2107
|
title: override.title ?? field.title,
|
|
1804
2108
|
indicator: {
|
|
1805
2109
|
...field.indicator,
|
|
2110
|
+
...override,
|
|
1806
2111
|
title: override.title ?? field.indicator?.title,
|
|
1807
2112
|
aggregator: override.aggregator ?? field.indicator?.aggregator,
|
|
1808
2113
|
precision: "precision" in override ? override.precision : field.indicator?.precision,
|
|
@@ -1813,8 +2118,8 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1813
2118
|
[baseFields, fieldOverrides]
|
|
1814
2119
|
);
|
|
1815
2120
|
const customizedOptions = useMemo(
|
|
1816
|
-
() =>
|
|
1817
|
-
[
|
|
2121
|
+
() => pivotLayoutEnabled ? resolvePivotFieldLayoutOptions(fields, fieldLayout) : null,
|
|
2122
|
+
[pivotLayoutEnabled, fieldLayout, fields]
|
|
1818
2123
|
);
|
|
1819
2124
|
const overriddenIndicators = useMemo(
|
|
1820
2125
|
() => tableOptions.indicators.map((indicator) => {
|
|
@@ -1822,6 +2127,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1822
2127
|
if (!override) return indicator;
|
|
1823
2128
|
return {
|
|
1824
2129
|
...indicator,
|
|
2130
|
+
...override,
|
|
1825
2131
|
title: override.title ?? indicator.title,
|
|
1826
2132
|
aggregator: override.aggregator ?? indicator.aggregator,
|
|
1827
2133
|
precision: "precision" in override ? override.precision : indicator.precision,
|
|
@@ -1837,10 +2143,12 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1837
2143
|
const options = {
|
|
1838
2144
|
...tableOptions,
|
|
1839
2145
|
...customizedOptions,
|
|
2146
|
+
scrollbar: effectiveScrollbar,
|
|
1840
2147
|
debug: resolvedDebug,
|
|
1841
2148
|
rowHeight: densityOverride == null ? tableOptions.rowHeight : resolveDensityRowHeight(densityOverride),
|
|
1842
2149
|
indicators: customizedOptions?.indicators ?? overriddenIndicators,
|
|
1843
2150
|
ui: {
|
|
2151
|
+
onLoadingRequest: (request) => setExportLoadingText(request ? request.text ?? "\u6B63\u5728\u5BFC\u51FA\u2026" : null),
|
|
1844
2152
|
onExportNameRequest: (request) => {
|
|
1845
2153
|
setExportNameRequest(request);
|
|
1846
2154
|
},
|
|
@@ -1851,6 +2159,39 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1851
2159
|
const fieldKey = request.indicatorKey;
|
|
1852
2160
|
const enhancedRequest = {
|
|
1853
2161
|
...request,
|
|
2162
|
+
scrollbar: effectiveScrollbar,
|
|
2163
|
+
cacheScrollbar: scrollbarCacheEnabled,
|
|
2164
|
+
scrollbarCacheAvailable: Boolean(scrollbarStorageKey),
|
|
2165
|
+
onChangeCacheScrollbar: (enabled) => {
|
|
2166
|
+
setScrollbarCacheEnabled(enabled);
|
|
2167
|
+
scrollbarRevisionRef.current += 1;
|
|
2168
|
+
if (scrollbarStorageKey)
|
|
2169
|
+
void savePivotScrollbarConfig(scrollbarStorageKey, {
|
|
2170
|
+
enabled,
|
|
2171
|
+
scrollbar: enabled ? effectiveScrollbar : void 0
|
|
2172
|
+
});
|
|
2173
|
+
},
|
|
2174
|
+
onChangeScrollbar: (value) => {
|
|
2175
|
+
setScrollbarOverride(value);
|
|
2176
|
+
if (getSharedScrollbarSettings().shared)
|
|
2177
|
+
setSharedScrollbarSettings({ shared: true, value });
|
|
2178
|
+
scrollbarRevisionRef.current += 1;
|
|
2179
|
+
if (scrollbarStorageKey && scrollbarCacheEnabled)
|
|
2180
|
+
void savePivotScrollbarConfig(scrollbarStorageKey, {
|
|
2181
|
+
enabled: true,
|
|
2182
|
+
scrollbar: value
|
|
2183
|
+
});
|
|
2184
|
+
},
|
|
2185
|
+
onResetScrollbar: () => {
|
|
2186
|
+
setScrollbarOverride(null);
|
|
2187
|
+
if (getSharedScrollbarSettings().shared)
|
|
2188
|
+
setSharedScrollbarSettings({ shared: true, value: {} });
|
|
2189
|
+
scrollbarRevisionRef.current += 1;
|
|
2190
|
+
if (scrollbarStorageKey && scrollbarCacheEnabled)
|
|
2191
|
+
void savePivotScrollbarConfig(scrollbarStorageKey, {
|
|
2192
|
+
enabled: true
|
|
2193
|
+
});
|
|
2194
|
+
},
|
|
1854
2195
|
onChangeDensity: (density) => {
|
|
1855
2196
|
nativeChangeDensity?.(density);
|
|
1856
2197
|
setDensityOverride(density);
|
|
@@ -1858,8 +2199,35 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1858
2199
|
onChangeDataFormat: fieldKey == null ? void 0 : (dataFormat) => updateField(fieldKey, { dataFormat })
|
|
1859
2200
|
};
|
|
1860
2201
|
if (request.target === "summary" && fieldKey != null) {
|
|
1861
|
-
|
|
1862
|
-
|
|
2202
|
+
const changeSummary = (patch, menuPatch) => {
|
|
2203
|
+
updateField(fieldKey, patch);
|
|
2204
|
+
setContextMenuRequest(
|
|
2205
|
+
(current) => current?.target === "summary" && current.indicatorKey === fieldKey ? { ...current, ...menuPatch } : current
|
|
2206
|
+
);
|
|
2207
|
+
};
|
|
2208
|
+
enhancedRequest.onChangeSummaryAggregator = (aggregator) => changeSummary(
|
|
2209
|
+
{
|
|
2210
|
+
aggregator,
|
|
2211
|
+
summaryAggregator: aggregator,
|
|
2212
|
+
summaryDisabled: false
|
|
2213
|
+
},
|
|
2214
|
+
{ summaryAggregator: aggregator, summaryDisabled: false }
|
|
2215
|
+
);
|
|
2216
|
+
enhancedRequest.onChangeSummaryPrecision = (precision) => changeSummary({ precision }, { summaryPrecision: precision });
|
|
2217
|
+
enhancedRequest.onChangeSummaryTitle = (summaryTitle) => changeSummary({ summaryTitle }, { summaryTitle });
|
|
2218
|
+
enhancedRequest.onChangeSummaryShowTypePrefix = (summaryShowTypePrefix) => changeSummary(
|
|
2219
|
+
{ summaryShowTypePrefix },
|
|
2220
|
+
{ summaryShowTypePrefix }
|
|
2221
|
+
);
|
|
2222
|
+
enhancedRequest.onChangeSummaryRoundingMode = (summaryRoundingMode) => changeSummary({ summaryRoundingMode }, { summaryRoundingMode });
|
|
2223
|
+
enhancedRequest.onChangeSummaryPreserveTrailingZeros = (summaryPreserveTrailingZeros) => changeSummary(
|
|
2224
|
+
{ summaryPreserveTrailingZeros },
|
|
2225
|
+
{ summaryPreserveTrailingZeros }
|
|
2226
|
+
);
|
|
2227
|
+
enhancedRequest.onClearSummary = () => changeSummary(
|
|
2228
|
+
{ summaryDisabled: true },
|
|
2229
|
+
{ summaryDisabled: true }
|
|
2230
|
+
);
|
|
1863
2231
|
}
|
|
1864
2232
|
setContextMenuRequest(enhancedRequest);
|
|
1865
2233
|
return;
|
|
@@ -1879,10 +2247,10 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1879
2247
|
};
|
|
1880
2248
|
const sharedFilterRequest = useMemo(() => {
|
|
1881
2249
|
if (!filterRequest) return null;
|
|
1882
|
-
const { axis, dimensionKey } = filterRequest;
|
|
2250
|
+
const { axis, dimensionKey, columnPathKey } = filterRequest;
|
|
1883
2251
|
return toSharedFilterRequest(filterRequest, (value) => {
|
|
1884
2252
|
setFilterRequest(
|
|
1885
|
-
(current) => current?.axis === axis && current.dimensionKey === dimensionKey ? { ...current, value } : current
|
|
2253
|
+
(current) => current?.axis === axis && current.dimensionKey === dimensionKey && current.columnPathKey === columnPathKey ? { ...current, value } : current
|
|
1886
2254
|
);
|
|
1887
2255
|
});
|
|
1888
2256
|
}, [filterRequest]);
|
|
@@ -1933,6 +2301,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1933
2301
|
title: patch.title ?? field.title,
|
|
1934
2302
|
indicator: {
|
|
1935
2303
|
...field.indicator,
|
|
2304
|
+
...patch,
|
|
1936
2305
|
title: patch.title ?? field.indicator?.title,
|
|
1937
2306
|
aggregator: patch.aggregator ?? field.indicator?.aggregator,
|
|
1938
2307
|
precision: "precision" in patch ? patch.precision : field.indicator?.precision,
|
|
@@ -1960,6 +2329,21 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1960
2329
|
table.updateOptions(options);
|
|
1961
2330
|
refreshChartModel();
|
|
1962
2331
|
}, [options]);
|
|
2332
|
+
useEffect(() => {
|
|
2333
|
+
if (!scrollbarStorageKey) return;
|
|
2334
|
+
let active = true;
|
|
2335
|
+
const revision = scrollbarRevisionRef.current;
|
|
2336
|
+
void loadPivotScrollbarConfig(scrollbarStorageKey).then((stored) => {
|
|
2337
|
+
if (!active || scrollbarRevisionRef.current !== revision || !stored)
|
|
2338
|
+
return;
|
|
2339
|
+
setScrollbarCacheEnabled(stored.enabled);
|
|
2340
|
+
if (stored.enabled && stored.scrollbar)
|
|
2341
|
+
setScrollbarOverride(stored.scrollbar);
|
|
2342
|
+
});
|
|
2343
|
+
return () => {
|
|
2344
|
+
active = false;
|
|
2345
|
+
};
|
|
2346
|
+
}, [scrollbarStorageKey]);
|
|
1963
2347
|
useEffect(() => {
|
|
1964
2348
|
const storageKey = customizationOptions?.storageKey;
|
|
1965
2349
|
if (!storageKey || customizationOptions?.layout !== void 0) return;
|
|
@@ -1984,6 +2368,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1984
2368
|
useImperativeHandle(
|
|
1985
2369
|
ref,
|
|
1986
2370
|
() => ({
|
|
2371
|
+
autoFitColumnWidths: (target, fillContainer) => tableRef.current?.autoFitColumnWidths(target, fillContainer) ?? false,
|
|
1987
2372
|
getPivotModel: () => tableRef.current?.getPivotModel() ?? null,
|
|
1988
2373
|
getVisibleRowNodes: () => tableRef.current?.getVisibleRowNodes() ?? [],
|
|
1989
2374
|
getVisibleColumnNodes: () => tableRef.current?.getVisibleColumnNodes() ?? [],
|
|
@@ -2005,6 +2390,15 @@ function ReactPivotTableInner(props, ref) {
|
|
|
2005
2390
|
expandAll: (axis) => tableRef.current?.expandAll(axis) ?? 0,
|
|
2006
2391
|
collapseAll: (axis) => tableRef.current?.collapseAll(axis) ?? 0,
|
|
2007
2392
|
setDimensionFilter: (axis, dimensionKey, filter) => tableRef.current?.setDimensionFilter(axis, dimensionKey, filter) ?? null,
|
|
2393
|
+
setIndicatorFilter: (indicatorKey, columnPathKey, filter) => tableRef.current?.setIndicatorFilter(
|
|
2394
|
+
indicatorKey,
|
|
2395
|
+
columnPathKey,
|
|
2396
|
+
filter
|
|
2397
|
+
) ?? null,
|
|
2398
|
+
getIndicatorFilterOptions: (indicatorKey, columnPathKey) => tableRef.current?.getIndicatorFilterOptions(
|
|
2399
|
+
indicatorKey,
|
|
2400
|
+
columnPathKey
|
|
2401
|
+
) ?? [],
|
|
2008
2402
|
getDimensionFilterOptions: (axis, dimensionKey) => tableRef.current?.getDimensionFilterOptions(axis, dimensionKey) ?? [],
|
|
2009
2403
|
resetFilters: () => tableRef.current?.resetFilters() ?? null,
|
|
2010
2404
|
setDimensionSort: (axis, dimensionKey, direction) => tableRef.current?.setDimensionSort(axis, dimensionKey, direction) ?? [],
|
|
@@ -2022,11 +2416,27 @@ function ReactPivotTableInner(props, ref) {
|
|
|
2022
2416
|
{
|
|
2023
2417
|
className: `react-pivot-table${className ? ` ${className}` : ""}`,
|
|
2024
2418
|
style: {
|
|
2419
|
+
position: "relative",
|
|
2025
2420
|
width: props.width ?? "100%",
|
|
2026
2421
|
height: props.height ?? "100%",
|
|
2027
2422
|
...style
|
|
2028
2423
|
},
|
|
2029
2424
|
children: [
|
|
2425
|
+
exportLoadingText ? /* @__PURE__ */ jsx(
|
|
2426
|
+
"div",
|
|
2427
|
+
{
|
|
2428
|
+
role: "status",
|
|
2429
|
+
style: {
|
|
2430
|
+
position: "absolute",
|
|
2431
|
+
inset: 0,
|
|
2432
|
+
zIndex: 10,
|
|
2433
|
+
display: "grid",
|
|
2434
|
+
placeItems: "center",
|
|
2435
|
+
background: "rgba(255,255,255,0.75)"
|
|
2436
|
+
},
|
|
2437
|
+
children: exportLoadingText
|
|
2438
|
+
}
|
|
2439
|
+
) : null,
|
|
2030
2440
|
/* @__PURE__ */ jsx(
|
|
2031
2441
|
PivotTitlebar,
|
|
2032
2442
|
{
|
|
@@ -2119,7 +2529,13 @@ function ReactPivotTableInner(props, ref) {
|
|
|
2119
2529
|
),
|
|
2120
2530
|
/* @__PURE__ */ jsx(ReactFilterPanel, { request: sharedFilterRequest }),
|
|
2121
2531
|
/* @__PURE__ */ jsx(PivotContextMenu, { request: contextMenuRequest }),
|
|
2122
|
-
exportNameRequest ? /* @__PURE__ */ jsx(
|
|
2532
|
+
exportNameRequest ? /* @__PURE__ */ jsx(
|
|
2533
|
+
PivotExportNameDialog,
|
|
2534
|
+
{
|
|
2535
|
+
request: exportNameRequest,
|
|
2536
|
+
onClose: () => setExportNameRequest(null)
|
|
2537
|
+
}
|
|
2538
|
+
) : null,
|
|
2123
2539
|
/* @__PURE__ */ jsx(PivotTooltip, { request: tooltipRequest })
|
|
2124
2540
|
] });
|
|
2125
2541
|
}
|