feat: 그룹 관리 > 그룹 수정 작업
This commit is contained in:
@@ -17,7 +17,6 @@ type SiteSelectProps = {
|
||||
} & React.ComponentPropsWithoutRef<typeof Select>;
|
||||
|
||||
function SiteSelect({
|
||||
defaultValue,
|
||||
placeholder = "선택",
|
||||
enabledAllSite,
|
||||
className,
|
||||
@@ -34,13 +33,10 @@ function SiteSelect({
|
||||
},
|
||||
});
|
||||
|
||||
const defaultValueText =
|
||||
sites?.find((item) => item.siteId === defaultValue)?.siteNm ?? placeholder;
|
||||
|
||||
return (
|
||||
<Select {...props}>
|
||||
<SelectTrigger className={cn("w-[12rem]", className)}>
|
||||
<SelectValue placeholder={defaultValueText} />
|
||||
<SelectValue placeholder={placeholder} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{sites?.map((item) => (
|
||||
|
||||
@@ -4,7 +4,7 @@ import type {
|
||||
GroupService,
|
||||
GroupSearchParams,
|
||||
GroupList,
|
||||
GroupDetailResponse,
|
||||
GroupResponseDto,
|
||||
GroupFormData,
|
||||
} from "../model/groups-interface";
|
||||
|
||||
@@ -19,16 +19,16 @@ export class GroupsApiService implements GroupService {
|
||||
}
|
||||
|
||||
// 그룹 단건 조회
|
||||
public async findById(groupId: string): Promise<GroupDetailResponse> {
|
||||
const response = await client.get<GroupDetailResponse>(
|
||||
public async findGroupById(groupId: string): Promise<GroupResponseDto> {
|
||||
const response = await client.get<GroupResponseDto>(
|
||||
`${ENDPOINT.CMS_SERVICE.GROUPS}/${groupId}`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// 그룹 저장
|
||||
public async saveGroup(data: GroupFormData): Promise<GroupDetailResponse> {
|
||||
const response = await client.post<GroupDetailResponse>(
|
||||
public async saveGroup(data: GroupFormData): Promise<GroupResponseDto> {
|
||||
const response = await client.post<GroupResponseDto>(
|
||||
`${ENDPOINT.CMS_SERVICE.GROUPS}`,
|
||||
data,
|
||||
);
|
||||
@@ -39,8 +39,8 @@ export class GroupsApiService implements GroupService {
|
||||
public async updateGroup(
|
||||
groupId: string,
|
||||
data: GroupFormData,
|
||||
): Promise<GroupDetailResponse> {
|
||||
const response = await client.put<GroupDetailResponse>(
|
||||
): Promise<GroupResponseDto> {
|
||||
const response = await client.put<GroupResponseDto>(
|
||||
`${ENDPOINT.CMS_SERVICE.GROUPS}/${groupId}`,
|
||||
data,
|
||||
);
|
||||
|
||||
@@ -34,17 +34,20 @@ export interface GroupListResponseDto {
|
||||
}
|
||||
|
||||
// 그룹 상세 응답 인터페이스
|
||||
export interface GroupDetailResponse {
|
||||
grpSn: number;
|
||||
grpNm: string;
|
||||
grpExpln: string;
|
||||
useYn: string;
|
||||
export interface GroupResponseDto {
|
||||
groupId: string;
|
||||
groupNm: string;
|
||||
groupSeCd: string;
|
||||
groupSeNm: string;
|
||||
groupExpln: string;
|
||||
delYn: string;
|
||||
regDt: string;
|
||||
rgtr: string;
|
||||
mdfcnDt: string;
|
||||
mdfr: string;
|
||||
rgtrNm: string;
|
||||
mdfrNm: string;
|
||||
authrtId: string;
|
||||
siteId: string;
|
||||
mngrYn: string;
|
||||
}
|
||||
|
||||
// 그룹 저장 데이터 스키마
|
||||
@@ -68,16 +71,16 @@ export interface GroupService {
|
||||
findPageGroup: (params: GroupSearchParams) => Promise<GroupList>;
|
||||
|
||||
// 그룹 단건 조회
|
||||
findById: (groupId: string) => Promise<GroupDetailResponse>;
|
||||
findGroupById: (groupId: string) => Promise<GroupResponseDto>;
|
||||
|
||||
// 그룹 저장
|
||||
saveGroup: (data: GroupFormData) => Promise<GroupDetailResponse>;
|
||||
saveGroup: (data: GroupFormData) => Promise<GroupResponseDto>;
|
||||
|
||||
// 그룹 수정
|
||||
updateGroup: (
|
||||
groupId: string,
|
||||
data: GroupFormData,
|
||||
) => Promise<GroupDetailResponse>;
|
||||
) => Promise<GroupResponseDto>;
|
||||
|
||||
// 그룹 삭제
|
||||
deleteGroup: (groupId: string) => Promise<boolean>;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { type ColumnDef } from "@tanstack/react-table";
|
||||
import { Button } from "@common/components";
|
||||
import { type GroupListResponseDto } from "./groups-interface";
|
||||
import { MenuAuthorityDialog } from "../ui/menu-authority-dialog";
|
||||
import { GroupsDialog } from "../ui/groups-dialog";
|
||||
|
||||
export const columns: ColumnDef<GroupListResponseDto>[] = [
|
||||
{
|
||||
@@ -19,8 +21,16 @@ export const columns: ColumnDef<GroupListResponseDto>[] = [
|
||||
id: "actions",
|
||||
header: "관리",
|
||||
cell: ({ row }) => (
|
||||
<div className="flex justify-center gap-2">
|
||||
<div
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="flex justify-center gap-2"
|
||||
>
|
||||
<MenuAuthorityDialog groupId={row.original.groupId} />
|
||||
<GroupsDialog groupId={row.original.groupId}>
|
||||
<Button size="sm" color="white">
|
||||
수정
|
||||
</Button>
|
||||
</GroupsDialog>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ import { memo, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
@@ -15,6 +16,7 @@ import {
|
||||
DialogClose,
|
||||
} from "@common/components";
|
||||
import { Form } from "@/shared/ui/form";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { useAlertStore, useMutationWrapper } from "@/shared/lib";
|
||||
import { GroupForm } from "./group-form";
|
||||
import { GroupsApi } from "../api/groups-service";
|
||||
@@ -22,21 +24,23 @@ import { groupFormSchema, type GroupFormData } from "../model/groups-interface";
|
||||
|
||||
type GroupsDialogProps = {
|
||||
groupId?: string;
|
||||
children: React.ReactNode;
|
||||
onSuccess?: () => void;
|
||||
};
|
||||
|
||||
const GroupsDialog = memo(
|
||||
({ groupId, onSuccess, ...props }: GroupsDialogProps) => {
|
||||
({ groupId, children, onSuccess, ...props }: GroupsDialogProps) => {
|
||||
const isRegistration = !groupId;
|
||||
|
||||
const { confirm } = useConfirm();
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const form = useForm<GroupFormData>({
|
||||
resolver: zodResolver(groupFormSchema),
|
||||
defaultValues: {
|
||||
mngrYn: "N",
|
||||
},
|
||||
const { data: group } = useQuery({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.GROUPS, groupId],
|
||||
queryFn: () => GroupsApi.findGroupById(groupId!),
|
||||
enabled: !!groupId,
|
||||
});
|
||||
|
||||
const { mutateAsync: createGroup } = useMutationWrapper({
|
||||
@@ -60,6 +64,20 @@ const GroupsDialog = memo(
|
||||
},
|
||||
});
|
||||
|
||||
const form = useForm<GroupFormData>({
|
||||
resolver: zodResolver(groupFormSchema),
|
||||
values: {
|
||||
groupId: group?.groupId ?? "",
|
||||
groupNm: group?.groupNm ?? "",
|
||||
groupSeCd: group?.groupSeCd ?? "",
|
||||
groupExpln: group?.groupExpln ?? "",
|
||||
delYn: group?.delYn ?? "",
|
||||
authrtId: group?.authrtId ?? "",
|
||||
siteId: group?.siteId ?? "",
|
||||
mngrYn: group?.mngrYn ?? "",
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit =
|
||||
(callback: (data: GroupFormData) => void) =>
|
||||
async (data: GroupFormData) => {
|
||||
@@ -72,9 +90,7 @@ const GroupsDialog = memo(
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen} {...props}>
|
||||
<DialogTrigger asChild>
|
||||
<Button>등록</Button>
|
||||
</DialogTrigger>
|
||||
<DialogTrigger asChild>{children}</DialogTrigger>
|
||||
<DialogContent className="max-w-[60rem]" aria-describedby={undefined}>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
useReactTable,
|
||||
type PaginationState,
|
||||
} from "@tanstack/react-table";
|
||||
import { DataTable } from "@common/components";
|
||||
import { Button, DataTable } from "@common/components";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { columns } from "../model/groups-table-columns";
|
||||
import { GroupsApi } from "../api/groups-service";
|
||||
@@ -55,7 +55,9 @@ function GroupsSection({ handleSelectedGroup }: GroupsSectionProps) {
|
||||
<div className="card card-border">
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">그룹 목록</h3>
|
||||
<GroupsDialog onSuccess={refetch} />
|
||||
<GroupsDialog onSuccess={refetch}>
|
||||
<Button>등록</Button>
|
||||
</GroupsDialog>
|
||||
</div>
|
||||
<div className="card !m-4 h-[calc(100vh-25.5rem)] overflow-auto !p-0">
|
||||
<DataTable table={table} onRowClick={handleRowClick} viewPagination />
|
||||
|
||||
@@ -17,20 +17,19 @@ function RoleSelect({ mngrYn = "N", ...props }: RoleSelectProps) {
|
||||
const { data: roles } = useQuery({
|
||||
queryKey: [ENDPOINT.USER_SERVICE.ROLES],
|
||||
queryFn: () => RoleApi.getRoles(),
|
||||
select: (data) => {
|
||||
return data.content.filter((role) => role.mngrYn === mngrYn);
|
||||
},
|
||||
});
|
||||
|
||||
const options = roles?.content.filter((role) => role.mngrYn === mngrYn);
|
||||
|
||||
return (
|
||||
<Select {...props}>
|
||||
<SelectTrigger className="w-[24rem]">
|
||||
<SelectValue placeholder="선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{roles?.map((role) => (
|
||||
<SelectItem key={role.roleId} value={role.roleId}>
|
||||
{role.roleName}
|
||||
{options?.map((item) => (
|
||||
<SelectItem key={item.roleId} value={item.roleId}>
|
||||
{item.roleName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
|
||||
Reference in New Issue
Block a user