Files
vexplor/frontend/lib/registry/components/conditional-container/ConditionalSectionViewer.tsx
kjs f5756e184f feat: 조건부 컨테이너를 화면 선택 방식으로 개선
- ConditionalSection 타입 변경 (components[] → screenId, screenName)
  * 각 조건마다 컴포넌트를 직접 배치하는 대신 기존 화면을 선택
  * 복잡한 입력 폼도 화면 재사용으로 간단히 구성

- ConditionalSectionDropZone을 ConditionalSectionViewer로 교체
  * 드롭존 대신 InteractiveScreenViewer 사용
  * 선택된 화면을 조건별로 렌더링
  * 디자인 모드에서 화면 미선택 시 안내 메시지 표시

- ConfigPanel에서 화면 선택 드롭다운 구현
  * screenManagementApi.getScreenList()로 화면 목록 로드
  * 각 섹션마다 화면 선택 Select 컴포넌트
  * 선택된 화면의 ID와 이름 자동 저장 및 표시
  * 로딩 상태 표시

- 기본 설정 업데이트
  * defaultConfig에서 components 제거, screenId 추가
  * 모든 섹션 기본값을 screenId: null로 설정

- README 문서 개선
  * 화면 선택 방식으로 사용법 업데이트
  * 사용 사례에 화면 ID 예시 추가
  * 구조 다이어그램 수정 (드롭존 → 화면 표시)
  * 디자인/실행 모드 설명 업데이트

장점:
- 기존 화면 재사용으로 생산성 향상
- 복잡한 입력 폼도 간단히 조건부 표시
- 화면 수정 시 자동 반영
- 유지보수 용이
2025-11-14 17:40:07 +09:00

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>
);
}