20260809223428

This commit is contained in:
oneao committed 2026-08-09 22:34:28 +08:00
1 parent d72ca4193d
commit c4891538a7
466 files changed
+21000 -3339

No files matched your search

@@ -1,177 +0,0 @@
import { h, ref } from "vue";
import { Dropdown, Modal } from "antdv-next";
import { createEditableCell } from "./createEditableCellRenderer";
const stop = (event) => event.stopPropagation();
function triggerAction(action, row) {
if (resolveActionState(action.disabled, row)) return;
if (!action.confirm) {
action.onClick?.(row);
return;
}
const confirm = typeof action.confirm === "string" ? { title: action.confirm } : action.confirm;
Modal.confirm({
okText: "确定",
okType: "danger",
cancelText: "取消",
...confirm,
onOk: () => action.onClick?.(row),
});
}
function resolveActionState(state, row) {
return typeof state === "function" ? Boolean(state(row)) : Boolean(state);
}
function isActionVisible(action, row) {
return action.visible === undefined || resolveActionState(action.visible, row);
}
function actionButton(action, row, className = "fms-action-btn") {
const disabled = resolveActionState(action.disabled, row);
const content = [];
if (action.icon) content.push(h(action.icon, { size: 14 }));
if (action.label || action.type) content.push(action.label || action.type);
return h(
"button",
{
type: "button",
class: [
className,
{
"fms-action-btn--danger":
action.danger || action.type === "danger" || action.type === "delete",
},
],
title: action.title || action.label,
disabled,
onMousedown: stop,
onClick: (event) => {
event.stopPropagation();
triggerAction(action, row);
},
},
content,
);
}
function createActionsCell(actions) {
if (!actions?.length) return undefined;
const inlineActions = actions.filter((action) => action.type !== "more");
const moreAction = actions.find((action) => action.type === "more");
const openRow = ref(null);
const itemByKey = new Map(
moreAction?.items?.map((item, index) => [String(item.key ?? item.type ?? index), item]) ?? [],
);
function closeMenu() {
openRow.value = null;
}
return ({ row }) => {
const children = inlineActions
.filter((action) => isActionVisible(action, row))
.map((action) => actionButton(action, row));
const visibleMoreItems = (moreAction?.items || []).filter((item) => isActionVisible(item, row));
if (!visibleMoreItems.length) return h("span", { class: "fms-actions-cell" }, children);
const menuItems = visibleMoreItems.map((item, index) => ({
key: String(item.key ?? item.type ?? index),
label: item.label,
icon: item.icon ? h(item.icon, { size: 14 }) : undefined,
disabled: resolveActionState(item.disabled, row),
danger: item.danger || item.type === "danger" || item.type === "delete",
}));
const visibleItemByKey = new Map(
visibleMoreItems.map((item, index) => [String(item.key ?? item.type ?? index), item]),
);
if (openRow.value !== row) {
children.push(
h(
"button",
{
type: "button",
class: "fms-action-btn fms-action-more",
title: moreAction.title || "更多操作",
"aria-label": moreAction.title || "更多操作",
onMousedown: stop,
onClick: (event) => {
event.stopPropagation();
openRow.value = row;
},
},
moreAction.label || "⋯",
),
);
return h("span", { class: "fms-actions-cell" }, children);
}
children.push(
h(
Dropdown,
{
open: true,
trigger: ["click"],
placement: "bottomRight",
menu: {
items: menuItems,
onClick: ({ key }) => {
const item = visibleItemByKey.get(String(key)) || itemByKey.get(String(key));
closeMenu();
if (item) triggerAction(item, row);
},
},
onOpenChange: (open) => {
if (!open) closeMenu();
},
},
{
default: () =>
h(
"button",
{
type: "button",
class: "fms-action-btn fms-action-more fms-action-more-open",
title: moreAction.title || "更多操作",
"aria-label": moreAction.title || "更多操作",
onMousedown: stop,
onClick: stop,
},
moreAction.label || "⋯",
),
},
),
);
return h("span", { class: "fms-actions-cell" }, children);
};
}
export function resolveCustomCell(col, editingContext) {
if (col.customCell) return col;
if (col.editor) return { ...col, customCell: createEditableCell(col, editingContext) };
if (col.actions?.length) {
const customCell = createActionsCell(col.actions);
if (customCell) return { ...col, customCell };
}
// 纯展示列(无 editor、无 actions):保持 mousedown 冒泡以支持点击激活行编辑,
// 文字选中通过 CSS 层 user-select: text 保障
if (col.dataIndex) {
return {
...col,
customCell: ({ row }) => {
const value = row[col.dataIndex];
const content = value ?? "";
return h("span", {
class: "fms-cell-display",
title: String(content),
}, content);
},
};
}
return col;
}