12컬럼 그리드로 변경
This commit is contained in:
@@ -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 위젯 렌더링
|
||||
|
||||
Reference in New Issue
Block a user