반응형 및 테이블 리스트 컴포넌트 오류 수정
This commit is contained in:
@@ -88,18 +88,19 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
|
||||
// 삭제 액션 감지 로직 (실제 필드명 사용)
|
||||
const isDeleteAction = () => {
|
||||
const deleteKeywords = ['삭제', 'delete', 'remove', '제거', 'del'];
|
||||
const deleteKeywords = ["삭제", "delete", "remove", "제거", "del"];
|
||||
return (
|
||||
component.componentConfig?.action?.type === 'delete' ||
|
||||
component.config?.action?.type === 'delete' ||
|
||||
component.webTypeConfig?.actionType === 'delete' ||
|
||||
component.text?.toLowerCase().includes('삭제') ||
|
||||
component.text?.toLowerCase().includes('delete') ||
|
||||
component.label?.toLowerCase().includes('삭제') ||
|
||||
component.label?.toLowerCase().includes('delete') ||
|
||||
deleteKeywords.some(keyword =>
|
||||
component.config?.buttonText?.toLowerCase().includes(keyword) ||
|
||||
component.config?.text?.toLowerCase().includes(keyword)
|
||||
component.componentConfig?.action?.type === "delete" ||
|
||||
component.config?.action?.type === "delete" ||
|
||||
component.webTypeConfig?.actionType === "delete" ||
|
||||
component.text?.toLowerCase().includes("삭제") ||
|
||||
component.text?.toLowerCase().includes("delete") ||
|
||||
component.label?.toLowerCase().includes("삭제") ||
|
||||
component.label?.toLowerCase().includes("delete") ||
|
||||
deleteKeywords.some(
|
||||
(keyword) =>
|
||||
component.config?.buttonText?.toLowerCase().includes(keyword) ||
|
||||
component.config?.text?.toLowerCase().includes(keyword),
|
||||
)
|
||||
);
|
||||
};
|
||||
@@ -109,9 +110,9 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
if (isDeleteAction() && !component.style?.labelColor) {
|
||||
// 삭제 액션이고 라벨 색상이 설정되지 않은 경우 빨간색으로 자동 설정
|
||||
if (component.style) {
|
||||
component.style.labelColor = '#ef4444';
|
||||
component.style.labelColor = "#ef4444";
|
||||
} else {
|
||||
component.style = { labelColor: '#ef4444' };
|
||||
component.style = { labelColor: "#ef4444" };
|
||||
}
|
||||
}
|
||||
}, [component.componentConfig?.action?.type, component.config?.action?.type, component.webTypeConfig?.actionType]);
|
||||
@@ -125,20 +126,20 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
// 🎨 동적 색상 설정 (속성편집 모달의 "색상" 필드와 연동)
|
||||
const getLabelColor = () => {
|
||||
if (isDeleteAction()) {
|
||||
return component.style?.labelColor || '#ef4444'; // 빨간색 기본값 (Tailwind red-500)
|
||||
return component.style?.labelColor || "#ef4444"; // 빨간색 기본값 (Tailwind red-500)
|
||||
}
|
||||
return component.style?.labelColor || '#212121'; // 검은색 기본값 (shadcn/ui primary)
|
||||
return component.style?.labelColor || "#212121"; // 검은색 기본값 (shadcn/ui primary)
|
||||
};
|
||||
|
||||
const buttonColor = getLabelColor();
|
||||
|
||||
|
||||
// 그라데이션용 어두운 색상 계산
|
||||
const getDarkColor = (baseColor: string) => {
|
||||
const hex = baseColor.replace('#', '');
|
||||
const hex = baseColor.replace("#", "");
|
||||
const r = Math.max(0, parseInt(hex.substr(0, 2), 16) - 40);
|
||||
const g = Math.max(0, parseInt(hex.substr(2, 2), 16) - 40);
|
||||
const b = Math.max(0, parseInt(hex.substr(4, 2), 16) - 40);
|
||||
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
||||
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
||||
};
|
||||
|
||||
const buttonDarkColor = getDarkColor(buttonColor);
|
||||
@@ -246,6 +247,23 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
currentLoadingToastRef.current = undefined;
|
||||
}
|
||||
|
||||
// 실패한 경우 오류 처리
|
||||
if (!success) {
|
||||
console.log("❌ 액션 실패, 오류 토스트 표시");
|
||||
const errorMessage =
|
||||
actionConfig.errorMessage ||
|
||||
(actionConfig.type === "save"
|
||||
? "저장 중 오류가 발생했습니다."
|
||||
: actionConfig.type === "delete"
|
||||
? "삭제 중 오류가 발생했습니다."
|
||||
: actionConfig.type === "submit"
|
||||
? "제출 중 오류가 발생했습니다."
|
||||
: "처리 중 오류가 발생했습니다.");
|
||||
toast.error(errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// 성공한 경우에만 성공 토스트 표시
|
||||
// edit 액션은 조용히 처리 (모달 열기만 하므로 토스트 불필요)
|
||||
if (actionConfig.type !== "edit") {
|
||||
const successMessage =
|
||||
@@ -268,24 +286,24 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
|
||||
// 저장/수정 성공 시 자동 처리
|
||||
if (actionConfig.type === "save" || actionConfig.type === "edit") {
|
||||
if (typeof window !== 'undefined') {
|
||||
if (typeof window !== "undefined") {
|
||||
// 1. 테이블 새로고침 이벤트 먼저 발송 (모달이 닫히기 전에)
|
||||
console.log("🔄 저장/수정 후 테이블 새로고침 이벤트 발송");
|
||||
window.dispatchEvent(new CustomEvent('refreshTable'));
|
||||
|
||||
window.dispatchEvent(new CustomEvent("refreshTable"));
|
||||
|
||||
// 2. 모달 닫기 (약간의 딜레이)
|
||||
setTimeout(() => {
|
||||
// EditModal 내부인지 확인 (isInModal prop 사용)
|
||||
const isInEditModal = (props as any).isInModal;
|
||||
|
||||
|
||||
if (isInEditModal) {
|
||||
console.log("🚪 EditModal 닫기 이벤트 발송");
|
||||
window.dispatchEvent(new CustomEvent('closeEditModal'));
|
||||
window.dispatchEvent(new CustomEvent("closeEditModal"));
|
||||
}
|
||||
|
||||
|
||||
// ScreenModal은 항상 닫기
|
||||
console.log("🚪 ScreenModal 닫기 이벤트 발송");
|
||||
window.dispatchEvent(new CustomEvent('closeSaveModal'));
|
||||
window.dispatchEvent(new CustomEvent("closeSaveModal"));
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
@@ -301,19 +319,8 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
|
||||
console.error("❌ 버튼 액션 실행 오류:", error);
|
||||
|
||||
// 오류 토스트 표시
|
||||
const errorMessage =
|
||||
actionConfig.errorMessage ||
|
||||
(actionConfig.type === "save"
|
||||
? "저장 중 오류가 발생했습니다."
|
||||
: actionConfig.type === "delete"
|
||||
? "삭제 중 오류가 발생했습니다."
|
||||
: actionConfig.type === "submit"
|
||||
? "제출 중 오류가 발생했습니다."
|
||||
: "처리 중 오류가 발생했습니다.");
|
||||
|
||||
console.log("💥 오류 토스트 표시:", errorMessage);
|
||||
toast.error(errorMessage);
|
||||
// 오류 토스트는 buttonActions.ts에서 이미 표시되므로 여기서는 제거
|
||||
// (중복 토스트 방지)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -379,7 +386,7 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
console.log("⚠️ 액션 실행 조건 불만족:", {
|
||||
isInteractive,
|
||||
hasAction: !!processedConfig.action,
|
||||
"이유": !isInteractive ? "인터랙티브 모드 아님" : "액션 없음",
|
||||
이유: !isInteractive ? "인터랙티브 모드 아님" : "액션 없음",
|
||||
});
|
||||
// 액션이 설정되지 않은 경우 기본 onClick 실행
|
||||
onClick?.();
|
||||
@@ -479,7 +486,7 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
maxHeight: "100%",
|
||||
border: "none",
|
||||
borderRadius: "8px",
|
||||
background: componentConfig.disabled
|
||||
background: componentConfig.disabled
|
||||
? "linear-gradient(135deg, #e5e7eb 0%, #d1d5db 100%)"
|
||||
: `linear-gradient(135deg, ${buttonColor} 0%, ${buttonDarkColor} 100%)`,
|
||||
color: componentConfig.disabled ? "#9ca3af" : "white",
|
||||
@@ -495,9 +502,7 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
margin: "0",
|
||||
lineHeight: "1",
|
||||
minHeight: "36px",
|
||||
boxShadow: componentConfig.disabled
|
||||
? "0 1px 2px 0 rgba(0, 0, 0, 0.05)"
|
||||
: `0 2px 4px 0 ${buttonColor}33`, // 33은 20% 투명도
|
||||
boxShadow: componentConfig.disabled ? "0 1px 2px 0 rgba(0, 0, 0, 0.05)" : `0 2px 4px 0 ${buttonColor}33`, // 33은 20% 투명도
|
||||
// isInteractive 모드에서는 사용자 스타일 우선 적용
|
||||
...(isInteractive && component.style ? component.style : {}),
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user