feat: 메뉴 삭제 로직 작업
This commit is contained in:
@@ -35,6 +35,13 @@ export class MenuApiService implements MenuService {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async deleteMenu(menuCd: number): Promise<void> {
|
||||
const response = await client.delete<void>(
|
||||
`${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getTreeMenuList(siteId: string): Promise<TreeMenu[]> {
|
||||
const response = await client.get<TreeMenu[]>(
|
||||
`${ENDPOINT.CMS_SERVICE.MENUS}/${siteId}/tree`,
|
||||
|
||||
@@ -75,6 +75,7 @@ export interface MenuService {
|
||||
menuCd: number,
|
||||
data: Omit<MenuFormData, "siteId">,
|
||||
) => Promise<void>;
|
||||
deleteMenu: (menuCd: number) => Promise<void>;
|
||||
getTreeMenuList: (siteId: string) => Promise<TreeMenu[]>;
|
||||
modifyTreeMenu: (siteId: string, data: TreeNode[]) => Promise<void>;
|
||||
modifyMenuName: (menuCd: number, name: string) => Promise<void>;
|
||||
|
||||
@@ -25,7 +25,7 @@ interface MenuFormProps {
|
||||
menuCd: number;
|
||||
data: Omit<MenuFormData, "siteId">;
|
||||
}) => void;
|
||||
handleDelete?: () => void;
|
||||
handleDelete?: (menuCd: number) => void;
|
||||
}
|
||||
|
||||
function MenuForm({
|
||||
@@ -73,7 +73,7 @@ function MenuForm({
|
||||
const onDelete = () => {
|
||||
handleConfirm(async () => {
|
||||
if (await confirm("삭제하시겠습니까?")) {
|
||||
handleDelete?.();
|
||||
handleDelete?.(menuCd!);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -90,7 +90,10 @@ function MenuNode({
|
||||
"diveicon di-arrow-forward mr-2 text-base text-label",
|
||||
isOpen && "rotate-90",
|
||||
)}
|
||||
onClick={handleToggle}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleToggle();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<span className="text-[1.4rem] font-medium text-label">{text}</span>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import type { NodeModel } from "@minoru/react-dnd-treeview";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
Button,
|
||||
@@ -16,6 +17,7 @@ import {
|
||||
import { SiteApi } from "@/entities/site";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { PageLayout } from "@/shared/ui/page-layout";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
import { useAlertStore } from "@/shared/lib/use-alert-store";
|
||||
import type { TreeMenu } from "../model/menu-interface";
|
||||
import { MenuApi } from "../api/menu-service";
|
||||
@@ -31,8 +33,10 @@ import { generateTreeData } from "../lib/utils";
|
||||
function MenuPage() {
|
||||
const queryClient = useQueryClient();
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
|
||||
const [siteId, setSiteId] = useState("");
|
||||
const [onConfirm, setOnConfirm] = useState(false);
|
||||
const [selectedMenu, setSelectedMenu] = useState<TreeMenu | null>(null);
|
||||
const [additionalNode, setAdditionalNode] =
|
||||
useState<NodeModel<TreeMenu> | null>(null);
|
||||
@@ -72,7 +76,7 @@ function MenuPage() {
|
||||
onSuccess: () => {
|
||||
alert("저장되었습니다.");
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.MENUS],
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId],
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -88,7 +92,17 @@ function MenuPage() {
|
||||
onSuccess: () => {
|
||||
alert("수정되었습니다.");
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.MENUS],
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const { mutate: deleteMenu } = useMutation({
|
||||
mutationFn: (menuCd: number) => MenuApi.deleteMenu(menuCd),
|
||||
onSuccess: () => {
|
||||
alert("삭제되었습니다.");
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId],
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -132,17 +146,14 @@ function MenuPage() {
|
||||
...additionalNodeForm.getValues(),
|
||||
prntMenuCd,
|
||||
});
|
||||
resetAdditionalNode();
|
||||
};
|
||||
|
||||
const resetAdditionalNode = () => {
|
||||
additionalNodeForm.setValue("menuKornNm", "");
|
||||
setAdditionalNode(null);
|
||||
};
|
||||
|
||||
const handleAdditionalNodeCancel = () => {
|
||||
additionalNodeForm.setValue("menuKornNm", "");
|
||||
setAdditionalNode(null);
|
||||
};
|
||||
|
||||
const handleDelete = async () => {};
|
||||
|
||||
const handleSiteIdChange = (value: string) => {
|
||||
form.setValue("siteId", value);
|
||||
additionalNodeForm.setValue("siteId", value);
|
||||
@@ -162,6 +173,14 @@ function MenuPage() {
|
||||
additionalNodeForm.setValue("levelNo", (node.data.levelNo ?? 0) + 1);
|
||||
};
|
||||
|
||||
const handleNodeDelete = async () => {
|
||||
setOnConfirm(true);
|
||||
if (await confirm("삭제하시겠습니까?")) {
|
||||
setOnConfirm(false);
|
||||
deleteMenu(selectedMenu!.menuCd!);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddMenu = () => {
|
||||
if (additionalNode) return;
|
||||
setAdditionalNode({
|
||||
@@ -176,66 +195,70 @@ function MenuPage() {
|
||||
: (treeData ?? []);
|
||||
|
||||
return (
|
||||
<PageLayout pageTitle="메뉴 관리">
|
||||
<div className="card flex !min-h-[calc(100vh-16.8rem)] gap-2">
|
||||
<div className="card card-border w-[24rem]">
|
||||
<Select value={siteId} onValueChange={handleSiteIdChange}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="선택하세요" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{options?.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{siteId && (
|
||||
<>
|
||||
<div className="my-4 flex gap-2">
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
className="flex-1"
|
||||
onClick={handleAddMenu}
|
||||
>
|
||||
메뉴 추가
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
color="red"
|
||||
className="flex-1"
|
||||
onClick={handleDelete}
|
||||
>
|
||||
메뉴 삭제
|
||||
</Button>
|
||||
</div>
|
||||
<div className="card card-border !mx-0">
|
||||
<MenuTree
|
||||
tree={tree}
|
||||
siteId={siteId}
|
||||
selectedMenu={selectedMenu}
|
||||
additionalNodeForm={additionalNodeForm}
|
||||
onSelectNode={handleNodeSelect}
|
||||
onAdditionalNodeSave={handleAdditionalNodeSave}
|
||||
onAdditionalNodeCancel={handleAdditionalNodeCancel}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<>
|
||||
<PageLayout pageTitle="메뉴 관리">
|
||||
<div className="card flex !min-h-[calc(100vh-16.8rem)] gap-2">
|
||||
<div className="card card-border w-[24rem]">
|
||||
<Select value={siteId} onValueChange={handleSiteIdChange}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="선택하세요" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{options?.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{siteId && (
|
||||
<>
|
||||
<div className="my-4 flex gap-2">
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
className="flex-1"
|
||||
onClick={handleAddMenu}
|
||||
>
|
||||
메뉴 추가
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
color="red"
|
||||
className="flex-1"
|
||||
onClick={handleNodeDelete}
|
||||
disabled={!selectedMenu}
|
||||
>
|
||||
메뉴 삭제
|
||||
</Button>
|
||||
</div>
|
||||
<div className="card card-border !mx-0">
|
||||
<MenuTree
|
||||
tree={tree}
|
||||
siteId={siteId}
|
||||
selectedMenu={selectedMenu}
|
||||
additionalNodeForm={additionalNodeForm}
|
||||
onSelectNode={handleNodeSelect}
|
||||
onAdditionalNodeSave={handleAdditionalNodeSave}
|
||||
onAdditionalNodeCancel={resetAdditionalNode}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="card card-border flex-1">
|
||||
<MenuForm
|
||||
form={form}
|
||||
menuCd={selectedMenu?.menuCd}
|
||||
handleCreate={createMenu}
|
||||
handleModify={modifyMenu}
|
||||
handleDelete={deleteMenu}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card card-border flex-1">
|
||||
<MenuForm
|
||||
form={form}
|
||||
menuCd={selectedMenu?.menuCd}
|
||||
handleCreate={createMenu}
|
||||
handleModify={modifyMenu}
|
||||
handleDelete={handleDelete}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</PageLayout>
|
||||
</PageLayout>
|
||||
<ConfirmDialog open={onConfirm} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user