feat: enhance component configuration and rendering

- Updated the RealtimePreviewDynamic component to display selected component information more clearly.
- Added dynamic field type labels in the RealtimePreviewDynamic component for better user understanding.
- Introduced a table refresh counter in the ScreenDesigner component to handle table column updates effectively.
- Improved the V2PropertiesPanel and V2SelectConfigPanel to support additional properties and enhance usability.
- Refactored the DynamicComponentRenderer to better handle field types and improve component configuration merging.

Made-with: Cursor
This commit is contained in:
DDD1542
2026-03-12 15:01:05 +09:00
parent 83aa8f3250
commit 80be7c5a76
11 changed files with 1163 additions and 70 deletions

View File

@@ -73,7 +73,6 @@ const SOURCE_CARDS = [
icon: Database,
title: "테이블 참조",
description: "다른 테이블에서 가져와요",
entityOnly: true,
},
] as const;
@@ -279,6 +278,8 @@ interface V2SelectConfigPanelProps {
inputType?: string;
tableName?: string;
columnName?: string;
tables?: Array<{ tableName: string; displayName?: string; tableComment?: string }>;
screenTableName?: string;
}
export const V2SelectConfigPanel: React.FC<V2SelectConfigPanelProps> = ({
@@ -287,6 +288,8 @@ export const V2SelectConfigPanel: React.FC<V2SelectConfigPanelProps> = ({
inputType,
tableName,
columnName,
tables = [],
screenTableName,
}) => {
const isEntityType = inputType === "entity" || config.source === "entity" || !!config.entityTable;
const isCategoryType = inputType === "category";
@@ -342,11 +345,12 @@ export const V2SelectConfigPanel: React.FC<V2SelectConfigPanelProps> = ({
loadFilterColumns();
}, [filterTargetTable]);
// 초기 source가 설정 안 된 경우에만 기본값 설정
useEffect(() => {
if (isCategoryType && config.source !== "category") {
if (!config.source && isCategoryType) {
onChange({ ...config, source: "category" });
}
}, [isCategoryType]);
}, []);
const loadCategoryValues = useCallback(async (catTable: string, catColumn: string) => {
if (!catTable || !catColumn) {
@@ -447,23 +451,13 @@ export const V2SelectConfigPanel: React.FC<V2SelectConfigPanelProps> = ({
updateConfig("options", newOptions);
};
const effectiveSource = isCategoryType
const effectiveSource = config.source === "code"
? "category"
: config.source === "code"
? "category"
: config.source || "static";
: config.source || (isCategoryType ? "category" : "static");
const visibleCards = useMemo(() => {
if (isCategoryType) {
return SOURCE_CARDS.filter((c) => c.value === "category");
}
return SOURCE_CARDS.filter((c) => {
if (c.entityOnly && !isEntityType) return false;
return true;
});
}, [isCategoryType, isEntityType]);
const visibleCards = SOURCE_CARDS;
const gridCols = isEntityType ? "grid-cols-3" : "grid-cols-2";
const gridCols = "grid-cols-3";
return (
<div className="space-y-4">
@@ -572,9 +566,25 @@ export const V2SelectConfigPanel: React.FC<V2SelectConfigPanelProps> = ({
<span className="text-sm font-medium"> </span>
</div>
<div className="rounded-md border bg-background p-3">
<p className="text-xs text-muted-foreground"> </p>
<p className="mt-0.5 text-sm font-medium">{config.entityTable || "미설정"}</p>
<div>
<p className="mb-1.5 text-xs text-muted-foreground"> </p>
<Select
value={config.entityTable || ""}
onValueChange={(v) => {
onChange({ ...config, entityTable: v, entityValueColumn: "", entityLabelColumn: "" });
}}
>
<SelectTrigger className="h-8 text-sm">
<SelectValue placeholder="테이블을 선택해주세요" />
</SelectTrigger>
<SelectContent>
{tables.map((t) => (
<SelectItem key={t.tableName} value={t.tableName}>
{t.displayName || t.tableComment ? `${t.displayName || t.tableComment} (${t.tableName})` : t.tableName}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{loadingColumns && (
@@ -628,16 +638,9 @@ export const V2SelectConfigPanel: React.FC<V2SelectConfigPanelProps> = ({
</div>
)}
{!loadingColumns && entityColumns.length === 0 && !config.entityTable && (
<div className="rounded-md border-2 border-dashed p-4 text-center">
<p className="text-sm text-muted-foreground"> </p>
<p className="mt-1 text-xs text-muted-foreground"> </p>
</div>
)}
{config.entityTable && !loadingColumns && entityColumns.length === 0 && (
<p className="text-[10px] text-amber-600">
. .
. .
</p>
)}
</div>