김재형

Implement file delete

1 -import React from "react"; 1 +import React, { useCallback } from "react";
2 -import { Table } from "antd"; 2 +import { Table, Popconfirm, message } from "antd";
3 import { ColumnsType } from "antd/lib/table"; 3 import { ColumnsType } from "antd/lib/table";
4 import filesize from "filesize"; 4 import filesize from "filesize";
5 5
6 import { useParams } from "react-router-dom"; 6 import { useParams } from "react-router-dom";
7 import { useFileList, FileItem } from "./useFileList"; 7 import { useFileList, FileItem } from "./useFileList";
8 +import { useApi } from "util/useApi";
8 import { FileListItem } from "./FileListItem"; 9 import { FileListItem } from "./FileListItem";
9 10
10 import styles from "./FileList.module.scss"; 11 import styles from "./FileList.module.scss";
11 12
12 -const columns: ColumnsType<FileItem> = [
13 - {
14 - title: "파일명",
15 - dataIndex: "name",
16 - render: (_name: string, item) => <FileListItem item={item} />,
17 - },
18 - {
19 - title: "크기",
20 - dataIndex: "size",
21 - width: 120,
22 - render: (bytes: number, item) =>
23 - item.is_folder ? "" : filesize(bytes, { round: 0 }),
24 - },
25 - {
26 - title: "",
27 - dataIndex: "",
28 - width: 200,
29 - render: (__: any, item) =>
30 - item.is_folder ? null : (
31 - <div className={styles.actions}>
32 - <a>공유</a>
33 - <a>이동</a>
34 - <a>복사</a>
35 - <a>삭제</a>
36 - </div>
37 - ),
38 - },
39 -];
40 -
41 export function FileList() { 13 export function FileList() {
42 const id = useParams<{ id: string }>().id; 14 const id = useParams<{ id: string }>().id;
43 - const { data } = useFileList(id); 15 + const { data, reload } = useFileList(id);
16 +
17 + const api = useApi();
18 +
19 + const handleDelete = useCallback(
20 + async (id: number) => {
21 + await api.delete(`/items/${id}/`);
22 + await reload();
23 + message.info("삭제되었습니다");
24 + },
25 + [api, reload]
26 + );
44 27
45 if (!data) { 28 if (!data) {
46 return null; 29 return null;
...@@ -62,7 +45,59 @@ export function FileList() { ...@@ -62,7 +45,59 @@ export function FileList() {
62 return ( 45 return (
63 <div> 46 <div>
64 {data.parent !== null && <h3>{data.name}</h3>} 47 {data.parent !== null && <h3>{data.name}</h3>}
65 - <Table columns={columns} dataSource={list} pagination={false} /> 48 + <Table
49 + rowKey="id"
50 + columns={getColumns({
51 + handleDelete,
52 + })}
53 + dataSource={list}
54 + pagination={false}
55 + />
66 </div> 56 </div>
67 ); 57 );
68 } 58 }
59 +
60 +type GetColumnsParams = {
61 + handleDelete: (id: number) => void;
62 +};
63 +
64 +function getColumns({ handleDelete }: GetColumnsParams): ColumnsType<FileItem> {
65 + return [
66 + {
67 + title: "파일명",
68 + key: "name",
69 + dataIndex: "name",
70 + render: (_name: string, item) => <FileListItem item={item} />,
71 + },
72 + {
73 + title: "크기",
74 + key: "size",
75 + dataIndex: "size",
76 + width: 120,
77 + render: (bytes: number, item) =>
78 + item.is_folder ? "" : filesize(bytes, { round: 0 }),
79 + },
80 + {
81 + title: "",
82 + key: "action",
83 + dataIndex: "",
84 + width: 200,
85 + render: (__: any, item) =>
86 + item.is_folder ? null : (
87 + <div className={styles.actions}>
88 + <a>공유</a>
89 + <a>이동</a>
90 + <a>복사</a>
91 + <Popconfirm
92 + title="정말로 삭제하시겠습니까?"
93 + onConfirm={() => handleDelete(item.id)}
94 + okText="삭제"
95 + cancelText="취소"
96 + >
97 + <a>삭제</a>
98 + </Popconfirm>
99 + </div>
100 + ),
101 + },
102 + ];
103 +}
......
1 +import { useMemo } from "react";
2 +import ky from "ky";
3 +
4 +// TODO: Implement Auth
5 +export function useApi() {
6 + return useMemo(() => {
7 + return ky.extend({
8 + hooks: {
9 + beforeRequest: [],
10 + },
11 + });
12 + }, []);
13 +}