feat: Refactor category mapping logic in TableListComponent
- Introduced a helper function to flatten tree structures for category mappings, improving code readability and maintainability. - Removed redundant checks for empty category columns, streamlining the data fetching process. - Enhanced error handling for category value loading, ensuring clearer logging of failures. - Updated the mapping logic to utilize the new flattening function, ensuring consistent handling of category data across components.
This commit is contained in:
@@ -1262,62 +1262,54 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (categoryColumns.length === 0) {
|
||||
setCategoryMappings({});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const mappings: Record<string, Record<string, { label: string; color?: string }>> = {};
|
||||
const apiClient = (await import("@/lib/api/client")).apiClient;
|
||||
|
||||
// 트리 구조를 평탄화하는 헬퍼 함수 (메인 테이블 + 엔티티 조인 공통 사용)
|
||||
const flattenTree = (items: any[], mapping: Record<string, { label: string; color?: string }>) => {
|
||||
items.forEach((item: any) => {
|
||||
if (item.valueCode) {
|
||||
mapping[String(item.valueCode)] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
}
|
||||
if (item.valueId !== undefined && item.valueId !== null) {
|
||||
mapping[String(item.valueId)] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
}
|
||||
if (item.children && Array.isArray(item.children) && item.children.length > 0) {
|
||||
flattenTree(item.children, mapping);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
for (const columnName of categoryColumns) {
|
||||
try {
|
||||
// 🆕 엔티티 조인 컬럼 처리: "테이블명.컬럼명" 형태인지 확인
|
||||
let targetTable = tableConfig.selectedTable;
|
||||
let targetColumn = columnName;
|
||||
|
||||
if (columnName.includes(".")) {
|
||||
const parts = columnName.split(".");
|
||||
targetTable = parts[0]; // 조인된 테이블명 (예: item_info)
|
||||
targetColumn = parts[1]; // 실제 컬럼명 (예: material)
|
||||
targetTable = parts[0];
|
||||
targetColumn = parts[1];
|
||||
}
|
||||
|
||||
const response = await apiClient.get(`/table-categories/${targetTable}/${targetColumn}/values`);
|
||||
|
||||
if (response.data.success && response.data.data && Array.isArray(response.data.data)) {
|
||||
const mapping: Record<string, { label: string; color?: string }> = {};
|
||||
|
||||
response.data.data.forEach((item: any) => {
|
||||
// valueCode를 문자열로 변환하여 키로 사용
|
||||
const key = String(item.valueCode);
|
||||
mapping[key] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
});
|
||||
flattenTree(response.data.data, mapping);
|
||||
|
||||
if (Object.keys(mapping).length > 0) {
|
||||
// 🆕 원래 컬럼명(item_info.material)으로 매핑 저장
|
||||
mappings[columnName] = mapping;
|
||||
} else {
|
||||
console.warn(`⚠️ [TableList] 매핑 데이터가 비어있음 [${columnName}]`);
|
||||
}
|
||||
} else {
|
||||
console.warn(`⚠️ [TableList] 카테고리 값 없음 [${columnName}]:`, {
|
||||
success: response.data.success,
|
||||
hasData: !!response.data.data,
|
||||
isArray: Array.isArray(response.data.data),
|
||||
response: response.data,
|
||||
});
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(`❌ [TableList] 카테고리 값 로드 실패 [${columnName}]:`, {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
response: error.response?.data,
|
||||
status: error.response?.status,
|
||||
});
|
||||
console.error(`[TableList] 카테고리 값 로드 실패 [${columnName}]:`, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1393,14 +1385,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
|
||||
if (response.data.success && response.data.data && Array.isArray(response.data.data)) {
|
||||
const mapping: Record<string, { label: string; color?: string }> = {};
|
||||
|
||||
response.data.data.forEach((item: any) => {
|
||||
const key = String(item.valueCode);
|
||||
mapping[key] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
});
|
||||
flattenTree(response.data.data, mapping);
|
||||
|
||||
if (Object.keys(mapping).length > 0) {
|
||||
mappings[col.columnName] = mapping;
|
||||
@@ -1449,8 +1434,8 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
// 연쇄관계 매핑이 없는 경우 무시 (404 등)
|
||||
}
|
||||
|
||||
setCategoryMappings(mappings);
|
||||
if (Object.keys(mappings).length > 0) {
|
||||
setCategoryMappings(mappings);
|
||||
setCategoryMappingsKey((prev) => prev + 1);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -1464,7 +1449,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
categoryColumns.length,
|
||||
JSON.stringify(categoryColumns),
|
||||
JSON.stringify(tableConfig.columns),
|
||||
]); // 더 명확한 의존성
|
||||
]);
|
||||
|
||||
// ========================================
|
||||
// 데이터 가져오기
|
||||
|
||||
@@ -1396,15 +1396,31 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (categoryColumns.length === 0) {
|
||||
setCategoryMappings({});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const mappings: Record<string, Record<string, { label: string; color?: string }>> = {};
|
||||
const apiClient = (await import("@/lib/api/client")).apiClient;
|
||||
|
||||
// 트리 구조를 평탄화하는 헬퍼 함수 (메인 테이블 + 엔티티 조인 공통 사용)
|
||||
const flattenTree = (items: any[], mapping: Record<string, { label: string; color?: string }>) => {
|
||||
items.forEach((item: any) => {
|
||||
if (item.valueCode) {
|
||||
mapping[String(item.valueCode)] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
}
|
||||
if (item.valueId !== undefined && item.valueId !== null) {
|
||||
mapping[String(item.valueId)] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
}
|
||||
if (item.children && Array.isArray(item.children) && item.children.length > 0) {
|
||||
flattenTree(item.children, mapping);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
for (const columnName of categoryColumns) {
|
||||
try {
|
||||
let targetTable = tableConfig.selectedTable;
|
||||
@@ -1429,39 +1445,10 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
|
||||
if (response.data.success && response.data.data && Array.isArray(response.data.data)) {
|
||||
const mapping: Record<string, { label: string; color?: string }> = {};
|
||||
|
||||
// 트리 구조를 평탄화하는 헬퍼 함수
|
||||
const flattenTree = (items: any[]) => {
|
||||
items.forEach((item: any) => {
|
||||
// valueCode를 문자열로 변환하여 키로 사용
|
||||
if (item.valueCode) {
|
||||
const key = String(item.valueCode);
|
||||
mapping[key] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
}
|
||||
// valueId도 키로 추가 (숫자 ID 저장 시 라벨 표시용)
|
||||
if (item.valueId !== undefined && item.valueId !== null) {
|
||||
mapping[String(item.valueId)] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
}
|
||||
// 자식 노드도 재귀적으로 처리
|
||||
if (item.children && Array.isArray(item.children) && item.children.length > 0) {
|
||||
flattenTree(item.children);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
flattenTree(response.data.data);
|
||||
flattenTree(response.data.data, mapping);
|
||||
|
||||
if (Object.keys(mapping).length > 0) {
|
||||
// 🆕 원래 컬럼명(item_info.material)으로 매핑 저장
|
||||
mappings[columnName] = mapping;
|
||||
} else {
|
||||
// 매핑 데이터가 비어있음 - 해당 컬럼에 카테고리 값이 없음
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
@@ -1541,24 +1528,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
|
||||
if (response.data.success && response.data.data && Array.isArray(response.data.data)) {
|
||||
const mapping: Record<string, { label: string; color?: string }> = {};
|
||||
|
||||
response.data.data.forEach((item: any) => {
|
||||
// valueCode로 매핑
|
||||
if (item.valueCode) {
|
||||
const key = String(item.valueCode);
|
||||
mapping[key] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
}
|
||||
// valueId도 키로 추가 (숫자 ID 저장 시 라벨 표시용)
|
||||
if (item.valueId !== undefined && item.valueId !== null) {
|
||||
mapping[String(item.valueId)] = {
|
||||
label: item.valueLabel,
|
||||
color: item.color,
|
||||
};
|
||||
}
|
||||
});
|
||||
flattenTree(response.data.data, mapping);
|
||||
|
||||
if (Object.keys(mapping).length > 0) {
|
||||
mappings[col.columnName] = mapping;
|
||||
@@ -1608,8 +1578,8 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
// 연쇄관계 매핑이 없는 경우 무시
|
||||
}
|
||||
|
||||
setCategoryMappings(mappings);
|
||||
if (Object.keys(mappings).length > 0) {
|
||||
setCategoryMappings(mappings);
|
||||
setCategoryMappingsKey((prev) => prev + 1);
|
||||
}
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user