From ce85528ddf0f89757360141407331890a87b12dd Mon Sep 17 00:00:00 2001 From: kjs Date: Thu, 15 Jan 2026 17:35:04 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=A7=80?= =?UTF-8?q?=EC=9B=90=20=EB=B0=8F=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=ED=98=84=ED=99=A9=20=EB=AC=B8=EC=84=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=ED=95=98=EA=B3=A0,=20Split?= =?UTF-8?q?PanelLayoutConfigPanel=EC=97=90=EC=84=9C=20=EC=A2=8C=EC=B8=A1?= =?UTF-8?q?=20=ED=8C=A8=EB=84=90=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=96=88=EC=8A=B5=EB=8B=88=EB=8B=A4.=20=EB=98=90=ED=95=9C,=20?= =?UTF-8?q?=EC=A1=B0=EC=9D=B8=20=ED=82=A4=EB=A5=BC=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=ED=82=A4=EB=A1=9C=20=EB=B3=80=EA=B2=BD=ED=95=98=EA=B3=A0,=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=ED=95=84=ED=84=B0=20=EB=AA=A8=EB=93=9C?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=84=A4=EB=AA=85=EC=9D=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=ED=95=98=EC=97=AC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EA=B2=BD=ED=97=98=EC=9D=84=20=EA=B0=9C=EC=84=A0?= =?UTF-8?q?=ED=96=88=EC=8A=B5=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/컴포넌트_기능_현황.md | 32 ++-- .../SplitPanelLayoutConfigPanel.tsx | 173 ++++++++++++++---- .../components/split-panel-layout/types.ts | 4 + 3 files changed, 154 insertions(+), 55 deletions(-) diff --git a/docs/컴포넌트_기능_현황.md b/docs/컴포넌트_기능_현황.md index 7778b3bc..b6e536f7 100644 --- a/docs/컴포넌트_기능_현황.md +++ b/docs/컴포넌트_기능_현황.md @@ -10,7 +10,7 @@ | 기능 | 적용 완료 | 미적용 | 해당없음 | | -------------------------- | --------- | ------ | -------- | | **다국어 지원** | 3개 | 10개 | 3개 | -| **컴포넌트별 테이블 설정** | 5개 | 5개 | 6개 | +| **컴포넌트별 테이블 설정** | 6개 | 4개 | 6개 | --- @@ -46,13 +46,13 @@ ### 레이아웃 (Layout) - 5개 -| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 | -| ----------------- | :---------: | :---------: | --------------------------------------------- | -| **분할 패널** | ✅ 적용 | ⚠️ 부분 | 다국어 지원, 테이블 설정은 하위 패널에서 처리 | -| **탭 컴포넌트** | ❌ 미적용 | ➖ 해당없음 | 화면 전환용 컨테이너 | -| **Section Card** | ❌ 미적용 | ➖ 해당없음 | 그룹화 컨테이너 | -| **Section Paper** | ❌ 미적용 | ➖ 해당없음 | 그룹화 컨테이너 | -| **구분선** | ❌ 미적용 | ➖ 해당없음 | 시각적 구분용 | +| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 | +| ----------------- | :---------: | :---------: | ----------------------------------------------------- | +| **분할 패널** | ✅ 적용 | ✅ 적용 | 다국어 지원, 좌우 패널 각각 Combobox UI로 테이블 선택 | +| **탭 컴포넌트** | ❌ 미적용 | ➖ 해당없음 | 화면 전환용 컨테이너 | +| **Section Card** | ❌ 미적용 | ➖ 해당없음 | 그룹화 컨테이너 | +| **Section Paper** | ❌ 미적용 | ➖ 해당없음 | 그룹화 컨테이너 | +| **구분선** | ❌ 미적용 | ➖ 해당없음 | 시각적 구분용 | --- @@ -94,20 +94,20 @@ **완전 적용 (5개)** -| 컴포넌트 | 적용 방식 | -| ------------------ | --------------------------------------------------------------------------------- | -| `table-list` | Combobox UI로 테이블 선택, `customTableName`, `useCustomTable`, `isReadOnly` 지원 | -| `unified-repeater` | Combobox UI로 테이블 선택, `mainTableName`, `foreignKeyColumn` 지원, FK 자동 연결 | -| `unified-list` | `TableListConfigPanel` 래핑하여 동일 기능 제공 | -| `card-display` | Combobox UI로 테이블 선택, `customTableName`, `useCustomTable` 지원 | +| 컴포넌트 | 적용 방식 | +| -------------------- | --------------------------------------------------------------------------------- | +| `table-list` | Combobox UI로 테이블 선택, `customTableName`, `useCustomTable`, `isReadOnly` 지원 | +| `unified-repeater` | Combobox UI로 테이블 선택, `mainTableName`, `foreignKeyColumn` 지원, FK 자동 연결 | +| `unified-list` | `TableListConfigPanel` 래핑하여 동일 기능 제공 | +| `card-display` | Combobox UI로 테이블 선택, `customTableName`, `useCustomTable` 지원 | +| `split-panel-layout` | 좌우 패널 각각 Combobox UI로 테이블 선택, 다국어 지원 | -**부분 적용 (5개)** +**부분 적용 (4개)** | 컴포넌트 | 현재 상태 | 필요 작업 | | ------------------------ | --------------------------- | --------------------- | | `pivot-grid` | `tableName` 설정 가능 | Combobox UI 추가 필요 | | `repeat-screen-modal` | `tableName` 설정 가능 | Combobox UI 추가 필요 | -| `split-panel-layout` | 하위 패널에서 처리 | 하위 컴포넌트에 위임 | | `location-swap-selector` | `customTableName` 지원 | Combobox UI 추가 필요 | | `table-search-widget` | `screenTableName` 자동 감지 | 현재 방식 유지 가능 | diff --git a/frontend/lib/registry/components/split-panel-layout/SplitPanelLayoutConfigPanel.tsx b/frontend/lib/registry/components/split-panel-layout/SplitPanelLayoutConfigPanel.tsx index 5779f600..724bcbc3 100644 --- a/frontend/lib/registry/components/split-panel-layout/SplitPanelLayoutConfigPanel.tsx +++ b/frontend/lib/registry/components/split-panel-layout/SplitPanelLayoutConfigPanel.tsx @@ -388,9 +388,9 @@ const AdditionalTabConfigPanel: React.FC = ({ )} - {/* ===== 4. 컬럼 매핑 (조인 키) ===== */} + {/* ===== 4. 컬럼 매핑 (연결 키) ===== */}
- +

좌측 패널 선택 시 관련 데이터만 표시합니다

@@ -1067,10 +1067,11 @@ export const SplitPanelLayoutConfigPanel: React.FC { + const [leftTableOpen, setLeftTableOpen] = useState(false); // 🆕 좌측 테이블 Combobox 상태 const [rightTableOpen, setRightTableOpen] = useState(false); const [loadedTableColumns, setLoadedTableColumns] = useState>({}); const [loadingColumns, setLoadingColumns] = useState>({}); - const [allTables, setAllTables] = useState([]); // 조인 모드용 전체 테이블 목록 + const [allTables, setAllTables] = useState([]); // 테이블 목록 // 엔티티 참조 테이블 컬럼 type EntityRefTable = { tableName: string; columns: ColumnInfo[] }; const [entityReferenceTables, setEntityReferenceTables] = useState>({}); @@ -1095,35 +1096,27 @@ export const SplitPanelLayoutConfigPanel: React.FC { - if (relationshipType === "join") { - const loadAllTables = async () => { - try { - const { tableManagementApi } = await import("@/lib/api/tableManagement"); - const response = await tableManagementApi.getTableList(); - if (response.success && response.data) { - console.log("✅ 분할패널 조인 모드: 전체 테이블 목록 로드", response.data.length, "개"); - setAllTables(response.data); - } - } catch (error) { - console.error("❌ 전체 테이블 목록 로드 실패:", error); + const loadAllTables = async () => { + try { + const { tableManagementApi } = await import("@/lib/api/tableManagement"); + const response = await tableManagementApi.getTableList(); + if (response.success && response.data) { + console.log("✅ 분할패널: 전체 테이블 목록 로드", response.data.length, "개"); + setAllTables(response.data); } - }; - loadAllTables(); - } else { - // 상세 모드일 때는 기본 테이블만 사용 - setAllTables([]); - } - }, [relationshipType]); - - // screenTableName이 변경되면 좌측 패널 테이블을 항상 화면 테이블로 설정 - useEffect(() => { - if (screenTableName) { - // 좌측 패널은 항상 현재 화면의 테이블 사용 - if (config.leftPanel?.tableName !== screenTableName) { - updateLeftPanel({ tableName: screenTableName }); + } catch (error) { + console.error("❌ 전체 테이블 목록 로드 실패:", error); } + }; + loadAllTables(); + }, []); + + // 초기 로드 시 좌측 패널 테이블이 없으면 화면 테이블로 설정 + useEffect(() => { + if (screenTableName && !config.leftPanel?.tableName) { + updateLeftPanel({ tableName: screenTableName }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [screenTableName]); @@ -1345,8 +1338,13 @@ export const SplitPanelLayoutConfigPanel: React.FC { + if (relationshipType === "detail") { + return leftTableName; // 상세 모드에서는 좌측과 동일 + } + return config.rightPanel?.tableName || ""; + }, [relationshipType, leftTableName, config.rightPanel?.tableName]); // 우측 테이블 컬럼 (로드된 컬럼 사용) const rightTableColumns = useMemo(() => { @@ -1406,8 +1404,8 @@ export const SplitPanelLayoutConfigPanel: React.FC
- 조인 (JOIN) - 좌측 테이블 → 우측 관련 테이블 (다른 테이블) + 조건 필터 (FILTERED) + 좌측 선택 항목 기준으로 우측 테이블 필터링
@@ -1418,6 +1416,103 @@ export const SplitPanelLayoutConfigPanel: React.FC

좌측 패널 설정 (마스터)

+ {/* 🆕 좌측 패널 테이블 선택 */} +
+ + + + + + + + + + + 테이블을 찾을 수 없습니다. + + + {/* 화면 기본 테이블 */} + {screenTableName && ( + + { + updateLeftPanel({ tableName: screenTableName, columns: [] }); + setLeftTableOpen(false); + }} + className="text-xs" + > + + + {allTables.find((t) => (t.tableName || t.table_name) === screenTableName)?.tableLabel || + allTables.find((t) => (t.tableName || t.table_name) === screenTableName)?.displayName || + screenTableName} + + + )} + + {/* 전체 테이블 */} + + {allTables + .filter((t) => (t.tableName || t.table_name) !== screenTableName) + .map((table) => { + const tableName = table.tableName || table.table_name; + const displayName = table.tableLabel || table.displayName || tableName; + return ( + { + updateLeftPanel({ tableName, columns: [] }); + setLeftTableOpen(false); + }} + className="text-xs" + > + + + {displayName} + + ); + })} + + + + + + {config.leftPanel?.tableName && config.leftPanel?.tableName !== screenTableName && ( +

+ 화면 기본 테이블이 아닌 다른 테이블의 데이터를 표시합니다. +

+ )} +
+
-

우측 패널 설정 ({relationshipType === "detail" ? "상세" : "조인"})

+

우측 패널 설정 ({relationshipType === "detail" ? "상세" : "조건 필터"})

@@ -1706,9 +1801,9 @@ export const SplitPanelLayoutConfigPanel: React.FC
) : ( - // 조인 모드: 전체 테이블에서 선택 가능 + // 조건 필터 모드: 전체 테이블에서 선택 가능
- +