@canvas-components/react-list-table 0.3.18 → 0.3.20
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/dist/index.cjs +548 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +549 -15
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -4,9 +4,9 @@ var react = require('react');
|
|
|
4
4
|
var reactDom = require('react-dom');
|
|
5
5
|
var reactComponents = require('@canvas-components/react-components');
|
|
6
6
|
var listTable = require('@canvas-components/list-table');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
8
|
var date = require('@canvas-components/utils/date');
|
|
8
9
|
var number = require('@canvas-components/utils/number');
|
|
9
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
10
10
|
|
|
11
11
|
// #style-inject:#style-inject
|
|
12
12
|
function styleInject(css, { insertAt } = {}) {
|
|
@@ -32,6 +32,328 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
32
32
|
|
|
33
33
|
// src/styles/table-overrides.css
|
|
34
34
|
styleInject(".react-list-table-filter-option {\n transition: background-color 0.2s ease;\n}\n.react-list-table-filter-option:hover {\n background: #f3f4f6;\n}\n.react-list-table-menu-action,\n.react-list-table-menu-row {\n transition: background-color 0.2s ease, color 0.2s ease;\n}\n.react-list-table-menu-action:hover,\n.react-list-table-menu-row:hover {\n background: #f3f4f6 !important;\n}\n.react-list-table-custom-selection-copy {\n transition: background-color 0.2s ease;\n}\n.react-list-table-custom-selection-copy:hover {\n background: #4096ff !important;\n}\n.react-list-table-custom-selection-input > .canvas-react-input-number-handler-down {\n display: none;\n}\n.react-list-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-list-table-menu-action:hover .react-list-table-menu-chevron,\n.react-list-table-menu-row:hover .react-list-table-menu-chevron {\n border-color: #6b7280;\n transform: rotate(135deg);\n}\n.react-list-table-menu-chevron-active {\n border-color: #6b7280;\n transform: rotate(135deg);\n}\n");
|
|
35
|
+
var conditionalOperators = {
|
|
36
|
+
eq: "\u7B49\u4E8E",
|
|
37
|
+
neq: "\u4E0D\u7B49\u4E8E",
|
|
38
|
+
gt: "\u5927\u4E8E",
|
|
39
|
+
gte: "\u5927\u4E8E\u7B49\u4E8E",
|
|
40
|
+
lt: "\u5C0F\u4E8E",
|
|
41
|
+
lte: "\u5C0F\u4E8E\u7B49\u4E8E",
|
|
42
|
+
between: "\u4ECB\u4E8E\uFF08\u542B\u8FB9\u754C\uFF09",
|
|
43
|
+
contains: "\u5305\u542B\u6587\u672C",
|
|
44
|
+
empty: "\u4E3A\u7A7A",
|
|
45
|
+
notEmpty: "\u4E0D\u4E3A\u7A7A"
|
|
46
|
+
};
|
|
47
|
+
function describeConditionalRule(rule) {
|
|
48
|
+
return resolveConditions(rule).map(
|
|
49
|
+
(condition, index) => `${index === 0 ? "" : (condition.relation ?? rule.conditionRelation ?? "and") === "or" ? " \u6216 " : " \u4E14 "}${conditionalOperators[condition.operator]}${condition.operator === "empty" || condition.operator === "notEmpty" ? "" : ` ${condition.value ?? ""}`}${condition.operator === "between" ? ` \uFF5E ${condition.endValue ?? ""}` : ""}`
|
|
50
|
+
).join("");
|
|
51
|
+
}
|
|
52
|
+
function resolveConditions(rule) {
|
|
53
|
+
return rule.conditions ?? (rule.operator ? [
|
|
54
|
+
{
|
|
55
|
+
operator: rule.operator,
|
|
56
|
+
value: rule.value,
|
|
57
|
+
endValue: rule.endValue
|
|
58
|
+
}
|
|
59
|
+
] : []);
|
|
60
|
+
}
|
|
61
|
+
function validateConditionalRule(rule) {
|
|
62
|
+
const conditions = resolveConditions(rule);
|
|
63
|
+
if (!conditions.length) return "\u8BF7\u81F3\u5C11\u6DFB\u52A0\u4E00\u4E2A\u6761\u4EF6\u3002";
|
|
64
|
+
for (const [index, condition] of conditions.entries()) {
|
|
65
|
+
const error = validateCondition(condition);
|
|
66
|
+
if (error) return `\u6761\u4EF6 ${index + 1}\uFF1A${error}`;
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
function validateCondition(rule) {
|
|
71
|
+
if (rule.operator === "empty" || rule.operator === "notEmpty") return null;
|
|
72
|
+
if (String(rule.value ?? "").trim() === "")
|
|
73
|
+
return "\u8BF7\u8F93\u5165\u6BD4\u8F83\u503C\uFF1B\u7A7A\u503C\u8BF7\u4F7F\u7528\u201C\u4E3A\u7A7A\u201D\u6761\u4EF6\u3002";
|
|
74
|
+
if (["gt", "gte", "lt", "lte", "between"].includes(rule.operator)) {
|
|
75
|
+
if (!Number.isFinite(Number(rule.value))) return "\u8BF7\u8F93\u5165\u6709\u6548\u6570\u503C\u3002";
|
|
76
|
+
if (rule.operator === "between" && (String(rule.endValue ?? "").trim() === "" || !Number.isFinite(Number(rule.endValue)) || Number(rule.endValue) < Number(rule.value)))
|
|
77
|
+
return "\u8BF7\u8F93\u5165\u4E0D\u5C0F\u4E8E\u8D77\u59CB\u503C\u7684\u7ED3\u675F\u6570\u503C\u3002";
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
function ConditionalFormatDialog(props) {
|
|
82
|
+
const rules = props.request.conditionalFormats ?? [];
|
|
83
|
+
const [rule, setRule] = react.useState(
|
|
84
|
+
() => props.index == null ? {
|
|
85
|
+
id: `rule-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
86
|
+
operator: "gt",
|
|
87
|
+
value: "",
|
|
88
|
+
backgroundColor: "#fff1b8",
|
|
89
|
+
textColor: "#1f2329"
|
|
90
|
+
} : { ...rules[props.index] }
|
|
91
|
+
);
|
|
92
|
+
const [error, setError] = react.useState(null);
|
|
93
|
+
const conditions = resolveConditions(rule);
|
|
94
|
+
const patch = (value) => {
|
|
95
|
+
setRule((current) => ({ ...current, ...value }));
|
|
96
|
+
setError(null);
|
|
97
|
+
};
|
|
98
|
+
const apply = (next) => {
|
|
99
|
+
props.request.onChangeConditionalFormats?.(next);
|
|
100
|
+
props.onClose();
|
|
101
|
+
};
|
|
102
|
+
const patchCondition = (index, value) => {
|
|
103
|
+
patch({
|
|
104
|
+
conditions: conditions.map(
|
|
105
|
+
(condition, i) => i === index ? { ...condition, ...value } : condition
|
|
106
|
+
)
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
110
|
+
reactComponents.ReactModal,
|
|
111
|
+
{
|
|
112
|
+
open: true,
|
|
113
|
+
title: props.index == null ? "\u65B0\u589E\u6761\u4EF6\u683C\u5F0F\u89C4\u5219" : "\u7F16\u8F91\u6761\u4EF6\u683C\u5F0F\u89C4\u5219",
|
|
114
|
+
width: 460,
|
|
115
|
+
onCancel: props.onClose,
|
|
116
|
+
onOk: () => {
|
|
117
|
+
const message = validateConditionalRule(rule);
|
|
118
|
+
if (message) {
|
|
119
|
+
setError(message);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const next = rules.map((item) => ({ ...item }));
|
|
123
|
+
if (props.index == null) next.push(rule);
|
|
124
|
+
else next[props.index] = rule;
|
|
125
|
+
apply(next);
|
|
126
|
+
},
|
|
127
|
+
okText: "\u4FDD\u5B58\u89C4\u5219",
|
|
128
|
+
cancelText: "\u53D6\u6D88",
|
|
129
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gap: 14, fontSize: 14 }, children: [
|
|
130
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#64748b" }, children: "\u4EC5\u5F53\u524D\u5217\u751F\u6548\uFF1B\u4ECE\u4E0A\u5230\u4E0B\u5339\u914D\uFF0C\u9996\u6761\u547D\u4E2D\u7684\u80CC\u666F\u751F\u6548\u3002 \u6761\u4EF6\u4E4B\u95F4\u53EF\u5206\u522B\u8BBE\u7F6E\u201C\u4E14 / \u6216\u201D\uFF0C\u4E14\u4F18\u5148\u4E8E\u6216\u3002" }),
|
|
131
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
|
|
132
|
+
"\u89C4\u5219\u540D\u79F0\uFF08\u53EF\u9009\uFF09",
|
|
133
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
134
|
+
reactComponents.ReactInput,
|
|
135
|
+
{
|
|
136
|
+
value: rule.name ?? "",
|
|
137
|
+
onChange: (event) => patch({ name: event.target.value })
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
] }),
|
|
141
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
142
|
+
"div",
|
|
143
|
+
{
|
|
144
|
+
style: {
|
|
145
|
+
display: "grid",
|
|
146
|
+
gap: 12,
|
|
147
|
+
maxHeight: "35vh",
|
|
148
|
+
overflowY: "auto"
|
|
149
|
+
},
|
|
150
|
+
children: conditions.map((condition, index) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
151
|
+
index > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
152
|
+
reactComponents.ReactSelect,
|
|
153
|
+
{
|
|
154
|
+
"aria-label": `\u6761\u4EF6 ${index} \u4E0E\u6761\u4EF6 ${index + 1} \u7684\u5173\u7CFB`,
|
|
155
|
+
value: condition.relation ?? rule.conditionRelation ?? "and",
|
|
156
|
+
options: [
|
|
157
|
+
{ value: "and", label: "\u4E14" },
|
|
158
|
+
{ value: "or", label: "\u6216" }
|
|
159
|
+
],
|
|
160
|
+
onChange: (value) => patchCondition(index, { relation: value }),
|
|
161
|
+
style: { width: 88, justifySelf: "center" }
|
|
162
|
+
}
|
|
163
|
+
),
|
|
164
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
165
|
+
"div",
|
|
166
|
+
{
|
|
167
|
+
style: {
|
|
168
|
+
display: "grid",
|
|
169
|
+
gap: 8,
|
|
170
|
+
padding: 12,
|
|
171
|
+
border: "1px solid #d9e1ec"
|
|
172
|
+
},
|
|
173
|
+
children: [
|
|
174
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
175
|
+
"div",
|
|
176
|
+
{
|
|
177
|
+
style: {
|
|
178
|
+
display: "flex",
|
|
179
|
+
justifyContent: "space-between",
|
|
180
|
+
alignItems: "center"
|
|
181
|
+
},
|
|
182
|
+
children: [
|
|
183
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
184
|
+
"\u6761\u4EF6 ",
|
|
185
|
+
index + 1
|
|
186
|
+
] }),
|
|
187
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
188
|
+
reactComponents.ReactButton,
|
|
189
|
+
{
|
|
190
|
+
type: "text",
|
|
191
|
+
size: "small",
|
|
192
|
+
disabled: conditions.length === 1,
|
|
193
|
+
"aria-label": `\u5220\u9664\u6761\u4EF6 ${index + 1}`,
|
|
194
|
+
onClick: () => patch({
|
|
195
|
+
conditions: conditions.filter((_, i) => i !== index)
|
|
196
|
+
}),
|
|
197
|
+
children: "\u5220\u9664\u6761\u4EF6"
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
),
|
|
203
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
204
|
+
reactComponents.ReactSelect,
|
|
205
|
+
{
|
|
206
|
+
"aria-label": `\u6761\u4EF6 ${index + 1} \u6BD4\u8F83\u65B9\u5F0F`,
|
|
207
|
+
value: condition.operator,
|
|
208
|
+
options: Object.entries(conditionalOperators).map(
|
|
209
|
+
([value, label]) => ({ value, label })
|
|
210
|
+
),
|
|
211
|
+
onChange: (value) => patchCondition(index, {
|
|
212
|
+
operator: value
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
),
|
|
216
|
+
condition.operator !== "empty" && condition.operator !== "notEmpty" && /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
|
|
217
|
+
"\u6BD4\u8F83\u503C",
|
|
218
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
219
|
+
reactComponents.ReactInput,
|
|
220
|
+
{
|
|
221
|
+
value: String(condition.value ?? ""),
|
|
222
|
+
onChange: (event) => patchCondition(index, { value: event.target.value })
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
] }),
|
|
226
|
+
condition.operator === "between" && /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
|
|
227
|
+
"\u7ED3\u675F\u503C",
|
|
228
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
229
|
+
reactComponents.ReactInput,
|
|
230
|
+
{
|
|
231
|
+
value: String(condition.endValue ?? ""),
|
|
232
|
+
onChange: (event) => patchCondition(index, { endValue: event.target.value })
|
|
233
|
+
}
|
|
234
|
+
)
|
|
235
|
+
] })
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
] }, index))
|
|
240
|
+
}
|
|
241
|
+
),
|
|
242
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
243
|
+
reactComponents.ReactButton,
|
|
244
|
+
{
|
|
245
|
+
onClick: () => patch({
|
|
246
|
+
conditions: [
|
|
247
|
+
...conditions,
|
|
248
|
+
{ operator: "gt", value: "", relation: "and" }
|
|
249
|
+
]
|
|
250
|
+
}),
|
|
251
|
+
children: "\u65B0\u589E\u6761\u4EF6"
|
|
252
|
+
}
|
|
253
|
+
),
|
|
254
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "grid", gap: 4 }, children: [
|
|
255
|
+
"\u5355\u5143\u683C\u80CC\u666F",
|
|
256
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
257
|
+
reactComponents.ReactColorPicker,
|
|
258
|
+
{
|
|
259
|
+
"aria-label": "\u5355\u5143\u683C\u80CC\u666F",
|
|
260
|
+
value: rule.backgroundColor,
|
|
261
|
+
onChange: (backgroundColor) => patch({ backgroundColor })
|
|
262
|
+
}
|
|
263
|
+
)
|
|
264
|
+
] }),
|
|
265
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "grid", gap: 4 }, children: [
|
|
266
|
+
"\u6587\u672C\u989C\u8272",
|
|
267
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
268
|
+
reactComponents.ReactColorPicker,
|
|
269
|
+
{
|
|
270
|
+
"aria-label": "\u6587\u672C\u989C\u8272",
|
|
271
|
+
value: rule.textColor,
|
|
272
|
+
onChange: (textColor) => patch({ textColor })
|
|
273
|
+
}
|
|
274
|
+
)
|
|
275
|
+
] }),
|
|
276
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
277
|
+
"div",
|
|
278
|
+
{
|
|
279
|
+
style: {
|
|
280
|
+
padding: "8px 12px",
|
|
281
|
+
backgroundColor: rule.backgroundColor,
|
|
282
|
+
color: rule.textColor,
|
|
283
|
+
border: "1px solid #d9e1ec"
|
|
284
|
+
},
|
|
285
|
+
children: [
|
|
286
|
+
"\u6837\u5F0F\u9884\u89C8\uFF1A",
|
|
287
|
+
describeConditionalRule(rule)
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
),
|
|
291
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "alert", style: { color: "#cf1322" }, children: error }),
|
|
292
|
+
props.index != null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
293
|
+
reactComponents.ReactButton,
|
|
294
|
+
{
|
|
295
|
+
type: "text",
|
|
296
|
+
danger: true,
|
|
297
|
+
onClick: () => apply(rules.filter((_, index) => index !== props.index)),
|
|
298
|
+
children: "\u5220\u9664\u6B64\u89C4\u5219"
|
|
299
|
+
}
|
|
300
|
+
)
|
|
301
|
+
] })
|
|
302
|
+
}
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// src/features/context-menu/cache-menu.ts
|
|
307
|
+
function buildCacheMenuItems(request) {
|
|
308
|
+
const available = request.columnSettingsCacheAvailable === true;
|
|
309
|
+
const items = [];
|
|
310
|
+
const state = {
|
|
311
|
+
disabled: !available,
|
|
312
|
+
title: available ? void 0 : "\u914D\u7F6E storageKey \u540E\u53EF\u7F13\u5B58\u914D\u7F6E"
|
|
313
|
+
};
|
|
314
|
+
if (request.onChangeColumnSettingsCache)
|
|
315
|
+
items.push({
|
|
316
|
+
...state,
|
|
317
|
+
key: "cache-columns",
|
|
318
|
+
label: "\u5217\u8BBE\u7F6E",
|
|
319
|
+
selected: available && request.cacheColumnSettings === true,
|
|
320
|
+
onClick: () => request.onChangeColumnSettingsCache?.(!request.cacheColumnSettings)
|
|
321
|
+
});
|
|
322
|
+
if (request.onChangeCachePreference) {
|
|
323
|
+
const categories = [
|
|
324
|
+
["sort", "\u6392\u5E8F"],
|
|
325
|
+
["filter", "\u7B5B\u9009"],
|
|
326
|
+
["summary", "\u6C47\u603B"],
|
|
327
|
+
["alignment", "\u5BF9\u9F50"],
|
|
328
|
+
["dataFormat", "\u683C\u5F0F"],
|
|
329
|
+
["density", "\u8868\u683C\u5BC6\u5EA6"],
|
|
330
|
+
["zoom", "\u7F29\u653E"]
|
|
331
|
+
];
|
|
332
|
+
for (const [category, label] of categories)
|
|
333
|
+
items.push({
|
|
334
|
+
...state,
|
|
335
|
+
key: `cache-${category}`,
|
|
336
|
+
label,
|
|
337
|
+
selected: available && request.cachePreferences?.[category] !== false,
|
|
338
|
+
onClick: () => request.onChangeCachePreference?.(
|
|
339
|
+
category,
|
|
340
|
+
request.cachePreferences?.[category] === false
|
|
341
|
+
)
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
if (request.onChangeConditionalFormats)
|
|
345
|
+
items.push({
|
|
346
|
+
...state,
|
|
347
|
+
key: "cache-conditional",
|
|
348
|
+
label: "\u5F53\u524D\u5217\u6761\u4EF6\u683C\u5F0F",
|
|
349
|
+
selected: available && request.cacheConditionalFormats !== false,
|
|
350
|
+
onClick: () => request.onChangeConditionalFormats?.(
|
|
351
|
+
request.conditionalFormats ?? [],
|
|
352
|
+
request.cacheConditionalFormats === false
|
|
353
|
+
)
|
|
354
|
+
});
|
|
355
|
+
return items;
|
|
356
|
+
}
|
|
35
357
|
var CONTEXT_MENU_SURFACE_STYLE = {
|
|
36
358
|
padding: 8,
|
|
37
359
|
background: "#ffffff",
|
|
@@ -40,10 +362,22 @@ var CONTEXT_MENU_SURFACE_STYLE = {
|
|
|
40
362
|
function ReactTableContextMenuView(props) {
|
|
41
363
|
const { request } = props;
|
|
42
364
|
const [menuOpen, setMenuOpen] = react.useState(true);
|
|
365
|
+
const [conditionalEditor, setConditionalEditor] = react.useState(null);
|
|
366
|
+
const conditionalDialog = conditionalEditor ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
367
|
+
ConditionalFormatDialog,
|
|
368
|
+
{
|
|
369
|
+
...conditionalEditor,
|
|
370
|
+
onClose: () => {
|
|
371
|
+
setConditionalEditor(null);
|
|
372
|
+
conditionalEditor.request.onClose();
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
) : null;
|
|
43
376
|
const [moreFormatRequest, setMoreFormatRequest] = react.useState(null);
|
|
44
377
|
const [customSelectionRequest, setCustomSelectionRequest] = react.useState(null);
|
|
45
378
|
if (!request) {
|
|
46
379
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
380
|
+
conditionalDialog,
|
|
47
381
|
moreFormatRequest ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
48
382
|
MoreFormatDialog,
|
|
49
383
|
{
|
|
@@ -68,15 +402,17 @@ function ReactTableContextMenuView(props) {
|
|
|
68
402
|
width: 260
|
|
69
403
|
};
|
|
70
404
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
405
|
+
conditionalDialog,
|
|
71
406
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
72
407
|
reactComponents.ReactPopup,
|
|
73
408
|
{
|
|
409
|
+
constrainHeight: true,
|
|
74
410
|
open: menuOpen,
|
|
75
411
|
anchorRect: { x: request.x, y: request.y, width: 0, height: 0 },
|
|
76
412
|
minWidth: 260,
|
|
77
413
|
onOpenChange: (open) => {
|
|
78
414
|
setMenuOpen(open);
|
|
79
|
-
if (!open && !moreFormatRequest && !customSelectionRequest) {
|
|
415
|
+
if (!open && !moreFormatRequest && !customSelectionRequest && !conditionalEditor) {
|
|
80
416
|
request.onClose();
|
|
81
417
|
}
|
|
82
418
|
},
|
|
@@ -111,7 +447,28 @@ function ReactTableContextMenuView(props) {
|
|
|
111
447
|
key: "copy-selection",
|
|
112
448
|
label: "\u590D\u5236\u9009\u533A",
|
|
113
449
|
onClick: request.onCopySelection
|
|
114
|
-
}
|
|
450
|
+
},
|
|
451
|
+
...request.onCopyImage ? [
|
|
452
|
+
{
|
|
453
|
+
key: "copy-image-all",
|
|
454
|
+
label: "\u590D\u5236\u4E3A\u56FE\u7247 \xB7 \u6240\u6709\u533A\u57DF",
|
|
455
|
+
separatorBefore: true,
|
|
456
|
+
title: "\u5F53\u524D\u5DF2\u52A0\u8F7D\u5E76\u7ECF\u8FC7\u6392\u5E8F\u8FC7\u6EE4\u7684\u5168\u90E8\u6570\u636E\uFF0C\u4E0D\u8BF7\u6C42\u672A\u52A0\u8F7D\u7684\u670D\u52A1\u7AEF\u6570\u636E",
|
|
457
|
+
onClick: () => request.onCopyImage?.("all")
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
key: "copy-image-selection",
|
|
461
|
+
label: "\u590D\u5236\u4E3A\u56FE\u7247 \xB7 \u9009\u4E2D\u533A\u57DF",
|
|
462
|
+
disabled: !request.canCopySelectionImage,
|
|
463
|
+
onClick: () => request.onCopyImage?.("selection")
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
key: "copy-image-viewport",
|
|
467
|
+
label: "\u590D\u5236\u4E3A\u56FE\u7247 \xB7 \u89C6\u53E3\u533A\u57DF",
|
|
468
|
+
title: "\u5F53\u524D\u53EF\u89C1\u8868\u683C\uFF0C\u5305\u542B\u8868\u5934\u548C\u6C47\u603B\u884C\uFF0C\u4E0D\u5305\u542B\u5206\u9875\u5668\u548C\u83DC\u5355",
|
|
469
|
+
onClick: () => request.onCopyImage?.("viewport")
|
|
470
|
+
}
|
|
471
|
+
] : []
|
|
115
472
|
],
|
|
116
473
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
117
474
|
CustomSelectionMenu,
|
|
@@ -150,7 +507,26 @@ function ReactTableContextMenuView(props) {
|
|
|
150
507
|
key: "export-json",
|
|
151
508
|
label: "\u5BFC\u51FA JSON",
|
|
152
509
|
onClick: request.onExportJson
|
|
153
|
-
}
|
|
510
|
+
},
|
|
511
|
+
...request.onExportImage ? [
|
|
512
|
+
{
|
|
513
|
+
key: "export-image-all",
|
|
514
|
+
label: "\u5BFC\u51FA\u56FE\u7247 \xB7 \u6240\u6709\u533A\u57DF",
|
|
515
|
+
separatorBefore: true,
|
|
516
|
+
onClick: () => request.onExportImage?.("all")
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
key: "export-image-selection",
|
|
520
|
+
label: "\u5BFC\u51FA\u56FE\u7247 \xB7 \u9009\u4E2D\u533A\u57DF",
|
|
521
|
+
disabled: !request.canCopySelectionImage,
|
|
522
|
+
onClick: () => request.onExportImage?.("selection")
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
key: "export-image-viewport",
|
|
526
|
+
label: "\u5BFC\u51FA\u56FE\u7247 \xB7 \u89C6\u53E3\u533A\u57DF",
|
|
527
|
+
onClick: () => request.onExportImage?.("viewport")
|
|
528
|
+
}
|
|
529
|
+
] : []
|
|
154
530
|
]
|
|
155
531
|
}
|
|
156
532
|
),
|
|
@@ -223,6 +599,41 @@ function ReactTableContextMenuView(props) {
|
|
|
223
599
|
),
|
|
224
600
|
/* @__PURE__ */ jsxRuntime.jsx(SummaryMenu, { request }),
|
|
225
601
|
/* @__PURE__ */ jsxRuntime.jsx(AlignmentMenu, { request }),
|
|
602
|
+
request.onChangeConditionalFormats && /* @__PURE__ */ jsxRuntime.jsx(
|
|
603
|
+
MenuSubmenu,
|
|
604
|
+
{
|
|
605
|
+
label: "\u6761\u4EF6\u683C\u5F0F",
|
|
606
|
+
items: [
|
|
607
|
+
{
|
|
608
|
+
key: "add-rule",
|
|
609
|
+
label: "\u65B0\u589E\u89C4\u5219",
|
|
610
|
+
onClick: () => {
|
|
611
|
+
setConditionalEditor({ request, index: null });
|
|
612
|
+
setMenuOpen(false);
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
key: "reset-rules",
|
|
617
|
+
label: "\u91CD\u7F6E\u6761\u4EF6\u683C\u5F0F",
|
|
618
|
+
disabled: !request.conditionalFormats?.length,
|
|
619
|
+
onClick: () => request.onChangeConditionalFormats?.([])
|
|
620
|
+
}
|
|
621
|
+
],
|
|
622
|
+
header: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "grid", gap: 4, paddingBottom: 8 }, children: request.conditionalFormats?.length ? request.conditionalFormats.map((rule, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
623
|
+
MenuAction,
|
|
624
|
+
{
|
|
625
|
+
label: rule.name?.trim() || `\u89C4\u5219 ${index + 1}`,
|
|
626
|
+
colorSwatch: rule.backgroundColor,
|
|
627
|
+
title: `${rule.name?.trim() || `\u89C4\u5219 ${index + 1}`}\uFF1A${describeConditionalRule(rule)}`,
|
|
628
|
+
onClick: () => {
|
|
629
|
+
setConditionalEditor({ request, index });
|
|
630
|
+
setMenuOpen(false);
|
|
631
|
+
}
|
|
632
|
+
},
|
|
633
|
+
rule.id
|
|
634
|
+
)) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#64748b", padding: 8 }, children: "\u6682\u65E0\u89C4\u5219" }) })
|
|
635
|
+
}
|
|
636
|
+
),
|
|
226
637
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
227
638
|
DataFormatMenu,
|
|
228
639
|
{
|
|
@@ -353,6 +764,13 @@ function ReactTableContextMenuView(props) {
|
|
|
353
764
|
}
|
|
354
765
|
),
|
|
355
766
|
/* @__PURE__ */ jsxRuntime.jsx(ZoomMenu, { value: request.zoom ?? 1, onChange: request.onChangeZoom }),
|
|
767
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
768
|
+
MenuSubmenu,
|
|
769
|
+
{
|
|
770
|
+
label: "\u7F13\u5B58\u5230\u672C\u5730",
|
|
771
|
+
items: buildCacheMenuItems(request)
|
|
772
|
+
}
|
|
773
|
+
),
|
|
356
774
|
request.columns?.length && request.onToggleColumn ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
357
775
|
/* @__PURE__ */ jsxRuntime.jsx(MenuDivider, {}),
|
|
358
776
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -399,6 +817,7 @@ function MenuAction(props) {
|
|
|
399
817
|
type: "button",
|
|
400
818
|
onClick: disabled ? void 0 : onClick,
|
|
401
819
|
disabled,
|
|
820
|
+
title: props.title,
|
|
402
821
|
className: "react-list-table-menu-action",
|
|
403
822
|
style: {
|
|
404
823
|
display: "flex",
|
|
@@ -427,7 +846,36 @@ function MenuAction(props) {
|
|
|
427
846
|
children: selected ? "\u2713" : ""
|
|
428
847
|
}
|
|
429
848
|
) : null,
|
|
430
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
849
|
+
props.colorSwatch ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
850
|
+
"span",
|
|
851
|
+
{
|
|
852
|
+
"aria-hidden": "true",
|
|
853
|
+
style: {
|
|
854
|
+
width: 14,
|
|
855
|
+
height: 14,
|
|
856
|
+
flex: "0 0 14px",
|
|
857
|
+
marginRight: 8,
|
|
858
|
+
borderRadius: 2,
|
|
859
|
+
backgroundColor: props.colorSwatch,
|
|
860
|
+
boxShadow: "inset 0 0 0 1px rgba(0, 0, 0, 0.12)"
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
) : null,
|
|
864
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
865
|
+
"span",
|
|
866
|
+
{
|
|
867
|
+
style: {
|
|
868
|
+
flex: 1,
|
|
869
|
+
whiteSpace: "nowrap",
|
|
870
|
+
...props.colorSwatch ? {
|
|
871
|
+
minWidth: 0,
|
|
872
|
+
overflow: "hidden",
|
|
873
|
+
textOverflow: "ellipsis"
|
|
874
|
+
} : null
|
|
875
|
+
},
|
|
876
|
+
children: label
|
|
877
|
+
}
|
|
878
|
+
),
|
|
431
879
|
preview ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
432
880
|
"span",
|
|
433
881
|
{
|
|
@@ -510,6 +958,7 @@ function MenuSubmenu(props) {
|
|
|
510
958
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
511
959
|
reactComponents.ReactPopup,
|
|
512
960
|
{
|
|
961
|
+
constrainHeight: true,
|
|
513
962
|
open,
|
|
514
963
|
anchorRef: triggerRef,
|
|
515
964
|
placement: "rightTop",
|
|
@@ -537,6 +986,7 @@ function MenuSubmenu(props) {
|
|
|
537
986
|
MenuAction,
|
|
538
987
|
{
|
|
539
988
|
label: item.label,
|
|
989
|
+
title: item.title,
|
|
540
990
|
preview: item.preview,
|
|
541
991
|
onClick: item.onClick,
|
|
542
992
|
selected: item.selected,
|
|
@@ -699,6 +1149,7 @@ function ZoomMenu(props) {
|
|
|
699
1149
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
700
1150
|
reactComponents.ReactPopup,
|
|
701
1151
|
{
|
|
1152
|
+
constrainHeight: true,
|
|
702
1153
|
open,
|
|
703
1154
|
anchorRef: triggerRef,
|
|
704
1155
|
placement: "rightTop",
|
|
@@ -863,6 +1314,7 @@ function ColumnVisibilityMenu(props) {
|
|
|
863
1314
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
864
1315
|
reactComponents.ReactPopup,
|
|
865
1316
|
{
|
|
1317
|
+
constrainHeight: true,
|
|
866
1318
|
open,
|
|
867
1319
|
anchorRef: triggerRef,
|
|
868
1320
|
placement: "rightTop",
|
|
@@ -969,6 +1421,7 @@ function ColumnVisibilityItem(props) {
|
|
|
969
1421
|
hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
970
1422
|
reactComponents.ReactPopup,
|
|
971
1423
|
{
|
|
1424
|
+
constrainHeight: true,
|
|
972
1425
|
open,
|
|
973
1426
|
anchorRef: triggerRef,
|
|
974
1427
|
placement: "rightTop",
|
|
@@ -1023,13 +1476,7 @@ function CustomSelectionMenu(props) {
|
|
|
1023
1476
|
if (!request.onCopyCustomSelection || !request.customSelection) {
|
|
1024
1477
|
return null;
|
|
1025
1478
|
}
|
|
1026
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1027
|
-
MenuAction,
|
|
1028
|
-
{
|
|
1029
|
-
label: "\u590D\u5236\u81EA\u5B9A\u4E49\u9009\u533A",
|
|
1030
|
-
onClick: props.onOpen
|
|
1031
|
-
}
|
|
1032
|
-
);
|
|
1479
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MenuAction, { label: "\u590D\u5236\u81EA\u5B9A\u4E49\u9009\u533A", onClick: props.onOpen });
|
|
1033
1480
|
}
|
|
1034
1481
|
function CustomSelectionDialog(props) {
|
|
1035
1482
|
const { request } = props;
|
|
@@ -1242,6 +1689,16 @@ function SummaryMenu(props) {
|
|
|
1242
1689
|
selected: request.summaryType === item.value,
|
|
1243
1690
|
onClick: () => request.onChangeSummaryType?.(item.value)
|
|
1244
1691
|
})),
|
|
1692
|
+
{
|
|
1693
|
+
key: "show-summary-type-prefix",
|
|
1694
|
+
label: "\u5C55\u793A\u6C47\u603B\u65B9\u5F0F\u524D\u7F00",
|
|
1695
|
+
separatorBefore: true,
|
|
1696
|
+
selected: request.summaryShowTypePrefix !== false,
|
|
1697
|
+
disabled: !request.summaryType,
|
|
1698
|
+
onClick: request.onChangeSummaryShowTypePrefix ? () => request.onChangeSummaryShowTypePrefix?.(
|
|
1699
|
+
request.summaryShowTypePrefix === false
|
|
1700
|
+
) : void 0
|
|
1701
|
+
},
|
|
1245
1702
|
{
|
|
1246
1703
|
key: "clear-summary",
|
|
1247
1704
|
label: "\u53D6\u6D88\u6C47\u603B",
|
|
@@ -2330,6 +2787,8 @@ function ReactTableEditorOverlay(props) {
|
|
|
2330
2787
|
}
|
|
2331
2788
|
function renderEditorByType(request, style) {
|
|
2332
2789
|
switch (request.config.valueType ?? "text") {
|
|
2790
|
+
case "cascader":
|
|
2791
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CascaderEditor, { request, style });
|
|
2333
2792
|
case "number":
|
|
2334
2793
|
return /* @__PURE__ */ jsxRuntime.jsx(NumberEditor, { request, style });
|
|
2335
2794
|
case "input-range":
|
|
@@ -2618,6 +3077,50 @@ function DateEditor(props) {
|
|
|
2618
3077
|
}
|
|
2619
3078
|
) });
|
|
2620
3079
|
}
|
|
3080
|
+
function CascaderEditor({
|
|
3081
|
+
request,
|
|
3082
|
+
style
|
|
3083
|
+
}) {
|
|
3084
|
+
const [value, setValue] = react.useState(
|
|
3085
|
+
Array.isArray(request.value) ? request.value : []
|
|
3086
|
+
);
|
|
3087
|
+
const skipBlurCommitRef = react.useRef(false);
|
|
3088
|
+
react.useEffect(() => {
|
|
3089
|
+
setValue(Array.isArray(request.value) ? request.value : []);
|
|
3090
|
+
}, [request.value]);
|
|
3091
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3092
|
+
reactComponents.ReactCascader,
|
|
3093
|
+
{
|
|
3094
|
+
value,
|
|
3095
|
+
options: request.config.options,
|
|
3096
|
+
autoFocus: true,
|
|
3097
|
+
placeholder: request.config.placeholder,
|
|
3098
|
+
showSearch: request.config.showSearch,
|
|
3099
|
+
allowClear: request.config.allowClear,
|
|
3100
|
+
changeOnSelect: request.config.changeOnSelect,
|
|
3101
|
+
expandTrigger: request.config.expandTrigger,
|
|
3102
|
+
displayRender: request.config.displayRender,
|
|
3103
|
+
style: getEditorInputStyle(request),
|
|
3104
|
+
onChange: (next, _options, info) => {
|
|
3105
|
+
setValue(next);
|
|
3106
|
+
request.onChange(next);
|
|
3107
|
+
if (info.complete && info.trigger !== "clear") {
|
|
3108
|
+
skipBlurCommitRef.current = true;
|
|
3109
|
+
request.onCommit();
|
|
3110
|
+
}
|
|
3111
|
+
},
|
|
3112
|
+
onBlur: (event) => handleEditorBlur(event, skipBlurCommitRef, request),
|
|
3113
|
+
onKeyDown: (event) => {
|
|
3114
|
+
if (event.key === "Tab")
|
|
3115
|
+
handleEditorNavigationKey(event, request, skipBlurCommitRef);
|
|
3116
|
+
if (event.key === "Escape") {
|
|
3117
|
+
skipBlurCommitRef.current = true;
|
|
3118
|
+
handleEditorEscapeKey(event, request);
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
}
|
|
3122
|
+
) });
|
|
3123
|
+
}
|
|
2621
3124
|
function SelectEditor(props) {
|
|
2622
3125
|
const { request, style } = props;
|
|
2623
3126
|
const options = request.config.options ?? [];
|
|
@@ -3444,7 +3947,7 @@ function resolveSortableTransform(index, sourceIndex, targetIndex, height) {
|
|
|
3444
3947
|
}
|
|
3445
3948
|
|
|
3446
3949
|
// src/features/toolbar/style.css
|
|
3447
|
-
styleInject('.react-list-table-shell {\n background: #fff;\n font-size: 14px;\n}\n.react-list-table-titlebar {\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n box-sizing: border-box;\n background: #fff;\n}\n.react-list-table-shell-fullscreen {\n width: 100% !important;\n height: 100% !important;\n}\n.react-list-table-shell-fullscreen .canvas-list-table-root {\n height: 100% !important;\n}\n.react-list-table-title {\n min-width: 0;\n color: #1f2937;\n font-size: 14px;\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-tools {\n display: flex;\n align-items: center;\n gap: 14px;\n color: #475569;\n}\n.react-list-table-tool-wrap {\n position: relative;\n display: inline-flex;\n}\n.react-list-table-tool {\n width: 20px;\n height: 24px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n font: 16px/24px sans-serif;\n cursor: pointer;\n}\n.react-list-table-tool:hover {\n color: #1677ff;\n}\n.react-list-table-tool-menu,\n.react-list-table-column-setting {\n position: absolute;\n z-index: 120;\n top: 28px;\n right: 0;\n min-width: 112px;\n padding: 6px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: #fff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, .14);\n}\n.react-list-table-tool-menu button {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 6px 10px;\n border: 0;\n border-radius: 4px;\n background: transparent;\n text-align: left;\n cursor: pointer;\n}\n.react-list-table-tool-menu button.active::after {\n content: "\\2713";\n margin-left: 12px;\n font-size: 14px;\n}\n.react-list-table-tool-menu button:hover,\n.react-list-table-tool-menu button.active {\n color: #1677ff;\n background: #e6f4ff;\n}\n.react-list-table-column-setting {\n width: 328px;\n max-height: 360px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.react-list-table-column-setting-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 6px 8px;\n border-bottom: 1px solid #f0f0f0;\n flex: 0 0 auto;\n}\n.react-list-table-column-setting-head button {\n border: 0;\n color: #1677ff;\n background: transparent;\n cursor: pointer;\n}\n.react-list-table-column-setting-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.react-list-table-column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n justify-content: space-between;\n padding: 7px 6px;\n box-sizing: border-box;\n cursor: pointer;\n}\n.react-list-table-column-main,\n.react-list-table-column-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.react-list-table-column-main {\n min-width: 0;\n}\n.react-list-table-column-actions {\n flex: 0 0 auto;\n}\n.react-list-table-column-actions > .canvas-react-select-wrap {\n flex: 0 0 96px;\n width: 96px;\n height: 24px;\n}\n.react-list-table-column-label {\n min-width: 64px;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-column-width-input {\n height: 22px;\n padding-inline: 5px;\n}\n.react-list-table-column-fixed-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-setting label.dragging {\n opacity: 0.45;\n background: #e6f4ff;\n}\n.react-list-table-column-setting [data-sortable-key].dragging {\n opacity: 0.28;\n}\n.react-list-table-column-drag {\n color: #94a3b8;\n display: inline-flex;\n font-size: 14px;\n cursor: grab;\n user-select: none;\n}\nbody.react-list-table-sorting,\nbody.react-list-table-sorting * {\n cursor: grabbing !important;\n}\n.react-list-table-sort-overlay {\n position: fixed;\n z-index: 1400;\n display: block;\n padding: 0;\n box-sizing: border-box;\n color: #334155;\n background: #fff;\n border: 1px solid #91caff;\n border-radius: 6px;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);\n pointer-events: none;\n}\n.react-list-table-sort-overlay .react-list-table-column-item {\n width: 100%;\n height: 100%;\n}\n');
|
|
3950
|
+
styleInject('.react-list-table-shell {\n background: #fff;\n font-size: 14px;\n}\n.react-list-table-titlebar {\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n box-sizing: border-box;\n background: #fff;\n}\n.react-list-table-shell-fullscreen {\n width: 100% !important;\n height: 100% !important;\n}\n.react-list-table-shell-fullscreen .canvas-list-table-root {\n height: 100% !important;\n}\n.react-list-table-title {\n min-width: 0;\n color: #1f2937;\n font-size: 14px;\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-tools {\n display: flex;\n align-items: center;\n gap: 14px;\n color: #475569;\n}\n.react-list-table-tool-wrap {\n position: relative;\n display: inline-flex;\n}\n.react-list-table-tool {\n width: 20px;\n height: 24px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n font: 16px/24px sans-serif;\n cursor: pointer;\n}\n.react-list-table-tool:hover {\n color: #1677ff;\n}\n.react-list-table-tool-menu,\n.react-list-table-column-setting {\n position: absolute;\n z-index: 120;\n top: 28px;\n right: 0;\n min-width: 112px;\n padding: 6px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: #fff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, .14);\n}\n.react-list-table-tool-menu button {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 6px 10px;\n border: 0;\n border-radius: 4px;\n background: transparent;\n text-align: left;\n cursor: pointer;\n}\n.react-list-table-tool-menu button.active::after {\n content: "\\2713";\n margin-left: 12px;\n font-size: 14px;\n}\n.react-list-table-tool-menu button:hover,\n.react-list-table-tool-menu button.active {\n color: #1677ff;\n background: #e6f4ff;\n}\n.react-list-table-column-setting {\n width: 328px;\n max-height: 360px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.react-list-table-column-setting-head {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 4px 6px 8px;\n border-bottom: 1px solid #f0f0f0;\n flex: 0 0 auto;\n}\n.react-list-table-column-setting-head button {\n border: 0;\n color: #1677ff;\n background: transparent;\n cursor: pointer;\n}\n.react-list-table-column-setting-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.react-list-table-column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n justify-content: space-between;\n padding: 7px 6px;\n box-sizing: border-box;\n cursor: pointer;\n}\n.react-list-table-column-main,\n.react-list-table-column-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.react-list-table-column-main {\n min-width: 0;\n}\n.react-list-table-column-actions {\n flex: 0 0 auto;\n}\n.react-list-table-column-actions > .canvas-react-select-wrap {\n flex: 0 0 96px;\n width: 96px;\n height: 24px;\n}\n.react-list-table-column-label {\n min-width: 64px;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-column-width-input {\n height: 22px;\n padding-inline: 5px;\n}\n.react-list-table-column-fixed-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-setting label.dragging {\n opacity: 0.45;\n background: #e6f4ff;\n}\n.react-list-table-column-setting [data-sortable-key].dragging {\n opacity: 0.28;\n}\n.react-list-table-column-drag {\n color: #94a3b8;\n display: inline-flex;\n font-size: 14px;\n cursor: grab;\n user-select: none;\n}\nbody.react-list-table-sorting,\nbody.react-list-table-sorting * {\n cursor: grabbing !important;\n}\n.react-list-table-sort-overlay {\n position: fixed;\n z-index: 1400;\n display: block;\n padding: 0;\n box-sizing: border-box;\n color: #334155;\n background: #fff;\n border: 1px solid #91caff;\n border-radius: 6px;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);\n pointer-events: none;\n}\n.react-list-table-sort-overlay .react-list-table-column-item {\n width: 100%;\n height: 100%;\n}\n');
|
|
3448
3951
|
function ReactTableToolbar(props) {
|
|
3449
3952
|
const { toolbar, title } = props;
|
|
3450
3953
|
const [densityOpen, setDensityOpen] = react.useState(false);
|
|
@@ -3561,6 +4064,18 @@ function ReactTableToolbar(props) {
|
|
|
3561
4064
|
children: [
|
|
3562
4065
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-column-setting-head", children: [
|
|
3563
4066
|
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "\u5217\u8BBE\u7F6E" }),
|
|
4067
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4068
|
+
reactComponents.ReactCheckbox,
|
|
4069
|
+
{
|
|
4070
|
+
checked: props.cacheColumnSettings === true,
|
|
4071
|
+
disabled: !props.columnSettingsCacheAvailable,
|
|
4072
|
+
title: props.columnSettingsCacheAvailable ? "\u7F13\u5B58\u5217\u5BBD\u3001\u663E\u9690\u3001\u56FA\u5B9A\u548C\u987A\u5E8F" : "\u914D\u7F6E storageKey \u540E\u53EF\u7F13\u5B58\u5217\u8BBE\u7F6E",
|
|
4073
|
+
onChange: (event) => props.onColumnSettingsCacheChange?.(
|
|
4074
|
+
event.target.checked
|
|
4075
|
+
),
|
|
4076
|
+
children: "\u7F13\u5B58\u5230\u672C\u5730"
|
|
4077
|
+
}
|
|
4078
|
+
),
|
|
3564
4079
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: "auto" }, children: config.columnSettingHeaderExtra }),
|
|
3565
4080
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: props.onResetColumns, children: "\u91CD\u7F6E" })
|
|
3566
4081
|
] }),
|
|
@@ -3896,6 +4411,8 @@ function ReactListTableInner(props, ref) {
|
|
|
3896
4411
|
stretchColumns,
|
|
3897
4412
|
resizable,
|
|
3898
4413
|
storageKey,
|
|
4414
|
+
cacheColumnSettings,
|
|
4415
|
+
cachePreferences,
|
|
3899
4416
|
draggable,
|
|
3900
4417
|
tableId,
|
|
3901
4418
|
rowDrag,
|
|
@@ -3917,6 +4434,10 @@ function ReactListTableInner(props, ref) {
|
|
|
3917
4434
|
);
|
|
3918
4435
|
const [columnConfig, setColumnConfig] = react.useState(() => /* @__PURE__ */ new Map());
|
|
3919
4436
|
const [columnConfigRevision, setColumnConfigRevision] = react.useState(0);
|
|
4437
|
+
const [columnSettingsCacheOverride, setColumnSettingsCacheOverride] = react.useState(null);
|
|
4438
|
+
const resolvedColumnSettingsCache = (columnSettingsCacheOverride?.storageKey === storageKey ? columnSettingsCacheOverride?.value : void 0) ?? cacheColumnSettings ?? true;
|
|
4439
|
+
const [cachePreferencesOverride, setCachePreferencesOverride] = react.useState();
|
|
4440
|
+
const resolvedCachePreferences = (cachePreferencesOverride?.storageKey === storageKey ? cachePreferencesOverride?.value : void 0) ?? cachePreferences;
|
|
3920
4441
|
const [columnConfigResetRevision, setColumnConfigResetRevision] = react.useState(0);
|
|
3921
4442
|
const resolvedColumns = react.useMemo(
|
|
3922
4443
|
() => applyColumnManagerState(
|
|
@@ -3970,6 +4491,8 @@ function ReactListTableInner(props, ref) {
|
|
|
3970
4491
|
stretchColumns,
|
|
3971
4492
|
resizable,
|
|
3972
4493
|
storageKey,
|
|
4494
|
+
cacheColumnSettings: resolvedColumnSettingsCache,
|
|
4495
|
+
cachePreferences: resolvedCachePreferences,
|
|
3973
4496
|
draggable,
|
|
3974
4497
|
tableId,
|
|
3975
4498
|
rowDrag,
|
|
@@ -3987,7 +4510,13 @@ function ReactListTableInner(props, ref) {
|
|
|
3987
4510
|
columnConfigResetRevision,
|
|
3988
4511
|
ui: {
|
|
3989
4512
|
...nextOptions.ui,
|
|
3990
|
-
onDensityChange: setDensityOverride
|
|
4513
|
+
onDensityChange: setDensityOverride,
|
|
4514
|
+
onColumnSettingsCacheChange: (value) => setColumnSettingsCacheOverride(
|
|
4515
|
+
(current) => current?.storageKey === storageKey && current?.value === value ? current : { storageKey, value }
|
|
4516
|
+
),
|
|
4517
|
+
onCachePreferencesChange: (next) => setCachePreferencesOverride(
|
|
4518
|
+
(current) => current?.storageKey === storageKey && JSON.stringify(current?.value ?? {}) === JSON.stringify(next) ? current : { storageKey, value: next }
|
|
4519
|
+
)
|
|
3991
4520
|
}
|
|
3992
4521
|
};
|
|
3993
4522
|
}, [
|
|
@@ -4023,6 +4552,8 @@ function ReactListTableInner(props, ref) {
|
|
|
4023
4552
|
stretchColumns,
|
|
4024
4553
|
resizable,
|
|
4025
4554
|
storageKey,
|
|
4555
|
+
resolvedColumnSettingsCache,
|
|
4556
|
+
resolvedCachePreferences,
|
|
4026
4557
|
draggable,
|
|
4027
4558
|
tableId,
|
|
4028
4559
|
rowDrag,
|
|
@@ -4091,6 +4622,9 @@ function ReactListTableInner(props, ref) {
|
|
|
4091
4622
|
{
|
|
4092
4623
|
title,
|
|
4093
4624
|
toolbar,
|
|
4625
|
+
cacheColumnSettings: Boolean(storageKey) && resolvedColumnSettingsCache,
|
|
4626
|
+
columnSettingsCacheAvailable: Boolean(storageKey),
|
|
4627
|
+
onColumnSettingsCacheChange: (enabled) => tableRef.current?.setColumnSettingsCache(enabled),
|
|
4094
4628
|
columns: resolvedColumns,
|
|
4095
4629
|
density: resolvedRowHeight ?? 32,
|
|
4096
4630
|
hostRef: shellRef,
|