ERP-node/frontend/lib/api/screenGroup.ts

417 lines
12 KiB
TypeScript

/**
* 화면 그룹 관리 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<string, any>;
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<T> {
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<ApiResponse<ScreenGroup[]>> {
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<ApiResponse<ScreenGroup>> {
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<ScreenGroup>): Promise<ApiResponse<ScreenGroup>> {
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<ScreenGroup>): Promise<ApiResponse<ScreenGroup>> {
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<ApiResponse<void>> {
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<ApiResponse<ScreenGroupScreen>> {
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<ApiResponse<ScreenGroupScreen>> {
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<ApiResponse<void>> {
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<ApiResponse<FieldJoin[]>> {
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<FieldJoin>): Promise<ApiResponse<FieldJoin>> {
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<FieldJoin>): Promise<ApiResponse<FieldJoin>> {
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<ApiResponse<void>> {
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<ApiResponse<DataFlow[]>> {
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<DataFlow>): Promise<ApiResponse<DataFlow>> {
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<DataFlow>): Promise<ApiResponse<DataFlow>> {
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<ApiResponse<void>> {
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<ApiResponse<TableRelation[]>> {
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<TableRelation>): Promise<ApiResponse<TableRelation>> {
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<TableRelation>): Promise<ApiResponse<TableRelation>> {
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<ApiResponse<void>> {
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<string, number>;
totalComponents: number;
// 미니어처 렌더링용 레이아웃 데이터
layoutItems: LayoutItem[];
canvasWidth: number;
canvasHeight: number;
}
// 단일 화면 레이아웃 요약 조회
export async function getScreenLayoutSummary(screenId: number): Promise<ApiResponse<ScreenLayoutSummary>> {
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<ApiResponse<Record<number, ScreenLayoutSummary>>> {
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<ApiResponse<Record<number, ScreenSubTablesData>>> {
try {
const response = await apiClient.post("/screen-groups/sub-tables/batch", { screenIds });
return response.data;
} catch (error: any) {
return { success: false, error: error.message };
}
}