feat: 화면 디자이너 모달 및 제어 관리 탭 기능 추가

- 화면 설정 모달에 "제어 관리" 탭 추가하여 버튼 제어 설정을 간편하게 관리
- 버튼 액션 설정 기능 구현: 버튼 목록 표시 및 각 버튼의 액션 타입 수정 가능
- 화면 디자이너 모달 통합: 전체화면 Dialog 내부에 ScreenDesigner 임베드
- URL 쿼리 파라미터로 화면 디자이너 자동 열기 기능 추가
- 화면 캔버스 크기 자동 조절 기능 구현: 최소 크기 보장 및 여유 마진 추가
- 필드 추가/제거 기능 개선: 기존 그리드 컬럼 변경 로직과 통합하여 사용자 경험 향상
This commit is contained in:
DDD1542
2026-01-14 14:35:27 +09:00
parent 905a9f62c3
commit f321aaf7aa
12 changed files with 3022 additions and 1124 deletions

View File

@@ -495,15 +495,50 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
...component.componentConfig, // 🔥 화면 디자이너에서 저장된 action 등 포함
} as ButtonPrimaryConfig;
// 🎨 동적 색상 설정 (속성편집 모달의 "색상" 필드와 연동)
const getLabelColor = () => {
if (isDeleteAction()) {
return component.style?.labelColor || "#ef4444"; // 빨간색 기본값 (Tailwind red-500)
// 🎨 동적 색상 설정 (webTypeConfig 우선, 레거시 style.labelColor 지원)
const getButtonBackgroundColor = () => {
// 1순위: webTypeConfig.backgroundColor (화면설정 모달에서 저장)
if (component.webTypeConfig?.backgroundColor) {
return component.webTypeConfig.backgroundColor;
}
return component.style?.labelColor || "#212121"; // 검은색 기본값 (shadcn/ui primary)
// 2순위: componentConfig.backgroundColor
if (componentConfig.backgroundColor) {
return componentConfig.backgroundColor;
}
// 3순위: style.backgroundColor
if (component.style?.backgroundColor) {
return component.style.backgroundColor;
}
// 4순위: style.labelColor (레거시)
if (component.style?.labelColor) {
return component.style.labelColor;
}
// 기본값: 삭제 버튼이면 빨강, 아니면 파랑
if (isDeleteAction()) {
return "#ef4444"; // 빨간색 (Tailwind red-500)
}
return "#3b82f6"; // 파란색 (Tailwind blue-500)
};
const buttonColor = getLabelColor();
const getButtonTextColor = () => {
// 1순위: webTypeConfig.textColor (화면설정 모달에서 저장)
if (component.webTypeConfig?.textColor) {
return component.webTypeConfig.textColor;
}
// 2순위: componentConfig.textColor
if (componentConfig.textColor) {
return componentConfig.textColor;
}
// 3순위: style.color
if (component.style?.color) {
return component.style.color;
}
// 기본값: 흰색
return "#ffffff";
};
const buttonColor = getButtonBackgroundColor();
const buttonTextColor = getButtonTextColor();
// 액션 설정 처리 - DB에서 문자열로 저장된 액션을 객체로 변환
const processedConfig = { ...componentConfig };
@@ -1115,7 +1150,7 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
} : undefined,
} as ButtonActionContext;
// 확인이 필요한 액션인지 확인
// 확인이 필요한 액션인지 확인 (save/delete만 확인 다이얼로그 표시)
if (confirmationRequiredActions.includes(processedConfig.action.type)) {
// 확인 다이얼로그 표시
setPendingAction({
@@ -1251,8 +1286,8 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
minHeight: "40px",
border: "none",
borderRadius: "0.5rem",
backgroundColor: finalDisabled ? "#e5e7eb" : buttonColor, // 🔧 background → backgroundColor로 변경
color: finalDisabled ? "#9ca3af" : "white",
backgroundColor: finalDisabled ? "#e5e7eb" : buttonColor,
color: finalDisabled ? "#9ca3af" : buttonTextColor, // 🔧 webTypeConfig.textColor 지원
// 🔧 크기 설정 적용 (sm/md/lg)
fontSize: componentConfig.size === "sm" ? "0.75rem" : componentConfig.size === "lg" ? "1rem" : "0.875rem",
fontWeight: "600",