김재형

Implement file copy

......@@ -7,15 +7,18 @@ import { FileListPopover } from "./FileListPopover";
export type FileItemActionsProps = {
item: FileItem;
onMove: (id: number, to: number) => void;
onCopy: (id: number, to: number) => void;
onDelete: (id: number) => void;
};
export function FileItemActions({
item,
onMove,
onCopy,
onDelete,
}: FileItemActionsProps) {
const [move, setMove] = useState<boolean>(false);
const [copy, setCopy] = useState<boolean>(false);
return (
<div className={styles.actions}>
......@@ -48,9 +51,26 @@ export function FileItemActions({
이동
</Button>
</Popover>
<Popover
title="복사할 폴더를 선택하세요"
content={
<FileListPopover
root={item.parent}
onSelect={(to: number) => {
onCopy(item.id, to);
setCopy(false);
}}
onCancel={() => setCopy(false)}
/>
}
trigger="click"
visible={copy}
onVisibleChange={setCopy}
>
<Button type="link" size="small">
복사
</Button>
</Popover>
<Popconfirm
title="정말로 삭제하시겠습니까?"
onConfirm={() => onDelete(item.id)}
......
......@@ -34,6 +34,23 @@ export function FileList() {
[api, reload]
);
const handleCopy = useCallback(
async (id: number, to: number) => {
try {
const body = new URLSearchParams();
body.set("parent", to.toString(10));
await api.post(`/items/${id}/copy/`, { body });
await reload();
message.info("복사되었습니다");
} catch {
message.error("파일 복사에 실패했습니다");
}
},
[api, reload]
);
const handleDelete = useCallback(
async (id: number) => {
try {
......@@ -81,6 +98,7 @@ export function FileList() {
rowKey="id"
columns={getColumns({
handleMove,
handleCopy,
handleDelete,
})}
dataSource={list}
......@@ -92,11 +110,13 @@ export function FileList() {
type GetColumnsParams = {
handleMove: (id: number, to: number) => void;
handleCopy: (id: number, to: number) => void;
handleDelete: (id: number) => void;
};
function getColumns({
handleMove,
handleCopy,
handleDelete,
}: GetColumnsParams): ColumnsType<FileItem> {
return [
......@@ -124,6 +144,7 @@ function getColumns({
<FileItemActions
item={item}
onMove={handleMove}
onCopy={handleCopy}
onDelete={handleDelete}
/>
),
......