Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into lhj
; Please enter a commit message to explain why this merge is necessary, ; especially if it merges an updated upstream into a topic branch. ; ; Lines starting with ';' will be ignored, and an empty message aborts ; the commit.
This commit is contained in:
@@ -13,6 +13,7 @@ import { GRID_CONFIG, snapToGrid, snapSizeToGrid, calculateCellSize } from "./gr
|
||||
import { Resolution, RESOLUTIONS, detectScreenResolution } from "./ResolutionSelector";
|
||||
import { DashboardProvider } from "@/contexts/DashboardContext";
|
||||
import { useMenu } from "@/contexts/MenuContext";
|
||||
import { useKeyboardShortcuts } from "./hooks/useKeyboardShortcuts";
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
import {
|
||||
AlertDialog,
|
||||
@@ -58,6 +59,9 @@ export default function DashboardDesigner({ dashboardId: initialDashboardId }: D
|
||||
const [successModalOpen, setSuccessModalOpen] = useState(false);
|
||||
const [clearConfirmOpen, setClearConfirmOpen] = useState(false);
|
||||
|
||||
// 클립보드 (복사/붙여넣기용)
|
||||
const [clipboard, setClipboard] = useState<DashboardElement | null>(null);
|
||||
|
||||
// 화면 해상도 자동 감지
|
||||
const [screenResolution] = useState<Resolution>(() => detectScreenResolution());
|
||||
const [resolution, setResolution] = useState<Resolution>(screenResolution);
|
||||
@@ -290,6 +294,51 @@ export default function DashboardDesigner({ dashboardId: initialDashboardId }: D
|
||||
[selectedElement],
|
||||
);
|
||||
|
||||
// 키보드 단축키 핸들러들
|
||||
const handleCopyElement = useCallback(() => {
|
||||
if (!selectedElement) return;
|
||||
const element = elements.find((el) => el.id === selectedElement);
|
||||
if (element) {
|
||||
setClipboard(element);
|
||||
}
|
||||
}, [selectedElement, elements]);
|
||||
|
||||
const handlePasteElement = useCallback(() => {
|
||||
if (!clipboard) return;
|
||||
|
||||
// 새 ID 생성
|
||||
const newId = `element-${elementCounter + 1}`;
|
||||
setElementCounter((prev) => prev + 1);
|
||||
|
||||
// 위치를 약간 오프셋 (오른쪽 아래로 20px씩)
|
||||
const newElement: DashboardElement = {
|
||||
...clipboard,
|
||||
id: newId,
|
||||
position: {
|
||||
x: clipboard.position.x + 20,
|
||||
y: clipboard.position.y + 20,
|
||||
},
|
||||
};
|
||||
|
||||
setElements((prev) => [...prev, newElement]);
|
||||
setSelectedElement(newId);
|
||||
}, [clipboard, elementCounter]);
|
||||
|
||||
const handleDeleteSelected = useCallback(() => {
|
||||
if (selectedElement) {
|
||||
removeElement(selectedElement);
|
||||
}
|
||||
}, [selectedElement, removeElement]);
|
||||
|
||||
// 키보드 단축키 활성화
|
||||
useKeyboardShortcuts({
|
||||
selectedElementId: selectedElement,
|
||||
onDelete: handleDeleteSelected,
|
||||
onCopy: handleCopyElement,
|
||||
onPaste: handlePasteElement,
|
||||
enabled: !saveModalOpen && !successModalOpen && !clearConfirmOpen,
|
||||
});
|
||||
|
||||
// 전체 삭제 확인 모달 열기
|
||||
const clearCanvas = useCallback(() => {
|
||||
setClearConfirmOpen(true);
|
||||
|
||||
Reference in New Issue
Block a user