import type { ActionType, ProColumns } from "@ant-design/pro-components"; import { EditableProTable, useRefFunction } from "@ant-design/pro-components"; import { Button, Dropdown, Form, Space, Typography } from "antd"; import React, { useEffect, useRef, useState } from "react"; import { useIntl } from "react-intl"; import ProjectEditDrawer from "./ProjectEditDrawer"; import type { IProjectData, IProjectListResponse, IProjectResponse, IProjectUpdateRequest, } from "../../api/task"; import { get, post } from "../../request"; import { TaskBuilderProjectsModal } from "./TaskBuilderProjects"; const { Text } = Typography; function generateUUID() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { const r = (Math.random() * 16) | 0, v = c === "x" ? r : (r & 0x3) | 0x8; return v.toString(16); }); } interface IWidget { studioName?: string; projectId?: string; onRowClick?: (data: IProjectData) => void; onSelect?: (id: string) => void; } const Project = ({ studioName, projectId, onRowClick, onSelect }: IWidget) => { const intl = useIntl(); const [open, setOpen] = useState(false); const [editId, setEditId] = useState(); const [title, setTitle] = useState(); const [curr, setCurr] = useState(); const actionRef = useRef(null); const [editableKeys, setEditableRowKeys] = useState([]); const [dataSource, setDataSource] = useState([]); const [buildProjectsOpen, setBuildProjectsOpen] = useState(false); const [form] = Form.useForm(); const ProjectTitle = ({ data }: { data?: IProjectData }) => ( {data?.title} {data?.path?.reverse().map((item, id) => { return ( {" <"} ); })} ); const loopDataSourceFilter = ( data: readonly IProjectData[], id: React.Key | undefined ): IProjectData[] => { return data .map((item) => { if (item.id !== id) { if (item.children) { const newChildren = loopDataSourceFilter(item.children, id); return { ...item, children: newChildren.length > 0 ? newChildren : undefined, }; } return item; } return null; }) .filter(Boolean) as IProjectData[]; }; const removeRow = useRefFunction((record: IProjectData) => { setDataSource(loopDataSourceFilter(dataSource, record.id)); }); const columns: ProColumns[] = [ { title: intl.formatMessage({ id: "forms.fields.title.label", }), dataIndex: "title", formItemProps: { rules: [ { required: true, message: "此项为必填项", }, ], }, width: "30%", render: (_dom, record, _, _action) => { return ( ); }, }, { title: intl.formatMessage({ id: "forms.fields.milestone.label", }), key: "state", dataIndex: "state", readonly: true, }, { title: intl.formatMessage({ id: "forms.fields.status.label", }), key: "state", dataIndex: "state", readonly: true, }, { title: "操作", valueType: "option", width: 250, render: (_text, record, _, _action) => [ , record.type === "workflow" ? ( <> ) : ( { switch (e.key) { case "multi": setCurr(record.id); setBuildProjectsOpen(true); break; default: break; } }, }} > 插入子节点 ), , ], }, ]; const getChildren = ( record: IProjectData, findIn: IProjectData[] ): IProjectData[] | undefined => { const children = findIn .filter((item) => item.parent?.id === record.id) .map((item) => { return { ...item, children: getChildren(item, findIn) }; }); if (children.length > 0) { return children; } return undefined; }; useEffect(() => { actionRef.current?.reload(); }, [projectId]); return ( <> setBuildProjectsOpen(false)} onDone={() => actionRef.current?.reload()} /> onRow={(record) => ({ onClick: () => { if (onRowClick) { onRowClick(record); } }, })} rowKey="id" scroll={{ x: 960, }} actionRef={actionRef} headerTitle={title} maxLength={5} search={false} // 关闭默认的新建按钮 recordCreatorProps={false} columns={columns} request={async () => { const url = `/v2/project?view=project-tree&project_id=${projectId}`; console.info("api request", url); const res = await get(url); console.info("project api response", res); const root = res.data.rows .filter((item) => item.id === projectId) .map((item) => { return { ...item, children: getChildren(item, res.data.rows) }; }); return { data: root, total: res.data.count, success: res.ok, }; }} value={dataSource} onChange={(value: readonly IProjectData[]) => { const root = value.find((item) => item.id === projectId); setTitle(ProjectTitle({ data: root })); setDataSource(value); }} editable={{ form, editableKeys, onSave: async (_key, values) => { const data: IProjectUpdateRequest = { ...values, studio_name: studioName ?? "", }; const url = `/v2/project`; console.info("save api request", url, data); const res = await post( url, data ); console.info("save api response", res); }, onChange: setEditableRowKeys, actionRender: (_row, _config, dom) => [dom.save, dom.cancel], }} /> setOpen(false)} /> ); }; export default Project;