@stcn52/pro 0.2.0 → 0.2.1
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/CHANGELOG.md +6 -0
- package/dist/index.cjs +160 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +160 -41
- package/dist/index.js.map +1 -1
- package/dist/styles.css +16 -6
- package/docs/api.md +15 -0
- package/docs/components.md +6 -2
- package/package.json +21 -19
package/dist/index.d.cts
CHANGED
|
@@ -2491,7 +2491,7 @@ type AttachmentUploadProps = {
|
|
|
2491
2491
|
size: number;
|
|
2492
2492
|
}, progress: (pct: number) => void): Promise<void> | void;
|
|
2493
2493
|
onRemove(relationId: string): void;
|
|
2494
|
-
/**
|
|
2494
|
+
/** Record identity: changing it cancels pending reads and resets attachment dialogs. */
|
|
2495
2495
|
entityId?: string;
|
|
2496
2496
|
/** Raised for the two failures no callback can carry: a refused file and a broken read. */
|
|
2497
2497
|
onNotify?: Notify;
|
|
@@ -2502,7 +2502,8 @@ type AttachmentUploadProps = {
|
|
|
2502
2502
|
* already linked to this record with a confirmed unlink. It reads the bytes
|
|
2503
2503
|
* itself — the bar cannot pass 88% until the read finishes — and hands the
|
|
2504
2504
|
* finished file to the host, which owns the store write.
|
|
2505
|
-
*/
|
|
2505
|
+
*/
|
|
2506
|
+
declare function AttachmentUpload(props: AttachmentUploadProps): react.JSX.Element;
|
|
2506
2507
|
|
|
2507
2508
|
/** One kind the picker can link to; `kind` is the host's own collection name. */
|
|
2508
2509
|
type LinkTarget = {
|
package/dist/index.d.ts
CHANGED
|
@@ -2491,7 +2491,7 @@ type AttachmentUploadProps = {
|
|
|
2491
2491
|
size: number;
|
|
2492
2492
|
}, progress: (pct: number) => void): Promise<void> | void;
|
|
2493
2493
|
onRemove(relationId: string): void;
|
|
2494
|
-
/**
|
|
2494
|
+
/** Record identity: changing it cancels pending reads and resets attachment dialogs. */
|
|
2495
2495
|
entityId?: string;
|
|
2496
2496
|
/** Raised for the two failures no callback can carry: a refused file and a broken read. */
|
|
2497
2497
|
onNotify?: Notify;
|
|
@@ -2502,7 +2502,8 @@ type AttachmentUploadProps = {
|
|
|
2502
2502
|
* already linked to this record with a confirmed unlink. It reads the bytes
|
|
2503
2503
|
* itself — the bar cannot pass 88% until the read finishes — and hands the
|
|
2504
2504
|
* finished file to the host, which owns the store write.
|
|
2505
|
-
*/
|
|
2505
|
+
*/
|
|
2506
|
+
declare function AttachmentUpload(props: AttachmentUploadProps): react.JSX.Element;
|
|
2506
2507
|
|
|
2507
2508
|
/** One kind the picker can link to; `kind` is the host's own collection name. */
|
|
2508
2509
|
type LinkTarget = {
|
package/dist/index.js
CHANGED
|
@@ -89,7 +89,10 @@ function useControllableState(options) {
|
|
|
89
89
|
});
|
|
90
90
|
const setValue = useCallback((next) => {
|
|
91
91
|
const resolved = typeof next === "function" ? next(currentRef.current) : next;
|
|
92
|
-
if (!controlledRef.current)
|
|
92
|
+
if (!controlledRef.current) {
|
|
93
|
+
currentRef.current = resolved;
|
|
94
|
+
setUncontrolled(resolved);
|
|
95
|
+
}
|
|
93
96
|
onChangeRef.current?.(resolved);
|
|
94
97
|
}, []);
|
|
95
98
|
return [current, setValue];
|
|
@@ -2326,7 +2329,7 @@ function SelectionBar({
|
|
|
2326
2329
|
"aria-expanded": moreOpen,
|
|
2327
2330
|
onClick: () => setMoreOpen(true),
|
|
2328
2331
|
children: [
|
|
2329
|
-
/* @__PURE__ */ jsx(Icon, { name: "
|
|
2332
|
+
/* @__PURE__ */ jsx(Icon, { name: "more", size: 14 }),
|
|
2330
2333
|
" ",
|
|
2331
2334
|
locale === "zh-CN" ? "\u66F4\u591A" : "More"
|
|
2332
2335
|
]
|
|
@@ -2356,7 +2359,8 @@ function buildBulkCommands({
|
|
|
2356
2359
|
more,
|
|
2357
2360
|
onNotify,
|
|
2358
2361
|
onEditProperties,
|
|
2359
|
-
onClear
|
|
2362
|
+
onClear,
|
|
2363
|
+
onComplete
|
|
2360
2364
|
}) {
|
|
2361
2365
|
const count = keys.length;
|
|
2362
2366
|
const many = count === 1 ? noun.one : noun.many;
|
|
@@ -2364,7 +2368,8 @@ function buildBulkCommands({
|
|
|
2364
2368
|
if (!count) return;
|
|
2365
2369
|
const finish = () => {
|
|
2366
2370
|
onNotify?.(message2);
|
|
2367
|
-
|
|
2371
|
+
if (onComplete) onComplete(keys);
|
|
2372
|
+
else onClear();
|
|
2368
2373
|
};
|
|
2369
2374
|
const result = run();
|
|
2370
2375
|
if (result) return result.then(finish);
|
|
@@ -4069,6 +4074,7 @@ function BulkBar({
|
|
|
4069
4074
|
someSelected,
|
|
4070
4075
|
onToggleAll,
|
|
4071
4076
|
onClear,
|
|
4077
|
+
onComplete,
|
|
4072
4078
|
onEditProperties,
|
|
4073
4079
|
onExportSelection,
|
|
4074
4080
|
onDelete,
|
|
@@ -4100,7 +4106,8 @@ function BulkBar({
|
|
|
4100
4106
|
],
|
|
4101
4107
|
onNotify,
|
|
4102
4108
|
onEditProperties,
|
|
4103
|
-
onClear
|
|
4109
|
+
onClear,
|
|
4110
|
+
onComplete
|
|
4104
4111
|
});
|
|
4105
4112
|
return /* @__PURE__ */ jsx(
|
|
4106
4113
|
SelectionBar,
|
|
@@ -4122,6 +4129,7 @@ function BulkBar({
|
|
|
4122
4129
|
|
|
4123
4130
|
// src/components/table/geometry.ts
|
|
4124
4131
|
var LEADING_WIDTH = 44;
|
|
4132
|
+
var COMPACT_ACTIONS_WIDTH = 96;
|
|
4125
4133
|
function widthStyle(width) {
|
|
4126
4134
|
if (width === void 0) return void 0;
|
|
4127
4135
|
return { width: typeof width === "number" ? `${width}px` : width };
|
|
@@ -4156,6 +4164,7 @@ function pinStyle(pin, direction = "ltr") {
|
|
|
4156
4164
|
}
|
|
4157
4165
|
function SkeletonRows({
|
|
4158
4166
|
columns,
|
|
4167
|
+
compact,
|
|
4159
4168
|
rows,
|
|
4160
4169
|
widths,
|
|
4161
4170
|
selectable,
|
|
@@ -4212,7 +4221,16 @@ function SkeletonRows({
|
|
|
4212
4221
|
},
|
|
4213
4222
|
column.id
|
|
4214
4223
|
)),
|
|
4215
|
-
hasRowActions ? /* @__PURE__ */ jsx(
|
|
4224
|
+
hasRowActions ? /* @__PURE__ */ jsx(
|
|
4225
|
+
"td",
|
|
4226
|
+
{
|
|
4227
|
+
className: cx(
|
|
4228
|
+
"pro-table__actions-col",
|
|
4229
|
+
pinned && (compact ? pinClass({ side: "right"}, true) : "is-fixed-right-first")
|
|
4230
|
+
),
|
|
4231
|
+
style: pinned && compact ? pinStyle({ side: "right", offset: 0 }, direction) : void 0
|
|
4232
|
+
}
|
|
4233
|
+
) : null,
|
|
4216
4234
|
/* @__PURE__ */ jsx("td", { className: "pro-table__filler" }),
|
|
4217
4235
|
hasHeaderTools ? /* @__PURE__ */ jsx("td", { className: "pro-table__tool-col" }) : null
|
|
4218
4236
|
] }, `skeleton-${rowIndex}`)) });
|
|
@@ -4235,7 +4253,7 @@ function ColumnMenu({
|
|
|
4235
4253
|
close();
|
|
4236
4254
|
};
|
|
4237
4255
|
const items = [
|
|
4238
|
-
...column.sortable && onSortChange ? [
|
|
4256
|
+
...(column.sortable || column.sorter) && onSortChange ? [
|
|
4239
4257
|
{
|
|
4240
4258
|
id: "sort",
|
|
4241
4259
|
label: "Sort by",
|
|
@@ -4489,10 +4507,10 @@ function TableHead({
|
|
|
4489
4507
|
"aria-label": `Sort by ${typeof column.header === "string" ? column.header : column.id}`,
|
|
4490
4508
|
children: [
|
|
4491
4509
|
column.header,
|
|
4492
|
-
/* @__PURE__ */
|
|
4493
|
-
/* @__PURE__ */ jsx(Icon, { name:
|
|
4494
|
-
/* @__PURE__ */ jsx(Icon, { name:
|
|
4495
|
-
] })
|
|
4510
|
+
/* @__PURE__ */ jsx("span", { className: "pro-table__sort-icon", "aria-hidden": "true", children: current ? /* @__PURE__ */ jsx(Icon, { name: current.direction === "asc" ? "angle-up" : "angle-down", size: 9 }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4511
|
+
/* @__PURE__ */ jsx(Icon, { name: "angle-up", size: 9 }),
|
|
4512
|
+
/* @__PURE__ */ jsx(Icon, { name: "angle-down", size: 9 })
|
|
4513
|
+
] }) })
|
|
4496
4514
|
]
|
|
4497
4515
|
}
|
|
4498
4516
|
) : column.header,
|
|
@@ -4639,17 +4657,22 @@ function nextCell(key, cell, rowCount, colCount) {
|
|
|
4639
4657
|
else return null;
|
|
4640
4658
|
return next;
|
|
4641
4659
|
}
|
|
4642
|
-
function CellCommands({
|
|
4660
|
+
function CellCommands({
|
|
4661
|
+
actions,
|
|
4662
|
+
row,
|
|
4663
|
+
disabled
|
|
4664
|
+
}) {
|
|
4643
4665
|
if (actions.length === 0) return null;
|
|
4644
4666
|
return /* @__PURE__ */ jsx("span", { className: "pro-table__cell-actions", children: actions.map((action) => /* @__PURE__ */ jsx(Tooltip, { label: action.label, children: /* @__PURE__ */ jsx(
|
|
4645
4667
|
"button",
|
|
4646
4668
|
{
|
|
4647
4669
|
type: "button",
|
|
4670
|
+
disabled,
|
|
4648
4671
|
className: "pro-table__cell-action",
|
|
4649
4672
|
"aria-label": action.label,
|
|
4650
4673
|
onClick: (event) => {
|
|
4651
4674
|
event.stopPropagation();
|
|
4652
|
-
action.onSelect(row);
|
|
4675
|
+
if (!disabled) action.onSelect(row);
|
|
4653
4676
|
},
|
|
4654
4677
|
children: /* @__PURE__ */ jsx(Icon, { name: action.icon, size: 14 })
|
|
4655
4678
|
}
|
|
@@ -4833,12 +4856,13 @@ function TableRow({
|
|
|
4833
4856
|
{
|
|
4834
4857
|
className: cx(
|
|
4835
4858
|
"pro-table__cell",
|
|
4859
|
+
column.ellipsis === false && "pro-table__cell--wrap",
|
|
4836
4860
|
column.align === "center" && "pro-table__cell--center",
|
|
4837
4861
|
column.align === "right" && "pro-table__cell--right"
|
|
4838
4862
|
),
|
|
4839
4863
|
children: [
|
|
4840
4864
|
/* @__PURE__ */ jsx(CellContent, { value: column.render(row, index), ellipsis: column.ellipsis }),
|
|
4841
|
-
column.actions?.length ? /* @__PURE__ */ jsx(CellCommands, { actions: column.actions, row }) : null
|
|
4865
|
+
column.actions?.length ? /* @__PURE__ */ jsx(CellCommands, { actions: column.actions, row, disabled }) : null
|
|
4842
4866
|
]
|
|
4843
4867
|
}
|
|
4844
4868
|
)
|
|
@@ -4850,7 +4874,11 @@ function TableRow({
|
|
|
4850
4874
|
/* @__PURE__ */ jsx(
|
|
4851
4875
|
"td",
|
|
4852
4876
|
{
|
|
4853
|
-
className: cx(
|
|
4877
|
+
className: cx(
|
|
4878
|
+
"pro-table__actions-col",
|
|
4879
|
+
pinned && (compact ? pinClass({ side: "right"}, true) : "is-fixed-right-first")
|
|
4880
|
+
),
|
|
4881
|
+
style: pinned && compact ? pinStyle({ side: "right", offset: 0 }, direction) : void 0,
|
|
4854
4882
|
onClick: (event) => event.stopPropagation(),
|
|
4855
4883
|
children: compact ? /* @__PURE__ */ jsx("div", { className: "pro-table__cell pro-table__cell--actions", children: rowActions(row) }) : /* @__PURE__ */ jsx("span", { className: "pro-table__row-actions", children: rowActions(row) })
|
|
4856
4884
|
}
|
|
@@ -5012,6 +5040,44 @@ function DataTable({
|
|
|
5012
5040
|
const { direction, locale } = useProConfig();
|
|
5013
5041
|
const { leaves: columns, headers } = useMemo(() => tableColumns(suppliedColumns), [suppliedColumns]);
|
|
5014
5042
|
const selectionName = useId();
|
|
5043
|
+
const selectionMounted = useRef(false);
|
|
5044
|
+
useLayoutEffect(() => {
|
|
5045
|
+
selectionMounted.current = true;
|
|
5046
|
+
return () => {
|
|
5047
|
+
selectionMounted.current = false;
|
|
5048
|
+
};
|
|
5049
|
+
}, []);
|
|
5050
|
+
const latestSelection = useRef({
|
|
5051
|
+
selectedKeys,
|
|
5052
|
+
onSelectedKeysChange,
|
|
5053
|
+
suppliedRows,
|
|
5054
|
+
rowKey,
|
|
5055
|
+
getChildren,
|
|
5056
|
+
isRowSelectable,
|
|
5057
|
+
onNotify
|
|
5058
|
+
});
|
|
5059
|
+
useLayoutEffect(() => {
|
|
5060
|
+
latestSelection.current = {
|
|
5061
|
+
selectedKeys,
|
|
5062
|
+
onSelectedKeysChange,
|
|
5063
|
+
suppliedRows,
|
|
5064
|
+
rowKey,
|
|
5065
|
+
getChildren,
|
|
5066
|
+
isRowSelectable,
|
|
5067
|
+
onNotify
|
|
5068
|
+
};
|
|
5069
|
+
});
|
|
5070
|
+
const clearSelection = (completed) => {
|
|
5071
|
+
if (!selectionMounted.current) return;
|
|
5072
|
+
const current = latestSelection.current;
|
|
5073
|
+
const locked = new Set(
|
|
5074
|
+
flattenRecords(tableRecords(current.suppliedRows, current.rowKey, current.getChildren), null).filter(({ row }) => current.isRowSelectable?.(row) === false).map(({ key }) => key)
|
|
5075
|
+
);
|
|
5076
|
+
const processed2 = completed ? new Set(completed) : void 0;
|
|
5077
|
+
current.onSelectedKeysChange?.(
|
|
5078
|
+
current.selectedKeys.filter((key) => locked.has(key) || processed2 !== void 0 && !processed2.has(key))
|
|
5079
|
+
);
|
|
5080
|
+
};
|
|
5015
5081
|
const [scrollTop, setScrollTop] = useState(0);
|
|
5016
5082
|
const [focusedKey, setFocusedKey] = useState(null);
|
|
5017
5083
|
const [headerHeight, setHeaderHeight] = useState(44);
|
|
@@ -5134,7 +5200,7 @@ function DataTable({
|
|
|
5134
5200
|
const columnsCount = columns.length + (selectable ? 1 : 0) + (showIndex ? 1 : 0) + (rowActions ? 1 : 0) + (headerTools ? 1 : 0) + (hasExpansion ? 1 : 0) + 1;
|
|
5135
5201
|
const pinned = columns.some((column) => column.fixed !== void 0);
|
|
5136
5202
|
const leadingWidth = (selectable ? LEADING_WIDTH : 0) + (showIndex ? LEADING_WIDTH : 0) + (hasExpansion ? LEADING_WIDTH : 0);
|
|
5137
|
-
const pins = pinOffsets(columns, leadingWidth, 0);
|
|
5203
|
+
const pins = pinOffsets(columns, leadingWidth, compact && rowActions ? COMPACT_ACTIONS_WIDTH : 0);
|
|
5138
5204
|
const lastLeft = [...columns].reverse().find((column) => column.fixed === "left")?.id;
|
|
5139
5205
|
const firstRight = columns.find((column) => column.fixed === "right")?.id;
|
|
5140
5206
|
const rootRef = useRef(null);
|
|
@@ -5195,7 +5261,9 @@ function DataTable({
|
|
|
5195
5261
|
const rowHeight = suppliedHeight !== void 0 && Number.isFinite(suppliedHeight) && suppliedHeight > 0 ? suppliedHeight : compact ? 36 : 45;
|
|
5196
5262
|
const overscan = suppliedOverscan !== void 0 && Number.isFinite(suppliedOverscan) ? Math.max(0, Math.floor(suppliedOverscan)) : 3;
|
|
5197
5263
|
const viewportHeight = typeof scroll?.y === "number" && Number.isFinite(scroll.y) && scroll.y > 0 ? scroll.y : 300;
|
|
5198
|
-
const windowed = Boolean(
|
|
5264
|
+
const windowed = Boolean(
|
|
5265
|
+
virtual && !groupBy && !expandedRowRender && !columns.some((column) => column.onCell || column.ellipsis === false)
|
|
5266
|
+
);
|
|
5199
5267
|
const start = windowed ? Math.min(
|
|
5200
5268
|
Math.max(0, rows.length - Math.ceil(viewportHeight / rowHeight)),
|
|
5201
5269
|
Math.max(0, Math.floor((scrollTop - (showHeader ? headerHeight : 0)) / rowHeight) - overscan)
|
|
@@ -5282,9 +5350,10 @@ function DataTable({
|
|
|
5282
5350
|
widths: loadingColumns,
|
|
5283
5351
|
selectable,
|
|
5284
5352
|
showIndex,
|
|
5353
|
+
compact,
|
|
5285
5354
|
hasRowActions: Boolean(rowActions),
|
|
5286
5355
|
hasHeaderTools: Boolean(headerTools),
|
|
5287
|
-
hasExpansion
|
|
5356
|
+
hasExpansion,
|
|
5288
5357
|
pinned,
|
|
5289
5358
|
pins,
|
|
5290
5359
|
lastLeft,
|
|
@@ -5321,6 +5390,7 @@ function DataTable({
|
|
|
5321
5390
|
const indexes = Array.from({ length: end - start }, (_, index) => start + index);
|
|
5322
5391
|
const focusedIndex = focusedKey === null ? -1 : visibleRecords.findIndex((record) => record.key === focusedKey);
|
|
5323
5392
|
if (windowed && focusedIndex >= 0 && !indexes.includes(focusedIndex)) indexes.push(focusedIndex);
|
|
5393
|
+
if (windowed && cursor && rows.length > 0 && !indexes.includes(cursorRow)) indexes.push(cursorRow);
|
|
5324
5394
|
indexes.sort((a, b) => a - b);
|
|
5325
5395
|
const spacer = (height, key) => /* @__PURE__ */ jsx("tr", { "aria-hidden": "true", children: /* @__PURE__ */ jsx("td", { colSpan: columnsCount, style: { height, padding: 0, border: 0 } }) }, key);
|
|
5326
5396
|
body = /* @__PURE__ */ jsxs("tbody", { children: [
|
|
@@ -5368,17 +5438,14 @@ function DataTable({
|
|
|
5368
5438
|
allSelected,
|
|
5369
5439
|
someSelected,
|
|
5370
5440
|
onToggleAll: toggleAll,
|
|
5371
|
-
onClear: () =>
|
|
5372
|
-
|
|
5373
|
-
(key) => flattenRecords(records, null).some(
|
|
5374
|
-
({ row }) => rowKey(row) === key && isRowSelectable?.(row) === false
|
|
5375
|
-
)
|
|
5376
|
-
)
|
|
5377
|
-
),
|
|
5441
|
+
onClear: () => clearSelection(),
|
|
5442
|
+
onComplete: clearSelection,
|
|
5378
5443
|
onEditProperties,
|
|
5379
5444
|
onExportSelection,
|
|
5380
5445
|
onDelete,
|
|
5381
|
-
onNotify
|
|
5446
|
+
onNotify: (message2) => {
|
|
5447
|
+
if (selectionMounted.current) latestSelection.current.onNotify?.(message2);
|
|
5448
|
+
}
|
|
5382
5449
|
}
|
|
5383
5450
|
) : null,
|
|
5384
5451
|
/* @__PURE__ */ jsxs(
|
|
@@ -5401,7 +5468,7 @@ function DataTable({
|
|
|
5401
5468
|
showIndex ? /* @__PURE__ */ jsx("col", { style: { width: LEADING_WIDTH } }) : null,
|
|
5402
5469
|
hasExpansion ? /* @__PURE__ */ jsx("col", { style: { width: LEADING_WIDTH } }) : null,
|
|
5403
5470
|
columns.map((column) => /* @__PURE__ */ jsx("col", { style: { width: column.width } }, column.id)),
|
|
5404
|
-
rowActions ? /* @__PURE__ */ jsx("col", { style: { width: compact ?
|
|
5471
|
+
rowActions ? /* @__PURE__ */ jsx("col", { style: { width: compact ? COMPACT_ACTIONS_WIDTH : 0 } }) : null,
|
|
5405
5472
|
/* @__PURE__ */ jsx("col", {}),
|
|
5406
5473
|
headerTools ? /* @__PURE__ */ jsx("col", { style: { width: LEADING_WIDTH } }) : null
|
|
5407
5474
|
] }),
|
|
@@ -10458,7 +10525,10 @@ function isPromise(value) {
|
|
|
10458
10525
|
function clamp(pct) {
|
|
10459
10526
|
return Number.isFinite(pct) ? Math.max(0, Math.min(100, Math.round(pct))) : 0;
|
|
10460
10527
|
}
|
|
10461
|
-
function AttachmentUpload({
|
|
10528
|
+
function AttachmentUpload(props) {
|
|
10529
|
+
return /* @__PURE__ */ jsx(AttachmentUploadSession, { ...props }, props.entityId);
|
|
10530
|
+
}
|
|
10531
|
+
function AttachmentUploadSession({
|
|
10462
10532
|
files,
|
|
10463
10533
|
label,
|
|
10464
10534
|
maxSizeMb = DEFAULT_MAX_MB,
|
|
@@ -11380,7 +11450,14 @@ function EntityDialog({
|
|
|
11380
11450
|
const fieldValue = (id) => Object.hasOwn(values, id) && typeof values[id] === "string" ? values[id] : "";
|
|
11381
11451
|
const dirty = Object.keys(values).some((key) => values[key] !== baseline[key]);
|
|
11382
11452
|
const errors = Object.fromEntries(
|
|
11383
|
-
[...fields, ...asideFields].
|
|
11453
|
+
[...fields, ...asideFields].flatMap((field) => {
|
|
11454
|
+
const value = fieldValue(field.id);
|
|
11455
|
+
if (field.required && !value.trim())
|
|
11456
|
+
return [[field.id, zh ? `\u8BF7\u586B\u5199${field.label}` : `${field.label} is required`]];
|
|
11457
|
+
if (field.kind === "select" && value && !field.options?.some((option) => option.value === value))
|
|
11458
|
+
return [[field.id, zh ? `\u8BF7\u9009\u62E9\u6709\u6548\u7684${field.label}` : `Choose a valid ${field.label}`]];
|
|
11459
|
+
return [];
|
|
11460
|
+
})
|
|
11384
11461
|
);
|
|
11385
11462
|
const invalid = Object.keys(errors).length > 0;
|
|
11386
11463
|
const idPrefix = useId();
|
|
@@ -13056,7 +13133,7 @@ function AssigneeCell({ field, row, rowKey }) {
|
|
|
13056
13133
|
disabled,
|
|
13057
13134
|
className: "pro-assignee-cell__assign",
|
|
13058
13135
|
"aria-label": field.assignLabel?.(row) ?? `Assign ${rowKey}`,
|
|
13059
|
-
tabIndex: -1,
|
|
13136
|
+
tabIndex: field.onAssign ? 0 : -1,
|
|
13060
13137
|
onClick: (event) => {
|
|
13061
13138
|
event.stopPropagation();
|
|
13062
13139
|
if (field.onAssign) {
|
|
@@ -13249,6 +13326,7 @@ function ListWorkbench({
|
|
|
13249
13326
|
const [deleteError, setDeleteError] = useState(false);
|
|
13250
13327
|
const [sessionIdentity, setSessionIdentity] = useState(identity);
|
|
13251
13328
|
const [hiddenColumns, setHiddenColumns] = useState([]);
|
|
13329
|
+
const [unfrozenColumns, setUnfrozenColumns] = useState([]);
|
|
13252
13330
|
const [columnsOpen, setColumnsOpen] = useState(false);
|
|
13253
13331
|
const [columnAnchor, setColumnAnchor] = useState(null);
|
|
13254
13332
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
@@ -13263,6 +13341,12 @@ function ListWorkbench({
|
|
|
13263
13341
|
const editable = Boolean(editFields && entityKind && onEdit);
|
|
13264
13342
|
const createSheet = Boolean(editFields && entityKind && onCreate);
|
|
13265
13343
|
const filteredEmpty = Boolean(view.q || view.rules.length);
|
|
13344
|
+
const [session, setSession] = useState({ identity });
|
|
13345
|
+
if (session.identity !== identity) setSession({ identity });
|
|
13346
|
+
const boardSession = useRef(session);
|
|
13347
|
+
useLayoutEffect(() => {
|
|
13348
|
+
boardSession.current = session;
|
|
13349
|
+
}, [session]);
|
|
13266
13350
|
const latest = useRef({ onImport, onNotify, onSelectionChange, selection, disabled });
|
|
13267
13351
|
useLayoutEffect(() => {
|
|
13268
13352
|
latest.current = { onImport, onNotify, onSelectionChange, selection, disabled };
|
|
@@ -13291,6 +13375,7 @@ function ListWorkbench({
|
|
|
13291
13375
|
setBulkEditOpen(false);
|
|
13292
13376
|
setBulkConfirm(false);
|
|
13293
13377
|
setHiddenColumns([]);
|
|
13378
|
+
setUnfrozenColumns([]);
|
|
13294
13379
|
}
|
|
13295
13380
|
if (disabled && columnsOpen) setColumnsOpen(false);
|
|
13296
13381
|
if (disabled && settingsOpen) setSettingsOpen(false);
|
|
@@ -13356,7 +13441,9 @@ function ListWorkbench({
|
|
|
13356
13441
|
};
|
|
13357
13442
|
}
|
|
13358
13443
|
return column;
|
|
13359
|
-
}).map(
|
|
13444
|
+
}).map(
|
|
13445
|
+
(column) => frozen.includes(column.id) ? { ...column, fixed: "left" } : unfrozenColumns.includes(column.id) ? { ...column, fixed: void 0 } : column
|
|
13446
|
+
);
|
|
13360
13447
|
const groupValue = useMemo(() => {
|
|
13361
13448
|
if (!view.group) return void 0;
|
|
13362
13449
|
return (row) => {
|
|
@@ -13367,7 +13454,15 @@ function ListWorkbench({
|
|
|
13367
13454
|
}, [view.group]);
|
|
13368
13455
|
const exportCsv = (keys = []) => {
|
|
13369
13456
|
if (disabled) return;
|
|
13370
|
-
const
|
|
13457
|
+
const selected = new Set(keys);
|
|
13458
|
+
const source = selected.size > 0 ? rows.filter((row) => selected.has(rowKey(row))) : sorted;
|
|
13459
|
+
if (selected.size > 0 && source.length !== selected.size) {
|
|
13460
|
+
notify(
|
|
13461
|
+
"error",
|
|
13462
|
+
zh ? "\u90E8\u5206\u6240\u9009\u8BB0\u5F55\u672A\u52A0\u8F7D\uFF0C\u8BF7\u52A0\u8F7D\u5B8C\u6574\u6570\u636E\u540E\u91CD\u8BD5\u3002" : "Some selected records are not loaded. Load all selected records and retry."
|
|
13463
|
+
);
|
|
13464
|
+
return;
|
|
13465
|
+
}
|
|
13371
13466
|
try {
|
|
13372
13467
|
if (onExport) download(`${slug}.csv`, onExport(source));
|
|
13373
13468
|
else exportRowsToCsv(slug, source);
|
|
@@ -13650,7 +13745,7 @@ function ListWorkbench({
|
|
|
13650
13745
|
{
|
|
13651
13746
|
title: `No ${noun.many} to show`,
|
|
13652
13747
|
hint: emptyBoardText ?? "Nothing matches the current filters. Clear them to see the full board.",
|
|
13653
|
-
action: /* @__PURE__ */ jsx(Button, { variant: "default", onClick: () => update({ rules: [], page: 1 }), children: "Clear filters" })
|
|
13748
|
+
action: /* @__PURE__ */ jsx(Button, { variant: "default", onClick: () => update({ q: "", rules: [], page: 1 }), children: "Clear filters" })
|
|
13654
13749
|
}
|
|
13655
13750
|
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13656
13751
|
selection.length > 0 ? /* @__PURE__ */ jsx(
|
|
@@ -13660,9 +13755,14 @@ function ListWorkbench({
|
|
|
13660
13755
|
count: selection.length,
|
|
13661
13756
|
clearLabel: "Cancel",
|
|
13662
13757
|
onClear: () => onSelectionChange([]),
|
|
13663
|
-
allSelected:
|
|
13664
|
-
someSelected: selection.some((key) =>
|
|
13665
|
-
onToggleAll: () =>
|
|
13758
|
+
allSelected: sorted.length > 0 && sorted.every((row) => selection.includes(rowKey(row))),
|
|
13759
|
+
someSelected: !sorted.every((row) => selection.includes(rowKey(row))) && selection.some((key) => sorted.some((row) => rowKey(row) === key)),
|
|
13760
|
+
onToggleAll: () => {
|
|
13761
|
+
const keys = sorted.map(rowKey);
|
|
13762
|
+
onSelectionChange(
|
|
13763
|
+
keys.every((key) => selection.includes(key)) ? selection.filter((key) => !keys.includes(key)) : [.../* @__PURE__ */ new Set([...selection, ...keys])]
|
|
13764
|
+
);
|
|
13765
|
+
},
|
|
13666
13766
|
...buildBulkCommands({
|
|
13667
13767
|
bulk,
|
|
13668
13768
|
keys: selection,
|
|
@@ -13676,9 +13776,16 @@ function ListWorkbench({
|
|
|
13676
13776
|
onSelect: () => exportCsv(selection)
|
|
13677
13777
|
}
|
|
13678
13778
|
],
|
|
13679
|
-
onNotify: (message2) =>
|
|
13779
|
+
onNotify: (message2) => {
|
|
13780
|
+
if (live.current && boardSession.current === session) notify("success", message2);
|
|
13781
|
+
},
|
|
13680
13782
|
onEditProperties: bulk?.properties ? () => setBulkEditOpen(true) : void 0,
|
|
13681
|
-
onClear: () => onSelectionChange([])
|
|
13783
|
+
onClear: () => onSelectionChange([]),
|
|
13784
|
+
onComplete: (keys) => {
|
|
13785
|
+
if (!live.current || boardSession.current !== session) return;
|
|
13786
|
+
const processed = new Set(keys);
|
|
13787
|
+
latest.current.onSelectionChange(latest.current.selection.filter((key) => !processed.has(key)));
|
|
13788
|
+
}
|
|
13682
13789
|
})
|
|
13683
13790
|
}
|
|
13684
13791
|
) : null,
|
|
@@ -13718,6 +13825,10 @@ function ListWorkbench({
|
|
|
13718
13825
|
onSortChange: sortFields.length ? (sort) => update({ sort }) : void 0,
|
|
13719
13826
|
onColumnCommand: (command) => {
|
|
13720
13827
|
if (command.kind === "freeze") {
|
|
13828
|
+
if (command.fixed === null && columns.find((column) => column.id === command.columnId)?.fixed) {
|
|
13829
|
+
if (onColumnCommand) onColumnCommand(command);
|
|
13830
|
+
else setUnfrozenColumns((current) => [.../* @__PURE__ */ new Set([...current, command.columnId])]);
|
|
13831
|
+
}
|
|
13721
13832
|
update({
|
|
13722
13833
|
frozen: command.fixed === null ? frozen.filter((id) => id !== command.columnId) : [...frozen.filter((id) => id !== command.columnId), command.columnId]
|
|
13723
13834
|
});
|
|
@@ -13779,7 +13890,10 @@ function ListWorkbench({
|
|
|
13779
13890
|
)
|
|
13780
13891
|
}
|
|
13781
13892
|
),
|
|
13782
|
-
/* @__PURE__ */
|
|
13893
|
+
view.group || view.view === "board" && boardView ? /* @__PURE__ */ jsxs("div", { className: "pro-row", style: { justifyContent: "space-between" }, children: [
|
|
13894
|
+
footerLeft ?? /* @__PURE__ */ jsx("span", { className: "pro-text-sm", children: title }),
|
|
13895
|
+
/* @__PURE__ */ jsx("span", { className: "pro-text-sm", children: zh ? `\u5171 ${total} \u6761` : `Total: ${total}` })
|
|
13896
|
+
] }) : /* @__PURE__ */ jsx(
|
|
13783
13897
|
Pagination,
|
|
13784
13898
|
{
|
|
13785
13899
|
page,
|
|
@@ -13846,6 +13960,7 @@ function ListWorkbench({
|
|
|
13846
13960
|
onSelect: () => {
|
|
13847
13961
|
update({ q: "", rules: [], sort: null, group: null, preview: "auto", page: 1 });
|
|
13848
13962
|
setHiddenColumns([]);
|
|
13963
|
+
setUnfrozenColumns([]);
|
|
13849
13964
|
}
|
|
13850
13965
|
}
|
|
13851
13966
|
]
|
|
@@ -16897,6 +17012,10 @@ function FormRoot({
|
|
|
16897
17012
|
const store = stores.get(instance);
|
|
16898
17013
|
if (!store) throw new Error("Form requires an instance created by useForm");
|
|
16899
17014
|
const config = useProConfig();
|
|
17015
|
+
const latestSubmit = useRef({ disabled: disabled ?? config.disabled, onFinish });
|
|
17016
|
+
useLayoutEffect(() => {
|
|
17017
|
+
latestSubmit.current = { disabled: disabled ?? config.disabled, onFinish };
|
|
17018
|
+
}, [disabled, config.disabled, onFinish]);
|
|
16900
17019
|
const initial = useRef(initialValues);
|
|
16901
17020
|
const submitting = useRef(false);
|
|
16902
17021
|
const generation = useRef(0);
|
|
@@ -16938,9 +17057,9 @@ function FormRoot({
|
|
|
16938
17057
|
}
|
|
16939
17058
|
return;
|
|
16940
17059
|
}
|
|
16941
|
-
if (generation.current !== current) return;
|
|
17060
|
+
if (generation.current !== current || latestSubmit.current.disabled) return;
|
|
16942
17061
|
try {
|
|
16943
|
-
await onFinish?.(values);
|
|
17062
|
+
await latestSubmit.current.onFinish?.(values);
|
|
16944
17063
|
} catch (error) {
|
|
16945
17064
|
if (generation.current !== current) return;
|
|
16946
17065
|
setSubmitError(true);
|