api-role Dialog가 호출됨
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { ModifyPage } from "@/pages/apiman/ui/modify-page";
|
||||
import { ModifyPage as VModifyPage } from "@/pages/apiman/ui/modify-page";
|
||||
|
||||
export default async function Page({
|
||||
|
||||
export default async function ModifyPage({
|
||||
params,
|
||||
}: {
|
||||
params: { id: string };
|
||||
params: Promise<{ id: number}>;
|
||||
}) {
|
||||
const authorizationNo = parseInt(params.id);
|
||||
return <ModifyPage authorizationNo={authorizationNo} />;
|
||||
const { id } = await params;
|
||||
return <VModifyPage authorizationNo={id} />;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ export interface Api {
|
||||
authorizationNo: number; // API 일련번호
|
||||
authorizationName: string; // API 명
|
||||
urlPatternValue: string; // URL 패턴
|
||||
httpMethodCode: string; // 하이퍼텍스트 전송 프로토콜 메쏘드 값 (예: GET, POST)
|
||||
httpMethodCode: string; // 하이퍼텍스트 전송 프로토콜 메쏘드 값 (예: GET, POST)
|
||||
sortSeq: number; // 정렬 순서
|
||||
useYn: string; // 사용 여부 (Y/N)
|
||||
regDt: string; // 등록 일시
|
||||
@@ -25,7 +25,7 @@ export interface ApiParams {
|
||||
|
||||
export interface ApiFormData {
|
||||
authorizationNo: number | null; // API 일련번호 (신규 등록 시 null)
|
||||
authorizationName: string; // API 명
|
||||
authorizationName: string; // API 명
|
||||
urlPatternValue: string; // URL 패턴
|
||||
httpMethodCode: string; // HTTP 메소드
|
||||
sortSeq: number; // 정렬 순서
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { ColumnDef } from "@tanstack/react-table";
|
||||
import { Badge } from "@common/components";
|
||||
import { Api } from "../api/apiman-api";
|
||||
import { Badge, Button } from "@common/components";
|
||||
import type { Api } from "../api/apiman-api";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
// API 권한 관리를 위한 타입 정의
|
||||
type ApiTableMeta = {
|
||||
openRoleDialog: (api: Api) => void;
|
||||
};
|
||||
|
||||
export const columns: ColumnDef<Api>[] = [
|
||||
{
|
||||
accessorKey: "authorizationNo",
|
||||
@@ -78,5 +83,29 @@ export const columns: ColumnDef<Api>[] = [
|
||||
header: "수정일시",
|
||||
cell: ({ row }) => dayjs(row.original.mdfcnDt).format("YYYY-MM-DD"),
|
||||
},
|
||||
|
||||
{
|
||||
id: "actions",
|
||||
header: "권한",
|
||||
cell: ({ row, table }) => {
|
||||
// 메타 데이터에서 권한 다이얼로그 열기 함수 가져오기
|
||||
const meta = table.options.meta as ApiTableMeta | undefined;
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="h-8 w-16 bg-blue-500 text-white hover:bg-blue-600"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation(); // 행 클릭 이벤트 전파 방지
|
||||
if (meta?.openRoleDialog) {
|
||||
// console.log(row.original);
|
||||
meta.openRoleDialog(row.original);
|
||||
}
|
||||
}}
|
||||
>
|
||||
권한
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import {
|
||||
Dialog,
|
||||
DialogTrigger,
|
||||
Button,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
Input,
|
||||
RadioGroup,
|
||||
RadioGroupItem,
|
||||
DialogFooter,
|
||||
DialogClose,
|
||||
Checkbox,
|
||||
Label,
|
||||
} from "@common/components";
|
||||
import { ApiRoleApi, type ApiRoleByApi } from "../../apirole/api/apirole-api";
|
||||
|
||||
// 페이지네이션 응답을 위한 인터페이스
|
||||
interface Page<T> {
|
||||
content: T[];
|
||||
pageable: {
|
||||
pageNumber: number;
|
||||
pageSize: number;
|
||||
};
|
||||
totalElements: number;
|
||||
totalPages: number;
|
||||
}
|
||||
|
||||
// API 역할 인터페이스 정의
|
||||
interface Role extends ApiRoleByApi {
|
||||
selected?: boolean;
|
||||
}
|
||||
|
||||
interface ApiRoleDialogProps {
|
||||
api: ApiRoleByApi | null;
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onSave: (roleIds: string[]) => Promise<void>;
|
||||
}
|
||||
|
||||
export function ApiRoleDialog({ api, isOpen, onClose, onSave }: ApiRoleDialogProps): JSX.Element {
|
||||
const [roles, setRoles] = useState<Role[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// API에서 역할 데이터 가져오기
|
||||
useEffect(() => {
|
||||
if (isOpen && api && api.authorizationNo) {
|
||||
// 실제 API 호출로 데이터 가져오기
|
||||
ApiRoleApi.getApiRoleByApiList({ authorizationNo: api.authorizationNo })
|
||||
.then((data: Page<ApiRoleByApi>) => {
|
||||
// 데이터를 Role 인터페이스에 맞게 변환
|
||||
const rolesWithSelected = data.content.map(role => ({
|
||||
...role,
|
||||
mode: role.useYn ==null?"C":"R",
|
||||
selected: role.useYn === "Y"
|
||||
}));
|
||||
setRoles(rolesWithSelected);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("역할 데이터 가져오기 오류:", error);
|
||||
// 오류 발생 시 빈 배열 설정
|
||||
setRoles([]);
|
||||
});
|
||||
}
|
||||
}, [isOpen, api]);
|
||||
|
||||
const handleToggleRole = (roleId: string) => {
|
||||
setRoles(
|
||||
roles.map((role) =>
|
||||
role.roleId === roleId ? { ...role, useYn: role.useYn === "Y" ? "N" : "Y", mode: role.mode === "R" ? "U" : "C" } : role
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
//const selectedRoleIds = roles.filter((role) => role.useYn === "Y").map((role) => role.roleId ?? "");
|
||||
await onSave(roles);
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error("권한 저장 중 오류 발생:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Dialog가 닫힐 때 호출되는 함수
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
if (!open) {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={handleOpenChange}>
|
||||
<DialogContent className="sm:max-w-[600px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-xl font-bold">
|
||||
API 권한 설정 - {api?.authorizationName}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="card mb-4">
|
||||
<Table>
|
||||
<colgroup>
|
||||
<col style={{ width: "20%" }} />
|
||||
<col style={{ width: "30%" }} />
|
||||
<col style={{ width: "20%" }} />
|
||||
<col style={{ width: "30%" }} />
|
||||
</colgroup>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell as="th">API 명</TableCell>
|
||||
<TableCell className="border">
|
||||
{api?.authorizationName || ""}
|
||||
</TableCell>
|
||||
<TableCell as="th">HTTP 메소드</TableCell>
|
||||
<TableCell className="border">
|
||||
{api?.httpMethodCode || ""}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell as="th">URL 패턴</TableCell>
|
||||
<TableCell colSpan={3} className="border">
|
||||
{api?.urlPatternValue || ""}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<div className="max-h-[400px] overflow-auto">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[50px]">허용</TableHead>
|
||||
<TableHead className="w-[150px]">권한 ID</TableHead>
|
||||
<TableHead>권한명</TableHead>
|
||||
<TableHead>권한내용</TableHead>
|
||||
<TableHead className="w-[80px]">사용여부</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{roles.map((role) => (
|
||||
<TableRow key={role.roleId}>
|
||||
<TableCell className="text-center">
|
||||
<Checkbox
|
||||
checked={role.useYn === "Y"}
|
||||
onCheckedChange={() => handleToggleRole(role.roleId)}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>{role.roleId}</TableCell>
|
||||
<TableCell>{role.roleName}</TableCell>
|
||||
<TableCell>{role.roleContent}</TableCell>
|
||||
<TableCell>
|
||||
<span className={role.useYn === "Y" ? "text-green-600" : "text-red-600"}>
|
||||
{role.useYn === "Y" ? "사용" : "미사용"}
|
||||
</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
{roles.length === 0 && (
|
||||
<TableRow>
|
||||
<TableCell colSpan={5} className="text-center py-4">
|
||||
권한 정보가 없습니다.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<DialogFooter className="flex justify-end gap-2 mt-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={onClose}
|
||||
disabled={loading}
|
||||
>
|
||||
취소
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleSave}
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? "저장 중..." : "저장"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -140,9 +140,9 @@ function ApimanForm({ form, authorizationNo, handleSave, handleDelete }: ApimanF
|
||||
)}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableHead>HTTP 메소드</TableHead>
|
||||
<TableHead>요청 메소드</TableHead>
|
||||
<TableCell className="border">
|
||||
<FormField
|
||||
control={form.control}
|
||||
@@ -155,7 +155,7 @@ function ApimanForm({ form, authorizationNo, handleSave, handleDelete }: ApimanF
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<SelectTrigger className="!text-[1.3rem]">
|
||||
<SelectValue placeholder="HTTP 메소드를 선택하세요" />
|
||||
<SelectValue placeholder="요청 메소드를 선택하세요" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="GET">GET</SelectItem>
|
||||
|
||||
@@ -22,8 +22,10 @@ import {
|
||||
} from "@common/components";
|
||||
|
||||
import { ApimanApi, type Api, type ApiParams } from "../api/apiman-api";
|
||||
import { type ApiRoleByApi } from "../../apirole/api/apirole-api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { columns } from "../model/apiman-table-columns";
|
||||
import { ApiRoleDialog } from "./api-role-dialog";
|
||||
|
||||
function ApimanPage() {
|
||||
const router = useRouter();
|
||||
@@ -34,9 +36,18 @@ function ApimanPage() {
|
||||
page: 0,
|
||||
size: 10,
|
||||
});
|
||||
|
||||
// API 역할 다이얼로그 상태 관리
|
||||
const [apiRoleDialog, setApiRoleDialog] = useState<{
|
||||
isOpen: boolean;
|
||||
api: ApiRoleByApi | null;
|
||||
}>({
|
||||
isOpen: false,
|
||||
api: null,
|
||||
});
|
||||
|
||||
const { data: apiList, refetch, isLoading } = useQuery({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.API, apiQuery],
|
||||
queryKey: [ENDPOINT.USER_SERVICE.AUTHRTS, apiQuery],
|
||||
queryFn: () => ApimanApi.getApiList(apiQuery),
|
||||
enabled: false,
|
||||
});
|
||||
@@ -53,6 +64,14 @@ function ApimanPage() {
|
||||
pageSize: apiQuery.size ?? 10,
|
||||
},
|
||||
},
|
||||
meta: {
|
||||
openRoleDialog: (api: ApiRoleByApi) => {
|
||||
setApiRoleDialog({
|
||||
isOpen: true,
|
||||
api,
|
||||
});
|
||||
},
|
||||
},
|
||||
onPaginationChange: (updater) => {
|
||||
const newPagination =
|
||||
typeof updater === "function"
|
||||
@@ -77,48 +96,46 @@ function ApimanPage() {
|
||||
setApiQuery(prev => ({ ...prev, page: 0 }));
|
||||
refetch();
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setApiQuery({
|
||||
authorizationName: "",
|
||||
httpMethodCode: "",
|
||||
useYn: "",
|
||||
page: 0,
|
||||
size: 10,
|
||||
});
|
||||
refetch();
|
||||
};
|
||||
|
||||
|
||||
const handleRowClick = (api: Api) => {
|
||||
router.push(`/apiman/register/${api.authorizationNo}`);
|
||||
};
|
||||
|
||||
// API 역할 저장 핸들러
|
||||
const handleSaveRoles = async (roles: ApiRoleByApi[]) => {
|
||||
try {
|
||||
// 실제 구현에서는 API 호출로 대체
|
||||
console.log(`API ${apiRoleDialog.api?.authorizationNo}에 권한 저장:`, roles);
|
||||
// 성공 시 다이얼로그 닫기
|
||||
setApiRoleDialog({ isOpen: false, api: null });
|
||||
// 목록 새로고침
|
||||
refetch();
|
||||
} catch (error) {
|
||||
console.error("권한 저장 중 오류 발생:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container mx-auto py-6">
|
||||
<div className="bg-white p-6 rounded-lg shadow mb-6">
|
||||
<form onSubmit={handleSubmit} className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="authorizationName">API 명</Label>
|
||||
<Input
|
||||
className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]"
|
||||
id="authorizationName"
|
||||
value={apiQuery.authorizationName || ""}
|
||||
onChange={(e) => setApiQuery( prev => ({ ...prev, authorizationName: e.target.value }))}
|
||||
placeholder="API 명 입력"
|
||||
/>
|
||||
<div className="card card-border !mt-6">
|
||||
{/* API 역할 다이얼로그 */}
|
||||
<ApiRoleDialog
|
||||
api={apiRoleDialog.api}
|
||||
isOpen={apiRoleDialog.isOpen}
|
||||
onClose={() => setApiRoleDialog({ isOpen: false, api: null })}
|
||||
onSave={handleSaveRoles}
|
||||
/>
|
||||
|
||||
<div className="card card-border">
|
||||
<form onSubmit={handleSubmit} className="flex items-center gap-2 p-2">
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
|
||||
<Label htmlFor="httpMethodCode">HTTP 메소드</Label>
|
||||
<Select
|
||||
<Label htmlFor="httpMethodCode" className="mr-2 text-label">요청 메소드</Label>
|
||||
<Select
|
||||
value={apiQuery.httpMethodCode || undefined}
|
||||
onValueChange={(value) => setApiQuery( prev => ({ ...prev, httpMethodCode: value === "ALL" ? "" : value }))}
|
||||
>
|
||||
<SelectTrigger id="httpMethodCode">
|
||||
<SelectValue placeholder="HTTP 메소드 선택" />
|
||||
<SelectTrigger id="httpMethodCode" className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]">
|
||||
<SelectValue placeholder="요청 메소드 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ALL">전체</SelectItem>
|
||||
@@ -131,78 +148,63 @@ function ApimanPage() {
|
||||
<SelectItem value="HEAD">HEAD</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="useYn">사용 여부</Label>
|
||||
<Select
|
||||
value={apiQuery.useYn || undefined}
|
||||
onValueChange={(value) => setApiQuery({ ...apiQuery, useYn: value === "ALL" ? "" : value })}
|
||||
>
|
||||
<SelectTrigger id="useYn">
|
||||
<SelectValue placeholder="사용 여부 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ALL">전체</SelectItem>
|
||||
<SelectItem value="Y">사용</SelectItem>
|
||||
<SelectItem value="N">미사용</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-3 flex justify-end gap-2">
|
||||
<Button type="button" variant="outline" onClick={handleReset}>
|
||||
초기화
|
||||
</Button>
|
||||
<Button type="submit">
|
||||
검색
|
||||
</Button>
|
||||
</div>
|
||||
<Label htmlFor="authorizationName" className="mr-2 text-label">API 명</Label>
|
||||
<Input
|
||||
className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]"
|
||||
id="authorizationName"
|
||||
value={apiQuery.authorizationName || ""}
|
||||
onChange={(e) => setApiQuery( prev => ({ ...prev, authorizationName: e.target.value }))}
|
||||
placeholder="API 명 입력"
|
||||
/>
|
||||
<Button className="h-[3.2rem]" type="submit">
|
||||
조회
|
||||
</Button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div className="bg-white rounded-lg shadow">
|
||||
<div className="p-4 flex justify-between items-center">
|
||||
<div>
|
||||
총 <span className="font-bold">{apiList?.totalElements || 0}</span>건
|
||||
</div>
|
||||
<Button onClick={() => router.push("/apiman/register")}>
|
||||
API 등록
|
||||
</Button>
|
||||
</div>
|
||||
<div className="bg-white rounded-lg shadow">
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">모듈API 목록</h3>
|
||||
<Button onClick={() => router.push("/apiman/register")}>+등록</Button>
|
||||
</div>
|
||||
|
||||
<DataTable
|
||||
table={table}
|
||||
isLoading={isLoading}
|
||||
onRowClick={handleRowClick}
|
||||
/>
|
||||
|
||||
{apiList && apiList.totalElements > 0 && (
|
||||
<div className="p-4 flex justify-center items-center gap-4">
|
||||
<Pagination
|
||||
currentPage={apiQuery.page ?? 0}
|
||||
totalPages={apiList.totalPages}
|
||||
onPageChange={(page) => setApiQuery({ ...apiQuery, page })}
|
||||
/>
|
||||
<Select
|
||||
value={String(apiQuery.size)}
|
||||
onValueChange={(value) =>
|
||||
setApiQuery(prev => ({ ...prev, page: 0, size: Number(value) }))
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="h-8 w-[70px]">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{[2,10, 20, 30, 40, 50,100].map((pageSize) => (
|
||||
<SelectItem key={pageSize} value={String(pageSize)}>
|
||||
{pageSize}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-center justify-end space-x-2 py-4">
|
||||
<div className="flex-1 text-lm text-muted-foreground">
|
||||
총 {apiList?.totalElements ?? 0} 건
|
||||
</div>
|
||||
<Pagination
|
||||
currentPage={apiQuery.page + 1}
|
||||
totalPages={apiList?.totalPages ?? 0}
|
||||
onPageChange={(page) =>
|
||||
setApiQuery(prev => ({ ...prev, page: page - 1 }))
|
||||
}
|
||||
/>
|
||||
<Select
|
||||
value={String(apiQuery.size)}
|
||||
onValueChange={(value) =>
|
||||
setApiQuery(prev => ({ ...prev, page: 0, size: Number(value) }))
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="h-8 w-[70px]">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{[2,10, 20, 30, 40, 50].map((pageSize) => (
|
||||
<SelectItem key={pageSize} value={String(pageSize)}>
|
||||
{pageSize}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -18,7 +18,7 @@ const apiFormSchema = z.object({
|
||||
urlPatternValue: z.string().min(1, "URL 패턴을 입력해주세요"),
|
||||
httpMethodCode: z.string().min(1, "HTTP 메소드를 선택해주세요"),
|
||||
sortSeq: z.number().min(0, "정렬 순서는 0 이상이어야 합니다"),
|
||||
useYn: z.string(),
|
||||
useYn: z.string(),
|
||||
});
|
||||
|
||||
function CreatePage() {
|
||||
@@ -56,7 +56,7 @@ function CreatePage() {
|
||||
urlPatternValue: "",
|
||||
httpMethodCode: "",
|
||||
sortSeq: 0,
|
||||
useYn: "Y"
|
||||
useYn: "Y"
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ const apiFormSchema = z.object({
|
||||
urlPatternValue: z.string().min(1, "URL 패턴을 입력해주세요"),
|
||||
httpMethodCode: z.string().min(1, "HTTP 메소드를 선택해주세요"),
|
||||
sortSeq: z.number(),
|
||||
useYn: z.string(),
|
||||
useYn: z.string(),
|
||||
});
|
||||
|
||||
function ModifyPage({ authorizationNo }: { authorizationNo: number }) {
|
||||
@@ -91,7 +91,10 @@ function ModifyPage({ authorizationNo }: { authorizationNo: number }) {
|
||||
<ApimanForm
|
||||
form={form}
|
||||
authorizationNo={authorizationNo}
|
||||
handleSave={updateApi}
|
||||
handleSave={async (data) => {
|
||||
await updateApi(data);
|
||||
return;
|
||||
}}
|
||||
handleDelete={deleteApi}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import type { Page } from "@/shared/types";
|
||||
import { client } from "@/shared/api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
|
||||
export interface ApiRole {
|
||||
roleId?: string;
|
||||
/** @format int64 */
|
||||
authorizationNo?: number;
|
||||
authorizationName?: string;
|
||||
urlPatternValue?: string;
|
||||
httpMethodCode?: string;
|
||||
/** @format int32 */
|
||||
sortSeq?: number;
|
||||
createdAt?: boolean;
|
||||
}
|
||||
/** API 에서 역할 추가 (API에 대한 역할) */
|
||||
export interface ApiRoleByApi {
|
||||
roleId?: string;
|
||||
roleName?: string;
|
||||
roleContent?: string;
|
||||
useYn?: string;
|
||||
/** @format int64 */
|
||||
authorizationNo?: number;
|
||||
mode?:string;
|
||||
}
|
||||
|
||||
export interface ApiRoleParams {
|
||||
authorizationNo?: number; // API 일련번호 검색
|
||||
roleId?: string; // API 역할 검색
|
||||
page?: number; // 페이지 번호
|
||||
size?: number; // 페이지 크기
|
||||
}
|
||||
|
||||
export interface ApiRoleFormData {
|
||||
authorizationNo: number | null; // API 일련번호 (신규 등록 시 null)
|
||||
authorizationName: string; // API 명
|
||||
urlPatternValue: string; // URL 패턴
|
||||
httpMethodCode: string; // HTTP 메소드
|
||||
sortSeq: number; // 정렬 순서
|
||||
useYn: string; // 사용 여부
|
||||
}
|
||||
|
||||
export const ApiRoleApi = {
|
||||
getApiRoleList: async (params: ApiRoleParams) => {
|
||||
const { data } = await client.get<Page<ApiRole>>(
|
||||
`${ENDPOINT.USER_SERVICE.ROLES_AUTHRTS}`,
|
||||
{ params }
|
||||
);
|
||||
return data;
|
||||
},
|
||||
getApiRoleByApiList: async (params: ApiRoleParams) => {
|
||||
const { data } = await client.get<Page<ApiRoleByApi>>(
|
||||
`${ENDPOINT.USER_SERVICE.ROLES_AUTHRTS}/api`,
|
||||
{ params }
|
||||
);
|
||||
return data;
|
||||
},
|
||||
getApiRole: async (authorizationNo: number) => {
|
||||
const { data } = await client.get<ApiRole>(`${ENDPOINT.USER_SERVICE.ROLES_AUTHRTS}/${authorizationNo}`);
|
||||
return data;
|
||||
},
|
||||
|
||||
createApiRole: async (apiData: ApiRoleFormData) => {
|
||||
const { data } = await client.post<ApiRole>(ENDPOINT.USER_SERVICE.ROLES_AUTHRTS, apiData);
|
||||
return data;
|
||||
},
|
||||
|
||||
updateApiRole: async (authorizationNo: number, apiData: ApiRoleFormData) => {
|
||||
const { data } = await client.put<ApiRole>(`${ENDPOINT.USER_SERVICE.ROLES_AUTHRTS}/${authorizationNo}`, apiData);
|
||||
return data;
|
||||
},
|
||||
|
||||
deleteApiRole: async (authorizationNo: number) => {
|
||||
const { data } = await client.delete<void>(`${ENDPOINT.USER_SERVICE.ROLES_AUTHRTS}/${authorizationNo}`);
|
||||
return data;
|
||||
},
|
||||
};
|
||||
@@ -103,13 +103,13 @@ function GroupPage() {
|
||||
<div className="card card-border">
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">그룹 목록</h3>
|
||||
<Button onClick={() => router.push("/group/register")}>등록</Button>
|
||||
<Button onClick={() => router.push("/group/register")}>+등록</Button>
|
||||
</div>
|
||||
<div className="card !m-[1.2rem] h-[49rem] overflow-auto !p-0">
|
||||
<DataTable table={table} onRowClick={handleRowClick} />
|
||||
<div className="flex items-center justify-end space-x-2 py-4">
|
||||
<div className="flex-1 text-lm text-muted-foreground">
|
||||
총 {groupList?.totalElements ?? 0} 개
|
||||
총 {groupList?.totalElements ?? 0} 건
|
||||
</div>
|
||||
<Pagination
|
||||
currentPage={groupQuery.page + 1}
|
||||
|
||||
@@ -11,7 +11,7 @@ export const ENDPOINT = {
|
||||
USERS: "/user-service/api/v1/users",
|
||||
SILENT_REFRESH: "/user-service/api/v1/users/token/refresh",
|
||||
AUTHRTS: "/user-service/api/v1/authorizations",
|
||||
|
||||
ROLES_AUTHRTS: "/user-service/api/v1/role-authorizations",
|
||||
},
|
||||
CMS_SERVICE: {
|
||||
SITES: "/cms-service/api/v1/sites",
|
||||
|
||||
Reference in New Issue
Block a user