feat: 수정 버튼 액션에 제목과 설명 설정 기능 추가

추가된 기능:
1. ButtonConfigPanel - 수정 모달 제목/설명 입력 필드 추가 
2. EditModal - 제목/설명 props 추가 및 조건부 헤더 렌더링 
3. DataTableConfigPanel - 수정 모달 설정 섹션 추가 
4. InteractiveDataTable - editModalConfig에서 제목/설명 읽기 
5. screen/[screenId]/page - 제목/설명 전달 추가 
6. 타입 정의 - editModalConfig 추가 

변경된 파일:
- frontend/components/screen/config-panels/ButtonConfigPanel.tsx
- frontend/components/screen/EditModal.tsx
- frontend/components/screen/InteractiveDataTable.tsx
- frontend/components/screen/panels/DataTableConfigPanel.tsx
- frontend/app/(main)/screens/[screenId]/page.tsx
- frontend/types/screen-legacy-backup.ts

결과:
-  수정 버튼에서 모달 제목과 설명을 설정할 수 있음
-  데이터테이블에서도 수정 모달 설정 가능
-  제목과 설명이 모달 헤더에 표시됨
-  설정하지 않으면 기본 동작 유지
This commit is contained in:
kjs 2025-10-01 17:41:30 +09:00
parent b452f148a9
commit 114928ca4f
6 changed files with 147 additions and 29 deletions

View File

@ -41,6 +41,8 @@ export default function ScreenViewPage() {
modalSize?: "sm" | "md" | "lg" | "xl" | "full";
editData?: any;
onSave?: () => void;
modalTitle?: string;
modalDescription?: string;
}>({});
useEffect(() => {
@ -67,6 +69,8 @@ export default function ScreenViewPage() {
modalSize: event.detail.modalSize,
editData: event.detail.editData,
onSave: event.detail.onSave,
modalTitle: event.detail.modalTitle,
modalDescription: event.detail.modalDescription,
});
setEditModalOpen(true);
};
@ -408,6 +412,8 @@ export default function ScreenViewPage() {
modalSize={editModalConfig.modalSize}
editData={editModalConfig.editData}
onSave={editModalConfig.onSave}
modalTitle={editModalConfig.modalTitle}
modalDescription={editModalConfig.modalDescription}
onDataChange={(changedFormData) => {
console.log("📝 EditModal에서 데이터 변경 수신:", changedFormData);
// 변경된 데이터를 메인 폼에 반영

View File

@ -18,6 +18,8 @@ interface EditModalProps {
editData?: any;
onSave?: () => void;
onDataChange?: (formData: Record<string, any>) => void; // 폼 데이터 변경 콜백 추가
modalTitle?: string; // 모달 제목
modalDescription?: string; // 모달 설명
}
/**
@ -32,6 +34,8 @@ export const EditModal: React.FC<EditModalProps> = ({
editData,
onSave,
onDataChange,
modalTitle,
modalDescription,
}) => {
const [loading, setLoading] = useState(false);
const [formData, setFormData] = useState<any>({});
@ -247,9 +251,20 @@ export const EditModal: React.FC<EditModalProps> = ({
}}
data-radix-portal="true"
>
<DialogHeader className="sr-only">
<DialogTitle></DialogTitle>
</DialogHeader>
{/* 모달 헤더 (제목/설명이 있으면 표시) */}
{(modalTitle || modalDescription) && (
<DialogHeader className="border-b bg-gray-50 px-6 py-4">
<DialogTitle className="text-lg font-semibold">{modalTitle || "수정"}</DialogTitle>
{modalDescription && <p className="mt-1 text-sm text-gray-600">{modalDescription}</p>}
</DialogHeader>
)}
{/* 제목/설명이 없으면 접근성을 위한 숨김 헤더만 표시 */}
{!modalTitle && !modalDescription && (
<DialogHeader className="sr-only">
<DialogTitle></DialogTitle>
</DialogHeader>
)}
<div className="flex-1 overflow-hidden">
{loading ? (

View File

@ -744,8 +744,15 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
setEditFormData(initialData);
setEditingRowData(selectedRowData);
// 수정 모달 설정에서 제목과 설명 가져오기
const editModalTitle = component.editModalConfig?.title || "";
const editModalDescription = component.editModalConfig?.description || "";
console.log("📝 수정 모달 설정:", { editModalTitle, editModalDescription });
setShowEditModal(true);
}, [selectedRows, data, getDisplayColumns]);
}, [selectedRows, data, getDisplayColumns, component.editModalConfig]);
// 수정 폼 데이터 변경 핸들러
const handleEditFormChange = useCallback((columnName: string, value: any) => {

View File

@ -395,29 +395,63 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
</div>
{config.action?.editMode === "modal" && (
<div>
<Label htmlFor="edit-modal-size"> </Label>
<Select
value={config.action?.modalSize || "lg"}
onValueChange={(value) =>
onUpdateProperty("componentConfig.action", {
...config.action,
modalSize: value,
})
}
>
<SelectTrigger>
<SelectValue placeholder="모달 크기 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="sm"> (Small)</SelectItem>
<SelectItem value="md"> (Medium)</SelectItem>
<SelectItem value="lg"> (Large)</SelectItem>
<SelectItem value="xl"> (Extra Large)</SelectItem>
<SelectItem value="full"> (Full)</SelectItem>
</SelectContent>
</Select>
</div>
<>
<div>
<Label htmlFor="edit-modal-title"> </Label>
<Input
id="edit-modal-title"
placeholder="모달 제목을 입력하세요 (예: 데이터 수정)"
value={config.action?.editModalTitle || ""}
onChange={(e) =>
onUpdateProperty("componentConfig.action", {
...config.action,
editModalTitle: e.target.value,
})
}
/>
<p className="mt-1 text-xs text-gray-500"> </p>
</div>
<div>
<Label htmlFor="edit-modal-description"> </Label>
<Input
id="edit-modal-description"
placeholder="모달 설명을 입력하세요 (예: 선택한 데이터를 수정합니다)"
value={config.action?.editModalDescription || ""}
onChange={(e) =>
onUpdateProperty("componentConfig.action", {
...config.action,
editModalDescription: e.target.value,
})
}
/>
<p className="mt-1 text-xs text-gray-500"> </p>
</div>
<div>
<Label htmlFor="edit-modal-size"> </Label>
<Select
value={config.action?.modalSize || "lg"}
onValueChange={(value) =>
onUpdateProperty("componentConfig.action", {
...config.action,
modalSize: value,
})
}
>
<SelectTrigger>
<SelectValue placeholder="모달 크기 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="sm"> (Small)</SelectItem>
<SelectItem value="md"> (Medium)</SelectItem>
<SelectItem value="lg"> (Large)</SelectItem>
<SelectItem value="xl"> (Extra Large)</SelectItem>
<SelectItem value="full"> (Full)</SelectItem>
</SelectContent>
</Select>
</div>
</>
)}
</div>
)}

View File

@ -52,7 +52,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
addButtonText: component.addButtonText || "추가",
editButtonText: component.editButtonText || "수정",
deleteButtonText: component.deleteButtonText || "삭제",
// 모달 설정
// 추가 모달 설정
modalTitle: component.addModalConfig?.title || "새 데이터 추가",
// 테이블명도 로컬 상태로 관리
tableName: component.tableName || "",
@ -62,6 +62,9 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
modalGridColumns: component.addModalConfig?.gridColumns || 2,
modalSubmitButtonText: component.addModalConfig?.submitButtonText || "추가",
modalCancelButtonText: component.addModalConfig?.cancelButtonText || "취소",
// 수정 모달 설정
editModalTitle: component.editModalConfig?.title || "",
editModalDescription: component.editModalConfig?.description || "",
paginationEnabled: component.pagination?.enabled ?? true,
showPageSizeSelector: component.pagination?.showPageSizeSelector ?? true,
showPageInfo: component.pagination?.showPageInfo ?? true,
@ -161,7 +164,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
addButtonText: component.addButtonText || "추가",
editButtonText: component.editButtonText || "수정",
deleteButtonText: component.deleteButtonText || "삭제",
// 모달 설정
// 추가 모달 설정
modalTitle: component.addModalConfig?.title || "새 데이터 추가",
modalDescription: component.addModalConfig?.description || "",
modalWidth: component.addModalConfig?.width || "lg",
@ -169,6 +172,9 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
modalGridColumns: component.addModalConfig?.gridColumns || 2,
modalSubmitButtonText: component.addModalConfig?.submitButtonText || "추가",
modalCancelButtonText: component.addModalConfig?.cancelButtonText || "취소",
// 수정 모달 설정
editModalTitle: component.editModalConfig?.title || "",
editModalDescription: component.editModalConfig?.description || "",
paginationEnabled: component.pagination?.enabled ?? true,
showPageSizeSelector: component.pagination?.showPageSizeSelector ?? true,
showPageInfo: component.pagination?.showPageInfo ?? true,
@ -1379,6 +1385,55 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
</div>
)}
{/* 수정 모달 설정 */}
{localValues.enableEdit && (
<div className="rounded-lg border border-gray-200 bg-gray-50 p-4">
<h4 className="mb-3 text-sm font-medium text-gray-900"> </h4>
<div className="space-y-3">
<div className="space-y-2">
<Label htmlFor="edit-modal-title" className="text-sm">
</Label>
<Input
id="edit-modal-title"
value={localValues.editModalTitle}
onChange={(e) => {
const newValue = e.target.value;
setLocalValues((prev) => ({ ...prev, editModalTitle: newValue }));
onUpdateComponent({
editModalConfig: { ...component.editModalConfig, title: newValue },
});
}}
placeholder="데이터 수정"
className="h-8 text-sm"
/>
<p className="text-xs text-gray-500"> </p>
</div>
<div className="space-y-2">
<Label htmlFor="edit-modal-description" className="text-sm">
</Label>
<Input
id="edit-modal-description"
value={localValues.editModalDescription}
onChange={(e) => {
const newValue = e.target.value;
setLocalValues((prev) => ({ ...prev, editModalDescription: newValue }));
onUpdateComponent({
editModalConfig: { ...component.editModalConfig, description: newValue },
});
}}
placeholder="선택한 데이터를 수정합니다"
className="h-8 text-sm"
/>
<p className="text-xs text-gray-500"> </p>
</div>
</div>
</div>
)}
<div className="space-y-2">
<Label htmlFor="grid-columns"> </Label>
<select

View File

@ -531,6 +531,7 @@ export interface DataTableComponent extends BaseComponent {
editButtonText: string; // 수정 버튼 텍스트
deleteButtonText: string; // 삭제 버튼 텍스트
addModalConfig: DataTableAddModalConfig; // 추가 모달 커스터마이징 설정
editModalConfig?: { title?: string; description?: string }; // 수정 모달 설정
gridColumns: number; // 테이블이 차지할 그리드 컬럼 수
}