제어관리 개선판
This commit is contained in:
@@ -73,19 +73,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
flowSelectedStepId,
|
||||
...props
|
||||
}) => {
|
||||
console.log("🔵 ButtonPrimaryComponent 렌더링, 받은 props:", {
|
||||
componentId: component.id,
|
||||
hasSelectedRowsData: !!selectedRowsData,
|
||||
selectedRowsDataLength: selectedRowsData?.length,
|
||||
selectedRowsData,
|
||||
hasFlowSelectedData: !!flowSelectedData,
|
||||
flowSelectedDataLength: flowSelectedData?.length,
|
||||
flowSelectedData,
|
||||
flowSelectedStepId,
|
||||
tableName,
|
||||
screenId,
|
||||
});
|
||||
|
||||
// 🆕 플로우 단계별 표시 제어
|
||||
const flowConfig = (component as any).webTypeConfig?.flowVisibilityConfig;
|
||||
const currentStep = useCurrentFlowStep(flowConfig?.targetFlowComponentId);
|
||||
@@ -101,7 +88,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
if (currentStep === null) {
|
||||
// 🔧 화이트리스트 모드일 때는 단계 미선택 시 숨김
|
||||
if (flowConfig.mode === "whitelist") {
|
||||
console.log("🔍 [ButtonPrimary] 화이트리스트 모드 + 단계 미선택 → 숨김");
|
||||
return false;
|
||||
}
|
||||
// 블랙리스트나 all 모드는 표시
|
||||
@@ -119,18 +105,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
result = true;
|
||||
}
|
||||
|
||||
// 항상 로그 출력
|
||||
console.log("🔍 [ButtonPrimary] 표시 체크:", {
|
||||
buttonId: component.id,
|
||||
buttonLabel: component.label,
|
||||
flowComponentId: flowConfig.targetFlowComponentId,
|
||||
currentStep,
|
||||
mode,
|
||||
visibleSteps,
|
||||
hiddenSteps,
|
||||
result: result ? "표시 ✅" : "숨김 ❌",
|
||||
});
|
||||
|
||||
return result;
|
||||
}, [flowConfig, currentStep, component.id, component.label]);
|
||||
|
||||
@@ -149,7 +123,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (currentLoadingToastRef.current !== undefined) {
|
||||
console.log("🧹 컴포넌트 언마운트 시 토스트 정리");
|
||||
toast.dismiss(currentLoadingToastRef.current);
|
||||
currentLoadingToastRef.current = undefined;
|
||||
}
|
||||
@@ -240,21 +213,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
};
|
||||
}
|
||||
|
||||
// 디버그 로그 (필요시 주석 해제)
|
||||
// console.log("🔧 버튼 컴포넌트 설정:", {
|
||||
// originalConfig: componentConfig,
|
||||
// processedConfig,
|
||||
// actionConfig: processedConfig.action,
|
||||
// webTypeConfig: component.webTypeConfig,
|
||||
// enableDataflowControl: component.webTypeConfig?.enableDataflowControl,
|
||||
// dataflowConfig: component.webTypeConfig?.dataflowConfig,
|
||||
// screenId,
|
||||
// tableName,
|
||||
// onRefresh,
|
||||
// onClose,
|
||||
// selectedRows,
|
||||
// selectedRowsData,
|
||||
// });
|
||||
|
||||
// 스타일 계산
|
||||
// height: 100%로 부모(RealtimePreviewDynamic의 내부 div)의 높이를 따라감
|
||||
@@ -278,12 +236,9 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
|
||||
// 실제 액션 실행 함수
|
||||
const executeAction = async (actionConfig: any, context: ButtonActionContext) => {
|
||||
// console.log("🚀 executeAction 시작:", { actionConfig, context });
|
||||
|
||||
try {
|
||||
// 기존 토스트가 있다면 먼저 제거
|
||||
if (currentLoadingToastRef.current !== undefined) {
|
||||
console.log("📱 기존 토스트 제거");
|
||||
toast.dismiss(currentLoadingToastRef.current);
|
||||
currentLoadingToastRef.current = undefined;
|
||||
}
|
||||
@@ -294,7 +249,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
// UI 전환 액션(edit, modal, navigate)을 제외하고만 로딩 토스트 표시
|
||||
const silentActions = ["edit", "modal", "navigate"];
|
||||
if (!silentActions.includes(actionConfig.type)) {
|
||||
console.log("📱 로딩 토스트 표시 시작");
|
||||
currentLoadingToastRef.current = toast.loading(
|
||||
actionConfig.type === "save"
|
||||
? "저장 중..."
|
||||
@@ -307,23 +261,12 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
duration: Infinity, // 명시적으로 무한대로 설정
|
||||
},
|
||||
);
|
||||
console.log("📱 로딩 토스트 ID:", currentLoadingToastRef.current);
|
||||
} else {
|
||||
console.log("🔕 UI 전환 액션은 로딩 토스트 표시 안함:", actionConfig.type);
|
||||
}
|
||||
|
||||
console.log("⚡ ButtonActionExecutor.executeAction 호출 시작");
|
||||
console.log("🔍 actionConfig 확인:", {
|
||||
type: actionConfig.type,
|
||||
successMessage: actionConfig.successMessage,
|
||||
errorMessage: actionConfig.errorMessage,
|
||||
});
|
||||
const success = await ButtonActionExecutor.executeAction(actionConfig, context);
|
||||
console.log("⚡ ButtonActionExecutor.executeAction 완료, success:", success);
|
||||
|
||||
// 로딩 토스트 제거 (있는 경우에만)
|
||||
if (currentLoadingToastRef.current !== undefined) {
|
||||
console.log("📱 로딩 토스트 제거 시도, ID:", currentLoadingToastRef.current);
|
||||
toast.dismiss(currentLoadingToastRef.current);
|
||||
currentLoadingToastRef.current = undefined;
|
||||
}
|
||||
@@ -333,11 +276,8 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
// UI 전환 액션(edit, modal, navigate)은 에러도 조용히 처리
|
||||
const silentActions = ["edit", "modal", "navigate"];
|
||||
if (silentActions.includes(actionConfig.type)) {
|
||||
console.log("🔕 UI 전환 액션 실패지만 에러 토스트 표시 안함:", actionConfig.type);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("❌ 액션 실패, 오류 토스트 표시");
|
||||
// 기본 에러 메시지 결정
|
||||
const defaultErrorMessage =
|
||||
actionConfig.type === "save"
|
||||
@@ -357,13 +297,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
|
||||
const errorMessage = useCustomMessage ? actionConfig.errorMessage : defaultErrorMessage;
|
||||
|
||||
console.log("🔍 에러 메시지 결정:", {
|
||||
actionType: actionConfig.type,
|
||||
customMessage: actionConfig.errorMessage,
|
||||
useCustom: useCustomMessage,
|
||||
finalMessage: errorMessage
|
||||
});
|
||||
|
||||
toast.error(errorMessage);
|
||||
return;
|
||||
}
|
||||
@@ -390,19 +323,13 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
|
||||
const successMessage = useCustomMessage ? actionConfig.successMessage : defaultSuccessMessage;
|
||||
|
||||
console.log("🎉 성공 토스트 표시:", successMessage);
|
||||
toast.success(successMessage);
|
||||
} else {
|
||||
console.log("🔕 UI 전환 액션은 조용히 처리 (토스트 없음):", actionConfig.type);
|
||||
}
|
||||
|
||||
console.log("✅ 버튼 액션 실행 성공:", actionConfig.type);
|
||||
|
||||
// 저장/수정 성공 시 자동 처리
|
||||
if (actionConfig.type === "save" || actionConfig.type === "edit") {
|
||||
if (typeof window !== "undefined") {
|
||||
// 1. 테이블 새로고침 이벤트 먼저 발송 (모달이 닫히기 전에)
|
||||
console.log("🔄 저장/수정 후 테이블 새로고침 이벤트 발송");
|
||||
window.dispatchEvent(new CustomEvent("refreshTable"));
|
||||
|
||||
// 2. 모달 닫기 (약간의 딜레이)
|
||||
@@ -411,22 +338,17 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
const isInEditModal = (props as any).isInModal;
|
||||
|
||||
if (isInEditModal) {
|
||||
console.log("🚪 EditModal 닫기 이벤트 발송");
|
||||
window.dispatchEvent(new CustomEvent("closeEditModal"));
|
||||
}
|
||||
|
||||
// ScreenModal은 항상 닫기
|
||||
console.log("🚪 ScreenModal 닫기 이벤트 발송");
|
||||
window.dispatchEvent(new CustomEvent("closeSaveModal"));
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("❌ executeAction catch 블록 진입:", error);
|
||||
|
||||
// 로딩 토스트 제거
|
||||
if (currentLoadingToastRef.current !== undefined) {
|
||||
console.log("📱 오류 시 로딩 토스트 제거, ID:", currentLoadingToastRef.current);
|
||||
toast.dismiss(currentLoadingToastRef.current);
|
||||
currentLoadingToastRef.current = undefined;
|
||||
}
|
||||
@@ -441,12 +363,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
// 이벤트 핸들러
|
||||
const handleClick = async (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
console.log("🖱️ 버튼 클릭 이벤트 발생", {
|
||||
isDesignMode,
|
||||
isInteractive,
|
||||
hasAction: !!processedConfig.action,
|
||||
processedConfig,
|
||||
});
|
||||
|
||||
// 디자인 모드에서는 기본 onClick만 실행
|
||||
if (isDesignMode) {
|
||||
@@ -454,29 +370,13 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("🔍 조건 체크:", {
|
||||
isInteractive,
|
||||
hasProcessedConfig: !!processedConfig,
|
||||
hasAction: !!processedConfig.action,
|
||||
actionType: processedConfig.action?.type,
|
||||
});
|
||||
|
||||
// 인터랙티브 모드에서 액션 실행
|
||||
if (isInteractive && processedConfig.action) {
|
||||
console.log("✅ 액션 실행 조건 통과", {
|
||||
actionType: processedConfig.action.type,
|
||||
requiresConfirmation: confirmationRequiredActions.includes(processedConfig.action.type),
|
||||
});
|
||||
|
||||
// 삭제 액션인데 선택된 데이터가 없으면 경고 메시지 표시하고 중단
|
||||
const hasDataToDelete =
|
||||
(selectedRowsData && selectedRowsData.length > 0) || (flowSelectedData && flowSelectedData.length > 0);
|
||||
|
||||
if (processedConfig.action.type === "delete" && !hasDataToDelete) {
|
||||
console.log("⚠️ 삭제할 데이터가 선택되지 않았습니다.", {
|
||||
hasSelectedRowsData: !!(selectedRowsData && selectedRowsData.length > 0),
|
||||
hasFlowSelectedData: !!(flowSelectedData && flowSelectedData.length > 0),
|
||||
});
|
||||
toast.warning("삭제할 항목을 먼저 선택해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -498,22 +398,8 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
flowSelectedStepId,
|
||||
};
|
||||
|
||||
console.log("🔍 버튼 액션 실행 전 context 확인:", {
|
||||
hasSelectedRowsData: !!selectedRowsData,
|
||||
selectedRowsDataLength: selectedRowsData?.length,
|
||||
selectedRowsData,
|
||||
hasFlowSelectedData: !!flowSelectedData,
|
||||
flowSelectedDataLength: flowSelectedData?.length,
|
||||
flowSelectedData,
|
||||
flowSelectedStepId,
|
||||
tableName,
|
||||
screenId,
|
||||
formData,
|
||||
});
|
||||
|
||||
// 확인이 필요한 액션인지 확인
|
||||
if (confirmationRequiredActions.includes(processedConfig.action.type)) {
|
||||
console.log("📋 확인 다이얼로그 표시 중...");
|
||||
// 확인 다이얼로그 표시
|
||||
setPendingAction({
|
||||
type: processedConfig.action.type,
|
||||
@@ -522,16 +408,10 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
});
|
||||
setShowConfirmDialog(true);
|
||||
} else {
|
||||
console.log("🚀 액션 바로 실행 중...");
|
||||
// 확인이 필요하지 않은 액션은 바로 실행
|
||||
await executeAction(processedConfig.action, context);
|
||||
}
|
||||
} else {
|
||||
console.log("⚠️ 액션 실행 조건 불만족:", {
|
||||
isInteractive,
|
||||
hasAction: !!processedConfig.action,
|
||||
이유: !isInteractive ? "인터랙티브 모드 아님" : "액션 없음",
|
||||
});
|
||||
// 액션이 설정되지 않은 경우 기본 onClick 실행
|
||||
onClick?.();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user