"use client"; /** * TextLayoutTabs.tsx — 텍스트 컴포넌트 설정 * * [역할] * - 텍스트 내용 입력 + 데이터 바인딩(queryId/fieldName) 설정 * - ComponentSettingsModal 내에 직접 임베드되어 사용 * * [사용처] * - TextProperties.tsx (section="data"일 때) */ import React, { useCallback, useMemo } from "react"; import { Textarea } from "@/components/ui/textarea"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Type, Database, Link2 } from "lucide-react"; import { useReportDesigner } from "@/contexts/ReportDesignerContext"; import { Section, TabContent, Field, FieldGroup, InfoBox } from "./shared"; import type { ComponentConfig } from "@/types/report"; interface TextLayoutTabsProps { component: ComponentConfig; } export function TextLayoutTabs({ component }: TextLayoutTabsProps) { const { updateComponent, queries, getQueryResult } = useReportDesigner(); const update = useCallback( (updates: Partial) => updateComponent(component.id, updates), [component.id, updateComponent], ); const selectedQueryFields = useMemo(() => { if (!component.queryId) return []; const result = getQueryResult(component.queryId); if (result?.fields) return result.fields; return []; }, [component.queryId, getQueryResult]); const hasBinding = !!(component.queryId && component.fieldName); return ( {/* 데이터 바인딩 섹션 */}
} title="데이터 바인딩" > {component.queryId && ( {selectedQueryFields.length > 0 ? ( ) : ( update({ fieldName: e.target.value || undefined })} placeholder="필드명 직접 입력 (예: doc_number)" className="h-9 text-sm" /> )} )} {!component.queryId && component.fieldName && (
update({ fieldName: e.target.value || undefined })} placeholder="필드명" className="h-9 text-sm" />

쿼리를 연결하면 실제 데이터가 표시됩니다.

)}
{hasBinding && ( 쿼리 실행 시 {`{${component.fieldName}}`} 값이 표시됩니다. )}
{/* 기본값 / 정적 텍스트 */}
} title={hasBinding ? "기본값 (데이터 없을 때)" : "텍스트 내용"}>