feat: 저장 테이블 정보 및 애니메이션 기능 추가

- 화면 서브 테이블에서 저장 테이블 정보를 추출하는 쿼리 추가
- 저장 테이블 정보 구조를 TableNodeData 인터페이스에 통합
- 저장 테이블의 시각적 표현을 위한 애니메이션 효과 추가
- 필터링 및 참조 관계 뱃지 레이아웃 개선
- 테이블 높이 부드러운 애니메이션 및 스크롤 기능 구현
This commit is contained in:
DDD1542
2026-01-09 11:19:30 +09:00
parent b8c8b31033
commit af4072cef1
6 changed files with 602 additions and 59 deletions

View File

@@ -1184,6 +1184,12 @@ export const getScreenSubTables = async (req: Request, res: Response) => {
relationType: string; // 'join' | 'lookup' | 'source' | 'reference'
fieldMappings?: Array<{ sourceField: string; targetField: string; sourceDisplayName?: string; targetDisplayName?: string }>;
}>;
saveTables?: Array<{
tableName: string;
saveType: 'save' | 'edit' | 'delete' | 'transferData';
componentType: string;
isMainTable: boolean;
}>;
}> = {};
// 1. 기존 방식: componentConfig에서 tableName, sourceTable, fieldMappings 추출
@@ -1892,13 +1898,74 @@ export const getScreenSubTables = async (req: Request, res: Response) => {
});
});
// ============================================================
// 저장 테이블 정보 추출
// ============================================================
const saveTableQuery = `
SELECT DISTINCT
sd.screen_id,
sd.screen_name,
sd.table_name as main_table,
sl.properties->'componentConfig'->'action'->>'type' as action_type,
sl.properties->>'componentType' as component_type,
sl.properties->'componentConfig'->>'targetTable' as target_table,
sl.properties->'componentConfig'->'action'->'dataTransfer'->>'targetTable' as transfer_target_table
FROM screen_definitions sd
JOIN screen_layouts sl ON sd.screen_id = sl.screen_id
WHERE sd.screen_id = ANY($1)
AND sl.properties->'componentConfig'->'action'->>'type' = 'save'
AND sl.properties->'componentConfig'->'action'->>'targetScreenId' IS NULL
ORDER BY sd.screen_id
`;
const saveTableResult = await pool.query(saveTableQuery, [screenIds]);
saveTableResult.rows.forEach((row: any) => {
const screenId = row.screen_id;
const mainTable = row.main_table;
const actionType = row.action_type as 'save' | 'edit' | 'delete' | 'transferData';
const componentType = row.component_type || 'component';
const targetTable = row.target_table || row.transfer_target_table || mainTable;
// 화면 정보가 없으면 초기화
if (!screenSubTables[screenId]) {
screenSubTables[screenId] = {
screenId,
screenName: row.screen_name,
mainTable: mainTable || '',
subTables: [],
saveTables: [],
};
}
// saveTables 배열 초기화
if (!screenSubTables[screenId].saveTables) {
screenSubTables[screenId].saveTables = [];
}
// 중복 체크
const existingSaveTable = screenSubTables[screenId].saveTables!.find(
(st) => st.tableName === targetTable && st.saveType === actionType
);
if (!existingSaveTable && targetTable) {
screenSubTables[screenId].saveTables!.push({
tableName: targetTable,
saveType: actionType,
componentType,
isMainTable: targetTable === mainTable,
});
}
});
logger.info("화면 서브 테이블 정보 조회 완료", {
screenIds,
resultCount: Object.keys(screenSubTables).length,
details: Object.values(screenSubTables).map(s => ({
screenId: s.screenId,
mainTable: s.mainTable,
subTables: s.subTables.map(st => st.tableName)
subTables: s.subTables.map(st => st.tableName),
saveTables: s.saveTables?.map(st => st.tableName) || []
}))
});