import { apiClient } from "./client"; import { ScreenDefinition, CreateScreenRequest, UpdateScreenRequest, PaginatedResponse, ScreenTemplate, LayoutData, } from "@/types/screen"; // 화면 정의 관련 API export const screenApi = { // 화면 목록 조회 getScreens: async (params: { page?: number; size?: number; companyCode?: string; searchTerm?: string; }): Promise> => { const response = await apiClient.get("/screen-management/screens", { params }); const raw = response.data || {}; const items: any[] = (raw.data ?? raw.items ?? []) as any[]; const mapped: ScreenDefinition[] = items.map((it) => ({ ...it, // 문자열로 온 날짜를 Date 객체로 변환 (이미 Date이면 그대로 유지) createdDate: it.createdDate ? new Date(it.createdDate) : undefined, updatedDate: it.updatedDate ? new Date(it.updatedDate) : undefined, })); const page = raw.page ?? params.page ?? 1; const size = raw.size ?? params.size ?? mapped.length; const total = raw.total ?? mapped.length; const totalPages = raw.totalPages ?? Math.max(1, Math.ceil(total / (size || 1))); return { data: mapped, total, page, size, totalPages }; }, // 화면 상세 조회 getScreen: async (screenId: number): Promise => { const response = await apiClient.get(`/screen-management/screens/${screenId}`); const raw = response.data?.data || response.data; return { ...raw, createdDate: raw?.createdDate ? new Date(raw.createdDate) : undefined, updatedDate: raw?.updatedDate ? new Date(raw.updatedDate) : undefined, } as ScreenDefinition; }, // 화면에 할당된 메뉴 조회 getScreenMenu: async (screenId: number): Promise<{ menuObjid: number; menuName?: string } | null> => { const response = await apiClient.get(`/screen-management/screens/${screenId}/menu`); return response.data?.data || null; }, // 화면 생성 createScreen: async (screenData: CreateScreenRequest): Promise => { const response = await apiClient.post("/screen-management/screens", screenData); return response.data.data; }, // 화면 코드 자동 생성 (회사코드 + 순번) generateScreenCode: async (companyCode: string): Promise => { const response = await apiClient.get(`/screen-management/generate-screen-code/${companyCode}`); return response.data.data.screenCode; }, // 여러 개의 화면 코드 일괄 생성 generateMultipleScreenCodes: async (companyCode: string, count: number): Promise => { const response = await apiClient.post("/screen-management/generate-screen-codes", { companyCode, count, }); return response.data.data.screenCodes; }, // 화면 수정 updateScreen: async (screenId: number, screenData: UpdateScreenRequest): Promise => { const response = await apiClient.put(`/screen-management/screens/${screenId}`, screenData); return response.data.data; }, // 화면 정보 수정 (메타데이터만) updateScreenInfo: async ( screenId: number, data: { screenName: string; description?: string; isActive: string }, ): Promise => { await apiClient.put(`/screen-management/screens/${screenId}/info`, data); }, // 화면 의존성 체크 checkScreenDependencies: async ( screenId: number, ): Promise<{ hasDependencies: boolean; dependencies: Array<{ screenId: number; screenName: string; screenCode: string; componentId: string; componentType: string; referenceType: string; }>; }> => { const response = await apiClient.get(`/screen-management/screens/${screenId}/dependencies`); return response.data; }, // 화면 삭제 (휴지통으로 이동) deleteScreen: async (screenId: number, deleteReason?: string, force?: boolean): Promise => { await apiClient.delete(`/screen-management/screens/${screenId}`, { data: { deleteReason, force }, }); }, // 활성 화면 일괄 삭제 (휴지통으로 이동) bulkDeleteScreens: async ( screenIds: number[], deleteReason?: string, force?: boolean, ): Promise<{ deletedCount: number; skippedCount: number; errors: Array<{ screenId: number; error: string }>; }> => { const response = await apiClient.delete("/screen-management/screens/bulk/delete", { data: { screenIds, deleteReason, force }, }); return response.data.result; }, // 휴지통 화면 목록 조회 getDeletedScreens: async (params: { page?: number; size?: number; }): Promise< PaginatedResponse > => { const response = await apiClient.get("/screen-management/screens/trash/list", { params }); const raw = response.data || {}; const items: any[] = (raw.data ?? raw.items ?? []) as any[]; const mapped = items.map((it) => ({ ...it, createdDate: it.createdDate ? new Date(it.createdDate) : undefined, updatedDate: it.updatedDate ? new Date(it.updatedDate) : undefined, deletedDate: it.deletedDate ? new Date(it.deletedDate) : undefined, })); const page = raw.page ?? params.page ?? 1; const size = raw.size ?? params.size ?? mapped.length; const total = raw.total ?? mapped.length; const totalPages = raw.totalPages ?? Math.max(1, Math.ceil(total / (size || 1))); return { data: mapped, total, page, size, totalPages }; }, // 휴지통 화면 일괄 영구 삭제 bulkPermanentDeleteScreens: async ( screenIds: number[], ): Promise<{ deletedCount: number; skippedCount: number; errors: Array<{ screenId: number; error: string }>; }> => { const response = await apiClient.delete("/screen-management/screens/trash/bulk", { data: { screenIds }, }); return response.data.result; }, // 화면 복원 (휴지통에서 복원) restoreScreen: async (screenId: number): Promise => { await apiClient.post(`/screen-management/screens/${screenId}/restore`); }, // 화면 영구 삭제 permanentDeleteScreen: async (screenId: number): Promise => { await apiClient.delete(`/screen-management/screens/${screenId}/permanent`); }, // 화면 레이아웃 저장 saveLayout: async (screenId: number, layoutData: LayoutData): Promise => { await apiClient.post(`/screen-management/screens/${screenId}/layout`, layoutData); }, // 화면 레이아웃 저장 (ScreenDesigner_new.tsx용) saveScreenLayout: async (screenId: number, layoutData: LayoutData): Promise> => { const response = await apiClient.post(`/screen-management/screens/${screenId}/layout`, layoutData); return response.data; }, // 화면 레이아웃 조회 getLayout: async (screenId: number): Promise => { const response = await apiClient.get(`/screen-management/screens/${screenId}/layout`); return response.data.data; }, // 연결된 모달 화면 감지 detectLinkedModals: async ( screenId: number, ): Promise> => { const response = await apiClient.get(`/screen-management/screens/${screenId}/linked-modals`); return response.data.data || []; }, // 화면명 중복 체크 checkDuplicateScreenName: async (companyCode: string, screenName: string): Promise => { const response = await apiClient.post("/screen-management/screens/check-duplicate-name", { companyCode, screenName, }); return response.data.data.isDuplicate || false; }, // 화면 복사 (화면정보 + 레이아웃 모두 복사) copyScreen: async ( sourceScreenId: number, copyData: { screenName: string; screenCode: string; description?: string; }, ): Promise => { const response = await apiClient.post(`/screen-management/screens/${sourceScreenId}/copy`, copyData); return response.data.data; }, // 메인 화면 + 모달 화면들 일괄 복사 copyScreenWithModals: async ( sourceScreenId: number, copyData: { targetCompanyCode?: string; // 최고 관리자 전용: 다른 회사로 복사 mainScreen: { screenName: string; screenCode: string; description?: string; }; modalScreens: Array<{ sourceScreenId: number; screenName: string; screenCode: string; }>; }, ): Promise<{ mainScreen: ScreenDefinition; modalScreens: ScreenDefinition[]; }> => { const response = await apiClient.post(`/screen-management/screens/${sourceScreenId}/copy-with-modals`, copyData); return response.data.data; }, }; // 템플릿 관련 API export const templateApi = { // 템플릿 목록 조회 getTemplates: async (params: { companyCode?: string; templateType?: string; isPublic?: boolean; }): Promise => { const response = await apiClient.get("/screen-management/templates", { params }); return response.data.data; }, // 템플릿 상세 조회 getTemplate: async (templateId: number): Promise => { const response = await apiClient.get(`/screen-management/templates/${templateId}`); return response.data.data; }, // 템플릿 생성 createTemplate: async (templateData: Partial): Promise => { const response = await apiClient.post("/screen-management/templates", templateData); return response.data.data; }, // 템플릿 수정 updateTemplate: async (templateId: number, templateData: Partial): Promise => { const response = await apiClient.put(`/screen-management/templates/${templateId}`, templateData); return response.data.data; }, // 템플릿 삭제 deleteTemplate: async (templateId: number): Promise => { await apiClient.delete(`/screen-management/templates/${templateId}`); }, }; // 테이블 타입 관련 API export const tableTypeApi = { // 테이블 목록 조회 getTables: async (): Promise< Array<{ tableName: string; displayName: string; description: string; columnCount: string }> > => { const response = await apiClient.get("/table-management/tables"); return response.data.data; }, // 테이블 라벨 조회 getTableLabel: async (tableName: string): Promise<{ tableLabel?: string; description?: string }> => { try { const response = await apiClient.get(`/table-management/tables/${tableName}/labels`); return response.data.data || {}; } catch (error) { // 라벨이 없으면 빈 객체 반환 return {}; } }, // 테이블 컬럼 정보 조회 (모든 컬럼) getColumns: async (tableName: string, bustCache: boolean = false): Promise => { // bustCache: 캐시 우회 (테이블 타입 변경 후 즉시 반영 필요 시) const cacheParam = bustCache ? `&_t=${Date.now()}` : ""; const response = await apiClient.get(`/table-management/tables/${tableName}/columns?size=1000${cacheParam}`); // 새로운 API 응답 구조에 맞게 수정: { columns, total, page, size, totalPages } const data = response.data.data || response.data; return data.columns || data || []; }, // 컬럼 입력 타입 정보 조회 getColumnInputTypes: async (tableName: string): Promise => { const response = await apiClient.get(`/table-management/tables/${tableName}/web-types`); return response.data.data || []; }, // 컬럼 웹 타입 설정 setColumnWebType: async ( tableName: string, columnName: string, webType: string, detailSettings?: Record, inputType?: "direct" | "auto", ): Promise => { await apiClient.put(`/table-management/tables/${tableName}/columns/${columnName}/web-type`, { webType, detailSettings, inputType, }); }, // 테이블 데이터 조회 (페이지네이션 + 검색) getTableData: async ( tableName: string, params: { page?: number; size?: number; search?: Record; // 검색 조건 sortBy?: string; sortOrder?: "asc" | "desc"; } = {}, ): Promise<{ data: Record[]; total: number; page: number; size: number; totalPages: number; }> => { // 🔒 멀티테넌시: company_code 자동 필터링 활성화 const requestBody = { ...params, autoFilter: { enabled: true, filterColumn: "company_code", userField: "companyCode", }, }; const response = await apiClient.post(`/table-management/tables/${tableName}/data`, requestBody); const raw = response.data?.data || response.data; return { data: raw.data || [], total: raw.total || 0, page: raw.page || params.page || 1, size: raw.size || params.size || 10, totalPages: raw.totalPages || Math.ceil((raw.total || 0) / (params.size || 10)), }; }, // 데이터 추가 addTableData: async (tableName: string, data: Record): Promise => { await apiClient.post(`/table-management/tables/${tableName}/add`, data); }, // 데이터 수정 editTableData: async ( tableName: string, originalData: Record, updatedData: Record, ): Promise => { await apiClient.put(`/table-management/tables/${tableName}/edit`, { originalData, updatedData, }); }, // 데이터 삭제 (단일 또는 다중) deleteTableData: async (tableName: string, data: Record[] | { ids: string[] }): Promise => { await apiClient.delete(`/table-management/tables/${tableName}/delete`, { data }); }, // 🆕 단일 레코드 조회 (자동 입력용) getTableRecord: async ( tableName: string, filterColumn: string, filterValue: any, displayColumn: string, ): Promise<{ value: any; record: Record }> => { const response = await apiClient.post(`/table-management/tables/${tableName}/record`, { filterColumn, filterValue, displayColumn, }); return response.data.data; }, }; // 메뉴-화면 할당 관련 API export const menuScreenApi = { // 화면을 메뉴에 할당 assignScreenToMenu: async (screenId: number, menuObjid: number, displayOrder?: number): Promise => { await apiClient.post(`/screen-management/screens/${screenId}/assign-menu`, { menuObjid, displayOrder, }); }, // 메뉴별 할당된 화면 목록 조회 getScreensByMenu: async (menuObjid: number): Promise => { const response = await apiClient.get(`/screen-management/menus/${menuObjid}/screens`); return response.data.data.map((screen: any) => ({ ...screen, createdDate: screen.createdDate ? new Date(screen.createdDate) : new Date(), updatedDate: screen.updatedDate ? new Date(screen.updatedDate) : new Date(), })); }, // 화면-메뉴 할당 해제 unassignScreenFromMenu: async (screenId: number, menuObjid: number): Promise => { await apiClient.delete(`/screen-management/screens/${screenId}/menus/${menuObjid}`); }, };