diff --git a/frontend/src/Editor/Container.jsx b/frontend/src/Editor/Container.jsx index 1d8f3332b4..e024501cf5 100644 --- a/frontend/src/Editor/Container.jsx +++ b/frontend/src/Editor/Container.jsx @@ -349,6 +349,76 @@ export const Container = ({ [isVersionReleased, enableReleasedVersionPopupState, boxes, setBoxes, selectedComponents, updateCanvasHeight] ); + const onResizeStop2 = (boxList, id, height, width, x, y) => { + const newBoxes = boxList.reduce((newBoxList, { id, height, width, x, y }) => { + const newWidth = (width * NO_OF_GRIDS) / canvasWidth; + return { + ...newBoxList, + [id]: { + ...boxes[id], + layouts: { + ...boxes[id]['layouts'], + [currentLayout]: { + ...boxes[id]['layouts'][currentLayout], + width: newWidth, + height, + top: y, + left: Math.round(x / gridWidth), + }, + }, + }, + }; + }, {}); + let updatedBoxes = { + ...boxes, + ...newBoxes, + }; + + setBoxes(updatedBoxes); + updateCanvasHeight(updatedBoxes); + }; + + function onDragStop2(boxPositions) { + const updatedBoxes = boxPositions.reduce( + (boxesObj, { id, x, y, parent }) => ({ + ...boxesObj, + [id]: { + ...boxes[id], + layouts: { + ...boxes[id]['layouts'], + [currentLayout]: { + ...boxes[id]['layouts'][currentLayout], + // ...{ top: layout.y, left: layout.x, height: layout.h, width: layout.w }, + top: y, + left: Math.round(x / gridWidth), + }, + }, + parent: parent ? parent : boxes[id].parent, + }, + }), + {} + ); + let newBoxes = { + ...boxes, + ...updatedBoxes, + // [id]: { + // ...boxes[id], + // layouts: { + // ...boxes[id]['layouts'], + // [currentLayout]: { + // ...boxes[id]['layouts'][currentLayout], + // // ...{ top: layout.y, left: layout.x, height: layout.h, width: layout.w }, + // top: y, + // left: Math.round(x / gridWidth), + // }, + // }, + // parent: parent ? parent : boxes[id].parent, + // }, + }; + + setBoxes(newBoxes); + } + const onResizeStop = useCallback( (id, e, direction, ref, d, position) => { if (isVersionReleased) { @@ -603,6 +673,80 @@ export const Container = ({ childComponents, ]); + const renderWidget = (key, height, setIsChildDragged) => { + const box = boxes[key]; + if (!box) { + return ''; + } + const canShowInCurrentLayout = + box.component.definition.others[currentLayout === 'mobile' ? 'showOnMobile' : 'showOnDesktop'].value; + const addDefaultChildren = box.withDefaultChildren; + if (!box.parent && resolveReferences(canShowInCurrentLayout, currentState)) { + return ( + setIsResizing(status)} + draggingStatusChanged={(status) => setIsDragging(status)} + inCanvas={true} + zoomLevel={zoomLevel} + setSelectedComponent={setSelectedComponent} + removeComponent={removeComponent} + deviceWindowWidth={deviceWindowWidth} + isSelectedComponent={mode === 'edit' ? selectedComponents.find((component) => component.id === key) : false} + darkMode={darkMode} + // onComponentHover={onComponentHover} + // hoveredComponent={hoveredComponent} + sideBarDebugger={sideBarDebugger} + isMultipleComponentsSelected={selectedComponents?.length > 1 ? true : false} + childComponents={childComponents[key]} + containerProps={{ + mode, + snapToGrid, + onComponentClick, + onEvent, + appDefinition, + appDefinitionChanged, + currentState, + onComponentOptionChanged, + onComponentOptionsChanged, + appLoading, + zoomLevel, + setSelectedComponent, + removeComponent, + currentLayout, + deviceWindowWidth, + selectedComponents, + darkMode, + // onComponentHover, + // hoveredComponent, + sideBarDebugger, + addDefaultChildren, + currentPageId, + childComponents, + setIsChildDragged, + }} + isVersionReleased={isVersionReleased} + /> + ); + } + return ''; + }; + return (
)} - ({ ...boxes[key], id: key }))} /> + ({ ...boxes[key], id: key }))} + renderWidget={renderWidget} + canvasWidth={canvasWidth} + onResizeStop={onResizeStop2} + onDrag={onDragStop2} + gridWidth={gridWidth} + selectedComponents={selectedComponents} + /> {/* {Object.keys(boxes).map((key) => { const box = boxes[key]; const canShowInCurrentLayout = diff --git a/frontend/src/Editor/DragContainer.css b/frontend/src/Editor/DragContainer.css index 92a5a7fb79..5c71362e7d 100644 --- a/frontend/src/Editor/DragContainer.css +++ b/frontend/src/Editor/DragContainer.css @@ -1,14 +1,14 @@ -.target { +.target, .nested-target { position: absolute; - width: 100px; - height: 100px; - top: 150px; - left: 100px; - line-height: 100px; + /* width: 100px; + height: 100px; */ + /* top: 150px; + left: 100px; */ + /* line-height: 100px; */ text-align: center; background: #ee8; color: #333; - font-weight: bold; + /* font-weight: bold; */ border: 1px solid #333; box-sizing: border-box; } \ No newline at end of file diff --git a/frontend/src/Editor/DragContainer.jsx b/frontend/src/Editor/DragContainer.jsx index dbc0670084..4424f808ff 100644 --- a/frontend/src/Editor/DragContainer.jsx +++ b/frontend/src/Editor/DragContainer.jsx @@ -1,35 +1,92 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import Moveable from 'react-moveable'; +import { useEditorStore } from '@/_stores/editorStore'; +import { shallow } from 'zustand/shallow'; import './DragContainer.css'; import DragContainerNested from './DragContainerNested'; import { isEmpty } from 'lodash'; +const NO_OF_GRIDS = 43; -export default function DragContainer({ boxes }) { +export default function DragContainer({ + boxes, + renderWidget, + canvasWidth, + onResizeStop, + onDrag, + gridWidth, + selectedComponents = [], +}) { + const [dragTarget, setDragTarget] = useState(); + const [draggedTarget, setDraggedTarget] = useState(); + const moveableRef = useRef(); const boxList = boxes.map((box) => ({ id: box.id, - height: box?.layout?.desktop?.height, - left: box?.layout?.desktop?.left, - top: box?.layout?.desktop?.top, - width: box?.layout?.desktop?.width, + height: box?.layouts?.desktop?.height, + left: box?.layouts?.desktop?.left, + top: box?.layouts?.desktop?.top, + width: box?.layouts?.desktop?.width, + parent: box.parent, })); const [list, setList] = useState(boxList); + + const hoveredComponent = useEditorStore((state) => state?.hoveredComponent, shallow); + + useEffect(() => { + moveableRef.current.updateRect(); + window.moveableRef = moveableRef.current.updateRect; + }, [selectedComponents.length]); + + useEffect(() => { + setList(boxList); + }, [boxes?.length]); + const [isChildDragged, setIsChildDragged] = useState(false); + + const getDimensions = (id) => { + const box = boxes.find((b) => b.id === id); + const layoutData = box?.layouts?.desktop; + if (isEmpty(layoutData)) { + return {}; + } + const width = (canvasWidth * layoutData.width) / NO_OF_GRIDS; + + return { + width: width + 'px', + height: layoutData.height + 'px', + transform: `translate(${layoutData.left * gridWidth}px, ${layoutData.top}px)`, + }; + }; + + const groupedTargets = [...selectedComponents.map((component) => '.ele-' + component.id)]; + const movableTargets = [groupedTargets]; + if (hoveredComponent && !groupedTargets?.length) { + movableTargets.push('.ele-' + hoveredComponent); + } + + if (draggedTarget && !movableTargets.includes(`.ele-${draggedTarget}`)) { + movableTargets.push('.ele-' + draggedTarget); + } + + // console.log("movableTargets", movableTargets, hoveredComponent); + return (
-
- - {list.map((i) => - isEmpty(i.children) ? ( -
- Target {i.id} - +
+ {list + .filter((i) => isEmpty(i.parent)) + .map((i) => ( +
+ {/* Target {i.id} */} + {renderWidget(i.id, undefined, setIsChildDragged)}
- ) : ( -
- -
- ) - )} + ))} {/*
*/} @@ -40,11 +97,16 @@ export default function DragContainer({ boxes }) { {/*
Target1
Target2
Target3
*/} - {/* { @@ -54,33 +116,114 @@ export default function DragContainer({ boxes }) { }; } }} - // onRender={(e) => { - // if (isChildDragged) { - // return; - // } - // console.log('e.target.style', e.cssText); - // e.target.style.cssText += e.cssText; - // }} + onResize={(e) => { + e.target.style.width = `${e.width}px`; + e.target.style.height = `${e.height}px`; + e.target.style.transform = e.drag.transform; + onResizeStop([ + { + id: e.target.id, + height: e.height, + width: e.width, + x: e.drag.translate[0], + y: e.drag.translate[1], + }, + ]); + }} + onResizeGroup={({ events }) => { + const newBoxs = []; + events.forEach((ev) => { + ev.target.style.width = `${ev.width}px`; + ev.target.style.height = `${ev.height}px`; + ev.target.style.transform = ev.drag.transform; + newBoxs.push({ + id: ev.target.id, + height: ev.height, + width: ev.width, + x: ev.drag.translate[0], + y: ev.drag.translate[1], + }); + }); + onResizeStop(newBoxs); + }} checkInput + onDragEnd={(e) => { + console.log('onDragEnd', e); + setDraggedTarget(); + if (isChildDragged) { + return; + } + + // onDrag(e.target.id, e.translate[0], e.translate[1]); + // console.log(e.target.style); + // if (!isChildDragged) { + // e.target.style.transform = `translate(${Math.round(e.translate[0] / 10) * 10}px, ${ + // Math.round(e.translate[1] / 10) * 10 + // }px)`; + // } + + let draggedOverElemId; + if (document.elementFromPoint(e.clientX, e.clientY)) { + const targetElems = document.elementsFromPoint(e.clientX, e.clientY); + // targetElems.forEach((e) => console.log('Element=>', { id: e.id, clist: e.classList, class: e.className })); + const draggedOverElem = targetElems.find( + (ele) => ele.id !== e.target.id && ele.classList.contains('target') + ); + setDragTarget(draggedOverElem?.id); + console.log('draggedOverElem =>', draggedOverElem?.id, dragTarget); + draggedOverElemId = draggedOverElem?.id; + } + onDrag([ + { id: e.target.id, x: e.lastEvent.translate[0], y: e.lastEvent.translate[1], parent: draggedOverElemId }, + ]); + }} onDrag={(e) => { - console.log('event', e.clientX, e.clientY, e.transform, e.translate); - console.log(e.target.style); + if (isChildDragged) { + return; + } + setDraggedTarget(e.target.id); + // onDrag(e.target.id, e.translate[0], e.translate[1]); + // console.log(e.target.style); if (!isChildDragged) { - e.target.style.transform = `translate(${Math.round(e.translate[0] / 10) * 10}px, ${ + e.target.style.transform = `translate(${Math.round(e.translate[0] / gridWidth) * gridWidth}px, ${ Math.round(e.translate[1] / 10) * 10 }px)`; } - if (document.elementFromPoint(e.clientX, e.clientY)) { - console.log('Hoverover=>', document.elementsFromPoint(e.clientX, e.clientY)); - } + + // let draggedOverElemId; + // if (document.elementFromPoint(e.clientX, e.clientY)) { + // const targetElems = document.elementsFromPoint(e.clientX, e.clientY); + // // targetElems.forEach((e) => console.log('Element=>', { id: e.id, clist: e.classList, class: e.className })); + // const draggedOverElem = targetElems.find( + // (ele) => ele.id !== e.target.id && ele.classList.contains('target') + // ); + // setDragTarget(draggedOverElem?.id); + // console.log('draggedOverElem =>', draggedOverElem?.id, dragTarget); + // draggedOverElemId = draggedOverElem?.id; + // } + // onDrag([{ id: e.target.id, x: e.translate[0], y: e.translate[1], parent: draggedOverElemId }]); + }} + onDragGroup={({ events }) => { + events.forEach((ev) => { + console.log('Grouped data=>', ev); + // ev.target.style.transform = ev.transform; + }); + onDrag( + events.map((ev) => ({ + id: ev.target.id, + x: ev.translate[0], + y: ev.translate[1], + })) + ); }} //snap settgins snappable={true} snapDirections={{ top: true, left: true, bottom: true, right: true }} snapThreshold={5} - verticalGuidelines={[50, 150, 250, 450, 550]} - horizontalGuidelines={[0, 100, 200, 400, 500]} - /> */} + elementGuidelines={list.map((l) => ({ element: `.ele-${l.id}` }))} + // verticalGuidelines={[50, 150, 250, 450, 550]} + // horizontalGuidelines={[0, 100, 200, 400, 500]} + />
); diff --git a/frontend/src/Editor/DragContainerNested.jsx b/frontend/src/Editor/DragContainerNested.jsx index b7459aabc8..efa853a4c0 100644 --- a/frontend/src/Editor/DragContainerNested.jsx +++ b/frontend/src/Editor/DragContainerNested.jsx @@ -1,27 +1,87 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import Moveable from 'react-moveable'; import './DragContainer.css'; +import { isEmpty } from 'lodash'; +const NO_OF_GRIDS = 43; + +export default function DragContainer({ + boxes, + renderWidget, + canvasWidth, + onResizeStop, + onDrag, + gridWidth, + setIsChildDragged, + parent, + parentLayout, +}) { + const [dragTarget, setDragTarget] = useState(); + const boxList = boxes.map((box) => ({ + id: box.id, + height: box?.layouts?.desktop?.height, + left: box?.layouts?.desktop?.left, + top: box?.layouts?.desktop?.top, + width: box?.layouts?.desktop?.width, + })); + const [list, setList] = useState(boxList); + const moveableRef = useRef(); + + useEffect(() => { + setList(boxList); + }, [boxes?.length]); + + useEffect(() => { + moveableRef.current.updateRect(); + }, [...Object.values(parentLayout)]); + + // const [isChildDragged, setIsChildDragged] = useState(false); + + const getDimensions = (id) => { + const box = boxes.find((b) => b.id === id); + const layoutData = box?.layouts?.desktop; + if (isEmpty(layoutData)) { + return {}; + } + const width = (canvasWidth * layoutData.width) / NO_OF_GRIDS; + return { + width: width + 'px', + height: layoutData.height + 'px', + transform: `translate(${layoutData.left * gridWidth}px, ${layoutData.top}px)`, + }; + }; -export default function DragContainer({ setIsChildDragged }) { - const [list, setList] = useState([1, 2, 3]); return ( -
-
- +
+
+ {/* */} {list.map((i) => ( -
- Target1 +
+ {/* Target {i.id} */} + {renderWidget(i.id)}
))} -
Target1
+ {/*
+ +
*/} + {/*
+ Target12 + +
*/} {/*
Target1
Target2
Target3
*/} { @@ -31,20 +91,93 @@ export default function DragContainer({ setIsChildDragged }) { }; } }} - onDragEnd={() => setIsChildDragged(false)} - onRender={(e) => { - console.log('e.target.style', e.cssText); + onResize={(e) => { + console.log('e._dragTarget.id', e.target, e.target.id, e.drag); + e.target.style.width = `${e.width}px`; + e.target.style.height = `${e.height}px`; + e.target.style.transform = e.drag.transform; + onResizeStop(e.target.id, e.height, e.width, e.drag.translate[0], e.drag.translate[1]); + }} + checkInput + onDrag={(e) => { setIsChildDragged(true); - e.target.style.cssText += e.cssText; + onDrag(e.target.id, e.translate[0], e.translate[1]); + // if (!isChildDragged) { + e.target.style.transform = `translate(${Math.round(e.translate[0] / gridWidth) * gridWidth}px, ${ + Math.round(e.translate[1] / 10) * 10 + }px)`; + // } + + // let draggedOverElemId; + // if (document.elementFromPoint(e.clientX, e.clientY)) { + // const targetElems = document.elementsFromPoint(e.clientX, e.clientY); + // // targetElems.forEach((e) => console.log('Element=>', { id: e.id, clist: e.classList, class: e.className })); + // const draggedOverElem = targetElems.find( + // (ele) => ele.id !== e.target.id && ele.classList.contains('target') + // ); + // setDragTarget(draggedOverElem?.id); + // console.log('draggedOverElem =>', draggedOverElem?.id, dragTarget); + // draggedOverElemId = draggedOverElem?.id; + // } + // onDrag(e.target.id, e.translate[0], e.translate[1], draggedOverElemId); }} //snap settgins snappable={true} + onDragEnd={() => setIsChildDragged(false)} snapDirections={{ top: true, left: true, bottom: true, right: true }} snapThreshold={5} - verticalGuidelines={[50, 150, 250, 450, 550]} - horizontalGuidelines={[0, 100, 200, 400, 500]} + elementGuidelines={list.map((l) => ({ element: `.ele-${l.id}` }))} + // verticalGuidelines={[50, 150, 250, 450, 550]} + // horizontalGuidelines={[0, 100, 200, 400, 500]} />
); } + +// export default function DragContainer({ setIsChildDragged }) { +// const [list, setList] = useState([1, 2, 3]); +// return ( +//
+//
+// +// {list.map((i) => ( +//
+// Target1 +//
+// ))} +//
Target1
+// {/*
Target1
+//
Target2
+//
Target3
*/} +// { +// if (element?.classList.contains('target2')) { +// return { +// resizable: false, +// }; +// } +// }} +// onDragEnd={() => setIsChildDragged(false)} +// onRender={(e) => { +// console.log('e.target.style', e.cssText); +// setIsChildDragged(true); +// e.target.style.cssText += e.cssText; +// }} +// //snap settgins +// snappable={true} +// snapDirections={{ top: true, left: true, bottom: true, right: true }} +// snapThreshold={5} +// verticalGuidelines={[50, 150, 250, 450, 550]} +// horizontalGuidelines={[0, 100, 200, 400, 500]} +// /> +//
+//
+// ); +// } diff --git a/frontend/src/Editor/DraggableBox.jsx b/frontend/src/Editor/DraggableBox.jsx index b58c87e83a..2871b1852d 100644 --- a/frontend/src/Editor/DraggableBox.jsx +++ b/frontend/src/Editor/DraggableBox.jsx @@ -219,7 +219,7 @@ export const DraggableBox = React.memo( > {inCanvas ? (
- -
- {mode === 'edit' && - !readOnly && - (configWidgetHandlerForModalComponent || mouseOver || isSelectedComponent) && - !isResizing && ( - - )} - - */} +
+ {mode === 'edit' && + !readOnly && + (configWidgetHandlerForModalComponent || mouseOver || isSelectedComponent) && + !isResizing && ( + - -
- + )} + + + +
+ {/*
*/}
) : (
diff --git a/frontend/src/Editor/Editor.jsx b/frontend/src/Editor/Editor.jsx index ce8cb2333a..a23b645080 100644 --- a/frontend/src/Editor/Editor.jsx +++ b/frontend/src/Editor/Editor.jsx @@ -1610,7 +1610,7 @@ class EditorComponent extends React.Component { {!this.props.showComments && ( { //Todo add custom resolve vars for other widgets too const mounted = useMounted(); @@ -490,6 +492,51 @@ export const SubContainer = ({ setBoxes(newBoxes); } + const onResizeStop2 = (id, height, width, x, y) => { + const newWidth = (width * NO_OF_GRIDS) / _containerCanvasWidth; + let newBoxes = { + ...boxes, + [id]: { + ...boxes[id], + layouts: { + ...boxes[id]['layouts'], + [currentLayout]: { + ...boxes[id]['layouts'][currentLayout], + width: newWidth, + height, + top: y, + left: Math.round(x / gridWidth), + }, + }, + }, + }; + + setBoxes(newBoxes); + // updateCanvasHeight(newBoxes); + }; + + function onDragStop2(id, x, y, parent) { + let newBoxes = { + ...boxes, + [id]: { + ...boxes[id], + layouts: { + ...boxes[id]['layouts'], + [currentLayout]: { + ...boxes[id]['layouts'][currentLayout], + // ...{ top: layout.y, left: layout.x, height: layout.h, width: layout.w }, + top: y, + left: Math.round(x / gridWidth), + }, + }, + parent: parent ? parent : boxes[id].parent, + }, + }; + + setChildWidgets(() => getChildWidgets(newBoxes)); + setBoxes(newBoxes); + } + function paramUpdated(id, param, value) { if (Object.keys(value).length > 0) { setBoxes((boxes) => { @@ -558,6 +605,80 @@ export const SubContainer = ({ return false; } + const renderWidget = (key, height) => { + console.log(key, height); + const addDefaultChildren = childWidgets[key]['withDefaultChildren'] || false; + + const box = childWidgets[key]; + const canShowInCurrentLayout = + box.component.definition.others[currentLayout === 'mobile' ? 'showOnMobile' : 'showOnDesktop'].value; + if (box.parent && resolveReferences(canShowInCurrentLayout, currentState)) { + return ( + setIsResizing(status)} + draggingStatusChanged={(status) => setIsDragging(status)} + inCanvas={true} + zoomLevel={zoomLevel} + setSelectedComponent={setSelectedComponent} + selectedComponent={selectedComponent} + deviceWindowWidth={deviceWindowWidth} + isSelectedComponent={mode === 'edit' ? selectedComponents.find((component) => component.id === key) : false} + removeComponent={customRemoveComponent} + canvasWidth={_containerCanvasWidth} + readOnly={readOnly} + darkMode={darkMode} + customResolvables={customResolvables} + onComponentHover={onComponentHover} + hoveredComponent={hoveredComponent} + parentId={parentComponent?.name} + sideBarDebugger={sideBarDebugger} + isMultipleComponentsSelected={selectedComponents?.length > 1 ? true : false} + exposedVariables={exposedVariables ?? {}} + childComponents={childComponents[key]} + containerProps={{ + mode, + snapToGrid, + onComponentClick, + onEvent, + appDefinition, + appDefinitionChanged, + currentState, + onComponentOptionChanged, + onComponentOptionsChanged, + appLoading, + zoomLevel, + setSelectedComponent, + removeComponent, + currentLayout, + deviceWindowWidth, + selectedComponents, + darkMode, + readOnly, + onComponentHover, + hoveredComponent, + sideBarDebugger, + addDefaultChildren, + currentPageId, + childComponents, + }} + /> + ); + } + }; + return (
- {checkParentVisibility() && + ({ ...boxes[key], id: key }))} + renderWidget={renderWidget} + canvasWidth={_containerCanvasWidth} + onResizeStop={onResizeStop2} + onDrag={onDragStop2} + gridWidth={gridWidth} + setIsChildDragged={setIsChildDragged} + parent={parent} + parentLayout={appDefinition.pages[currentPageId]?.components[parent]?.layouts?.[currentLayout]} + /> + {/* {checkParentVisibility() && Object.keys(childWidgets).map((key) => { const addDefaultChildren = childWidgets[key]['withDefaultChildren'] || false; const box = childWidgets[key]; @@ -645,7 +777,7 @@ export const SubContainer = ({ /> ); } - })} + })} */} {appLoading && (
diff --git a/frontend/src/_helpers/appUtils.js b/frontend/src/_helpers/appUtils.js index d81889df77..bee1890ba5 100644 --- a/frontend/src/_helpers/appUtils.js +++ b/frontend/src/_helpers/appUtils.js @@ -1627,7 +1627,10 @@ export const addNewWidgetToTheEditor = ( [left, top] = snapToGrid(subContainerWidth, left, top); } - left = (left * 100) / subContainerWidth; + const gridWidth = subContainerWidth / 43; + left = Math.round(left / gridWidth); + console.log('Top calc', { top, initialClientOffset, delta, zoomLevel, offsetFromTopOfWindow, subContainerWidth }); + // left = (left * 100) / subContainerWidth; if (currentLayout === 'mobile') { componentData.definition.others.showOnDesktop.value = false;