Files
sam-react-prod/src/components/items/ItemMasterDataManagement/services/pageService.ts

194 lines
4.9 KiB
TypeScript
Raw Normal View History

/**
* Page Service
*
* - validation
* - path generation
* - transform ( API)
* - defaults
*/
import type { ItemPage } from '@/contexts/ItemMasterContext';
// ===== Types =====
export type ItemType = 'FG' | 'PT' | 'SM' | 'RM' | 'CS';
export interface PageFormData {
pageName: string;
itemType: ItemType;
absolutePath?: string;
}
export interface PageValidationResult {
valid: boolean;
errors: {
page_name?: string;
item_type?: string;
absolute_path?: string;
};
}
// ===== Constants =====
const ITEM_TYPE_MAP: Record<ItemType, string> = {
'FG': '제품관리',
'PT': '부품관리',
'SM': '부자재관리',
'RM': '원자재관리',
'CS': '소모품관리',
};
// ===== Service =====
export const pageService = {
// ===== Validation =====
/**
*
*/
validate: (data: Partial<PageFormData>): PageValidationResult => {
const errors: PageValidationResult['errors'] = {};
const nameValidation = pageService.validatePageName(data.pageName || '');
if (!nameValidation.valid) {
errors.page_name = nameValidation.error;
}
const typeValidation = pageService.validateItemType(data.itemType || '');
if (!typeValidation.valid) {
errors.item_type = typeValidation.error;
}
return {
valid: Object.keys(errors).length === 0,
errors,
};
},
/**
*
*/
validatePageName: (name: string): { valid: boolean; error?: string } => {
if (!name || !name.trim()) {
return { valid: false, error: '페이지명을 입력해주세요' };
}
return { valid: true };
},
/**
*
*/
validateItemType: (type: string): { valid: boolean; error?: string } => {
const validTypes: ItemType[] = ['FG', 'PT', 'SM', 'RM', 'CS'];
if (!validTypes.includes(type as ItemType)) {
return { valid: false, error: '유효하지 않은 품목 타입입니다' };
}
return { valid: true };
},
/**
*
*/
validateAbsolutePath: (path: string): { valid: boolean; error?: string } => {
if (!path || !path.trim()) {
return { valid: false, error: '절대경로를 입력해주세요' };
}
if (!path.startsWith('/')) {
return { valid: false, error: '절대경로는 /로 시작해야 합니다' };
}
return { valid: true };
},
// ===== Path Generation =====
/**
*
*/
generateAbsolutePath: (itemType: ItemType, pageName: string): string => {
const category = ITEM_TYPE_MAP[itemType] || '기타';
return `/${category}/${pageName}`;
},
/**
*
*/
getItemTypeLabel: (itemType: ItemType): string => {
return ITEM_TYPE_MAP[itemType] || '기타';
},
// ===== Transform =====
/**
* API
*/
toApiRequest: (
formData: PageFormData
): Omit<ItemPage, 'id' | 'tenant_id' | 'created_at' | 'updated_at' | 'created_by' | 'updated_by'> => {
const absolutePath = formData.absolutePath ||
pageService.generateAbsolutePath(formData.itemType, formData.pageName);
return {
page_name: formData.pageName,
item_type: formData.itemType,
absolute_path: absolutePath,
is_active: true,
sections: [],
order_no: 0,
};
},
/**
* ItemPage
*/
toFormData: (page: ItemPage): PageFormData => {
return {
pageName: page.page_name,
itemType: page.item_type as ItemType,
absolutePath: page.absolute_path,
};
},
/**
*
*/
toDuplicateRequest: (
originalPage: ItemPage
): Omit<ItemPage, 'id' | 'tenant_id' | 'created_at' | 'updated_at' | 'created_by' | 'updated_by'> => {
const duplicatedName = `${originalPage.page_name} (복제)`;
const absolutePath = pageService.generateAbsolutePath(
originalPage.item_type as ItemType,
duplicatedName
);
return {
page_name: duplicatedName,
item_type: originalPage.item_type,
absolute_path: absolutePath,
is_active: true,
sections: [], // 섹션은 별도 API로 복제
order_no: 0,
};
},
// ===== Defaults =====
/**
*
*/
getDefaultFormData: (): PageFormData => ({
pageName: '',
itemType: 'FG',
}),
/**
*
*/
itemTypes: [
{ value: 'FG', label: '제품관리', description: '완제품' },
{ value: 'PT', label: '부품관리', description: '조립 부품' },
{ value: 'SM', label: '부자재관리', description: '부자재' },
{ value: 'RM', label: '원자재관리', description: '원자재' },
{ value: 'CS', label: '소모품관리', description: '소모품' },
] as const,
};