drawDB/src/components/EditorHeader/SideSheet/Todo.jsx

275 lines
8.3 KiB
React
Raw Normal View History

2024-03-15 22:00:23 +08:00
import { useState } from "react";
2023-09-19 20:50:53 +08:00
import {
Checkbox,
Input,
TextArea,
Row,
Col,
Dropdown,
Button,
Popover,
Tag,
List,
RadioGroup,
Radio,
} from "@douyinfe/semi-ui";
import {
IconPlus,
IconMore,
IconDeleteStroked,
IconCaretdown,
} from "@douyinfe/semi-icons";
import { State } from "../../../data/constants";
import { useTasks, useSaveState } from "../../../hooks";
import { useTranslation } from "react-i18next";
2024-03-15 22:00:23 +08:00
const Priority = {
NONE: 0,
LOW: 1,
MEDIUM: 2,
HIGH: 3,
};
const SortOrder = {
ORIGINAL: "my_order",
PRIORITY: "priority",
COMPLETED: "completed",
ALPHABETICALLY: "alphabetically",
2024-03-15 22:00:23 +08:00
};
2024-03-14 03:09:29 +08:00
2023-09-19 20:50:53 +08:00
export default function Todo() {
const [activeTask, setActiveTask] = useState(-1);
const [, setSortOrder] = useState(SortOrder.ORIGINAL);
2024-03-14 03:09:29 +08:00
const { tasks, setTasks, updateTask } = useTasks();
2024-03-15 22:00:23 +08:00
const { setSaveState } = useSaveState();
const { t } = useTranslation();
2023-09-19 20:50:53 +08:00
const priorityLabel = (p) => {
switch (p) {
case Priority.NONE:
return t("none");
2023-09-19 20:50:53 +08:00
case Priority.LOW:
return t("low");
2023-09-19 20:50:53 +08:00
case Priority.MEDIUM:
return t("medium");
2023-09-19 20:50:53 +08:00
case Priority.HIGH:
return t("high");
2023-09-19 20:50:53 +08:00
default:
return "";
}
};
const priorityColor = (p) => {
switch (p) {
case Priority.NONE:
return "blue";
case Priority.LOW:
return "green";
case Priority.MEDIUM:
return "yellow";
case Priority.HIGH:
return "red";
default:
return "";
}
};
const sort = (s) => {
2023-09-19 20:51:13 +08:00
setActiveTask(-1);
2023-09-19 20:50:53 +08:00
switch (s) {
case SortOrder.ORIGINAL:
setTasks((prev) => prev.sort((a, b) => a.order - b.order));
return;
case SortOrder.PRIORITY:
setTasks((prev) => prev.sort((a, b) => b.priority - a.priority));
return;
case SortOrder.COMPLETED:
setTasks((prev) =>
prev.sort((a, b) => {
if (a.complete && !b.complete) {
return 1;
} else if (!a.complete && b.complete) {
return -1;
} else {
return 0;
}
}),
2023-09-19 20:50:53 +08:00
);
break;
case SortOrder.ALPHABETICALLY:
setTasks((prev) => prev.sort((a, b) => a.title.localeCompare(b.title)));
break;
default:
break;
}
};
return (
<>
2023-09-19 20:51:08 +08:00
<div className="flex justify-between items-center mx-5 mb-2 sidesheet-theme">
2023-09-19 20:50:53 +08:00
<Dropdown
render={
<Dropdown.Menu>
{Object.values(SortOrder).map((order) => (
<Dropdown.Item
2023-09-19 20:50:57 +08:00
key={order}
2023-09-19 20:50:53 +08:00
onClick={() => {
setSortOrder(order);
sort(order);
}}
>
{t(order)}
2023-09-19 20:50:53 +08:00
</Dropdown.Item>
))}
</Dropdown.Menu>
}
trigger="click"
>
<Button
style={{ marginRight: "10px" }}
theme="borderless"
type="tertiary"
>
{t("sort_by")} <IconCaretdown />
2023-09-19 20:50:53 +08:00
</Button>
</Dropdown>
<Button
icon={<IconPlus />}
block
onClick={() => {
setTasks((prev) => [
{
complete: false,
details: "",
title: "",
priority: Priority.NONE,
order: prev.length,
},
...prev,
]);
}}
>
{t("add_task")}
2023-09-19 20:50:53 +08:00
</Button>
</div>
2023-09-19 20:50:55 +08:00
{tasks.length > 0 ? (
2023-09-19 20:51:08 +08:00
<List className="sidesheet-theme">
{tasks.map((task, i) => (
2023-09-19 20:50:55 +08:00
<List.Item
key={i}
style={{ paddingLeft: "18px", paddingRight: "18px" }}
2023-09-19 20:51:08 +08:00
className="hover-1"
2023-09-19 20:50:55 +08:00
onClick={() => setActiveTask(i)}
>
<div className="w-full">
<Row gutter={6} align="middle" type="flex" className="mb-2">
<Col span={2}>
<Checkbox
checked={task.complete}
2024-02-20 15:03:08 +08:00
onChange={(e) => {
updateTask(i, { complete: e.target.checked });
2024-03-15 22:00:23 +08:00
setSaveState(State.SAVING);
2024-02-20 15:03:08 +08:00
}}
2023-09-19 20:50:55 +08:00
></Checkbox>
</Col>
<Col span={19}>
<Input
placeholder={t("title")}
2023-09-19 20:50:55 +08:00
onChange={(v) => updateTask(i, { title: v })}
value={task.title}
2024-03-15 22:00:23 +08:00
onBlur={() => setSaveState(State.SAVING)}
/>
2023-09-19 20:50:55 +08:00
</Col>
<Col span={3}>
<Popover
content={
2023-09-19 20:51:08 +08:00
<div className="p-2 popover-theme">
2023-09-19 20:50:55 +08:00
<div className="mb-2 font-semibold">
{t("priority")}:
2023-09-19 20:50:55 +08:00
</div>
<RadioGroup
2024-02-20 15:03:08 +08:00
onChange={(e) => {
updateTask(i, { priority: e.target.value });
2024-03-15 22:00:23 +08:00
setSaveState(State.SAVING);
2024-02-20 15:03:08 +08:00
}}
value={task.priority}
2023-09-19 20:50:55 +08:00
direction="vertical"
>
<Radio value={Priority.NONE}>
<Tag color={priorityColor(Priority.NONE)}>
{priorityLabel(Priority.NONE)}
</Tag>
</Radio>
<Radio value={Priority.LOW}>
<Tag color={priorityColor(Priority.LOW)}>
{priorityLabel(Priority.LOW)}
</Tag>
</Radio>
<Radio value={Priority.MEDIUM}>
<Tag color={priorityColor(Priority.MEDIUM)}>
{priorityLabel(Priority.MEDIUM)}
</Tag>
</Radio>
<Radio value={Priority.HIGH}>
<Tag color={priorityColor(Priority.HIGH)}>
{priorityLabel(Priority.HIGH)}
</Tag>
</Radio>
</RadioGroup>
<Button
icon={<IconDeleteStroked />}
type="danger"
block
style={{ marginTop: "12px" }}
2024-02-20 15:03:08 +08:00
onClick={() => {
2023-09-19 20:50:55 +08:00
setTasks((prev) =>
prev.filter((_, j) => i !== j),
2024-02-20 15:03:08 +08:00
);
2024-03-15 22:00:23 +08:00
setSaveState(State.SAVING);
2024-02-20 15:03:08 +08:00
}}
2023-09-19 20:50:55 +08:00
>
{t("delete")}
2023-09-19 20:50:55 +08:00
</Button>
</div>
}
trigger="click"
showArrow
className="w-[180px]"
>
2024-03-16 08:23:10 +08:00
<Button icon={<IconMore />} type="tertiary" />
2023-09-19 20:50:55 +08:00
</Popover>
</Col>
</Row>
{activeTask === i && (
<Row className="mb-2">
<Col span={2}></Col>
<Col span={22}>
<TextArea
placeholder={t("details")}
2023-09-19 20:50:55 +08:00
onChange={(v) => updateTask(i, { details: v })}
value={t.details}
2024-03-15 22:00:23 +08:00
onBlur={() => setSaveState(State.SAVING)}
2023-09-19 20:50:55 +08:00
></TextArea>
</Col>
</Row>
)}
<Row>
2023-09-19 20:50:53 +08:00
<Col span={2}></Col>
<Col span={22}>
{t("priority")}:{" "}
<Tag color={priorityColor(task.priority)}>
{priorityLabel(task.priority)}
2023-09-19 20:50:55 +08:00
</Tag>
2023-09-19 20:50:53 +08:00
</Col>
</Row>
2023-09-19 20:50:55 +08:00
</div>
</List.Item>
))}
</List>
) : (
<div className="m-5 sidesheet-theme">{t("no_tasks")}</div>
2023-09-19 20:50:55 +08:00
)}
2023-09-19 20:50:53 +08:00
</>
);
}