feat: Enhance category column handling and data mapping
- Updated the `getCategoryColumnsByCompany` and `getCategoryColumnsByMenu` functions to exclude reference columns from category column queries, improving data integrity. - Modified the `TableManagementService` to include `category_ref` in the column management logic, ensuring proper handling of category references during data operations. - Enhanced the frontend components to support category reference mapping, allowing for better data representation and user interaction. - Implemented category label conversion in various components to improve the display of category data, ensuring a seamless user experience.
This commit is contained in:
@@ -559,6 +559,7 @@ export class ButtonActionExecutor {
|
||||
}
|
||||
|
||||
// 🆕 EditModal 등에서 전달된 onSave 콜백이 있으면 우선 사용
|
||||
// EditModal이 내부에서 직접 repeaterSave 이벤트를 발행하고 완료를 기다림
|
||||
if (onSave) {
|
||||
try {
|
||||
await onSave();
|
||||
@@ -626,6 +627,7 @@ export class ButtonActionExecutor {
|
||||
|
||||
// 🆕 EditModal 등에서 전달된 onSave 콜백이 있으면 우선 사용
|
||||
// 단, _tableSection_ 데이터가 있으면 건너뛰기 (handleUniversalFormModalTableSectionSave가 처리)
|
||||
// EditModal이 내부에서 직접 repeaterSave 이벤트를 발행하고 완료를 기다림
|
||||
if (onSave && !hasTableSectionData) {
|
||||
try {
|
||||
await onSave();
|
||||
@@ -1494,13 +1496,24 @@ export class ButtonActionExecutor {
|
||||
// @ts-ignore - window에 동적 속성 사용
|
||||
const v2RepeaterTables = Array.from(window.__v2RepeaterInstances || []);
|
||||
|
||||
// V2Repeater가 동일 테이블에 존재하는지 allComponents로 감지
|
||||
// (useCustomTable 미설정 = 화면 테이블에 직접 저장하는 리피터)
|
||||
const hasRepeaterOnSameTable = context.allComponents?.some((c: any) => {
|
||||
const compType = c.componentType || c.overrides?.type;
|
||||
if (compType !== "v2-repeater") return false;
|
||||
const compConfig = c.componentConfig || c.overrides || {};
|
||||
return !compConfig.useCustomTable;
|
||||
}) || false;
|
||||
|
||||
// 메인 저장 건너뛰기 조건:
|
||||
// 1. RepeatScreenModal 또는 RepeaterFieldGroup에서 같은 테이블 처리
|
||||
// 2. V2Repeater가 같은 테이블에 존재 (리피터 데이터에 메인 폼 데이터 병합되어 저장됨)
|
||||
// 3. allComponents에서 useCustomTable 미설정 V2Repeater 감지 (글로벌 등록 없는 경우)
|
||||
const shouldSkipMainSave =
|
||||
repeatScreenModalTables.includes(tableName) ||
|
||||
repeaterFieldGroupTables.includes(tableName) ||
|
||||
v2RepeaterTables.includes(tableName);
|
||||
v2RepeaterTables.includes(tableName) ||
|
||||
hasRepeaterOnSameTable;
|
||||
|
||||
if (shouldSkipMainSave) {
|
||||
saveResult = { success: true, message: "RepeaterFieldGroup/RepeatScreenModal/V2Repeater에서 처리" };
|
||||
@@ -1779,16 +1792,7 @@ export class ButtonActionExecutor {
|
||||
throw new Error("저장에 필요한 정보가 부족합니다. (테이블명 또는 화면ID 누락)");
|
||||
}
|
||||
|
||||
// 테이블과 플로우 새로고침 (모달 닫기 전에 실행)
|
||||
context.onRefresh?.();
|
||||
context.onFlowRefresh?.();
|
||||
|
||||
// 저장 성공 후 이벤트 발생
|
||||
window.dispatchEvent(new CustomEvent("closeEditModal")); // EditModal 닫기
|
||||
window.dispatchEvent(new CustomEvent("saveSuccessInModal")); // ScreenModal 연속 등록 모드 처리
|
||||
|
||||
// V2Repeater 저장 이벤트 발생 (메인 폼 데이터 + 리피터 데이터 병합 저장)
|
||||
// 🔧 formData를 리피터에 전달하여 각 행에 병합 저장
|
||||
// V2Repeater 저장 이벤트 발생 (모달 닫기 전에 실행해야 V2Repeater가 이벤트를 수신할 수 있음)
|
||||
const savedId = saveResult?.data?.id || saveResult?.data?.data?.id || formData.id || context.formData?.id;
|
||||
|
||||
// _deferSave 데이터 처리 (마스터-디테일 순차 저장: 레벨별 저장 + temp→real ID 매핑)
|
||||
@@ -1866,17 +1870,45 @@ export class ButtonActionExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
console.log("🟢 [buttonActions] repeaterSave 이벤트 발행:", {
|
||||
parentId: savedId,
|
||||
tableName: context.tableName,
|
||||
masterRecordId: savedId,
|
||||
mainFormDataKeys: Object.keys(mainFormData),
|
||||
});
|
||||
|
||||
// V2Repeater 저장 완료를 기다리기 위한 Promise
|
||||
const repeaterSavePromise = new Promise<void>((resolve) => {
|
||||
const fallbackTimeout = setTimeout(resolve, 5000);
|
||||
const handler = () => {
|
||||
clearTimeout(fallbackTimeout);
|
||||
window.removeEventListener("repeaterSaveComplete", handler);
|
||||
resolve();
|
||||
};
|
||||
window.addEventListener("repeaterSaveComplete", handler);
|
||||
});
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("repeaterSave", {
|
||||
detail: {
|
||||
parentId: savedId,
|
||||
tableName: context.tableName,
|
||||
mainFormData, // 🆕 메인 폼 데이터 전달
|
||||
masterRecordId: savedId, // 🆕 마스터 레코드 ID (FK 자동 연결용)
|
||||
mainFormData,
|
||||
masterRecordId: savedId,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
await repeaterSavePromise;
|
||||
|
||||
// 테이블과 플로우 새로고침 (모달 닫기 전에 실행)
|
||||
context.onRefresh?.();
|
||||
context.onFlowRefresh?.();
|
||||
|
||||
// 저장 성공 후 모달 닫기 이벤트 발생
|
||||
window.dispatchEvent(new CustomEvent("closeEditModal"));
|
||||
window.dispatchEvent(new CustomEvent("saveSuccessInModal"));
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error("저장 오류:", error);
|
||||
@@ -1884,6 +1916,50 @@ export class ButtonActionExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* V2Repeater 디테일 데이터 저장 이벤트 발행 (onSave 콜백 경로에서도 사용)
|
||||
*/
|
||||
private static async dispatchRepeaterSave(context: ButtonActionContext): Promise<void> {
|
||||
const formData = context.formData || {};
|
||||
const savedId = formData.id;
|
||||
|
||||
if (!savedId) {
|
||||
console.log("⚠️ [dispatchRepeaterSave] savedId(formData.id) 없음 - 스킵");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("🟢 [dispatchRepeaterSave] repeaterSave 이벤트 발행:", {
|
||||
parentId: savedId,
|
||||
tableName: context.tableName,
|
||||
masterRecordId: savedId,
|
||||
formDataKeys: Object.keys(formData),
|
||||
});
|
||||
|
||||
const repeaterSavePromise = new Promise<void>((resolve) => {
|
||||
const fallbackTimeout = setTimeout(resolve, 5000);
|
||||
const handler = () => {
|
||||
clearTimeout(fallbackTimeout);
|
||||
window.removeEventListener("repeaterSaveComplete", handler);
|
||||
resolve();
|
||||
};
|
||||
window.addEventListener("repeaterSaveComplete", handler);
|
||||
});
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("repeaterSave", {
|
||||
detail: {
|
||||
parentId: savedId,
|
||||
tableName: context.tableName,
|
||||
mainFormData: formData,
|
||||
masterRecordId: savedId,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
await repeaterSavePromise;
|
||||
console.log("✅ [dispatchRepeaterSave] repeaterSave 완료");
|
||||
}
|
||||
|
||||
/**
|
||||
* DB에서 조회한 실제 기본키로 formData에서 값 추출
|
||||
* @param formData 폼 데이터
|
||||
|
||||
Reference in New Issue
Block a user