메뉴 복사로직 개선
This commit is contained in:
parent
c3f066f88f
commit
75e5326b3e
|
|
@ -3394,13 +3394,23 @@ export async function copyMenu(
|
|||
}
|
||||
: undefined;
|
||||
|
||||
// 추가 복사 옵션 (카테고리, 코드, 채번규칙 등)
|
||||
const additionalCopyOptions = req.body.additionalCopyOptions
|
||||
? {
|
||||
copyCodeCategory: req.body.additionalCopyOptions.copyCodeCategory === true,
|
||||
copyNumberingRules: req.body.additionalCopyOptions.copyNumberingRules === true,
|
||||
copyCategoryMapping: req.body.additionalCopyOptions.copyCategoryMapping === true,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
// 메뉴 복사 실행
|
||||
const menuCopyService = new MenuCopyService();
|
||||
const result = await menuCopyService.copyMenu(
|
||||
parseInt(menuObjid, 10),
|
||||
targetCompanyCode,
|
||||
userId,
|
||||
screenNameConfig
|
||||
screenNameConfig,
|
||||
additionalCopyOptions
|
||||
);
|
||||
|
||||
logger.info("✅ 메뉴 복사 API 성공");
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -56,6 +56,12 @@ export function MenuCopyDialog({
|
|||
const [removeText, setRemoveText] = useState("");
|
||||
const [addPrefix, setAddPrefix] = useState("");
|
||||
|
||||
// 카테고리/코드 복사 옵션
|
||||
const [copyCodeCategory, setCopyCodeCategory] = useState(false);
|
||||
const [copyNumberingRules, setCopyNumberingRules] = useState(false);
|
||||
const [copyCategoryMapping, setCopyCategoryMapping] = useState(false);
|
||||
const [copyTableTypeColumns, setCopyTableTypeColumns] = useState(false);
|
||||
|
||||
// 회사 목록 로드
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
|
|
@ -66,6 +72,10 @@ export function MenuCopyDialog({
|
|||
setUseBulkRename(false);
|
||||
setRemoveText("");
|
||||
setAddPrefix("");
|
||||
setCopyCodeCategory(false);
|
||||
setCopyNumberingRules(false);
|
||||
setCopyCategoryMapping(false);
|
||||
setCopyTableTypeColumns(false);
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
|
|
@ -112,10 +122,19 @@ export function MenuCopyDialog({
|
|||
}
|
||||
: undefined;
|
||||
|
||||
// 추가 복사 옵션
|
||||
const additionalCopyOptions = {
|
||||
copyCodeCategory,
|
||||
copyNumberingRules,
|
||||
copyCategoryMapping,
|
||||
copyTableTypeColumns,
|
||||
};
|
||||
|
||||
const response = await menuApi.copyMenu(
|
||||
menuObjid,
|
||||
targetCompanyCode,
|
||||
screenNameConfig
|
||||
screenNameConfig,
|
||||
additionalCopyOptions
|
||||
);
|
||||
|
||||
if (response.success && response.data) {
|
||||
|
|
@ -264,19 +283,82 @@ export function MenuCopyDialog({
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* 추가 복사 옵션 */}
|
||||
{!result && (
|
||||
<div className="space-y-3">
|
||||
<p className="text-xs font-medium">추가 복사 옵션 (선택사항):</p>
|
||||
<div className="space-y-2 pl-2 border-l-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
id="copyCodeCategory"
|
||||
checked={copyCodeCategory}
|
||||
onCheckedChange={(checked) => setCopyCodeCategory(checked as boolean)}
|
||||
disabled={copying}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="copyCodeCategory"
|
||||
className="text-xs cursor-pointer"
|
||||
>
|
||||
코드 카테고리 + 코드 복사
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
id="copyNumberingRules"
|
||||
checked={copyNumberingRules}
|
||||
onCheckedChange={(checked) => setCopyNumberingRules(checked as boolean)}
|
||||
disabled={copying}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="copyNumberingRules"
|
||||
className="text-xs cursor-pointer"
|
||||
>
|
||||
채번 규칙 복사
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
id="copyCategoryMapping"
|
||||
checked={copyCategoryMapping}
|
||||
onCheckedChange={(checked) => setCopyCategoryMapping(checked as boolean)}
|
||||
disabled={copying}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="copyCategoryMapping"
|
||||
className="text-xs cursor-pointer"
|
||||
>
|
||||
카테고리 매핑 + 값 복사
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
id="copyTableTypeColumns"
|
||||
checked={copyTableTypeColumns}
|
||||
onCheckedChange={(checked) => setCopyTableTypeColumns(checked as boolean)}
|
||||
disabled={copying}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="copyTableTypeColumns"
|
||||
className="text-xs cursor-pointer"
|
||||
>
|
||||
테이블 타입관리 입력타입 설정 복사
|
||||
</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 복사 항목 안내 */}
|
||||
{!result && (
|
||||
<div className="rounded-md border p-3 text-xs">
|
||||
<p className="font-medium mb-2">복사되는 항목:</p>
|
||||
<p className="font-medium mb-2">기본 복사 항목:</p>
|
||||
<ul className="list-disc list-inside space-y-1 text-muted-foreground">
|
||||
<li>메뉴 구조 (하위 메뉴 포함)</li>
|
||||
<li>화면 + 레이아웃 (모달, 조건부 컨테이너)</li>
|
||||
<li>플로우 제어 (스텝, 연결)</li>
|
||||
<li>코드 카테고리 + 코드</li>
|
||||
<li>카테고리 설정 + 채번 규칙</li>
|
||||
</ul>
|
||||
<p className="mt-2 text-warning">
|
||||
⚠️ 실제 데이터는 복사되지 않습니다.
|
||||
<p className="mt-2 text-muted-foreground">
|
||||
* 코드, 채번규칙, 카테고리는 위 옵션 선택 시 복사됩니다.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -294,10 +376,40 @@ export function MenuCopyDialog({
|
|||
<span className="text-muted-foreground">화면:</span>{" "}
|
||||
<span className="font-medium">{result.copiedScreens}개</span>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<div>
|
||||
<span className="text-muted-foreground">플로우:</span>{" "}
|
||||
<span className="font-medium">{result.copiedFlows}개</span>
|
||||
</div>
|
||||
{(result.copiedCodeCategories ?? 0) > 0 && (
|
||||
<div>
|
||||
<span className="text-muted-foreground">코드 카테고리:</span>{" "}
|
||||
<span className="font-medium">{result.copiedCodeCategories}개</span>
|
||||
</div>
|
||||
)}
|
||||
{(result.copiedCodes ?? 0) > 0 && (
|
||||
<div>
|
||||
<span className="text-muted-foreground">코드:</span>{" "}
|
||||
<span className="font-medium">{result.copiedCodes}개</span>
|
||||
</div>
|
||||
)}
|
||||
{(result.copiedNumberingRules ?? 0) > 0 && (
|
||||
<div>
|
||||
<span className="text-muted-foreground">채번규칙:</span>{" "}
|
||||
<span className="font-medium">{result.copiedNumberingRules}개</span>
|
||||
</div>
|
||||
)}
|
||||
{(result.copiedCategoryMappings ?? 0) > 0 && (
|
||||
<div>
|
||||
<span className="text-muted-foreground">카테고리 매핑:</span>{" "}
|
||||
<span className="font-medium">{result.copiedCategoryMappings}개</span>
|
||||
</div>
|
||||
)}
|
||||
{(result.copiedTableTypeColumns ?? 0) > 0 && (
|
||||
<div>
|
||||
<span className="text-muted-foreground">테이블 타입 설정:</span>{" "}
|
||||
<span className="font-medium">{result.copiedTableTypeColumns}개</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -170,6 +170,12 @@ export const menuApi = {
|
|||
screenNameConfig?: {
|
||||
removeText?: string;
|
||||
addPrefix?: string;
|
||||
},
|
||||
additionalCopyOptions?: {
|
||||
copyCodeCategory?: boolean;
|
||||
copyNumberingRules?: boolean;
|
||||
copyCategoryMapping?: boolean;
|
||||
copyTableTypeColumns?: boolean;
|
||||
}
|
||||
): Promise<ApiResponse<MenuCopyResult>> => {
|
||||
try {
|
||||
|
|
@ -177,7 +183,8 @@ export const menuApi = {
|
|||
`/admin/menus/${menuObjid}/copy`,
|
||||
{
|
||||
targetCompanyCode,
|
||||
screenNameConfig
|
||||
screenNameConfig,
|
||||
additionalCopyOptions
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
|
|
@ -199,6 +206,11 @@ export interface MenuCopyResult {
|
|||
copiedMenus: number;
|
||||
copiedScreens: number;
|
||||
copiedFlows: number;
|
||||
copiedCodeCategories?: number;
|
||||
copiedCodes?: number;
|
||||
copiedNumberingRules?: number;
|
||||
copiedCategoryMappings?: number;
|
||||
copiedTableTypeColumns?: number;
|
||||
menuIdMap: Record<number, number>;
|
||||
screenIdMap: Record<number, number>;
|
||||
flowIdMap: Record<number, number>;
|
||||
|
|
|
|||
Loading…
Reference in New Issue