Browse Source

看板编辑和删除

master
YuJian920 3 years ago
parent
commit
be5abce3ed
  1. 21
      src/components/Mark.tsx
  2. 10
      src/hook/useKanban.ts
  3. 10
      src/hook/useTask.ts
  4. 67
      src/pages/Kanban/KanbanColumn/index.tsx
  5. 26
      src/pages/Kanban/TaskModal/index.tsx

21
src/components/Mark.tsx

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
import React from "react";
const Mark = ({ name, keyword }: { name: string; keyword: string }) => {
const arr = name.split(keyword);
if (!keyword) return <>{name}</>;
else
return (
<>
{arr.map((str, index) => (
<span key={index}>
{str}
{index === arr.length - 1 ? null : (
<span style={{ color: "#257AFD" }}>{keyword}</span>
)}
</span>
))}
</>
);
};
export default React.memo(Mark);

10
src/hook/useKanban.ts

@ -35,3 +35,13 @@ export const useProjectInUrl = () => useProject(useProjectIdInUrl()); @@ -35,3 +35,13 @@ export const useProjectInUrl = () => useProject(useProjectIdInUrl());
export const useKanbanSearchParams = () => ({ projectId: useProjectIdInUrl() });
export const useKanbansQueryKey = () => ["kanbans", useKanbanSearchParams()];
export const useDeleteKanban = () => {
const request = useRequest();
const queryClient = useQueryClient();
return useMutation(
({ id }: { id: number }) => request(`/kanbans/${id}`, { method: "DELETE" }),
{ onSuccess: () => queryClient.invalidateQueries("kanbans") }
);
};

10
src/hook/useTask.ts

@ -98,3 +98,13 @@ export const useEditTask = () => { @@ -98,3 +98,13 @@ export const useEditTask = () => {
{ onSuccess: () => queryClient.invalidateQueries("tasks") }
);
};
export const useDeleteTask = () => {
const request = useRequest();
const queryClient = useQueryClient();
return useMutation(
({ id }: { id: number }) => request(`/tasks/${id}`, { method: "DELETE" }),
{ onSuccess: () => queryClient.invalidateQueries("tasks") }
);
};

67
src/pages/Kanban/KanbanColumn/index.tsx

@ -1,12 +1,15 @@ @@ -1,12 +1,15 @@
import { Card } from "antd";
import { Button, Card, Dropdown, Menu, Modal } from "antd";
import React from "react";
import { Row } from "../../../components/lib";
import Mark from "../../../components/Mark";
import { useDeleteKanban } from "../../../hook/useKanban";
import {
useTaskModal,
useTasks,
useTasksSearchParmas,
useTasksTypes,
} from "../../../hook/useTask";
import { Kanban } from "../../../type";
import { Kanban, Task } from "../../../type";
import CreateTask from "../CreateTask";
import { Container, TasksContainer } from "../style";
@ -28,24 +31,64 @@ const TaskTypeIcon = ({ id }: { id: number }) => { @@ -28,24 +31,64 @@ const TaskTypeIcon = ({ id }: { id: number }) => {
);
};
const TaskCard = ({ task }: { task: Task }) => {
const { startEdit } = useTaskModal();
const { name: keyword } = useTasksSearchParmas();
return (
<Card
onClick={() => startEdit(task.id)}
style={{ marginBottom: "0.5rem", cursor: "pointer" }}
key={task.id}
>
<p>
<Mark keyword={keyword} name={task.name} />
</p>
<TaskTypeIcon id={task.typeId} />
</Card>
);
};
const More = ({ kanban }: { kanban: Kanban }) => {
const { mutateAsync, isLoading } = useDeleteKanban();
const startEdit = () => {
Modal.confirm({
okText: "确定",
cancelText: "取消",
title: "确定删除看板吗?",
onOk: () => {
return mutateAsync({ id: kanban.id });
},
});
};
const overlay = (
<Menu>
<Menu.Item>
<Button type="link" onClick={startEdit}>
</Button>
</Menu.Item>
</Menu>
);
return (
<Dropdown overlay={overlay}>
<Button type="link">...</Button>
</Dropdown>
);
};
const KanbanColumn = ({ kanban }: { kanban: Kanban }) => {
const { data: allTasks } = useTasks(useTasksSearchParmas());
const tasks = allTasks?.filter((task) => task.kanbanId === kanban.id);
const { startEdit } = useTaskModal();
return (
<Container>
<h3>{kanban.name}</h3>
<Row between={true}>
<h3>{kanban.name}</h3>
<More kanban={kanban} />
</Row>
<TasksContainer>
{tasks?.map((task) => (
<Card
onClick={() => startEdit(task.id)}
style={{ marginBottom: "0.5rem", cursor: "pointer" }}
key={task.id}
>
<div>{task.name}</div>
<TaskTypeIcon id={task.typeId} />
</Card>
<TaskCard task={task} />
))}
<CreateTask kanbanId={kanban.id} />
</TasksContainer>

26
src/pages/Kanban/TaskModal/index.tsx

@ -1,7 +1,11 @@ @@ -1,7 +1,11 @@
import React, { useEffect } from "react";
import { useForm } from "antd/es/form/Form";
import { useEditTask, useTaskModal } from "../../../hook/useTask";
import { Form, Input, Modal } from "antd";
import {
useDeleteTask,
useEditTask,
useTaskModal,
} from "../../../hook/useTask";
import { Button, Form, Input, Modal } from "antd";
import UserSelect from "../../../components/UserSelect";
import TaskTypeSelect from "../../../components/TaskTypeSelect";
@ -14,6 +18,7 @@ const TaskModal = () => { @@ -14,6 +18,7 @@ const TaskModal = () => {
const [form] = useForm();
const { editingTaskId, editingTask, close } = useTaskModal();
const { mutateAsync: editTask, isLoading: editLoading } = useEditTask();
const { mutateAsync: deleteTask } = useDeleteTask();
const onCancel = () => {
close();
@ -29,6 +34,18 @@ const TaskModal = () => { @@ -29,6 +34,18 @@ const TaskModal = () => {
form.setFieldsValue(editingTask);
}, [form, editingTask]);
const startDelete = () => {
close();
Modal.confirm({
okText: "确定",
cancelText: "取消",
title: "确定删除任务吗?",
onOk() {
return deleteTask({ id: Number(editingTaskId) });
},
});
};
return (
<Modal
forceRender={true}
@ -55,6 +72,11 @@ const TaskModal = () => { @@ -55,6 +72,11 @@ const TaskModal = () => {
<TaskTypeSelect />
</Form.Item>
</Form>
<div style={{ textAlign: "right" }}>
<Button style={{ fontSize: "14px" }} size="small" onClick={startDelete}>
</Button>
</div>
</Modal>
);
};

Loading…
Cancel
Save