리사이징, 체크박스,엔터치면 다음 칸으로 이동, 표수정, 컬럼에서 이미지 넣는거 등등

This commit is contained in:
leeheejin
2025-11-06 12:11:49 +09:00
parent 0b676098a5
commit 0839f7f603
38 changed files with 1285 additions and 260 deletions
+79 -16
View File
@@ -1,6 +1,6 @@
"use client";
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useMemo } from "react";
import {
ResizableDialog,
ResizableDialogContent,
@@ -12,6 +12,7 @@ import { InteractiveScreenViewerDynamic } from "@/components/screen/InteractiveS
import { screenApi } from "@/lib/api/screen";
import { ComponentData } from "@/types/screen";
import { toast } from "sonner";
import { useAuth } from "@/hooks/useAuth";
interface ScreenModalState {
isOpen: boolean;
@@ -26,6 +27,8 @@ interface ScreenModalProps {
}
export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
const { userId } = useAuth();
const [modalState, setModalState] = useState<ScreenModalState>({
isOpen: false,
screenId: null,
@@ -218,28 +221,88 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
};
const modalStyle = getModalStyle();
// 안정적인 modalId를 상태로 저장 (모달이 닫혀도 유지)
const [persistedModalId, setPersistedModalId] = useState<string | undefined>(undefined);
// modalId 생성 및 업데이트
useEffect(() => {
// 모달이 열려있고 screenId가 있을 때만 업데이트
if (!modalState.isOpen) return;
let newModalId: string | undefined;
// 1순위: screenId (가장 안정적)
if (modalState.screenId) {
newModalId = `screen-modal-${modalState.screenId}`;
console.log("🔑 ScreenModal modalId 생성:", {
method: "screenId",
screenId: modalState.screenId,
result: newModalId,
});
}
// 2순위: 테이블명
else if (screenData?.screenInfo?.tableName) {
newModalId = `screen-modal-table-${screenData.screenInfo.tableName}`;
console.log("🔑 ScreenModal modalId 생성:", {
method: "tableName",
tableName: screenData.screenInfo.tableName,
result: newModalId,
});
}
// 3순위: 화면명
else if (screenData?.screenInfo?.screenName) {
newModalId = `screen-modal-name-${screenData.screenInfo.screenName}`;
console.log("🔑 ScreenModal modalId 생성:", {
method: "screenName",
screenName: screenData.screenInfo.screenName,
result: newModalId,
});
}
// 4순위: 제목
else if (modalState.title) {
const titleId = modalState.title.replace(/\s+/g, '-');
newModalId = `screen-modal-title-${titleId}`;
console.log("🔑 ScreenModal modalId 생성:", {
method: "title",
title: modalState.title,
result: newModalId,
});
}
if (newModalId) {
setPersistedModalId(newModalId);
}
}, [modalState.isOpen, modalState.screenId, modalState.title, screenData?.screenInfo?.tableName, screenData?.screenInfo?.screenName]);
return (
<ResizableDialog open={modalState.isOpen} onOpenChange={handleClose}>
<ResizableDialogContent
className={`${modalStyle.className} ${className || ""}`}
<ResizableDialogContent
className={`${modalStyle.className} ${className || ""}`}
style={modalStyle.style}
defaultWidth={800}
defaultHeight={600}
minWidth={600}
defaultWidth={600}
defaultHeight={800}
minWidth={500}
minHeight={400}
maxWidth={1400}
maxHeight={1000}
modalId={`screen-modal-${modalState.screenId}`}
maxWidth={1600}
maxHeight={1200}
modalId={persistedModalId}
userId={userId || "guest"}
>
<ResizableDialogHeader className="shrink-0 border-b px-4 py-3">
<ResizableDialogTitle className="text-base">{modalState.title}</ResizableDialogTitle>
{modalState.description && !loading && (
<ResizableDialogDescription className="text-muted-foreground text-xs">{modalState.description}</ResizableDialogDescription>
)}
{loading && (
<ResizableDialogDescription className="text-xs">{loading ? "화면을 불러오는 중입니다..." : ""}</ResizableDialogDescription>
)}
<div className="flex items-center gap-2">
<ResizableDialogTitle className="text-base">{modalState.title}</ResizableDialogTitle>
{modalState.description && !loading && (
<ResizableDialogDescription className="text-muted-foreground text-xs">
{modalState.description}
</ResizableDialogDescription>
)}
{loading && (
<ResizableDialogDescription className="text-xs">
{loading ? "화면을 불러오는 중입니다..." : ""}
</ResizableDialogDescription>
)}
</div>
</ResizableDialogHeader>
<div className="flex flex-1 items-center justify-center overflow-auto">