From a3e6afa93e21bedbc02b05fecfcd4952a8e73722 Mon Sep 17 00:00:00 2001 From: kjs Date: Tue, 17 Mar 2026 21:05:59 +0900 Subject: [PATCH] feat: enhance V2ButtonConfigPanel to support dynamic column mapping - Implemented logic to load reference table columns based on selected target table, improving the configurability of button mappings. - Added error handling for API calls to ensure robustness when fetching column data. - Updated dependencies in the useEffect hook to ensure proper reactivity when available tables change. These enhancements aim to provide users with a more flexible and dynamic configuration experience in the V2ButtonConfigPanel, allowing for better management of button mappings based on table relationships. --- .../v2/config-panels/V2ButtonConfigPanel.tsx | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/frontend/components/v2/config-panels/V2ButtonConfigPanel.tsx b/frontend/components/v2/config-panels/V2ButtonConfigPanel.tsx index ab7f8732..4df68117 100644 --- a/frontend/components/v2/config-panels/V2ButtonConfigPanel.tsx +++ b/frontend/components/v2/config-panels/V2ButtonConfigPanel.tsx @@ -387,13 +387,51 @@ export const V2ButtonConfigPanel: React.FC = ({ if (targetTable) { const cols = await loadTableColumns(targetTable); + + try { + const fullResponse = await apiClient.get(`/table-management/tables/${targetTable}/columns`); + let fullColumnData = fullResponse.data?.data; + if (!Array.isArray(fullColumnData) && fullColumnData?.columns) fullColumnData = fullColumnData.columns; + if (!Array.isArray(fullColumnData) && fullColumnData?.data) fullColumnData = fullColumnData.data; + + if (Array.isArray(fullColumnData)) { + const refTableSet = new Set(); + fullColumnData.forEach((col: any) => { + const inputType = col.inputType || col.input_type; + if (inputType !== "entity") return; + let refTable = col.referenceTable || col.reference_table; + if (!refTable && col.detailSettings) { + try { + const ds = typeof col.detailSettings === "string" ? JSON.parse(col.detailSettings) : col.detailSettings; + refTable = ds?.referenceTable; + } catch { /* ignore */ } + } + if (refTable) refTableSet.add(refTable); + }); + + const targetColumnNames = new Set(cols.map((c) => c.name)); + for (const refTable of refTableSet) { + const refCols = await loadTableColumns(refTable); + const refTableLabel = availableTables.find((t) => t.name === refTable)?.label || refTable; + refCols.forEach((rc) => { + if (!targetColumnNames.has(rc.name)) { + cols.push({ + name: rc.name, + label: `${rc.label} [${refTableLabel}]`, + }); + } + }); + } + } + } catch { /* ignore */ } + setMappingTargetColumns(cols); } else { setMappingTargetColumns([]); } }; loadAll(); - }, [actionType, config.action?.dataTransfer?.multiTableMappings, config.action?.dataTransfer?.targetTable, loadTableColumns]); + }, [actionType, config.action?.dataTransfer?.multiTableMappings, config.action?.dataTransfer?.targetTable, availableTables, loadTableColumns]); // 화면 목록 로드 (모달 액션용) useEffect(() => {