/** * 화면 그룹 관리 API 클라이언트 * - 화면 그룹 (screen_groups) * - 화면-그룹 연결 (screen_group_screens) * - 필드 조인 (screen_field_joins) * - 데이터 흐름 (screen_data_flows) * - 화면-테이블 관계 (screen_table_relations) */ import { apiClient } from "./client"; // ============================================================ // 타입 정의 // ============================================================ export interface ScreenGroup { id: number; group_name: string; group_code: string; main_table_name?: string; description?: string; icon?: string; display_order: number; is_active: string; company_code: string; created_date?: string; updated_date?: string; writer?: string; screen_count?: number; screens?: ScreenGroupScreen[]; parent_group_id?: number | null; // 상위 그룹 ID group_level?: number; // 그룹 레벨 (0: 대분류, 1: 중분류, 2: 소분류 ...) hierarchy_path?: string; // 계층 경로 } export interface ScreenGroupScreen { id: number; group_id: number; screen_id: number; screen_name?: string; screen_role: string; display_order: number; is_default: string; company_code: string; } export interface FieldJoin { id: number; screen_id: number; layout_id?: number; component_id?: string; field_name?: string; save_table: string; save_column: string; join_table: string; join_column: string; display_column: string; join_type: string; filter_condition?: string; sort_column?: string; sort_direction?: string; is_active: string; save_table_label?: string; join_table_label?: string; } export interface DataFlow { id: number; group_id?: number; source_screen_id: number; source_action?: string; target_screen_id: number; target_action?: string; data_mapping?: Record; flow_type: string; flow_label?: string; condition_expression?: string; is_active: string; source_screen_name?: string; target_screen_name?: string; group_name?: string; } export interface TableRelation { id: number; group_id?: number; screen_id: number; table_name: string; relation_type: string; crud_operations: string; description?: string; is_active: string; screen_name?: string; group_name?: string; table_label?: string; } export interface ApiResponse { success: boolean; data?: T; message?: string; error?: string; total?: number; page?: number; size?: number; totalPages?: number; } // ============================================================ // 화면 그룹 (screen_groups) API // ============================================================ export async function getScreenGroups(params?: { page?: number; size?: number; searchTerm?: string; }): Promise> { try { const queryParams = new URLSearchParams(); if (params?.page) queryParams.append("page", params.page.toString()); if (params?.size) queryParams.append("size", params.size.toString()); if (params?.searchTerm) queryParams.append("searchTerm", params.searchTerm); const response = await apiClient.get(`/screen-groups/groups?${queryParams.toString()}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function getScreenGroup(id: number): Promise> { try { const response = await apiClient.get(`/screen-groups/groups/${id}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function createScreenGroup(data: Partial): Promise> { try { const response = await apiClient.post("/screen-groups/groups", data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function updateScreenGroup(id: number, data: Partial): Promise> { try { const response = await apiClient.put(`/screen-groups/groups/${id}`, data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function deleteScreenGroup(id: number): Promise> { try { const response = await apiClient.delete(`/screen-groups/groups/${id}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } // ============================================================ // 화면-그룹 연결 (screen_group_screens) API // ============================================================ export async function addScreenToGroup(data: { group_id: number; screen_id: number; screen_role?: string; display_order?: number; is_default?: string; }): Promise> { try { const response = await apiClient.post("/screen-groups/group-screens", data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function updateScreenInGroup(id: number, data: { screen_role?: string; display_order?: number; is_default?: string; }): Promise> { try { const response = await apiClient.put(`/screen-groups/group-screens/${id}`, data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function removeScreenFromGroup(id: number): Promise> { try { const response = await apiClient.delete(`/screen-groups/group-screens/${id}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } // ============================================================ // 필드 조인 (screen_field_joins) API // ============================================================ export async function getFieldJoins(screenId?: number): Promise> { try { const queryParams = screenId ? `?screen_id=${screenId}` : ""; const response = await apiClient.get(`/screen-groups/field-joins${queryParams}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function createFieldJoin(data: Partial): Promise> { try { const response = await apiClient.post("/screen-groups/field-joins", data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function updateFieldJoin(id: number, data: Partial): Promise> { try { const response = await apiClient.put(`/screen-groups/field-joins/${id}`, data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function deleteFieldJoin(id: number): Promise> { try { const response = await apiClient.delete(`/screen-groups/field-joins/${id}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } // ============================================================ // 데이터 흐름 (screen_data_flows) API // ============================================================ export async function getDataFlows(groupId?: number): Promise> { try { const queryParams = groupId ? `?group_id=${groupId}` : ""; const response = await apiClient.get(`/screen-groups/data-flows${queryParams}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function createDataFlow(data: Partial): Promise> { try { const response = await apiClient.post("/screen-groups/data-flows", data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function updateDataFlow(id: number, data: Partial): Promise> { try { const response = await apiClient.put(`/screen-groups/data-flows/${id}`, data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function deleteDataFlow(id: number): Promise> { try { const response = await apiClient.delete(`/screen-groups/data-flows/${id}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } // ============================================================ // 화면-테이블 관계 (screen_table_relations) API // ============================================================ export async function getTableRelations(params?: { screen_id?: number; group_id?: number; }): Promise> { try { const queryParams = new URLSearchParams(); if (params?.screen_id) queryParams.append("screen_id", params.screen_id.toString()); if (params?.group_id) queryParams.append("group_id", params.group_id.toString()); const response = await apiClient.get(`/screen-groups/table-relations?${queryParams.toString()}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function createTableRelation(data: Partial): Promise> { try { const response = await apiClient.post("/screen-groups/table-relations", data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function updateTableRelation(id: number, data: Partial): Promise> { try { const response = await apiClient.put(`/screen-groups/table-relations/${id}`, data); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } export async function deleteTableRelation(id: number): Promise> { try { const response = await apiClient.delete(`/screen-groups/table-relations/${id}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } // ============================================================ // 화면 레이아웃 요약 (미리보기용) API // ============================================================ // 레이아웃 아이템 (미니어처 렌더링용) export interface LayoutItem { x: number; y: number; width: number; height: number; componentKind: string; // 정확한 컴포넌트 종류 (table-list, button-primary 등) widgetType: string; // 일반적인 위젯 타입 (button, text 등) label?: string; } export interface ScreenLayoutSummary { screenId: number; screenType: 'form' | 'grid' | 'dashboard' | 'action'; widgetCounts: Record; totalComponents: number; // 미니어처 렌더링용 레이아웃 데이터 layoutItems: LayoutItem[]; canvasWidth: number; canvasHeight: number; } // 단일 화면 레이아웃 요약 조회 export async function getScreenLayoutSummary(screenId: number): Promise> { try { const response = await apiClient.get(`/screen-groups/layout-summary/${screenId}`); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } // 여러 화면 레이아웃 요약 일괄 조회 export async function getMultipleScreenLayoutSummary( screenIds: number[] ): Promise>> { try { const response = await apiClient.post("/screen-groups/layout-summary/batch", { screenIds }); return response.data; } catch (error: any) { return { success: false, error: error.message }; } } // 서브 테이블 정보 타입 export interface SubTableInfo { tableName: string; componentType: string; relationType: 'lookup' | 'source' | 'join'; } export interface ScreenSubTablesData { screenId: number; screenName: string; mainTable: string; subTables: SubTableInfo[]; } // 여러 화면의 서브 테이블 정보 조회 (메인 테이블 → 서브 테이블 관계) export async function getScreenSubTables( screenIds: number[] ): Promise>> { try { const response = await apiClient.post("/screen-groups/sub-tables/batch", { screenIds }); return response.data; } catch (error: any) { return { success: false, error: error.message }; } }