mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
fix
This commit is contained in:
parent
768cca40ac
commit
9a0430a94a
9 changed files with 176 additions and 226 deletions
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
|
|
@ -8,8 +8,11 @@
|
|||
"typescript",
|
||||
"typescriptreact"
|
||||
],
|
||||
"eslint.format.enable": false,
|
||||
"editor.formatOnSave": false,
|
||||
"eslint.format.enable": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": [
|
||||
|
|
|
|||
|
|
@ -4,19 +4,14 @@ import cx from 'classnames';
|
|||
import WidgetWrapper from './WidgetWrapper';
|
||||
import useStore from '@/AppBuilder/_stores/store';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
import { useDrop, useDragLayer } from 'react-dnd';
|
||||
import { useDrop, useDragLayer, useDragDropManager } from 'react-dnd';
|
||||
import {
|
||||
addChildrenWidgetsToParent,
|
||||
addNewWidgetToTheEditor,
|
||||
computeViewerBackgroundColor,
|
||||
getSubContainerWidthAfterPadding,
|
||||
} from './appCanvasUtils';
|
||||
import {
|
||||
CANVAS_WIDTHS,
|
||||
NO_OF_GRIDS,
|
||||
WIDGETS_WITH_DEFAULT_CHILDREN,
|
||||
GRID_HEIGHT,
|
||||
} from './appCanvasConstants';
|
||||
import { CANVAS_WIDTHS, NO_OF_GRIDS, WIDGETS_WITH_DEFAULT_CHILDREN, GRID_HEIGHT } from './appCanvasConstants';
|
||||
import { useGridStore } from '@/_stores/gridStore';
|
||||
import NoComponentCanvasContainer from './NoComponentCanvasContainer';
|
||||
import { RIGHT_SIDE_BAR_TAB } from '../RightSideBar/rightSidebarConstants';
|
||||
|
|
@ -27,6 +22,7 @@ import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
|
|||
import useSortedComponents from '../_hooks/useSortedComponents';
|
||||
import { noop } from 'lodash';
|
||||
import { useGhostMoveable } from '@/AppBuilder/_hooks/useGhostMoveable';
|
||||
import { useCanvasDropHandler } from './useCanvasDropHandler';
|
||||
|
||||
//TODO: Revisit the logic of height (dropRef)
|
||||
|
||||
|
|
@ -70,7 +66,7 @@ export const Container = React.memo(
|
|||
const setFocusedParentId = useStore((state) => state.setFocusedParentId, shallow);
|
||||
const setShowModuleBorder = useStore((state) => state.setShowModuleBorder, shallow) || noop;
|
||||
|
||||
// Initialize ghost moveable hook (only for main canvas)
|
||||
// Initialize ghost moveable hook
|
||||
const { activateGhost, deactivateGhost } = useGhostMoveable(id);
|
||||
|
||||
// Monitor drag layer to update ghost position continuously
|
||||
|
|
@ -78,14 +74,12 @@ export const Container = React.memo(
|
|||
isDragging: monitor.isDragging(),
|
||||
}));
|
||||
|
||||
// // Cleanup ghost when drag ends
|
||||
// useEffect(() => {
|
||||
// if (!isDragging) {
|
||||
// setTimeout(() => {
|
||||
// deactivateGhost();
|
||||
// }, 1000);
|
||||
// }
|
||||
// }, [id, isDragging, deactivateGhost]);
|
||||
// // // Cleanup ghost when drag ends
|
||||
useEffect(() => {
|
||||
if (!isDragging) {
|
||||
deactivateGhost();
|
||||
}
|
||||
}, [id, isDragging, deactivateGhost]);
|
||||
|
||||
const isContainerReadOnly = useMemo(() => {
|
||||
return (index !== 0 && (componentType === 'Listview' || componentType === 'Kanban')) || currentMode === 'view';
|
||||
|
|
@ -93,29 +87,29 @@ export const Container = React.memo(
|
|||
|
||||
const setCurrentDragCanvasId = useGridStore((state) => state.actions.setCurrentDragCanvasId);
|
||||
|
||||
// Get the drop handler from the new hook
|
||||
const handleDrop = useCanvasDropHandler({
|
||||
appType,
|
||||
});
|
||||
|
||||
const [{ isOverCurrent }, drop] = useDrop({
|
||||
accept: 'box',
|
||||
hover: (item, monitor) => {
|
||||
// Use mouse position to determine the most specific container
|
||||
hover: (item, monitor) => {
|
||||
const clientOffset = monitor.getClientOffset();
|
||||
|
||||
// If no client offset, the drag might be ending - clean up ghost
|
||||
// if (!clientOffset) {
|
||||
// deactivateGhost();
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
const appCanvasWidth = realCanvasRef?.current?.offsetWidth || 0;
|
||||
|
||||
if (clientOffset) {
|
||||
const elementAtPoint = document.elementFromPoint(clientOffset.x, clientOffset.y);
|
||||
const closestCanvas = elementAtPoint?.closest('.real-canvas');
|
||||
const canvasId = closestCanvas?.getAttribute('data-parentId') ||
|
||||
closestCanvas?.id?.replace('canvas-', '') ||
|
||||
(closestCanvas?.id === 'real-canvas' ? 'canvas' : null);
|
||||
|
||||
const canvasId =
|
||||
closestCanvas?.getAttribute('data-parentId') ||
|
||||
closestCanvas?.id?.replace('canvas-', '') ||
|
||||
(closestCanvas?.id === 'real-canvas' ? 'canvas' : null);
|
||||
|
||||
// Only update if this container is the most specific one under the mouse
|
||||
if (canvasId === id) {
|
||||
// console.log('Container hover', canvasId, id);
|
||||
setCurrentDragCanvasId(id);
|
||||
}
|
||||
}
|
||||
|
|
@ -123,73 +117,17 @@ export const Container = React.memo(
|
|||
let width = (appCanvasWidth * item.component?.defaultSize?.width) / NO_OF_GRIDS;
|
||||
const componentSize = {
|
||||
width: width,
|
||||
height: item.component?.defaultSize?.height
|
||||
height: item.component?.defaultSize?.height,
|
||||
};
|
||||
|
||||
// const clientOffset = monitor.getClientOffset();
|
||||
if (clientOffset) {
|
||||
if (clientOffset && id === 'canvas') {
|
||||
activateGhost(componentSize, clientOffset, realCanvasRef);
|
||||
}
|
||||
},
|
||||
drop: async ({ componentType, component }, monitor) => {
|
||||
console.log('drop');
|
||||
// Reset canvas ID when dropping
|
||||
setCurrentDragCanvasId(null);
|
||||
|
||||
// Ensure ghost is deactivated before processing drop
|
||||
deactivateGhost();
|
||||
|
||||
// Add a small delay to allow moveable to properly clean up
|
||||
// await new Promise(resolve => setTimeout(resolve, 10));
|
||||
|
||||
// Deactivate ghost when dropping
|
||||
setShowModuleBorder(false); // Hide the module border when dropping
|
||||
if (currentMode === 'view' || (appType === 'module' && componentType !== 'ModuleContainer')) return;
|
||||
const didDrop = monitor.didDrop();
|
||||
if (didDrop) return;
|
||||
if (componentType === 'PDF' && !isPDFSupported()) {
|
||||
toast.error(
|
||||
'PDF is not supported in this version of browser. We recommend upgrading to the latest version for full support.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// IMPORTANT: This logic needs to be changed when we implement the module versioning
|
||||
const moduleInfo = component?.moduleId
|
||||
? {
|
||||
moduleId: component.moduleId,
|
||||
versionId: component.versionId,
|
||||
environmentId: component.environmentId,
|
||||
moduleName: component.displayName,
|
||||
moduleContainer: component.moduleContainer,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
if (WIDGETS_WITH_DEFAULT_CHILDREN.includes(componentType)) {
|
||||
const parentComponent = addNewWidgetToTheEditor(
|
||||
componentType,
|
||||
monitor,
|
||||
currentLayout,
|
||||
realCanvasRef,
|
||||
id,
|
||||
moduleInfo
|
||||
);
|
||||
const childComponents = addChildrenWidgetsToParent(componentType, parentComponent?.id, currentLayout);
|
||||
const newComponents = [parentComponent, ...childComponents];
|
||||
await addComponentToCurrentPage(newComponents);
|
||||
setActiveRightSideBarTab(RIGHT_SIDE_BAR_TAB.CONFIGURATION);
|
||||
} else {
|
||||
const newComponent = addNewWidgetToTheEditor(
|
||||
componentType,
|
||||
monitor,
|
||||
currentLayout,
|
||||
realCanvasRef,
|
||||
id,
|
||||
moduleInfo
|
||||
);
|
||||
await addComponentToCurrentPage([newComponent]);
|
||||
setActiveRightSideBarTab(RIGHT_SIDE_BAR_TAB.CONFIGURATION);
|
||||
}
|
||||
drop: (item, monitor) => {
|
||||
console.log('Container drop', item, monitor.getClientOffset());
|
||||
handleDrop(item, monitor, id);
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isOverCurrent: monitor.isOver({ shallow: true }),
|
||||
|
|
|
|||
|
|
@ -86,12 +86,17 @@ export default function Grid({ gridWidth, currentLayout }) {
|
|||
const getExposedValueOfComponent = useStore((state) => state.getExposedValueOfComponent, shallow);
|
||||
const setReorderContainerChildren = useStore((state) => state.setReorderContainerChildren, shallow);
|
||||
const currentDragCanvasId = useGridStore((state) => state.currentDragCanvasId, shallow);
|
||||
|
||||
const snapContainer = useMemo(() => {
|
||||
if (currentDragCanvasId) {
|
||||
return `#canvas-${currentDragCanvasId}`;
|
||||
}
|
||||
if (dragParentId) {
|
||||
return `#canvas-${dragParentId}`;
|
||||
}
|
||||
return '#real-canvas';
|
||||
}, [currentDragCanvasId]);
|
||||
}, [currentDragCanvasId, dragParentId]);
|
||||
|
||||
const moveableTarget = useMemo(() => {
|
||||
if (virtualTarget) {
|
||||
return '#moveable-ghost-element';
|
||||
|
|
@ -109,57 +114,6 @@ export default function Grid({ gridWidth, currentLayout }) {
|
|||
};
|
||||
}, []);
|
||||
|
||||
// useEffect(() => {
|
||||
// const selectedSet = new Set(selectedComponents);
|
||||
// const draggingOrResizingId = draggingComponentId || resizingComponentId;
|
||||
// const isGrouped = findHighestLevelofSelection().length > 1;
|
||||
// const firstSelectedParent =
|
||||
// selectedComponents.length > 0 ? boxList.find((b) => b.id === selectedComponents[0])?.parent : null;
|
||||
// const selectedParent = dragParentId || firstSelectedParent;
|
||||
|
||||
// const guidelines = boxList
|
||||
// .filter((box) => {
|
||||
// const isVisible =
|
||||
// getResolvedValue(box?.component?.definition?.properties?.visibility?.value) ||
|
||||
// getResolvedValue(box?.component?.definition?.styles?.visibility?.value);
|
||||
|
||||
// // Early return for non-visible elements
|
||||
// if (!isVisible) return false;
|
||||
|
||||
// // if (virtualTarget) {
|
||||
// // return true;
|
||||
// // }
|
||||
|
||||
// if (isGrouped) {
|
||||
// // If component is selected, don't show its guidelines
|
||||
// if (selectedSet.has(box.id)) return false;
|
||||
// return selectedParent ? box.parent === selectedParent : !box.parent;
|
||||
// }
|
||||
|
||||
// if (draggingOrResizingId) {
|
||||
// if (box.id === draggingOrResizingId) return false;
|
||||
// return dragParentId ? box.parent === dragParentId : !box.parent;
|
||||
// }
|
||||
|
||||
// // if (virtualTarget) {
|
||||
// // return true;
|
||||
// // }
|
||||
|
||||
// return true;
|
||||
// })
|
||||
// .map((box) => `.ele-${box.id}`);
|
||||
|
||||
// // Combine static guidelines with dynamic ones (for ghost elements)
|
||||
// setElementGuidelines(guidelines);
|
||||
// }, [
|
||||
// boxList,
|
||||
// dragParentId,
|
||||
// draggingComponentId,
|
||||
// resizingComponentId,
|
||||
// selectedComponents,
|
||||
// getResolvedValue,
|
||||
// ]);
|
||||
|
||||
useEffect(() => {
|
||||
setBoxList(
|
||||
Object.keys(currentPageComponents)
|
||||
|
|
@ -626,12 +580,12 @@ export default function Grid({ gridWidth, currentLayout }) {
|
|||
(component) => !selectedComponents.includes(component.getAttribute('widgetid'))
|
||||
);
|
||||
const draggingOrResizing = draggingComponentId || resizingComponentId;
|
||||
if (!draggingOrResizing && components.length > 0) {
|
||||
if (!draggingOrResizing && components.length > 0 && !virtualTarget) {
|
||||
for (const component of components) {
|
||||
component?.classList?.remove('active-target');
|
||||
}
|
||||
}
|
||||
}, [draggingComponentId, resizingComponentId, isGroupDragging, selectedComponents]);
|
||||
}, [draggingComponentId, resizingComponentId, isGroupDragging, selectedComponents, virtualTarget]);
|
||||
|
||||
useGroupedTargetsScrollHandler(groupedTargets, boxList, moveableRef);
|
||||
if (mode !== 'edit') return null;
|
||||
|
|
@ -995,18 +949,17 @@ export default function Grid({ gridWidth, currentLayout }) {
|
|||
}}
|
||||
onDrag={(e) => {
|
||||
if (e.target.id === 'moveable-ghost-element') {
|
||||
// showGridLines();
|
||||
//
|
||||
showGridLines();
|
||||
const _gridWidth = useGridStore.getState().subContainerWidths[currentDragCanvasId] || gridWidth;
|
||||
let left = e.translate[0];
|
||||
let top = e.translate[1];
|
||||
// console.log('e.translate', e.translate);
|
||||
if (currentDragCanvasId === 'canvas') {
|
||||
left = Math.round(e.translate[0] / _gridWidth) * _gridWidth;
|
||||
top = Math.round(e.translate[1] / GRID_HEIGHT) * GRID_HEIGHT;
|
||||
}
|
||||
// if (currentDragCanvasId === 'canvas') {
|
||||
// console.log('e.translate', e.translate, _gridWidth);
|
||||
left = Math.round(e.translate[0] / _gridWidth) * _gridWidth;
|
||||
top = Math.round(e.translate[1] / GRID_HEIGHT) * GRID_HEIGHT;
|
||||
console.log('e.translate', e.translate, left, top);
|
||||
e.target.style.transform = `translate(${left}px, ${top}px)`;
|
||||
console.log('e.target', false);
|
||||
return false;
|
||||
}
|
||||
// Since onDrag is called multiple times when dragging, hence we are using isDraggingRef to prevent setting state again and again
|
||||
|
|
@ -1029,10 +982,10 @@ export default function Grid({ gridWidth, currentLayout }) {
|
|||
e.target.style.width = `${draggingWidgetWidth}px`;
|
||||
|
||||
// This logic is to handle the case when the dragged element is over a new canvas
|
||||
if (_dragParentId !== currentParentId) {
|
||||
left = e.translate[0];
|
||||
top = e.translate[1];
|
||||
}
|
||||
// if (_dragParentId !== currentParentId) {
|
||||
// left = e.translate[0];
|
||||
// top = e.translate[1];
|
||||
// }
|
||||
|
||||
// Special case for Modal
|
||||
const oldParentId = boxList.find((b) => b.id === e.target.id)?.parent;
|
||||
|
|
@ -1200,7 +1153,7 @@ export default function Grid({ gridWidth, currentLayout }) {
|
|||
// snapGridAll={true}
|
||||
scrollable={true}
|
||||
snapContainer={snapContainer}
|
||||
snapGridWidth={100}
|
||||
// snapGridWidth={100}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ export const addNewWidgetToTheEditor = (
|
|||
parentId,
|
||||
moduleInfo = undefined
|
||||
) => {
|
||||
const canvasBoundingRect = realCanvasRef?.current?.getBoundingClientRect();
|
||||
const canvasBoundingRect = realCanvasRef?.current?.getBoundingClientRect() || realCanvasRef?.getBoundingClientRect();
|
||||
const componentMeta = componentTypes.find((component) => component.component === componentType);
|
||||
const componentName = computeComponentName(componentType, useStore.getState().getCurrentPageComponents());
|
||||
|
||||
|
|
|
|||
94
frontend/src/AppBuilder/AppCanvas/useCanvasDropHandler.js
Normal file
94
frontend/src/AppBuilder/AppCanvas/useCanvasDropHandler.js
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import useStore from '@/AppBuilder/_stores/store';
|
||||
import { useGridStore } from '@/_stores/gridStore';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
import { noop } from 'lodash';
|
||||
import { addChildrenWidgetsToParent, addNewWidgetToTheEditor } from '../AppCanvas/appCanvasUtils';
|
||||
import { WIDGETS_WITH_DEFAULT_CHILDREN } from '../AppCanvas/appCanvasConstants';
|
||||
import { RIGHT_SIDE_BAR_TAB } from '../RightSideBar/rightSidebarConstants';
|
||||
import { isPDFSupported } from '@/_helpers/appUtils';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
|
||||
import { useGhostMoveable } from '../_hooks/useGhostMoveable';
|
||||
|
||||
export const useCanvasDropHandler = ({ appType }) => {
|
||||
const { moduleId } = useModuleContext();
|
||||
|
||||
const addComponentToCurrentPage = useStore((state) => state.addComponentToCurrentPage, shallow);
|
||||
const setActiveRightSideBarTab = useStore((state) => state.setActiveRightSideBarTab, shallow);
|
||||
const setShowModuleBorder = useStore((state) => state.setShowModuleBorder, shallow) || noop;
|
||||
const currentMode = useStore((state) => state.modeStore.modules[moduleId].currentMode, shallow);
|
||||
const currentLayout = useStore((state) => state.currentLayout, shallow);
|
||||
const setCurrentDragCanvasId = useGridStore((state) => state.actions.setCurrentDragCanvasId);
|
||||
const { deactivateGhost } = useGhostMoveable();
|
||||
const currentDragCanvasId = useGridStore((state) => state.currentDragCanvasId, shallow);
|
||||
|
||||
// console.log('currentDragCanvasId', currentDragCanvasId);
|
||||
|
||||
const handleDrop = ({ componentType: draggedComponentType, component }, monitor, canvasId) => {
|
||||
const realCanvasRef =
|
||||
document.getElementById(`canvas-${currentDragCanvasId}`) || document.getElementById(`real-canvas`);
|
||||
// Reset canvas ID when dropping
|
||||
setCurrentDragCanvasId(null);
|
||||
|
||||
// Ensure ghost is deactivated before processing drop
|
||||
deactivateGhost();
|
||||
|
||||
// Deactivate ghost when dropping
|
||||
setShowModuleBorder(false); // Hide the module border when dropping
|
||||
|
||||
if (currentMode === 'view' || (appType === 'module' && draggedComponentType !== 'ModuleContainer')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// const didDrop = monitor.didDrop();
|
||||
// if (didDrop) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (draggedComponentType === 'PDF' && !isPDFSupported()) {
|
||||
toast.error(
|
||||
'PDF is not supported in this version of browser. We recommend upgrading to the latest version for full support.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// IMPORTANT: This logic needs to be changed when we implement the module versioning
|
||||
const moduleInfo = component?.moduleId
|
||||
? {
|
||||
moduleId: component.moduleId,
|
||||
versionId: component.versionId,
|
||||
environmentId: component.environmentId,
|
||||
moduleName: component.displayName,
|
||||
moduleContainer: component.moduleContainer,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
if (WIDGETS_WITH_DEFAULT_CHILDREN.includes(draggedComponentType)) {
|
||||
const parentComponent = addNewWidgetToTheEditor(
|
||||
draggedComponentType,
|
||||
monitor,
|
||||
currentLayout,
|
||||
realCanvasRef,
|
||||
currentDragCanvasId,
|
||||
moduleInfo
|
||||
);
|
||||
const childComponents = addChildrenWidgetsToParent(draggedComponentType, parentComponent?.id, currentLayout);
|
||||
const newComponents = [parentComponent, ...childComponents];
|
||||
addComponentToCurrentPage(newComponents);
|
||||
setActiveRightSideBarTab(RIGHT_SIDE_BAR_TAB.CONFIGURATION);
|
||||
} else {
|
||||
const newComponent = addNewWidgetToTheEditor(
|
||||
draggedComponentType,
|
||||
monitor,
|
||||
currentLayout,
|
||||
realCanvasRef,
|
||||
currentDragCanvasId,
|
||||
moduleInfo
|
||||
);
|
||||
addComponentToCurrentPage([newComponent]);
|
||||
setActiveRightSideBarTab(RIGHT_SIDE_BAR_TAB.CONFIGURATION);
|
||||
}
|
||||
};
|
||||
|
||||
return handleDrop;
|
||||
};
|
||||
|
|
@ -10,21 +10,36 @@ import { shallow } from 'zustand/shallow';
|
|||
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
|
||||
import { noop } from 'lodash';
|
||||
import { useGridStore } from '@/_stores/gridStore';
|
||||
import { useCanvasDropHandler } from '@/AppBuilder/AppCanvas/useCanvasDropHandler';
|
||||
|
||||
export const DragLayer = ({ index, component, isModuleTab = false }) => {
|
||||
const { isModuleEditor } = useModuleContext();
|
||||
const setShowModuleBorder = useStore((state) => state.setShowModuleBorder, shallow) || noop;
|
||||
const handleDrop = useCanvasDropHandler({ appType: isModuleTab ? 'module' : 'app' }) || noop;
|
||||
const currentDragCanvasId = useGridStore((state) => state.currentDragCanvasId, shallow);
|
||||
|
||||
const [{ isDragging }, drag, preview] = useDrag(
|
||||
() => ({
|
||||
type: 'box',
|
||||
item: { componentType: component.component, component },
|
||||
collect: (monitor) => ({ isDragging: monitor.isDragging() }),
|
||||
end: (item, monitor) => {
|
||||
const clientOffset = monitor.getClientOffset();
|
||||
console.log('end', item, monitor.getDropResult(), monitor.getClientOffset());
|
||||
console.log('currentDragCanvasId', currentDragCanvasId);
|
||||
if (clientOffset) {
|
||||
// const canvas = document.getElementById(`canvas-${currentDragCanvasId}`);
|
||||
const realCanvas = document.getElementById(`real-canvas`);
|
||||
handleDrop(item, monitor, realCanvas, currentDragCanvasId);
|
||||
}
|
||||
// if (didDrop) {
|
||||
// handleDrop(item, monitor);
|
||||
// }
|
||||
},
|
||||
}),
|
||||
[component.component]
|
||||
);
|
||||
const getMoveableRef = useGridStore((state) => state.moveableRef);
|
||||
const setVirtualTarget = useGridStore((state) => state.actions.setVirtualTarget);
|
||||
const newDiv = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
preview(getEmptyImage(), { captureDraggingState: true });
|
||||
}, []);
|
||||
|
|
@ -41,7 +56,6 @@ export const DragLayer = ({ index, component, isModuleTab = false }) => {
|
|||
// ? component.module_container.layouts[currentLayout]
|
||||
// : component.defaultSize || { width: 30, height: 40 };
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* {isDragging && <CustomDragLayer size={size} />} */}
|
||||
|
|
@ -49,66 +63,13 @@ export const DragLayer = ({ index, component, isModuleTab = false }) => {
|
|||
ref={drag}
|
||||
className="draggable-box"
|
||||
style={{ height: '100%', width: isModuleTab && '100%' }}
|
||||
// onDragEnd={(e) => {
|
||||
// const realCanvas = document.getElementById(`real-canvas`);
|
||||
// handleDrop(e, realCanvas, currentDragCanvasId);
|
||||
// }}
|
||||
>
|
||||
{isModuleTab ? <ModuleWidgetBox module={component} /> : <WidgetBox index={index} component={component} />}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const CustomDragLayer = ({ size }) => {
|
||||
const { currentOffset, item } = useDragLayer((monitor) => ({
|
||||
currentOffset: monitor.getSourceClientOffset(),
|
||||
item: monitor.getItem(),
|
||||
}));
|
||||
if (!currentOffset) return null;
|
||||
|
||||
const canvasWidth = item?.canvasWidth;
|
||||
const canvasBounds = item?.canvasRef?.getBoundingClientRect();
|
||||
const height = size.height;
|
||||
|
||||
const appCanvasWidth = document.getElementById('real-canvas')?.offsetWidth || 0;
|
||||
|
||||
// Calculate width based on the app canvas's grid
|
||||
let width = (appCanvasWidth * size.width) / NO_OF_GRIDS;
|
||||
|
||||
// Calculate position relative to the current canvas (parent or child)
|
||||
const left = currentOffset.x - (canvasBounds?.left || 0);
|
||||
const top = currentOffset.y - (canvasBounds?.top || 0);
|
||||
|
||||
// Ensure width doesn't exceed the current container's width
|
||||
if (width > canvasWidth) {
|
||||
width = canvasWidth;
|
||||
}
|
||||
|
||||
// Snap width to grid (round to nearest grid unit)
|
||||
const gridUnitWidth = canvasWidth / NO_OF_GRIDS;
|
||||
const gridUnits = Math.round(width / gridUnitWidth);
|
||||
width = gridUnits * gridUnitWidth;
|
||||
|
||||
const [x, y] = snapToGrid(canvasWidth, left, top);
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'fixed',
|
||||
pointerEvents: 'none',
|
||||
left: canvasBounds?.left || 0,
|
||||
top: canvasBounds?.top || 0,
|
||||
height: `${height}px`,
|
||||
width: `${width}px`,
|
||||
zIndex: -1,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
transform: `translate(${x}px, ${y}px)`,
|
||||
background: '#D9E2FC',
|
||||
opacity: '0.7',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
outline: '1px solid #4af',
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useGridStore } from '@/_stores/gridStore';
|
|||
import { NO_OF_GRIDS, GRID_HEIGHT } from '@/AppBuilder/AppCanvas/appCanvasConstants';
|
||||
import { snapToGrid } from '@/AppBuilder/AppCanvas/appCanvasUtils';
|
||||
|
||||
export const useGhostMoveable = (canvasId) => {
|
||||
export const useGhostMoveable = () => {
|
||||
const ghostElementRef = useRef(null);
|
||||
const isActiveRef = useRef(false);
|
||||
|
||||
|
|
@ -29,7 +29,6 @@ export const useGhostMoveable = (canvasId) => {
|
|||
left: 0;
|
||||
`;
|
||||
|
||||
// const container = document.querySelectorAll(`[component-id="${canvasId}"]`)[0];
|
||||
const container = document.getElementById('real-canvas');
|
||||
container.appendChild(ghost);
|
||||
ghostElementRef.current = ghost;
|
||||
|
|
@ -49,7 +48,7 @@ export const useGhostMoveable = (canvasId) => {
|
|||
const snappedX = Math.round(relativeX / gridWidth) * gridWidth;
|
||||
const snappedY = Math.round(relativeY / GRID_HEIGHT) * GRID_HEIGHT;
|
||||
console.log(snappedX, snappedY);
|
||||
ghostElementRef.current.style.transform = `translate(${snappedX}px, ${snappedY}px)`;
|
||||
ghostElementRef.current.style.transform = `translate(${relativeX}px, ${relativeY}px)`;
|
||||
};
|
||||
|
||||
const activateGhost = (componentSize, mousePosition, canvasRef) => {
|
||||
|
|
@ -98,8 +97,6 @@ export const useGhostMoveable = (canvasId) => {
|
|||
ghostElementRef.current = null;
|
||||
// End any active drag operation first
|
||||
// moveableInstance.dragEnd();
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.warn('Failed to trigger moveable dragEnd:', error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const initialState = {
|
|||
containerId: null,
|
||||
triggerUpdate: 0,
|
||||
},
|
||||
shouldPreventDrop: false,
|
||||
};
|
||||
|
||||
export const createGridSlice = (set, get) => ({
|
||||
|
|
@ -99,4 +100,7 @@ export const createGridSlice = (set, get) => ({
|
|||
reorderContainerChildren: { containerId, triggerUpdate: state.reorderContainerChildren.triggerUpdate + 1 },
|
||||
}));
|
||||
},
|
||||
setShouldPreventDrop: (shouldPreventDrop) => {
|
||||
set(() => ({ shouldPreventDrop }));
|
||||
},
|
||||
});
|
||||
|
|
|
|||
2
server/package-lock.json
generated
2
server/package-lock.json
generated
|
|
@ -20645,4 +20645,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue