feat: 탭 컨테이너로의 드롭 처리 기능 추가
- 드래그 종료 시 탭 컨테이너에 컴포넌트를 드롭할 수 있는 기능을 구현하였습니다. - 드래그된 컴포넌트를 탭 내부 컴포넌트로 변환하여 해당 탭에 추가하는 로직을 추가하였습니다. - 드래그 상태 초기화 및 성공적인 드롭 시 사용자에게 알림을 표시하도록 하였습니다.
This commit is contained in:
@@ -3568,8 +3568,104 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
||||
);
|
||||
|
||||
// 드래그 종료
|
||||
const endDrag = useCallback(() => {
|
||||
const endDrag = useCallback((mouseEvent?: MouseEvent) => {
|
||||
if (dragState.isDragging && dragState.draggedComponent) {
|
||||
// 🎯 탭 컨테이너로의 드롭 처리 (기존 컴포넌트 이동)
|
||||
if (mouseEvent) {
|
||||
const dropTarget = document.elementFromPoint(mouseEvent.clientX, mouseEvent.clientY) as HTMLElement;
|
||||
const tabsContainer = dropTarget?.closest('[data-tabs-container="true"]');
|
||||
|
||||
if (tabsContainer) {
|
||||
const containerId = tabsContainer.getAttribute("data-component-id");
|
||||
const activeTabId = tabsContainer.getAttribute("data-active-tab-id");
|
||||
|
||||
if (containerId && activeTabId) {
|
||||
const targetComponent = layout.components.find((c) => c.id === containerId);
|
||||
const compType = (targetComponent as any)?.componentType;
|
||||
|
||||
// 자기 자신을 자신에게 드롭하는 것 방지
|
||||
if (targetComponent &&
|
||||
(compType === "tabs-widget" || compType === "v2-tabs-widget") &&
|
||||
dragState.draggedComponent !== containerId) {
|
||||
|
||||
const draggedComponent = layout.components.find((c) => c.id === dragState.draggedComponent);
|
||||
if (draggedComponent) {
|
||||
const currentConfig = (targetComponent as any).componentConfig || {};
|
||||
const tabs = currentConfig.tabs || [];
|
||||
|
||||
// 탭 컨텐츠 영역 기준 드롭 위치 계산
|
||||
const tabContentRect = tabsContainer.getBoundingClientRect();
|
||||
const dropX = (mouseEvent.clientX - tabContentRect.left) / zoomLevel;
|
||||
const dropY = (mouseEvent.clientY - tabContentRect.top) / zoomLevel;
|
||||
|
||||
// 기존 컴포넌트를 탭 내부 컴포넌트로 변환
|
||||
const newTabComponent = {
|
||||
id: `tab_comp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
||||
componentType: (draggedComponent as any).componentType || draggedComponent.type,
|
||||
label: (draggedComponent as any).label || "컴포넌트",
|
||||
position: { x: Math.max(0, dropX), y: Math.max(0, dropY) },
|
||||
size: draggedComponent.size || { width: 200, height: 100 },
|
||||
componentConfig: (draggedComponent as any).componentConfig || {},
|
||||
style: (draggedComponent as any).style || {},
|
||||
};
|
||||
|
||||
// 해당 탭에 컴포넌트 추가
|
||||
const updatedTabs = tabs.map((tab: any) => {
|
||||
if (tab.id === activeTabId) {
|
||||
return {
|
||||
...tab,
|
||||
components: [...(tab.components || []), newTabComponent],
|
||||
};
|
||||
}
|
||||
return tab;
|
||||
});
|
||||
|
||||
// 탭 컴포넌트 업데이트 + 원래 컴포넌트 캔버스에서 제거
|
||||
const newLayout = {
|
||||
...layout,
|
||||
components: layout.components
|
||||
.filter((c) => c.id !== dragState.draggedComponent) // 캔버스에서 제거
|
||||
.map((c) => {
|
||||
if (c.id === containerId) {
|
||||
return {
|
||||
...c,
|
||||
componentConfig: {
|
||||
...currentConfig,
|
||||
tabs: updatedTabs,
|
||||
},
|
||||
};
|
||||
}
|
||||
return c;
|
||||
}),
|
||||
};
|
||||
|
||||
setLayout(newLayout);
|
||||
saveToHistory(newLayout);
|
||||
setSelectedComponent(null);
|
||||
toast.success("컴포넌트가 탭으로 이동되었습니다");
|
||||
|
||||
// 드래그 상태 초기화 후 종료
|
||||
setDragState({
|
||||
isDragging: false,
|
||||
draggedComponent: null,
|
||||
draggedComponents: [],
|
||||
originalPosition: { x: 0, y: 0, z: 1 },
|
||||
currentPosition: { x: 0, y: 0, z: 1 },
|
||||
grabOffset: { x: 0, y: 0 },
|
||||
justFinishedDrag: true,
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
setDragState((prev) => ({ ...prev, justFinishedDrag: false }));
|
||||
}, 100);
|
||||
|
||||
return; // 탭으로 이동 완료, 일반 드래그 종료 로직 스킵
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 주 드래그 컴포넌트의 최종 위치 계산
|
||||
const draggedComponent = layout.components.find((c) => c.id === dragState.draggedComponent);
|
||||
let finalPosition = dragState.currentPosition;
|
||||
@@ -4445,12 +4541,12 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
const handleMouseUp = (e: MouseEvent) => {
|
||||
if (dragState.isDragging) {
|
||||
if (animationFrameId) {
|
||||
cancelAnimationFrame(animationFrameId);
|
||||
}
|
||||
endDrag();
|
||||
endDrag(e);
|
||||
} else if (selectionDrag.isSelecting) {
|
||||
endSelectionDrag();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user