- ConditionalSection 타입 변경 (components[] → screenId, screenName) * 각 조건마다 컴포넌트를 직접 배치하는 대신 기존 화면을 선택 * 복잡한 입력 폼도 화면 재사용으로 간단히 구성 - ConditionalSectionDropZone을 ConditionalSectionViewer로 교체 * 드롭존 대신 InteractiveScreenViewer 사용 * 선택된 화면을 조건별로 렌더링 * 디자인 모드에서 화면 미선택 시 안내 메시지 표시 - ConfigPanel에서 화면 선택 드롭다운 구현 * screenManagementApi.getScreenList()로 화면 목록 로드 * 각 섹션마다 화면 선택 Select 컴포넌트 * 선택된 화면의 ID와 이름 자동 저장 및 표시 * 로딩 상태 표시 - 기본 설정 업데이트 * defaultConfig에서 components 제거, screenId 추가 * 모든 섹션 기본값을 screenId: null로 설정 - README 문서 개선 * 화면 선택 방식으로 사용법 업데이트 * 사용 사례에 화면 ID 예시 추가 * 구조 다이어그램 수정 (드롭존 → 화면 표시) * 디자인/실행 모드 설명 업데이트 장점: - 기존 화면 재사용으로 생산성 향상 - 복잡한 입력 폼도 간단히 조건부 표시 - 화면 수정 시 자동 반영 - 유지보수 용이
90 lines
2.7 KiB
TypeScript
90 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState, useEffect } from "react";
|
|
import { ConditionalSectionViewerProps } from "./types";
|
|
import { InteractiveScreenViewer } from "@/components/screen/InteractiveScreenViewer";
|
|
import { cn } from "@/lib/utils";
|
|
import { Loader2 } from "lucide-react";
|
|
|
|
/**
|
|
* 조건부 섹션 뷰어 컴포넌트
|
|
* 각 조건에 해당하는 화면을 표시
|
|
*/
|
|
export function ConditionalSectionViewer({
|
|
sectionId,
|
|
condition,
|
|
label,
|
|
screenId,
|
|
screenName,
|
|
isActive,
|
|
isDesignMode,
|
|
showBorder = true,
|
|
formData,
|
|
onFormDataChange,
|
|
}: ConditionalSectionViewerProps) {
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
// 디자인 모드가 아니고 비활성 섹션이면 렌더링하지 않음
|
|
if (!isDesignMode && !isActive) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"relative min-h-[200px] transition-all",
|
|
showBorder && "rounded-lg border-2",
|
|
isDesignMode ? (
|
|
"border-dashed border-muted-foreground/30 bg-muted/20"
|
|
) : (
|
|
showBorder ? "border-border bg-card" : ""
|
|
),
|
|
!isDesignMode && !isActive && "hidden"
|
|
)}
|
|
data-section-id={sectionId}
|
|
>
|
|
{/* 섹션 라벨 (디자인 모드에서만 표시) */}
|
|
{isDesignMode && (
|
|
<div className="absolute -top-3 left-4 bg-background px-2 text-xs font-medium text-muted-foreground z-10">
|
|
{label} {isActive && "(활성)"}
|
|
{screenId && ` - 화면 ID: ${screenId}`}
|
|
</div>
|
|
)}
|
|
|
|
{/* 화면 미선택 안내 (디자인 모드 + 화면 없을 때) */}
|
|
{isDesignMode && !screenId && (
|
|
<div className="absolute inset-0 flex items-center justify-center">
|
|
<div className="text-center text-muted-foreground">
|
|
<p className="text-sm">설정 패널에서 화면을 선택하세요</p>
|
|
<p className="text-xs mt-1">조건: {condition}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* 로딩 중 */}
|
|
{isLoading && (
|
|
<div className="absolute inset-0 flex items-center justify-center bg-background/50 z-20">
|
|
<div className="flex flex-col items-center gap-2">
|
|
<Loader2 className="h-6 w-6 animate-spin text-primary" />
|
|
<p className="text-xs text-muted-foreground">화면 로드 중...</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* 화면 렌더링 */}
|
|
{screenId && (
|
|
<div className="relative p-4 min-h-[200px]">
|
|
<InteractiveScreenViewer
|
|
screenId={screenId}
|
|
formData={formData}
|
|
onFormDataChange={onFormDataChange}
|
|
mode="view" // 항상 뷰 모드로 표시
|
|
isInModal={true} // 모달 내부처럼 처리
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|