Browse Source

feat: 添加代办

liaojiaxing 5 months ago
parent
commit
1b6fde922a

+ 4 - 3
apps/er-designer/src/models/erModel.tsx

@@ -70,7 +70,8 @@ export default function erModel() {
   const setProject = (
     info: ProjectInfo | ((state: ProjectInfo) => ProjectInfo),
     ingoreHistory?: boolean,
-    isInit?: boolean
+    isInit?: boolean,
+    ingoreRender?: boolean
   ) => {
     if (isInit) {
       historyRef.current = [];
@@ -80,7 +81,7 @@ export default function erModel() {
     if (info && typeof info === "function") {
       setProjectInfo((state) => {
         const result = info(state);
-        graphRef.current && render(graphRef.current, result);
+        graphRef.current && !ingoreRender && render(graphRef.current, result);
         // 添加记录
         if (!ingoreHistory) {
           historyRef.current?.push(result);
@@ -94,7 +95,7 @@ export default function erModel() {
       });
     } else {
       setProjectInfo(info);
-      graphRef.current && render(graphRef.current, info);
+      graphRef.current && !ingoreRender && render(graphRef.current, info);
       // 添加记录
       if (!ingoreHistory) {
         historyRef.current?.push(info);

+ 3 - 6
apps/er-designer/src/models/renderer.ts

@@ -9,7 +9,7 @@ const dasharrayMap = {
   [RelationLineType.Dotted]: "1,5",
 }
 export const render = (graph: Graph, project: ProjectInfo) => {
-  const { tables, relations, topicAreas, remarks } = project;
+  const { tables, relations, topicAreas, remarkInfos } = project;
   // 渲染表格
   const renderTable = (tableItem: TableItemType) => {
     graph.addNode({
@@ -175,7 +175,7 @@ export const render = (graph: Graph, project: ProjectInfo) => {
   const allIds = [
     ...tables.map((table) => table.table.id),
     ...topicAreas.map((topicArea) => topicArea.id),
-    ...remarks.map((remark) => remark.id),
+    ...remarkInfos.map((remark) => remark.id),
     ...relations.map((relation) => relation.id),
   ];
   // 移除空数据节点
@@ -205,7 +205,7 @@ export const render = (graph: Graph, project: ProjectInfo) => {
       }
     }
   });
-  remarks.forEach((remark) => {
+  remarkInfos.forEach((remark) => {
     if (!graph.getCellById(remark.id)) {
       renderRemark(remark);
     } else {
@@ -215,9 +215,6 @@ export const render = (graph: Graph, project: ProjectInfo) => {
       }
     }
   });
-  // setTimeout(() => {
-
-  // }, 100);
   relations.forEach((relation) => {
     if (!graph.getCellById(relation.id)) {
       renderRelationEdge(relation);

+ 119 - 37
apps/er-designer/src/pages/er/components/TodoDrawer.tsx

@@ -1,14 +1,25 @@
 import React, { useImperativeHandle, forwardRef } from "react";
-import { DownOutlined, PlusOutlined } from "@ant-design/icons";
+import { DownOutlined, PlusOutlined, DeleteOutlined } from "@ant-design/icons";
 import type { MenuProps } from "antd";
-import { Dropdown, Space, Drawer, Button, Checkbox, Input } from "antd";
+import {
+  Dropdown,
+  Space,
+  Drawer,
+  Button,
+  Checkbox,
+  Input,
+  Popover,
+  Radio,
+} from "antd";
 import { useModel } from "umi";
 import { TodoItem } from "@/type";
 import { uuid } from "@/utils";
+import noData from "@/assets/no-data.png";
 
 const TodoDrawer = forwardRef((props: {}, ref) => {
   const [open, setOpen] = React.useState(false);
   const { project, setProject } = useModel("erModel");
+  const [activeKey, setActiveKey] = React.useState("");
 
   useImperativeHandle(ref, () => ({
     open: () => setOpen(true),
@@ -33,19 +44,19 @@ const TodoDrawer = forwardRef((props: {}, ref) => {
   const levelMap = {
     0: {
       label: "无",
-      color: "gray",
+      color: "#1890ff",
     },
     1: {
       label: "低",
-      color: "green",
+      color: "#52c41a",
     },
     2: {
       label: "中",
-      color: "orange",
+      color: "#d89614",
     },
     3: {
       label: "高",
-      color: "red",
+      color: "#ff4d4f",
     },
   };
 
@@ -55,27 +66,51 @@ const TodoDrawer = forwardRef((props: {}, ref) => {
       ...newTodos[index],
       [key]: value,
     };
-    setProject({
-      ...project,
-      todos: newTodos,
-    });
+    setProject(
+      {
+        ...project,
+        todos: newTodos,
+      },
+      false,
+      false,
+      true
+    );
   };
 
   const addToto = () => {
-    setProject({
-      ...project,
-      todos: [
-        ...project.todos,
-        {
-          id: uuid(),
-          name: "",
-          text: "",
-          isDone: false,
-          level: 1,
-        },
-      ],
-    });
-  }
+    setProject(
+      {
+        ...project,
+        todos: [
+          ...project.todos,
+          {
+            id: uuid(),
+            name: "",
+            text: "",
+            isDone: false,
+            level: 1,
+          },
+        ],
+      },
+      false,
+      false,
+      true
+    );
+  };
+
+  const handleDelete = (index: number) => {
+    const newTodos = [...project.todos];
+    newTodos.splice(index, 1);
+    setProject(
+      {
+        ...project,
+        todos: newTodos,
+      },
+      false,
+      false,
+      true
+    );
+  };
 
   return (
     <Drawer
@@ -92,12 +127,16 @@ const TodoDrawer = forwardRef((props: {}, ref) => {
             <DownOutlined />
           </Space>
         </Dropdown>
-        <Button type="primary" icon={<PlusOutlined />}>
+        <Button type="primary" icon={<PlusOutlined />} onClick={addToto}>
           新建待办
         </Button>
       </div>
       {project.todos.map((todo: TodoItem, index: number) => (
-        <div className="todo-item flex border-b-1 border-b-solid border-#eee p-b-12px">
+        <div
+          className="todo-item flex border-b-1 border-b-solid border-#eee p-b-12px m-b-12px"
+          key={todo.id}
+          onClick={() => setActiveKey(todo.id)}
+        >
           <div className="left m-r-12px">
             <Checkbox
               checked={todo.isDone}
@@ -113,26 +152,69 @@ const TodoDrawer = forwardRef((props: {}, ref) => {
                 value={todo.name}
                 onChange={(e) => handleChange(index, "name", e.target.value)}
               />
-              <div className="rounded-4px cus-btn w-32px h-32px bg-#eee flex-none text-center leading-32px cursor-pointer hover:bg-#ddd m-l-12px">
-                <i className="iconfont icon-gengduo" />
-              </div>
+              <Popover
+                trigger={["click"]}
+                placement="bottom"
+                content={
+                  <div className="w-200px">
+                    <div className="font-bold">优先级:</div>
+                    <div className="p-l-12px">
+                      <Radio.Group value={todo.level} onChange={(e) => handleChange(index, "level", e.target.value)}>
+                        <Space direction="vertical">
+                          <Radio value={0}>无</Radio>
+                          <Radio value={1}>低</Radio>
+                          <Radio value={2}>中</Radio>
+                          <Radio value={3}>高</Radio>
+                        </Space>
+                      </Radio.Group>
+                    </div>
+                    <div>
+                    <Button danger icon={<DeleteOutlined />} className="m-t-12px w-full" onClick={() => {handleDelete(index)}}>删除</Button>
+                    </div>
+                  </div>
+                }
+              >
+                <div className="rounded-4px cus-btn w-32px h-32px bg-#eee flex-none text-center leading-32px cursor-pointer hover:bg-#ddd m-l-12px">
+                  <i className="iconfont icon-gengduo" />
+                </div>
+              </Popover>
             </div>
-            <div className="m-b-12px">
-              <Input.TextArea
-                placeholder="描述..."
-                value={todo.text}
-                onChange={(e) => handleChange(index, "text", e.target.value)}
-              />
+            <div
+              className="m-b-12px grid"
+              style={{
+                transition: "all 0.3s",
+                gridTemplateRows: activeKey === todo.id ? "1fr" : "0fr",
+              }}
+            >
+              <div className="overflow-hidden">
+                <Input.TextArea
+                  placeholder="描述..."
+                  value={todo.text}
+                  onChange={(e) => handleChange(index, "text", e.target.value)}
+                />
+              </div>
             </div>
             <div>
               优先级:{" "}
-              <span className="inline-block w-20px h-20px bg-red-500 text-center color-#fff leading-16px rounded-4px">
-                高
+              <span
+                className="inline-block w-20px h-20px bg-red-500 color-#fff rounded-4px text-center leading-20px"
+                style={{
+                  background: levelMap[todo.level].color,
+                  fontSize: "12px",
+                }}
+              >
+                {levelMap[todo.level].label}
               </span>
             </div>
           </div>
         </div>
       ))}
+      {project.todos.length === 0 && (
+        <div className="flex flex-col items-center justify-center h-[300px]">
+          <img src={noData} alt="暂无数据" className="w-[200px] h-[200px]" />
+          <div className="text-gray-400">暂无待办项!</div>
+        </div>
+      )}
     </Drawer>
   );
 });

+ 1 - 1
apps/er-designer/src/type.d.ts

@@ -79,7 +79,7 @@ export interface TodoItem {
   name: string;
   text: string;
   isDone: boolean;
-  level: number;
+  level: 0 | 1 | 2 | 3;
 }
 
 /**