From 86eb9f042574300fd4e2932ee278af8183a61a8e Mon Sep 17 00:00:00 2001 From: kjs Date: Thu, 20 Nov 2025 17:44:33 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=20=EC=B1=84=EC=9A=B0?= =?UTF-8?q?=EA=B8=B0=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EB=93=9C=EB=A1=AD=EB=8B=A4=EC=9A=B4=20=EB=B0=8F=20=EB=8F=99?= =?UTF-8?q?=EC=A0=81=20=EC=BB=AC=EB=9F=BC=20=EB=A1=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 추가 입력 필드에서 자동 채우기 테이블을 드롭다운으로 선택 가능 - 텍스트 입력 대신 allTables에서 선택하는 방식으로 개선 - 테이블 선택 시 해당 테이블의 컬럼을 자동으로 로드 - autoFillTableColumns 상태로 필드별 테이블 컬럼 관리 - 선택한 테이블에 따라 컬럼 드롭다운이 동적으로 변경됨 사용자 경험 개선: - 테이블명을 직접 입력하는 대신 목록에서 선택 - 선택한 테이블의 컬럼만 표시되어 혼란 방지 - 원본 테이블(기본) 또는 다른 테이블 선택 가능 --- .../SelectedItemsDetailInputConfigPanel.tsx | 165 ++++++++++++++---- 1 file changed, 134 insertions(+), 31 deletions(-) diff --git a/frontend/lib/registry/components/selected-items-detail-input/SelectedItemsDetailInputConfigPanel.tsx b/frontend/lib/registry/components/selected-items-detail-input/SelectedItemsDetailInputConfigPanel.tsx index b08fbc64..0a05ed0c 100644 --- a/frontend/lib/registry/components/selected-items-detail-input/SelectedItemsDetailInputConfigPanel.tsx +++ b/frontend/lib/registry/components/selected-items-detail-input/SelectedItemsDetailInputConfigPanel.tsx @@ -73,6 +73,9 @@ export const SelectedItemsDetailInputConfigPanel: React.FC>>({}); + // 🆕 추가 입력 필드별 자동 채우기 테이블 컬럼 상태 + const [autoFillTableColumns, setAutoFillTableColumns] = useState>>({}); + // 🆕 원본/대상 테이블 컬럼 상태 (내부에서 로드) const [loadedSourceTableColumns, setLoadedSourceTableColumns] = useState>([]); const [loadedTargetTableColumns, setLoadedTargetTableColumns] = useState>([]); @@ -137,6 +140,38 @@ export const SelectedItemsDetailInputConfigPanel: React.FC { + if (!tableName) { + setAutoFillTableColumns(prev => ({ ...prev, [fieldIndex]: [] })); + return; + } + + try { + console.log(`🔍 [필드 ${fieldIndex}] 자동 채우기 테이블 컬럼 로드:`, tableName); + + const { tableManagementApi } = await import("@/lib/api/tableManagement"); + const response = await tableManagementApi.getColumnList(tableName); + + if (response.success && response.data) { + const columns = response.data.columns || []; + setAutoFillTableColumns(prev => ({ + ...prev, + [fieldIndex]: columns.map((col: any) => ({ + columnName: col.columnName, + columnLabel: col.displayName || col.columnLabel || col.columnName, + dataType: col.dataType, + })) + })); + console.log(`✅ [필드 ${fieldIndex}] 컬럼 로드 성공:`, columns.length); + } else { + console.error(`❌ [필드 ${fieldIndex}] 컬럼 로드 실패:`, response); + } + } catch (error) { + console.error(`❌ [필드 ${fieldIndex}] 컬럼 로드 오류:`, error); + } + }; + // 🆕 소스 테이블 선택 시 컬럼 로드 const loadMappingSourceColumns = async (tableName: string, mappingIndex: number) => { try { @@ -745,15 +780,66 @@ export const SelectedItemsDetailInputConfigPanel: React.FC - {/* 테이블명 입력 */} - updateField(index, { autoFillFromTable: e.target.value })} - placeholder="비워두면 주 데이터 (예: item_price)" - className="h-6 w-full text-[10px] sm:h-7 sm:text-xs" - /> + {/* 테이블 선택 드롭다운 */} + + + + + + + + 테이블을 찾을 수 없습니다. + + { + updateField(index, { autoFillFromTable: undefined, autoFillFrom: undefined }); + setAutoFillTableColumns(prev => ({ ...prev, [index]: [] })); + }} + className="text-[10px] sm:text-xs" + > + + 원본 테이블 ({config.sourceTable || "미설정"}) + + {allTables.map((table) => ( + { + updateField(index, { autoFillFromTable: value, autoFillFrom: undefined }); + loadAutoFillTableColumns(value, index); + }} + className="text-[10px] sm:text-xs" + > + + {table.displayName || table.tableName} + + ))} + + + +

- 다른 테이블에서 가져올 경우 테이블명 입력 + 다른 테이블에서 가져올 경우 테이블 선택

{/* 필드 선택 */} @@ -764,16 +850,26 @@ export const SelectedItemsDetailInputConfigPanel: React.FC - {field.autoFillFrom - ? sourceTableColumns.find(c => c.columnName === field.autoFillFrom)?.columnLabel || field.autoFillFrom - : "필드 선택 안 함"} + {(() => { + if (!field.autoFillFrom) return "필드 선택 안 함"; + + // 선택된 테이블의 컬럼에서 찾기 + const columns = field.autoFillFromTable + ? (autoFillTableColumns[index] || []) + : (loadedSourceTableColumns.length > 0 ? loadedSourceTableColumns : sourceTableColumns); + + const found = columns.find(c => c.columnName === field.autoFillFrom); + return found?.columnLabel || field.autoFillFrom; + })()} - 원본 테이블을 먼저 선택하세요. + + {field.autoFillFromTable ? "컬럼을 찾을 수 없습니다" : "원본 테이블을 먼저 선택하세요"} + 선택 안 함 - {sourceTableColumns.map((column) => ( - updateField(index, { autoFillFrom: column.columnName })} - className="text-[10px] sm:text-xs" - > - -
-
{column.columnLabel}
-
{column.columnName}
-
-
- ))} + {(() => { + // 선택된 테이블의 컬럼 또는 기본 원본 테이블 컬럼 + const columns = field.autoFillFromTable + ? (autoFillTableColumns[index] || []) + : (loadedSourceTableColumns.length > 0 ? loadedSourceTableColumns : sourceTableColumns); + + return columns.map((column) => ( + updateField(index, { autoFillFrom: value })} + className="text-[10px] sm:text-xs" + > + +
+
{column.columnLabel || column.columnName}
+ {column.dataType &&
{column.dataType}
} +
+
+ )); + })()}