12컬럼 그리드로 변경

This commit is contained in:
dohyeons
2025-10-22 16:37:14 +09:00
parent f1d74cfd0e
commit 9dca73f4c4
3 changed files with 157 additions and 66 deletions

View File

@@ -4,7 +4,7 @@ import React, { useState, useCallback, useRef, useEffect } from "react";
import dynamic from "next/dynamic";
import { DashboardElement, QueryResult, Position } from "./types";
import { ChartRenderer } from "./charts/ChartRenderer";
import { GRID_CONFIG } from "./gridUtils";
import { GRID_CONFIG, magneticSnap } from "./gridUtils";
// 위젯 동적 임포트
const WeatherWidget = dynamic(() => import("@/components/dashboard/widgets/WeatherWidget"), {
@@ -135,6 +135,8 @@ interface CanvasElementProps {
cellSize: number;
subGridSize: number;
canvasWidth?: number;
verticalGuidelines: number[];
horizontalGuidelines: number[];
onUpdate: (id: string, updates: Partial<DashboardElement>) => void;
onUpdateMultiple?: (updates: { id: string; updates: Partial<DashboardElement> }[]) => void; // 🔥 다중 업데이트
onMultiDragStart?: (draggedId: string, otherOffsets: Record<string, { x: number; y: number }>) => void;
@@ -159,6 +161,8 @@ export function CanvasElement({
cellSize,
subGridSize,
canvasWidth = 1560,
verticalGuidelines,
horizontalGuidelines,
onUpdate,
onUpdateMultiple,
onMultiDragStart,
@@ -315,15 +319,18 @@ export function CanvasElement({
const maxX = canvasWidth - element.size.width;
rawX = Math.min(rawX, maxX);
// 드래그 중 실시간 스냅 (서브그리드만 사용)
const snappedX = Math.round(rawX / subGridSize) * subGridSize;
const snappedY = Math.round(rawY / subGridSize) * subGridSize;
// 자석 스냅으로 변경
const snappedX = magneticSnap(rawX, verticalGuidelines);
const snappedY = magneticSnap(rawY, horizontalGuidelines);
setTempPosition({ x: snappedX, y: snappedY });
// 스냅 후 X 좌표 다시 체크
const finalSnappedX = Math.min(snappedX, maxX);
setTempPosition({ x: finalSnappedX, y: snappedY });
// 🔥 다중 드래그 중 - 다른 위젯들의 위치 업데이트
if (selectedElements.length > 1 && selectedElements.includes(element.id) && onMultiDragMove) {
onMultiDragMove(element, { x: snappedX, y: snappedY });
onMultiDragMove(element, { x: finalSnappedX, y: snappedY });
}
} else if (isResizing) {
const deltaX = e.clientX - resizeStart.x;
@@ -367,14 +374,20 @@ export function CanvasElement({
const maxWidth = canvasWidth - newX;
newWidth = Math.min(newWidth, maxWidth);
// 리사이즈 중 실시간 스냅 (서브그리드만 사용)
const snappedX = Math.round(newX / subGridSize) * subGridSize;
const snappedY = Math.round(newY / subGridSize) * subGridSize;
const snappedWidth = Math.round(newWidth / subGridSize) * subGridSize;
const snappedHeight = Math.round(newHeight / subGridSize) * subGridSize;
// 자석 스냅으로 변경
const snappedX = magneticSnap(newX, verticalGuidelines);
const snappedY = magneticSnap(newY, horizontalGuidelines);
// 크기는 12px 단위로 스냅
const snappedWidth = Math.round(newWidth / 12) * 12;
const snappedHeight = Math.round(newHeight / 12) * 12;
// 스냅 후 경계 체크
const finalSnappedX = Math.max(0, Math.min(snappedX, canvasWidth - snappedWidth));
const finalSnappedY = Math.max(0, snappedY);
// 임시 크기/위치 저장 (스냅됨)
setTempPosition({ x: Math.max(0, snappedX), y: Math.max(0, snappedY) });
setTempPosition({ x: finalSnappedX, y: finalSnappedY });
setTempSize({ width: snappedWidth, height: snappedHeight });
}
},
@@ -386,7 +399,8 @@ export function CanvasElement({
element,
canvasWidth,
cellSize,
subGridSize,
verticalGuidelines,
horizontalGuidelines,
selectedElements,
allElements,
onUpdateMultiple,
@@ -891,12 +905,7 @@ export function CanvasElement({
) : element.type === "widget" && element.subtype === "list" ? (
// 리스트 위젯 렌더링
<div className="h-full w-full">
<ListWidget
element={element}
onConfigUpdate={(newConfig) => {
onUpdate(element.id, { listConfig: newConfig as any });
}}
/>
<ListWidget element={element} />
</div>
) : element.type === "widget" && element.subtype === "yard-management-3d" ? (
// 야드 관리 3D 위젯 렌더링