@sia.soul/sia-react-ui 0.1.82 → 0.1.84

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 CHANGED
@@ -1578,7 +1578,7 @@ function Steps({ items, current = 0, initial: initial3 = 0, direction = "horizon
1578
1578
  ] }, index);
1579
1579
  }) });
1580
1580
  }
1581
- function Segmented({ options, value, defaultValue, size: sizeProp, block = false, vertical = false, disabled = false, onChange, className = "", onKeyDown, ...props }) {
1581
+ function Segmented({ options, value, defaultValue, variant = "default", size: sizeProp, block = false, vertical = false, disabled = false, onChange, className = "", onKeyDown, ...props }) {
1582
1582
  const size = useControlSize(sizeProp);
1583
1583
  const normalized = (0, import_react5.useMemo)(() => options.map((option) => typeof option === "object" ? option : { label: option, value: option }), [options]);
1584
1584
  const [current, setCurrent] = useControllableState({ value, defaultValue: defaultValue ?? normalized[0]?.value, onChange: (next) => next !== void 0 && onChange?.(next) });
@@ -1591,7 +1591,7 @@ function Segmented({ options, value, defaultValue, size: sizeProp, block = false
1591
1591
  const next = event.key === "ArrowRight" || event.key === "ArrowDown" ? enabled[(index + 1) % enabled.length] : enabled[(index - 1 + enabled.length) % enabled.length];
1592
1592
  if (next) setCurrent(next.value);
1593
1593
  }
1594
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `sia-segmented sia-segmented--${size}${block ? " sia-segmented--block" : ""}${vertical ? " sia-segmented--vertical" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), role: "radiogroup", onKeyDown: keyboard, ...withTitleTooltip(props), children: normalized.map((option) => /* @__PURE__ */ (0, import_react6.createElement)("button", { type: "button", role: "radio", "aria-checked": option.value === current, ...withTitleTooltip({ title: option.title }), className: option.value === current ? "is-selected" : "", disabled: disabled || option.disabled, key: option.value, onClick: () => setCurrent(option.value) }, option.icon, /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: option.label ?? option.value }))) });
1594
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `sia-segmented sia-segmented--${size}${variant === "zigzag" && !vertical && normalized.length === 2 ? " sia-segmented--zigzag" : ""}${block ? " sia-segmented--block" : ""}${vertical ? " sia-segmented--vertical" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), role: "radiogroup", onKeyDown: keyboard, ...withTitleTooltip(props), children: normalized.map((option) => /* @__PURE__ */ (0, import_react6.createElement)("button", { type: "button", role: "radio", "aria-checked": option.value === current, ...withTitleTooltip({ title: option.title }), className: option.value === current ? "is-selected" : "", disabled: disabled || option.disabled, key: option.value, onClick: () => setCurrent(option.value) }, option.icon, /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: option.label ?? option.value }))) });
1595
1595
  }
1596
1596
 
1597
1597
  // src/components/Dropdown.tsx
@@ -12583,6 +12583,22 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
12583
12583
  return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("canvas", { ref: canvasRef, "aria-hidden": "true", className: "sia-table__canvas-layer" });
12584
12584
  }
12585
12585
 
12586
+ // src/components/Table/rowIdentity.ts
12587
+ function createRowIdentity() {
12588
+ const keys = /* @__PURE__ */ new WeakMap();
12589
+ let sequence = 0;
12590
+ return (record, index, rowKey) => {
12591
+ const explicit = typeof rowKey === "function" ? rowKey(record, index) : rowKey == null ? void 0 : record[rowKey];
12592
+ if (typeof explicit === "string" || typeof explicit === "bigint" || typeof explicit === "number" && Number.isFinite(explicit)) return explicit;
12593
+ let key = keys.get(record);
12594
+ if (key === void 0) {
12595
+ key = `__sia_internal_row_${++sequence}`;
12596
+ keys.set(record, key);
12597
+ }
12598
+ return key;
12599
+ };
12600
+ }
12601
+
12586
12602
  // src/components/Table/Table.tsx
12587
12603
  var import_react53 = require("react");
12588
12604
 
@@ -12650,6 +12666,29 @@ function mergeColumnSettings(columns, saved, active) {
12650
12666
  return [...merged.values()].sort((left, right) => left.order - right.order);
12651
12667
  }
12652
12668
 
12669
+ // src/components/settingsPersistence.ts
12670
+ var queues = /* @__PURE__ */ new WeakMap();
12671
+ function saveSettingsPatch(adapter, scope, patch) {
12672
+ let scoped = queues.get(adapter);
12673
+ if (!scoped) {
12674
+ scoped = /* @__PURE__ */ new Map();
12675
+ queues.set(adapter, scoped);
12676
+ }
12677
+ const key = JSON.stringify([scope.moduleName, scope.businessKey]);
12678
+ const previous = scoped.get(key) ?? Promise.resolve();
12679
+ const task = previous.catch(() => void 0).then(async () => {
12680
+ const current = await adapter.load(scope);
12681
+ const defined = Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== void 0));
12682
+ await adapter.save(scope, { ...current, ...defined });
12683
+ });
12684
+ scoped.set(key, task);
12685
+ const cleanup2 = () => {
12686
+ if (scoped.get(key) === task) scoped.delete(key);
12687
+ };
12688
+ void task.then(cleanup2, cleanup2);
12689
+ return task;
12690
+ }
12691
+
12653
12692
  // src/components/Table/plugins.tsx
12654
12693
  var import_jsx_runtime51 = require("react/jsx-runtime");
12655
12694
  function TableCheckbox({
@@ -14742,7 +14781,7 @@ function createColumnSettingPlugin(options = {}) {
14742
14781
  return items.filter((item) => keys.has(item.key));
14743
14782
  };
14744
14783
  const currentItems = (context) => reconcileColumnSettings(context.baseColumns, baseItems(context), context.state.items ?? []);
14745
- const save = (snapshot) => options.adapter && options.scope ? options.adapter.save(options.scope, snapshot).catch(() => void 0) : Promise.resolve();
14784
+ const save = (snapshot) => options.adapter && options.scope ? saveSettingsPatch(options.adapter, options.scope, snapshot).catch(() => void 0) : Promise.resolve();
14746
14785
  function apply(items, context, persist = true) {
14747
14786
  const normalized = orderColumnSettings(
14748
14787
  editableItems(items, context).sort((a, b) => a.order - b.order)
@@ -15269,7 +15308,7 @@ function TableInner(props, ref) {
15269
15308
  const {
15270
15309
  dataSource = EMPTY_DATA,
15271
15310
  columns: baseColumns = EMPTY_COLUMNS,
15272
- rowKey = "id",
15311
+ rowKey,
15273
15312
  plugins: providedPlugins = EMPTY_PLUGINS,
15274
15313
  loading = false,
15275
15314
  emptyText = "\u6682\u65E0\u6570\u636E",
@@ -15312,7 +15351,8 @@ function TableInner(props, ref) {
15312
15351
  const [viewportHeight, setViewportHeight] = (0, import_react53.useState)(420);
15313
15352
  const [viewportWidth, setViewportWidth] = (0, import_react53.useState)(0);
15314
15353
  const [autoColumnWidths, setAutoColumnWidths] = (0, import_react53.useState)({});
15315
- const getRowKey = (0, import_react53.useCallback)((record, index) => typeof rowKey === "function" ? rowKey(record, index) : record[String(rowKey)] ?? index, [rowKey]);
15354
+ const [resolveRowIdentity] = (0, import_react53.useState)(createRowIdentity);
15355
+ const getRowKey = (0, import_react53.useCallback)((record, index) => resolveRowIdentity(record, index, typeof rowKey === "function" ? rowKey : rowKey == null ? void 0 : String(rowKey)), [rowKey, resolveRowIdentity]);
15316
15356
  const builtInResizePlugin = (0, import_react53.useMemo)(() => createResizePlugin(), []);
15317
15357
  const builtInHighlightPlugin = (0, import_react53.useMemo)(() => createHighlightPlugin(), []);
15318
15358
  const builtInCellSelectionPlugin = (0, import_react53.useMemo)(() => createCellSelectionPlugin(), []);
@@ -23787,10 +23827,318 @@ var InputSelect = (0, import_react93.forwardRef)(function InputSelect2({
23787
23827
  });
23788
23828
 
23789
23829
  // src/components/QueryForm.tsx
23830
+ var import_react96 = require("react");
23831
+
23832
+ // src/components/QueryFormSettings.tsx
23833
+ var import_react95 = require("react");
23834
+
23835
+ // src/components/useQueryFieldSort.ts
23790
23836
  var import_react94 = require("react");
23837
+ function getQuerySortPreview(keys, rects, from, dy, gap) {
23838
+ const center = rects[from].top + rects[from].height / 2 + dy;
23839
+ const rest = keys.map((_, index) => index).filter((index) => index !== from);
23840
+ const to = rest.filter((index) => center > rects[index].top + rects[index].height / 2).length;
23841
+ const ordered = [...keys];
23842
+ ordered.splice(to, 0, ordered.splice(from, 1)[0]);
23843
+ const offsets = {};
23844
+ const last = rects[rects.length - 1];
23845
+ const boundedDy = Math.max(rects[0].top - rects[from].top, Math.min(dy, last.top + last.height - rects[from].height - rects[from].top));
23846
+ let top = rects[0].top;
23847
+ for (const key of ordered) {
23848
+ const index = keys.indexOf(key);
23849
+ offsets[key] = index === from ? boundedDy : top - rects[index].top;
23850
+ top += rects[index].height + gap;
23851
+ }
23852
+ return { ordered, offsets };
23853
+ }
23854
+ function useQueryFieldSort(keys, enabled, onCommit) {
23855
+ const listRef = (0, import_react94.useRef)(null);
23856
+ const cancelRef = (0, import_react94.useRef)();
23857
+ const commitRef = (0, import_react94.useRef)(onCommit);
23858
+ commitRef.current = onCommit;
23859
+ const [preview, setPreview] = (0, import_react94.useState)();
23860
+ const signature = JSON.stringify(keys);
23861
+ (0, import_react94.useEffect)(() => {
23862
+ cancelRef.current?.();
23863
+ return () => cancelRef.current?.();
23864
+ }, [enabled, signature]);
23865
+ function start(event, key) {
23866
+ if (!enabled || event.button !== 0 || event.target.closest("button, input, label")) return;
23867
+ const list = listRef.current;
23868
+ const from = keys.indexOf(key);
23869
+ if (!list || from < 0) return;
23870
+ cancelRef.current?.();
23871
+ const elements = [...list.querySelectorAll(".sia-query-settings__item")];
23872
+ if (elements.length !== keys.length) return;
23873
+ const rects = elements.map((element) => element.getBoundingClientRect());
23874
+ const gap = parseFloat(getComputedStyle(list).rowGap) || 0;
23875
+ const original = [...keys];
23876
+ const target = event.currentTarget;
23877
+ const pointerId = event.pointerId;
23878
+ const startY = event.clientY;
23879
+ const initialScroll = list.scrollTop;
23880
+ const maxScroll = Math.max(0, list.scrollHeight - list.clientHeight);
23881
+ const originalUserSelect = document.body.style.userSelect;
23882
+ let lastY = startY;
23883
+ let moved = false;
23884
+ let ended = false;
23885
+ let ordered = original;
23886
+ let frame = 0;
23887
+ target.setPointerCapture(pointerId);
23888
+ const update = () => {
23889
+ const dy = lastY - startY + list.scrollTop - initialScroll;
23890
+ if (!moved && Math.abs(dy) < 4) return;
23891
+ moved = true;
23892
+ document.body.style.userSelect = "none";
23893
+ const next = getQuerySortPreview(original, rects, from, dy, gap);
23894
+ ordered = next.ordered;
23895
+ setPreview({ key, offsets: next.offsets });
23896
+ };
23897
+ const tick = () => {
23898
+ if (moved) {
23899
+ const bounds = list.getBoundingClientRect();
23900
+ const delta = lastY < bounds.top + 32 ? -10 : lastY > bounds.bottom - 32 ? 10 : 0;
23901
+ const nextScroll = Math.max(0, Math.min(maxScroll, list.scrollTop + delta));
23902
+ if (delta && nextScroll !== list.scrollTop) {
23903
+ list.scrollTop = nextScroll;
23904
+ update();
23905
+ }
23906
+ }
23907
+ frame = requestAnimationFrame(tick);
23908
+ };
23909
+ const move = (next) => {
23910
+ if (next.pointerId === pointerId) {
23911
+ lastY = next.clientY;
23912
+ update();
23913
+ }
23914
+ };
23915
+ const finish = (commit) => {
23916
+ if (ended) return;
23917
+ ended = true;
23918
+ document.removeEventListener("pointermove", move);
23919
+ document.removeEventListener("pointerup", up);
23920
+ document.removeEventListener("pointercancel", cancelPointer);
23921
+ target.removeEventListener("lostpointercapture", cancel);
23922
+ window.removeEventListener("blur", cancel);
23923
+ window.removeEventListener("keydown", escape, true);
23924
+ cancelAnimationFrame(frame);
23925
+ if (target.hasPointerCapture(pointerId)) target.releasePointerCapture(pointerId);
23926
+ document.body.style.userSelect = originalUserSelect;
23927
+ cancelRef.current = void 0;
23928
+ setPreview(void 0);
23929
+ if (commit && moved) commitRef.current(ordered);
23930
+ };
23931
+ const up = (next) => {
23932
+ if (next.pointerId === pointerId) {
23933
+ lastY = next.clientY;
23934
+ update();
23935
+ finish(true);
23936
+ }
23937
+ };
23938
+ const cancel = () => finish(false);
23939
+ const cancelPointer = (next) => {
23940
+ if (next.pointerId === pointerId) cancel();
23941
+ };
23942
+ const escape = (next) => {
23943
+ if (next.key === "Escape") {
23944
+ next.preventDefault();
23945
+ next.stopImmediatePropagation();
23946
+ cancel();
23947
+ }
23948
+ };
23949
+ cancelRef.current = cancel;
23950
+ document.addEventListener("pointermove", move);
23951
+ document.addEventListener("pointerup", up);
23952
+ document.addEventListener("pointercancel", cancelPointer);
23953
+ target.addEventListener("lostpointercapture", cancel);
23954
+ window.addEventListener("blur", cancel);
23955
+ window.addEventListener("keydown", escape, true);
23956
+ frame = requestAnimationFrame(tick);
23957
+ }
23958
+ return { listRef, preview, start };
23959
+ }
23960
+
23961
+ // src/components/queryFormSettingsUtils.ts
23962
+ function reconcileQueryFields(keys, saved = []) {
23963
+ const stored = new Map(saved.map((item) => [item.key, item]));
23964
+ return keys.map((key, index) => ({
23965
+ key,
23966
+ visible: stored.get(key)?.visible !== false,
23967
+ order: Number.isFinite(stored.get(key)?.order) ? stored.get(key).order : Infinity,
23968
+ index
23969
+ })).sort((a, b) => a.order - b.order || a.index - b.index).map(({ key, visible }, order) => ({ key, visible, order }));
23970
+ }
23971
+ function mergeQueryFields(saved, active) {
23972
+ const current = new Set(active.map((item) => item.key));
23973
+ return [...active, ...saved.filter((item) => !current.has(item.key))];
23974
+ }
23975
+
23976
+ // src/components/QueryFormSettings.tsx
23791
23977
  var import_jsx_runtime91 = require("react/jsx-runtime");
23978
+ function useQueryFormSettings(config, fields, defaultCollapsed, applyCollapsed, disabled) {
23979
+ const [snapshot, setSnapshot] = (0, import_react95.useState)();
23980
+ const [draft, setDraft] = (0, import_react95.useState)({ fields: [], defaultCollapsed });
23981
+ const [open, setOpen] = (0, import_react95.useState)(false);
23982
+ const [loading, setLoading] = (0, import_react95.useState)(false);
23983
+ const [saving, setSaving] = (0, import_react95.useState)(false);
23984
+ const [error, setError] = (0, import_react95.useState)("");
23985
+ const [loadFailed, setLoadFailed] = (0, import_react95.useState)(false);
23986
+ const token = (0, import_react95.useRef)(0);
23987
+ const saveLock = (0, import_react95.useRef)(false);
23988
+ const latest = (0, import_react95.useRef)({ config, fields, defaultCollapsed, applyCollapsed });
23989
+ latest.current = { config, fields, defaultCollapsed, applyCollapsed };
23990
+ const moduleName = config?.scope.moduleName;
23991
+ const businessKey = config?.scope.businessKey;
23992
+ const adapter = config?.adapter;
23993
+ async function load(edit) {
23994
+ const current = latest.current;
23995
+ if (!current.config) return;
23996
+ const request = ++token.current;
23997
+ setLoading(true);
23998
+ setError("");
23999
+ setLoadFailed(false);
24000
+ try {
24001
+ const stored = (await current.config.adapter.load(current.config.scope))?.queryForm;
24002
+ if (request !== token.current) return;
24003
+ const next = stored ?? { fields: [], defaultCollapsed: current.defaultCollapsed };
24004
+ setSnapshot(next);
24005
+ setDraft({ ...next, fields: reconcileQueryFields(latest.current.fields.map((field) => field.key), next.fields) });
24006
+ if (!edit) latest.current.applyCollapsed(next.defaultCollapsed);
24007
+ } catch (reason) {
24008
+ if (request !== token.current) return;
24009
+ setLoadFailed(true);
24010
+ setError(reason instanceof Error ? reason.message : "\u8BFB\u53D6\u67E5\u8BE2\u8BBE\u7F6E\u5931\u8D25");
24011
+ current.config.onError?.(reason, "load");
24012
+ } finally {
24013
+ if (request === token.current) setLoading(false);
24014
+ }
24015
+ }
24016
+ (0, import_react95.useEffect)(() => {
24017
+ setSnapshot(void 0);
24018
+ setOpen(false);
24019
+ setError("");
24020
+ setLoadFailed(false);
24021
+ setLoading(false);
24022
+ setSaving(false);
24023
+ saveLock.current = false;
24024
+ latest.current.applyCollapsed(latest.current.defaultCollapsed);
24025
+ if (adapter) void load(false);
24026
+ return () => {
24027
+ token.current++;
24028
+ };
24029
+ }, [adapter, moduleName, businessKey]);
24030
+ async function save() {
24031
+ const current = latest.current;
24032
+ if (!current.config || loading || loadFailed || disabled || saveLock.current) return false;
24033
+ saveLock.current = true;
24034
+ setSaving(true);
24035
+ setError("");
24036
+ const request = token.current;
24037
+ const active = reconcileQueryFields(current.fields.map((field) => field.key), draft.fields);
24038
+ const next = { ...draft, fields: mergeQueryFields(snapshot?.fields ?? [], active) };
24039
+ try {
24040
+ await saveSettingsPatch(current.config.adapter, current.config.scope, { queryForm: next });
24041
+ if (request !== token.current) return false;
24042
+ setSnapshot(next);
24043
+ current.applyCollapsed(next.defaultCollapsed);
24044
+ setOpen(false);
24045
+ return true;
24046
+ } catch (reason) {
24047
+ if (request !== token.current) return false;
24048
+ setError(reason instanceof Error ? reason.message : "\u4FDD\u5B58\u67E5\u8BE2\u8BBE\u7F6E\u5931\u8D25");
24049
+ current.config.onError?.(reason, "save");
24050
+ return false;
24051
+ } finally {
24052
+ if (request === token.current) {
24053
+ saveLock.current = false;
24054
+ setSaving(false);
24055
+ }
24056
+ }
24057
+ }
24058
+ const visibleDraft = reconcileQueryFields(fields.map((field) => field.key), draft.fields);
24059
+ const labels = new Map(fields.map((field) => [field.key, field.label]));
24060
+ const locked = loading || saving || loadFailed || disabled;
24061
+ const move = (from, to) => {
24062
+ if (locked || from === to || to < 0 || to >= visibleDraft.length) return;
24063
+ const next = [...visibleDraft];
24064
+ next.splice(to, 0, next.splice(from, 1)[0]);
24065
+ setDraft((current) => ({ ...current, fields: next.map((item, order) => ({ ...item, order })) }));
24066
+ };
24067
+ const sort = useQueryFieldSort(visibleDraft.map((item) => item.key), open && !locked, (keys) => {
24068
+ const items = new Map(visibleDraft.map((item) => [item.key, item]));
24069
+ setDraft((current) => ({ ...current, fields: keys.map((key, order) => ({ ...items.get(key), order })) }));
24070
+ });
24071
+ const control = config ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24072
+ Button,
24073
+ {
24074
+ type: "button",
24075
+ className: "sia-query-settings__trigger",
24076
+ title: "\u67E5\u8BE2\u8BBE\u7F6E",
24077
+ "aria-label": "\u67E5\u8BE2\u8BBE\u7F6E",
24078
+ disabled: disabled || saving,
24079
+ loading: loading && !open,
24080
+ icon: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Icon, { name: "more-vertical" }),
24081
+ onClick: () => {
24082
+ setOpen(true);
24083
+ void load(true);
24084
+ }
24085
+ }
24086
+ ) : null;
24087
+ const panel = config ? /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(import_jsx_runtime91.Fragment, { children: [
24088
+ !open && error ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "sia-query-form__error", role: "alert", children: "\u67E5\u8BE2\u8BBE\u7F6E\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u6253\u5F00\u8BBE\u7F6E\u91CD\u8BD5" }) : null,
24089
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24090
+ Modal2,
24091
+ {
24092
+ title: "\u67E5\u8BE2\u8BBE\u7F6E",
24093
+ open,
24094
+ width: 520,
24095
+ okText: "\u4FDD\u5B58",
24096
+ confirmLoading: saving,
24097
+ okButtonProps: { disabled: locked },
24098
+ onOk: save,
24099
+ onOpenChange: (next) => {
24100
+ if (!saveLock.current) setOpen(next);
24101
+ },
24102
+ children: /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "sia-query-settings", children: [
24103
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { role: "status", children: "\u6B63\u5728\u8BFB\u53D6\u67E5\u8BE2\u8BBE\u7F6E\u2026" }) : null,
24104
+ error ? /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { role: "alert", className: "sia-query-form__error", children: [
24105
+ error,
24106
+ loadFailed ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Button, { type: "button", variant: "link", onClick: () => void load(true), children: "\u91CD\u8BD5" }) : null
24107
+ ] }) : null,
24108
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Checkbox2, { checked: draft.defaultCollapsed, disabled: locked, onChange: (checked) => setDraft((current) => ({ ...current, defaultCollapsed: checked })), children: "\u9ED8\u8BA4\u6536\u8D77\u67E5\u8BE2\u6761\u4EF6" }),
24109
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { className: "sia-query-settings__hint", children: "\u52FE\u9009\u9700\u8981\u663E\u793A\u7684\u6761\u4EF6\uFF0C\u62D6\u52A8\u6216\u4F7F\u7528\u4E0A\u4E0B\u6309\u94AE\u8C03\u6574\u987A\u5E8F\u3002" }),
24110
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { ref: sort.listRef, className: `sia-query-settings__list${sort.preview ? " is-sorting" : ""}`, children: visibleDraft.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
24111
+ "div",
24112
+ {
24113
+ "data-query-field-key": item.key,
24114
+ className: `sia-query-settings__item${sort.preview?.key === item.key ? " is-dragging" : ""}${locked ? " is-disabled" : ""}`,
24115
+ style: sort.preview ? { transform: `translateY(${sort.preview.offsets[item.key] ?? 0}px)` } : void 0,
24116
+ onPointerDown: (event) => sort.start(event, item.key),
24117
+ children: [
24118
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Icon, { name: "menu", size: 15 }),
24119
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Checkbox2, { "aria-label": `\u663E\u793A ${item.key}`, checked: item.visible, disabled: locked, onChange: (checked) => setDraft((current) => ({ ...current, fields: visibleDraft.map((field) => field.key === item.key ? { ...field, visible: checked } : field) })) }),
24120
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "sia-query-settings__name", children: labels.get(item.key) ?? item.key }),
24121
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "sia-query-settings__order", children: [
24122
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Button, { type: "button", size: "small", variant: "text", "aria-label": `\u4E0A\u79FB ${item.key}`, disabled: locked || index === 0, icon: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Icon, { name: "chevron-up" }), onClick: () => move(index, index - 1) }),
24123
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Button, { type: "button", size: "small", variant: "text", "aria-label": `\u4E0B\u79FB ${item.key}`, disabled: locked || index === visibleDraft.length - 1, icon: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Icon, { name: "chevron-down" }), onClick: () => move(index, index + 1) })
24124
+ ] })
24125
+ ]
24126
+ },
24127
+ item.key
24128
+ )) }),
24129
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Button, { type: "button", disabled: locked, onClick: () => setDraft({ fields: reconcileQueryFields(fields.map((field) => field.key)), defaultCollapsed }), children: "\u6062\u590D\u9ED8\u8BA4" })
24130
+ ] })
24131
+ }
24132
+ )
24133
+ ] }) : null;
24134
+ return { snapshot, control, panel };
24135
+ }
24136
+
24137
+ // src/components/QueryForm.tsx
24138
+ var import_jsx_runtime92 = require("react/jsx-runtime");
23792
24139
  function QueryForm({
23793
24140
  fields,
24141
+ settings,
23794
24142
  children,
23795
24143
  form: providedForm,
23796
24144
  onSearch,
@@ -23821,39 +24169,51 @@ function QueryForm({
23821
24169
  ...formProps
23822
24170
  }) {
23823
24171
  const [form] = useForm(providedForm);
23824
- const [internalCollapsed, setInternalCollapsed] = (0, import_react94.useState)(defaultCollapsed);
23825
- const [needsCollapse, setNeedsCollapse] = (0, import_react94.useState)(false);
24172
+ const [internalCollapsed, setInternalCollapsed] = (0, import_react96.useState)(defaultCollapsed);
24173
+ const [needsCollapse, setNeedsCollapse] = (0, import_react96.useState)(false);
23826
24174
  const collapsed = collapsible && needsCollapse && (controlledCollapsed ?? internalCollapsed);
23827
- const [searching, setSearching] = (0, import_react94.useState)(false);
23828
- const [saving, setSaving] = (0, import_react94.useState)(false);
23829
- const [removing, setRemoving] = (0, import_react94.useState)(false);
23830
- const [saveOpen, setSaveOpen] = (0, import_react94.useState)(false);
23831
- const [saveName, setSaveName] = (0, import_react94.useState)("");
23832
- const [saveError, setSaveError] = (0, import_react94.useState)("");
23833
- const [error, setError] = (0, import_react94.useState)("");
23834
- const [activeShortcut, setActiveShortcut] = (0, import_react94.useState)("");
23835
- const source = (0, import_react94.useRef)({ source: "submit" });
23836
- const searchLock = (0, import_react94.useRef)(false);
23837
- const saveLock = (0, import_react94.useRef)(false);
23838
- const removeLock = (0, import_react94.useRef)(false);
23839
- const snapshot = (0, import_react94.useRef)();
24175
+ const [searching, setSearching] = (0, import_react96.useState)(false);
24176
+ const [saving, setSaving] = (0, import_react96.useState)(false);
24177
+ const [removing, setRemoving] = (0, import_react96.useState)(false);
24178
+ const [saveOpen, setSaveOpen] = (0, import_react96.useState)(false);
24179
+ const [saveName, setSaveName] = (0, import_react96.useState)("");
24180
+ const [saveError, setSaveError] = (0, import_react96.useState)("");
24181
+ const [error, setError] = (0, import_react96.useState)("");
24182
+ const [activeShortcut, setActiveShortcut] = (0, import_react96.useState)("");
24183
+ const source = (0, import_react96.useRef)({ source: "submit" });
24184
+ const searchLock = (0, import_react96.useRef)(false);
24185
+ const saveLock = (0, import_react96.useRef)(false);
24186
+ const removeLock = (0, import_react96.useRef)(false);
24187
+ const snapshot = (0, import_react96.useRef)();
23840
24188
  const busy = disabled || loading || searching;
23841
24189
  const shortcutBusy = busy || shortcutsLoading || saving || removing;
23842
- const entries = fields ? fields.map(({ key, width, ...item }) => ({
24190
+ const fieldLabel = (content) => {
24191
+ if (!(0, import_react96.isValidElement)(content)) return void 0;
24192
+ return content.props.label ?? content.props.placeholder ?? fieldLabel(content.props.children);
24193
+ };
24194
+ const sourceEntries = fields ? fields.map(({ key, width, settingsLabel, ...item }) => ({
23843
24195
  key,
23844
24196
  width,
23845
- content: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Form.Item, { noStyle: true, ...item })
23846
- })) : import_react94.Children.toArray(children).map((content, index) => ({
23847
- key: String(index),
24197
+ label: settingsLabel ?? item.label ?? (typeof item.children === "function" ? void 0 : fieldLabel(item.children)) ?? key,
24198
+ content: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(Form.Item, { noStyle: true, ...item })
24199
+ })) : import_react96.Children.toArray(children).map((content, index) => ({
24200
+ key: (0, import_react96.isValidElement)(content) && content.key != null ? String(content.key) : String(index),
23848
24201
  width: void 0,
24202
+ label: fieldLabel(content) ?? `\u6761\u4EF6 ${index + 1}`,
23849
24203
  content
23850
24204
  }));
24205
+ const cloudSettings = useQueryFormSettings(settings, sourceEntries, defaultCollapsed, setInternalCollapsed, disabled);
24206
+ const configured = reconcileQueryFields(sourceEntries.map((entry) => entry.key), cloudSettings.snapshot?.fields);
24207
+ const entriesByKey = new Map(sourceEntries.map((entry) => [entry.key, entry]));
24208
+ let visibleIndex = 0;
24209
+ const entries = configured.map((item) => ({ ...entriesByKey.get(item.key), visible: item.visible, visibleIndex: item.visible ? visibleIndex++ : -1 }));
24210
+ const layoutKey = JSON.stringify(configured);
23851
24211
  const limit = Math.max(1, Math.floor(collapsedCount));
23852
- const rowRef = (0, import_react94.useRef)(null);
23853
- const actionsRef = (0, import_react94.useRef)(null);
23854
- const toggleRef = (0, import_react94.useRef)(null);
23855
- const [fittingCount, setFittingCount] = (0, import_react94.useState)(limit);
23856
- (0, import_react94.useLayoutEffect)(() => {
24212
+ const rowRef = (0, import_react96.useRef)(null);
24213
+ const actionsRef = (0, import_react96.useRef)(null);
24214
+ const toggleRef = (0, import_react96.useRef)(null);
24215
+ const [fittingCount, setFittingCount] = (0, import_react96.useState)(limit);
24216
+ (0, import_react96.useLayoutEffect)(() => {
23857
24217
  const row = rowRef.current;
23858
24218
  const actions = actionsRef.current;
23859
24219
  if (!row || !actions) return;
@@ -23861,7 +24221,7 @@ function QueryForm({
23861
24221
  if (!row || !actions) return;
23862
24222
  const gap = parseFloat(getComputedStyle(row).columnGap) || 0;
23863
24223
  const allFields = Array.from(
23864
- row.querySelectorAll(":scope > .sia-query-form__field")
24224
+ row.querySelectorAll(":scope > .sia-query-form__field:not([data-settings-hidden])")
23865
24225
  );
23866
24226
  const hiddenFields = allFields.filter((field) => field.hidden);
23867
24227
  const wasCollapsed = row.classList.contains("is-collapsed");
@@ -23903,6 +24263,7 @@ function QueryForm({
23903
24263
  return () => observer.disconnect();
23904
24264
  }, [
23905
24265
  collapsed,
24266
+ layoutKey,
23906
24267
  needsCollapse,
23907
24268
  collapsible,
23908
24269
  limit,
@@ -23991,8 +24352,8 @@ function QueryForm({
23991
24352
  setRemoving(false);
23992
24353
  }
23993
24354
  }
23994
- return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: `sia-query-form ${className}`.trim(), children: [
23995
- /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
24355
+ return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: `sia-query-form ${className}`.trim(), children: [
24356
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
23996
24357
  Form,
23997
24358
  {
23998
24359
  ...formProps,
@@ -24011,8 +24372,8 @@ function QueryForm({
24011
24372
  onValuesChange?.(changed, values);
24012
24373
  },
24013
24374
  children: [
24014
- quickQueries.length ? /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "sia-query-form__quick", "aria-label": "\u9884\u8BBE\u5FEB\u6377\u67E5\u8BE2", children: [
24015
- quickQueries.map((query) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24375
+ quickQueries.length ? /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "sia-query-form__quick", "aria-label": "\u9884\u8BBE\u5FEB\u6377\u67E5\u8BE2", children: [
24376
+ quickQueries.map((query) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24016
24377
  Badge,
24017
24378
  {
24018
24379
  className: "sia-query-form__quick-badge",
@@ -24021,7 +24382,7 @@ function QueryForm({
24021
24382
  title: query.count === void 0 ? void 0 : `\u5171 ${query.count} \u6761`,
24022
24383
  ...query.badgeProps,
24023
24384
  count: query.count,
24024
- children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24385
+ children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24025
24386
  Button,
24026
24387
  {
24027
24388
  size: query.size ?? quickQuerySize,
@@ -24037,7 +24398,7 @@ function QueryForm({
24037
24398
  )),
24038
24399
  " "
24039
24400
  ] }) : null,
24040
- /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
24401
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
24041
24402
  "div",
24042
24403
  {
24043
24404
  ref: rowRef,
@@ -24046,11 +24407,12 @@ function QueryForm({
24046
24407
  "--sia-query-field-width": typeof fieldWidth === "number" ? `${fieldWidth}px` : fieldWidth
24047
24408
  },
24048
24409
  children: [
24049
- entries.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24410
+ entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24050
24411
  "div",
24051
24412
  {
24052
24413
  className: "sia-query-form__field",
24053
- hidden: collapsed && index >= Math.min(limit, fittingCount),
24414
+ "data-settings-hidden": !entry.visible || void 0,
24415
+ hidden: !entry.visible || collapsed && entry.visibleIndex >= Math.min(limit, fittingCount),
24054
24416
  style: entry.width !== void 0 ? {
24055
24417
  "--sia-query-item-width": typeof entry.width === "number" ? `${entry.width}px` : entry.width
24056
24418
  } : void 0,
@@ -24058,9 +24420,9 @@ function QueryForm({
24058
24420
  },
24059
24421
  entry.key
24060
24422
  )),
24061
- /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { ref: actionsRef, className: "sia-query-form__actions", children: [
24062
- /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(Space.Compact, { children: [
24063
- /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24423
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { ref: actionsRef, className: "sia-query-form__actions", children: [
24424
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(Space.Compact, { children: [
24425
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24064
24426
  Button,
24065
24427
  {
24066
24428
  type: "submit",
@@ -24070,8 +24432,8 @@ function QueryForm({
24070
24432
  children: searchText
24071
24433
  }
24072
24434
  ),
24073
- /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Button, { disabled: busy, onClick: reset, children: resetText }),
24074
- onSaveQuery ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24435
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(Button, { disabled: busy, onClick: reset, children: resetText }),
24436
+ onSaveQuery ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24075
24437
  Button,
24076
24438
  {
24077
24439
  disabled: shortcutBusy,
@@ -24083,14 +24445,15 @@ function QueryForm({
24083
24445
  },
24084
24446
  children: saveText
24085
24447
  }
24086
- ) : null
24448
+ ) : null,
24449
+ cloudSettings.control
24087
24450
  ] }),
24088
- collapsible && entries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { ref: toggleRef, hidden: !needsCollapse, children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24451
+ collapsible && entries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { ref: toggleRef, hidden: !needsCollapse, children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24089
24452
  Button,
24090
24453
  {
24091
24454
  variant: "link",
24092
24455
  "aria-expanded": !collapsed,
24093
- icon: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Icon, { name: collapsed ? "chevron-down" : "chevron-up" }),
24456
+ icon: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(Icon, { name: collapsed ? "chevron-down" : "chevron-up" }),
24094
24457
  iconPosition: "end",
24095
24458
  onClick: () => {
24096
24459
  setInternalCollapsed(!collapsed);
@@ -24099,13 +24462,14 @@ function QueryForm({
24099
24462
  children: collapsed ? "\u5C55\u5F00" : "\u6536\u8D77"
24100
24463
  }
24101
24464
  ) }) : null,
24102
- actionsExtra
24465
+ actionsExtra,
24466
+ cloudSettings.panel
24103
24467
  ] })
24104
24468
  ]
24105
24469
  }
24106
24470
  ),
24107
- savedQueries.length ? /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "sia-query-form__saved", "aria-label": "\u5DF2\u4FDD\u5B58\u5FEB\u6377\u67E5\u8BE2", children: [
24108
- savedQueries.map((query, index) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24471
+ savedQueries.length ? /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "sia-query-form__saved", "aria-label": "\u5DF2\u4FDD\u5B58\u5FEB\u6377\u67E5\u8BE2", children: [
24472
+ savedQueries.map((query, index) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24109
24473
  Tag,
24110
24474
  {
24111
24475
  status: query.status ?? ["processing", "success", "warning", "error"][index % 4],
@@ -24131,11 +24495,11 @@ function QueryForm({
24131
24495
  )),
24132
24496
  " "
24133
24497
  ] }) : null,
24134
- error ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { className: "sia-query-form__error", role: "alert", children: error }) : null
24498
+ error ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("p", { className: "sia-query-form__error", role: "alert", children: error }) : null
24135
24499
  ]
24136
24500
  }
24137
24501
  ),
24138
- /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
24502
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
24139
24503
  Modal2,
24140
24504
  {
24141
24505
  open: saveOpen,
@@ -24147,7 +24511,7 @@ function QueryForm({
24147
24511
  if (!saveLock.current) setSaveOpen(next);
24148
24512
  },
24149
24513
  children: [
24150
- /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
24514
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24151
24515
  Input,
24152
24516
  {
24153
24517
  autoFocus: true,
@@ -24166,7 +24530,7 @@ function QueryForm({
24166
24530
  }
24167
24531
  }
24168
24532
  ),
24169
- saveError ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { className: "sia-query-form__error", role: "alert", children: saveError }) : null
24533
+ saveError ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("p", { className: "sia-query-form__error", role: "alert", children: saveError }) : null
24170
24534
  ]
24171
24535
  }
24172
24536
  )
@@ -24174,9 +24538,9 @@ function QueryForm({
24174
24538
  }
24175
24539
 
24176
24540
  // src/components/NumberRange.tsx
24177
- var import_react95 = require("react");
24178
- var import_jsx_runtime92 = require("react/jsx-runtime");
24179
- var NumberRange = (0, import_react95.forwardRef)(function NumberRange2({
24541
+ var import_react97 = require("react");
24542
+ var import_jsx_runtime93 = require("react/jsx-runtime");
24543
+ var NumberRange = (0, import_react97.forwardRef)(function NumberRange2({
24180
24544
  value,
24181
24545
  defaultValue = [null, null],
24182
24546
  onChange,
@@ -24204,7 +24568,7 @@ var NumberRange = (0, import_react95.forwardRef)(function NumberRange2({
24204
24568
  setValue2(index === 0 ? [next, range[1]] : [range[0], next]);
24205
24569
  }
24206
24570
  const inputProps = { min, max, step, precision, size, status, disabled, readOnly, placeholderMode, controls: false };
24207
- return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
24571
+ return /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
24208
24572
  "span",
24209
24573
  {
24210
24574
  ...props,
@@ -24213,7 +24577,7 @@ var NumberRange = (0, import_react95.forwardRef)(function NumberRange2({
24213
24577
  "aria-disabled": disabled || void 0,
24214
24578
  className: `sia-number-range sia-number-range--${size} sia-number-range--${status}${disabled ? " is-disabled" : ""} ${className}`.trim(),
24215
24579
  children: [
24216
- /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24580
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
24217
24581
  InputNumber,
24218
24582
  {
24219
24583
  ...inputProps,
@@ -24225,8 +24589,8 @@ var NumberRange = (0, import_react95.forwardRef)(function NumberRange2({
24225
24589
  onChange: (next) => change(0, next)
24226
24590
  }
24227
24591
  ),
24228
- /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(Icon, { className: "sia-number-range__separator", name: "tilde", size: 12, strokeWidth: 1.5, "aria-hidden": "true" }),
24229
- /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
24592
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(Icon, { className: "sia-number-range__separator", name: "tilde", size: 12, strokeWidth: 1.5, "aria-hidden": "true" }),
24593
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
24230
24594
  InputNumber,
24231
24595
  {
24232
24596
  ...inputProps,
@@ -24238,7 +24602,7 @@ var NumberRange = (0, import_react95.forwardRef)(function NumberRange2({
24238
24602
  onChange: (next) => change(1, next)
24239
24603
  }
24240
24604
  ),
24241
- allowClear && !disabled && !readOnly && range.some((item) => item !== null) ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("button", { type: "button", className: "sia-number-range__clear", "aria-label": "\u6E05\u9664\u6570\u5B57\u533A\u95F4", onClick: () => setValue2([null, null]), children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null
24605
+ allowClear && !disabled && !readOnly && range.some((item) => item !== null) ? /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("button", { type: "button", className: "sia-number-range__clear", "aria-label": "\u6E05\u9664\u6570\u5B57\u533A\u95F4", onClick: () => setValue2([null, null]), children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null
24242
24606
  ]
24243
24607
  }
24244
24608
  );