|
@@ -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>
|
|
|
);
|
|
|
});
|