feat: 메뉴 복사 기능 - 2단계 복사 방식으로 화면 참조 매핑 문제 해결
- 문제: 화면 복사 시 참조되는 화면이 아직 복사되지 않아 screenIdMap에 매핑 정보가 없었음 - 해결: 2단계 복사 방식 도입 1단계: 모든 screen_definitions 먼저 복사하여 screenIdMap 완성 2단계: screen_layouts 복사하면서 완성된 screenIdMap으로 참조 업데이트 - 결과: targetScreenId가 올바르게 새 회사의 화면 ID로 매핑됨 (예: 149 → 517) - 추가: 화면 수집 시 문자열 타입 ID도 올바르게 파싱하도록 개선 - 추가: 참조 화면 발견 및 업데이트 로그 추가 관련 파일: - backend-node/src/services/menuCopyService.ts - db/migrations/1003_add_source_menu_objid_to_menu_info.sql - db/scripts/cleanup_company_11_*.sql
This commit is contained in:
@@ -14,6 +14,7 @@ interface MenuTableProps {
|
||||
title: string;
|
||||
onAddMenu: (parentId: string, menuType: string, level: number) => void;
|
||||
onEditMenu: (menuId: string) => void;
|
||||
onCopyMenu: (menuId: string, menuName: string) => void; // 복사 추가
|
||||
onToggleStatus: (menuId: string) => void;
|
||||
selectedMenus: Set<string>;
|
||||
onMenuSelectionChange: (menuId: string, checked: boolean) => void;
|
||||
@@ -22,6 +23,7 @@ interface MenuTableProps {
|
||||
onToggleExpand: (menuId: string) => void;
|
||||
// 다국어 텍스트 props 추가
|
||||
uiTexts: Record<string, string>;
|
||||
isSuperAdmin?: boolean; // SUPER_ADMIN 여부 추가
|
||||
}
|
||||
|
||||
export const MenuTable: React.FC<MenuTableProps> = ({
|
||||
@@ -29,6 +31,7 @@ export const MenuTable: React.FC<MenuTableProps> = ({
|
||||
title,
|
||||
onAddMenu,
|
||||
onEditMenu,
|
||||
onCopyMenu,
|
||||
onToggleStatus,
|
||||
selectedMenus,
|
||||
onMenuSelectionChange,
|
||||
@@ -36,6 +39,7 @@ export const MenuTable: React.FC<MenuTableProps> = ({
|
||||
expandedMenus,
|
||||
onToggleExpand,
|
||||
uiTexts,
|
||||
isSuperAdmin = false, // 기본값 false
|
||||
}) => {
|
||||
// 다국어 텍스트 가져오기 함수
|
||||
const getText = (key: string, fallback?: string): string => {
|
||||
@@ -281,14 +285,26 @@ export const MenuTable: React.FC<MenuTableProps> = ({
|
||||
<TableCell className="h-16">
|
||||
<div className="flex flex-nowrap gap-1">
|
||||
{lev === 1 && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-w-[40px] px-1 py-1 text-xs"
|
||||
onClick={() => onAddMenu(objid, menuType, lev)}
|
||||
>
|
||||
{getText(MENU_MANAGEMENT_KEYS.BUTTON_ADD)}
|
||||
</Button>
|
||||
<>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-w-[40px] px-1 py-1 text-xs"
|
||||
onClick={() => onAddMenu(objid, menuType, lev)}
|
||||
>
|
||||
{getText(MENU_MANAGEMENT_KEYS.BUTTON_ADD)}
|
||||
</Button>
|
||||
{isSuperAdmin && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-w-[40px] px-1 py-1 text-xs"
|
||||
onClick={() => onCopyMenu(objid, menuNameKor || "메뉴")}
|
||||
>
|
||||
복사
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{lev === 2 && (
|
||||
<>
|
||||
@@ -308,17 +324,39 @@ export const MenuTable: React.FC<MenuTableProps> = ({
|
||||
>
|
||||
{getText(MENU_MANAGEMENT_KEYS.BUTTON_EDIT)}
|
||||
</Button>
|
||||
{isSuperAdmin && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-w-[40px] px-1 py-1 text-xs"
|
||||
onClick={() => onCopyMenu(objid, menuNameKor || "메뉴")}
|
||||
>
|
||||
복사
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{lev > 2 && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-w-[40px] px-1 py-1 text-xs"
|
||||
onClick={() => onEditMenu(objid)}
|
||||
>
|
||||
{getText(MENU_MANAGEMENT_KEYS.BUTTON_EDIT)}
|
||||
</Button>
|
||||
<>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-w-[40px] px-1 py-1 text-xs"
|
||||
onClick={() => onEditMenu(objid)}
|
||||
>
|
||||
{getText(MENU_MANAGEMENT_KEYS.BUTTON_EDIT)}
|
||||
</Button>
|
||||
{isSuperAdmin && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-w-[40px] px-1 py-1 text-xs"
|
||||
onClick={() => onCopyMenu(objid, menuNameKor || "메뉴")}
|
||||
>
|
||||
복사
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</TableCell>
|
||||
|
||||
Reference in New Issue
Block a user