Merge branch 'iipbs/cs/dev' of https://www.onasys.co.kr:3000/ONAANDALL/frontend
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
# apps/cs/src/shared/config/env.ts 참고
|
||||
NEXT_PUBLIC_PORT=3000
|
||||
NEXT_PUBLIC_PROXY_HOST=http://localhost:3000
|
||||
SERVER_API_URL=http://192.168.0.102:8000
|
||||
NEXT_PUBLIC_SITE_ID=CS
|
||||
NEXT_PUBLIC_SUB_DOMAIN=http://localhost:3000
|
||||
NEXT_PUBLIC_SERVER_API_URL=http://192.168.0.102:8000
|
||||
NEXT_PUBLIC_TINY_API_KEY=t9nc4z6inquvvd5pq1vea8wcp7lb01qmqseh6egms9vpaju2
|
||||
NEXT_PUBLIC_TINY_API_KEY=t9nc4z6inquvvd5pq1vea8wcp7lb01qmqseh6egms9vpaju2
|
||||
NEXT_PUBLIC_TINY_BASE_URL=
|
||||
+17
-8
@@ -1,21 +1,25 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
import {
|
||||
CLAIM_NAME,
|
||||
AUTH_USER_ID,
|
||||
CLAIM_NAME,
|
||||
PORT,
|
||||
PROXY_HOST,
|
||||
SERVER_API_URL,
|
||||
SITE_ID,
|
||||
} from "./src/shared/config";
|
||||
|
||||
const serverApiUrl =
|
||||
process.env.NEXT_PUBLIC_SERVER_API_URL ?? "http://localhost:3000";
|
||||
const serverApiUrl = process.env.SERVER_API_URL ?? "http://localhost:3000";
|
||||
|
||||
const linkBackendApiHost = process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST ?? "http://localhost:8080";
|
||||
const linkBackendApiHost =
|
||||
process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST ?? "http://localhost:8080";
|
||||
|
||||
// CSP 헤더 설정 함수 (img-src만)
|
||||
function addSecurityHeaders(response: NextResponse): NextResponse {
|
||||
response.headers.set("Content-Security-Policy", "img-src 'self' data: https: blob:;");
|
||||
response.headers.set(
|
||||
"Content-Security-Policy",
|
||||
"img-src 'self' data: https: blob:;",
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -66,7 +70,7 @@ export function middleware(req: NextRequest) {
|
||||
const requestHeaders = new Headers(req.headers);
|
||||
const token = req.cookies.get(CLAIM_NAME)?.value;
|
||||
const userId = req.cookies.get(AUTH_USER_ID)?.value;
|
||||
|
||||
|
||||
// /api/link 경로를 제거하고 백엔드 API 경로로 변환
|
||||
const apiPath = pathname.replace("/api/link", "");
|
||||
const queryParams = searchParams.toString();
|
||||
@@ -94,11 +98,16 @@ export function middleware(req: NextRequest) {
|
||||
|
||||
logMessages.push("\n--------------------------------\n");
|
||||
// console.log(logMessages.join("\n"));
|
||||
|
||||
|
||||
const response = NextResponse.next();
|
||||
return addSecurityHeaders(response);
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/"],
|
||||
matcher: [
|
||||
"/server/:path*",
|
||||
"/attach-service/:path*",
|
||||
"/api/link/:path*",
|
||||
"/",
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SERVER_API_URL } from "@/shared/config";
|
||||
import { TINY_BASE_URL } from "@/shared/config";
|
||||
|
||||
export const editorBaseConfig = {
|
||||
// 폐쇄망 환경에서는 API 키 없이 자체 호스팅 모드 사용
|
||||
@@ -7,7 +7,7 @@ export const editorBaseConfig = {
|
||||
licenseKey: "gpl",
|
||||
init: {
|
||||
language: "ko_KR",
|
||||
language_url: '/tinymce/langs/ko_KR.js', // 직접 호스팅한 경우 경로 지정
|
||||
language_url: "/tinymce/langs/ko_KR.js", // 직접 호스팅한 경우 경로 지정
|
||||
height: 500,
|
||||
// 폐쇄망 환경을 위한 설정
|
||||
base_url: "/tinymce",
|
||||
@@ -38,7 +38,7 @@ export const editorBaseConfig = {
|
||||
"undo redo | blocks fontfamily fontsize | bold italic underline strikethrough forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist blockquote | table",
|
||||
"link image",
|
||||
],
|
||||
images_upload_base_path: SERVER_API_URL,
|
||||
images_upload_base_path: TINY_BASE_URL,
|
||||
file_picker_types: "image",
|
||||
// 폐쇄망 환경을 위한 추가 설정
|
||||
content_css: "/tinymce/skins/content/default/content.min.css",
|
||||
|
||||
@@ -43,7 +43,7 @@ const GroupsDialog = memo(
|
||||
const { data: group } = useQuery({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.GROUPS, groupId],
|
||||
queryFn: () => GroupApi.findGroupById(groupId!),
|
||||
enabled: !!groupId && open, // open 시점 groupId가 있을 때만 상세 조회 API 호출
|
||||
enabled: !isRegistration,
|
||||
});
|
||||
|
||||
const { mutateAsync: createGroup } = useMutationWrapper({
|
||||
@@ -92,8 +92,9 @@ const GroupsDialog = memo(
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (open) form.reset();
|
||||
}, [open]);
|
||||
// 그룹 등록 및 취소 시 폼 초기화
|
||||
if (isRegistration && !open) form.reset();
|
||||
}, [groupId, open]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen} {...props}>
|
||||
|
||||
@@ -16,7 +16,13 @@ type RoleSelectProps = React.ComponentPropsWithoutRef<typeof Select> & {
|
||||
function RoleSelect({ mngrYn = "N", ...props }: RoleSelectProps) {
|
||||
const { data: roles } = useQuery({
|
||||
queryKey: [ENDPOINT.USER_SERVICE.ROLES],
|
||||
queryFn: () => RoleApi.getRoles(),
|
||||
queryFn: () =>
|
||||
RoleApi.getRoles({
|
||||
keywordType: "useYn",
|
||||
keyword: "Y",
|
||||
page: 0,
|
||||
size: 100,
|
||||
}),
|
||||
});
|
||||
|
||||
const options = roles?.content.filter((role) => role.mngrYn === mngrYn);
|
||||
|
||||
@@ -3,13 +3,8 @@ import { useState } from "react";
|
||||
import type { Role } from "@/entities/role";
|
||||
import type { ColumnDef } from "@tanstack/react-table";
|
||||
import { MappingRoleDialog } from "../ui/mapping-role-dialog";
|
||||
import { Button } from "@common/components";
|
||||
|
||||
export const createColumns = ({
|
||||
deleteRole,
|
||||
}: {
|
||||
deleteRole: (roleId: string) => void;
|
||||
}): ColumnDef<Role>[] => [
|
||||
export const createColumns = (): ColumnDef<Role>[] => [
|
||||
{
|
||||
id: "no",
|
||||
header: "NO",
|
||||
@@ -44,18 +39,7 @@ export const createColumns = ({
|
||||
{
|
||||
id: "action",
|
||||
header: "관리",
|
||||
cell: ({ row }) => (
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<MappingRoleButton roleId={row.original.roleId} />
|
||||
<Button
|
||||
size="sm"
|
||||
color="red"
|
||||
onClick={() => deleteRole(row.original.roleId)}
|
||||
>
|
||||
삭제
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
cell: ({ row }) => <MappingRoleButton roleId={row.original.roleId} />,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -24,13 +24,6 @@ function ModifyPage({ roleId }: { roleId: string }) {
|
||||
},
|
||||
});
|
||||
|
||||
const { mutateAsync: deleteRole } = useMutationWrapper({
|
||||
mutationFn: () => RoleApi.deleteRole(roleId),
|
||||
onSuccess: () => {
|
||||
alert("삭제되었습니다.", () => router.push("/role"));
|
||||
},
|
||||
});
|
||||
|
||||
const form = useForm<RoleFormData>({
|
||||
resolver: zodResolver(roleFormSchema),
|
||||
values: {
|
||||
@@ -47,12 +40,7 @@ function ModifyPage({ roleId }: { roleId: string }) {
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">권한 수정</h3>
|
||||
</div>
|
||||
<RoleForm
|
||||
roleId={roleId}
|
||||
form={form}
|
||||
handleSave={updateRole}
|
||||
handleDelete={deleteRole}
|
||||
/>
|
||||
<RoleForm roleId={roleId} form={form} handleSave={updateRole} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ type RoleFormProps = {
|
||||
roleId?: string;
|
||||
form: UseFormReturn<RoleFormData>;
|
||||
handleSave: (data: RoleFormData) => Promise<void>;
|
||||
handleDelete?: () => Promise<void>;
|
||||
};
|
||||
|
||||
function RoleForm({ roleId, form, handleSave, ...props }: RoleFormProps) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { getCoreRowModel, type PaginationState } from "@tanstack/react-table";
|
||||
import { Button, Input, Label } from "@common/components";
|
||||
import { RoleApi, type Role, type RoleParams } from "@/entities/role";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { useAlertStore, useDataTable, useMutationWrapper } from "@/shared/lib";
|
||||
import { useAlertStore, useDataTable } from "@/shared/lib";
|
||||
import { createColumns } from "../model/table-columns";
|
||||
|
||||
function RolePage() {
|
||||
@@ -16,6 +16,7 @@ function RolePage() {
|
||||
|
||||
const [keyword, setKeyword] = useState("");
|
||||
const [searchParams, setSearchParams] = useState<RoleParams>({
|
||||
keywordType: "roleName",
|
||||
keyword: "",
|
||||
sort: "regDt,desc",
|
||||
});
|
||||
@@ -34,13 +35,6 @@ function RolePage() {
|
||||
}),
|
||||
});
|
||||
|
||||
const { mutateAsync: deleteRole } = useMutationWrapper({
|
||||
mutationFn: (roleId: string) => RoleApi.deleteRole(roleId),
|
||||
onSuccess: () => {
|
||||
alert("삭제되었습니다.", query.refetch);
|
||||
},
|
||||
});
|
||||
|
||||
const handleRowClick = (row: Role) => {
|
||||
router.push(`/role/register/${row.roleId}`);
|
||||
};
|
||||
@@ -48,9 +42,7 @@ function RolePage() {
|
||||
const { tableComponent } = useDataTable({
|
||||
query,
|
||||
tableOptions: {
|
||||
columns: createColumns({
|
||||
deleteRole,
|
||||
}),
|
||||
columns: createColumns(),
|
||||
state: {
|
||||
pagination,
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export const PORT = process.env.NEXT_PUBLIC_PORT || "3000";
|
||||
export const PROXY_HOST =
|
||||
process.env.NEXT_PUBLIC_PROXY_HOST || `http://localhost:${PORT}`;
|
||||
export const SERVER_API_URL = process.env.NEXT_PUBLIC_SERVER_API_URL;
|
||||
export const SERVER_API_URL = process.env.SERVER_API_URL;
|
||||
export const AUTH_LOGIN_REDIRECT_URL =
|
||||
process.env.NEXT_PUBLIC_AUTH_LOGIN_REDIRECT_URL || "/auth/login";
|
||||
export const SITE_ID = process.env.NEXT_PUBLIC_SITE_ID || "CS";
|
||||
@@ -11,4 +11,5 @@ export const ACCESS_TOKEN =
|
||||
export const REFRESH_TOKEN =
|
||||
process.env.NEXT_PUBLIC_REFRESH_TOKEN || "refresh-token";
|
||||
export const AUTH_USER_ID = process.env.NEXT_PUBLIC_AUTH_USER_ID || "token-id";
|
||||
export const TINY_BASE_URL = process.env.NEXT_PUBLIC_TINY_BASE_URL;
|
||||
export const COOKIE_DOMAIN = process.env.NEXT_PUBLIC_COOKIE_DOMAIN;
|
||||
|
||||
Reference in New Issue
Block a user