mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
feat: replace dnd with moveable
This commit is contained in:
parent
462b5c0140
commit
c985383c47
8 changed files with 674 additions and 112 deletions
|
|
@ -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 (
|
||||
<DraggableBox
|
||||
className={showComments && 'pointer-events-none'}
|
||||
canvasWidth={canvasWidth}
|
||||
onComponentClick={
|
||||
config.COMMENT_FEATURE_ENABLE && showComments ? handleAddThreadOnComponent : onComponentClick
|
||||
}
|
||||
onEvent={onEvent}
|
||||
height={height}
|
||||
onComponentOptionChanged={onComponentOptionChanged}
|
||||
onComponentOptionsChanged={onComponentOptionsChanged}
|
||||
key={key}
|
||||
onResizeStop={onResizeStop}
|
||||
onDragStop={onDragStop}
|
||||
paramUpdated={paramUpdated}
|
||||
id={key}
|
||||
{...boxes[key]}
|
||||
mode={mode}
|
||||
resizingStatusChanged={(status) => 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 (
|
||||
<div
|
||||
{...(config.COMMENT_FEATURE_ENABLE && showComments && { onClick: handleAddThread })}
|
||||
|
|
@ -643,7 +787,15 @@ export const Container = ({
|
|||
))}
|
||||
</>
|
||||
)}
|
||||
<DragContainer boxes={Object.keys(boxes).map((key) => ({ ...boxes[key], id: key }))} />
|
||||
<DragContainer
|
||||
boxes={Object.keys(boxes).map((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 =
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 (
|
||||
<div className="root">
|
||||
<div className="container">
|
||||
<button onClick={() => setList((list) => [...list, { id: new Date().getTime() }])}>Add</button>
|
||||
{list.map((i) =>
|
||||
isEmpty(i.children) ? (
|
||||
<div className="target target1" key={i} style={{ transform: 'translate(332px, -134px)' }}>
|
||||
Target {i.id}
|
||||
<input type="text" />
|
||||
<div className="container p-0">
|
||||
{list
|
||||
.filter((i) => isEmpty(i.parent))
|
||||
.map((i) => (
|
||||
<div
|
||||
className={`target widget-target target1 ele-${i.id}`}
|
||||
data-id={`${i.parent}`}
|
||||
key={i.id}
|
||||
id={i.id}
|
||||
widgetid={i.id}
|
||||
style={{ transform: `translate(332px, -134px)`, ...getDimensions(i.id) }}
|
||||
>
|
||||
{/* Target {i.id} */}
|
||||
{renderWidget(i.id, undefined, setIsChildDragged)}
|
||||
</div>
|
||||
) : (
|
||||
<div key={i} className="target target1">
|
||||
<DragContainerNested setIsChildDragged={setIsChildDragged} />
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
))}
|
||||
{/* <div className="target target1">
|
||||
<DragContainerNested setIsChildDragged={setIsChildDragged} />
|
||||
</div> */}
|
||||
|
|
@ -40,11 +97,16 @@ export default function DragContainer({ boxes }) {
|
|||
{/* <div className="target target1">Target1</div>
|
||||
<div className="target target2">Target2</div>
|
||||
<div className="target target3">Target3</div> */}
|
||||
{/* <Moveable
|
||||
target={'.target'}
|
||||
individualGroupable={true}
|
||||
<Moveable
|
||||
ref={moveableRef}
|
||||
// target={'.target'}
|
||||
target={movableTargets}
|
||||
// hideChildMoveableDefaultLines={false}
|
||||
// individualGroupable={true}
|
||||
individualGroupable={selectedComponents.length <= 1}
|
||||
draggable={true}
|
||||
resizable={true}
|
||||
keepRatio={false}
|
||||
rotatable={true}
|
||||
key={list.length}
|
||||
individualGroupableProps={(element) => {
|
||||
|
|
@ -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]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<div className="root">
|
||||
<div className="container">
|
||||
<button onClick={() => setList((list) => [...list, new Date().getTime()])}>Add</button>
|
||||
<div className="root h-100">
|
||||
<div className="container p-0 h-100">
|
||||
{/* <button onClick={() => setList((list) => [...list, { id: new Date().getTime() }])}>Add</button> */}
|
||||
{list.map((i) => (
|
||||
<div className="nested-target nested-target1" key={i} style={{ transform: 'translate(332px, -134px)' }}>
|
||||
Target1
|
||||
<div
|
||||
className={`target-${parent} target1-${i.parent} ele-${i.id} nested-target`}
|
||||
key={i.id}
|
||||
id={i.id}
|
||||
style={{ transform: `translate(332px, -134px)`, ...getDimensions(i.id) }}
|
||||
>
|
||||
{/* Target {i.id} */}
|
||||
{renderWidget(i.id)}
|
||||
</div>
|
||||
))}
|
||||
<div className="nested-target">Target1</div>
|
||||
{/* <div className="target target1">
|
||||
<DragContainerNested setIsChildDragged={setIsChildDragged} />
|
||||
</div> */}
|
||||
{/* <div className="target target1">
|
||||
Target12
|
||||
<input type="text" />
|
||||
</div> */}
|
||||
{/* <div className="target target1">Target1</div>
|
||||
<div className="target target2">Target2</div>
|
||||
<div className="target target3">Target3</div> */}
|
||||
<Moveable
|
||||
target={'.nested-target'}
|
||||
ref={moveableRef}
|
||||
target={`.target-${parent}`}
|
||||
individualGroupable={true}
|
||||
draggable={true}
|
||||
resizable={true}
|
||||
keepRatio={false}
|
||||
rotatable={true}
|
||||
key={list.length}
|
||||
individualGroupableProps={(element) => {
|
||||
|
|
@ -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]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// export default function DragContainer({ setIsChildDragged }) {
|
||||
// const [list, setList] = useState([1, 2, 3]);
|
||||
// return (
|
||||
// <div className="root">
|
||||
// <div className="container">
|
||||
// <button onClick={() => setList((list) => [...list, new Date().getTime()])}>Add</button>
|
||||
// {list.map((i) => (
|
||||
// <div className="nested-target nested-target1" key={i} style={{ transform: 'translate(332px, -134px)' }}>
|
||||
// Target1
|
||||
// </div>
|
||||
// ))}
|
||||
// <div className="nested-target">Target1</div>
|
||||
// {/* <div className="target target1">Target1</div>
|
||||
// <div className="target target2">Target2</div>
|
||||
// <div className="target target3">Target3</div> */}
|
||||
// <Moveable
|
||||
// target={'.nested-target'}
|
||||
// individualGroupable={true}
|
||||
// draggable={true}
|
||||
// resizable={true}
|
||||
// rotatable={true}
|
||||
// key={list.length}
|
||||
// individualGroupableProps={(element) => {
|
||||
// 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]}
|
||||
// />
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ export const DraggableBox = React.memo(
|
|||
>
|
||||
{inCanvas ? (
|
||||
<div
|
||||
className={cx(`draggable-box widget-${id}`, {
|
||||
className={cx(`draggable-box w-100 widget-${id}`, {
|
||||
[className]: !!className,
|
||||
'draggable-box-in-editor': mode === 'edit',
|
||||
})}
|
||||
|
|
@ -234,8 +234,7 @@ export const DraggableBox = React.memo(
|
|||
}}
|
||||
style={getStyles(isDragging, isSelectedComponent)}
|
||||
>
|
||||
<Rnd
|
||||
maxWidth={canvasWidth}
|
||||
{/* <Rnd
|
||||
style={{ ...style }}
|
||||
resizeGrid={[gridWidth, 10]}
|
||||
dragGrid={[gridWidth, 10]}
|
||||
|
|
@ -274,52 +273,52 @@ export const DraggableBox = React.memo(
|
|||
}}
|
||||
bounds={parent !== undefined ? `#canvas-${parent}` : '.real-canvas'}
|
||||
widgetId={id}
|
||||
>
|
||||
<div ref={preview} role="DraggableBox" style={isResizing ? { opacity: 0.5 } : { opacity: 1 }}>
|
||||
{mode === 'edit' &&
|
||||
!readOnly &&
|
||||
(configWidgetHandlerForModalComponent || mouseOver || isSelectedComponent) &&
|
||||
!isResizing && (
|
||||
<ConfigHandle
|
||||
id={id}
|
||||
removeComponent={removeComponent}
|
||||
component={component}
|
||||
position={layoutData.top < 15 ? 'bottom' : 'top'}
|
||||
widgetTop={layoutData.top}
|
||||
widgetHeight={layoutData.height}
|
||||
isMultipleComponentsSelected={isMultipleComponentsSelected}
|
||||
configWidgetHandlerForModalComponent={configWidgetHandlerForModalComponent}
|
||||
/>
|
||||
)}
|
||||
<ErrorBoundary showFallback={mode === 'edit'}>
|
||||
<Box
|
||||
component={component}
|
||||
> */}
|
||||
<div ref={preview} role="DraggableBox" style={isResizing ? { opacity: 0.5 } : { opacity: 1 }}>
|
||||
{mode === 'edit' &&
|
||||
!readOnly &&
|
||||
(configWidgetHandlerForModalComponent || mouseOver || isSelectedComponent) &&
|
||||
!isResizing && (
|
||||
<ConfigHandle
|
||||
id={id}
|
||||
width={width}
|
||||
height={layoutData.height - 4}
|
||||
mode={mode}
|
||||
changeCanDrag={changeCanDrag}
|
||||
inCanvas={inCanvas}
|
||||
paramUpdated={paramUpdated}
|
||||
onEvent={onEvent}
|
||||
onComponentOptionChanged={onComponentOptionChanged}
|
||||
onComponentOptionsChanged={onComponentOptionsChanged}
|
||||
onComponentClick={onComponentClick}
|
||||
currentState={currentState}
|
||||
containerProps={containerProps}
|
||||
darkMode={darkMode}
|
||||
removeComponent={removeComponent}
|
||||
canvasWidth={canvasWidth}
|
||||
readOnly={readOnly}
|
||||
customResolvables={customResolvables}
|
||||
parentId={parentId}
|
||||
allComponents={allComponents}
|
||||
sideBarDebugger={sideBarDebugger}
|
||||
childComponents={childComponents}
|
||||
component={component}
|
||||
position={layoutData.top < 15 ? 'bottom' : 'top'}
|
||||
widgetTop={layoutData.top}
|
||||
widgetHeight={layoutData.height}
|
||||
isMultipleComponentsSelected={isMultipleComponentsSelected}
|
||||
configWidgetHandlerForModalComponent={configWidgetHandlerForModalComponent}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
</Rnd>
|
||||
)}
|
||||
<ErrorBoundary showFallback={mode === 'edit'}>
|
||||
<Box
|
||||
component={component}
|
||||
id={id}
|
||||
width={width}
|
||||
height={layoutData.height - 4}
|
||||
mode={mode}
|
||||
changeCanDrag={changeCanDrag}
|
||||
inCanvas={inCanvas}
|
||||
paramUpdated={paramUpdated}
|
||||
onEvent={onEvent}
|
||||
onComponentOptionChanged={onComponentOptionChanged}
|
||||
onComponentOptionsChanged={onComponentOptionsChanged}
|
||||
onComponentClick={onComponentClick}
|
||||
currentState={currentState}
|
||||
containerProps={containerProps}
|
||||
darkMode={darkMode}
|
||||
removeComponent={removeComponent}
|
||||
canvasWidth={canvasWidth}
|
||||
readOnly={readOnly}
|
||||
customResolvables={customResolvables}
|
||||
parentId={parentId}
|
||||
allComponents={allComponents}
|
||||
sideBarDebugger={sideBarDebugger}
|
||||
childComponents={childComponents}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
{/* </Rnd> */}
|
||||
</div>
|
||||
) : (
|
||||
<div ref={drag} role="DraggableBox" className="draggable-box" style={{ height: '100%' }}>
|
||||
|
|
|
|||
|
|
@ -1610,7 +1610,7 @@ class EditorComponent extends React.Component {
|
|||
{!this.props.showComments && (
|
||||
<Selecto
|
||||
dragContainer={'.canvas-container'}
|
||||
selectableTargets={['.react-draggable']}
|
||||
selectableTargets={['.widget-target']}
|
||||
hitRate={0}
|
||||
selectByClick={true}
|
||||
toggleContinueSelect={['shift']}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { shallow } from 'zustand/shallow';
|
|||
import { useMounted } from '@/_hooks/use-mount';
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { diff } from 'deep-object-diff';
|
||||
import DragContainerNested from './DragContainerNested';
|
||||
|
||||
const NO_OF_GRIDS = 43;
|
||||
|
||||
|
|
@ -55,6 +56,7 @@ export const SubContainer = ({
|
|||
childComponents = null,
|
||||
listmode = null,
|
||||
columns = 1,
|
||||
setIsChildDragged,
|
||||
}) => {
|
||||
//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 (
|
||||
<DraggableBox
|
||||
onComponentClick={onComponentClick}
|
||||
onEvent={onEvent}
|
||||
height={height}
|
||||
onComponentOptionChanged={onComponentOptionChangedForSubcontainer}
|
||||
onComponentOptionsChanged={onComponentOptionsChanged}
|
||||
key={key}
|
||||
onResizeStop={onResizeStop}
|
||||
onDragStop={onDragStop}
|
||||
paramUpdated={paramUpdated}
|
||||
id={key}
|
||||
allComponents={allComponents}
|
||||
{...childWidgets[key]}
|
||||
mode={mode}
|
||||
resizingStatusChanged={(status) => 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 (
|
||||
<div
|
||||
ref={drop}
|
||||
|
|
@ -565,7 +686,18 @@ export const SubContainer = ({
|
|||
id={`canvas-${parent}`}
|
||||
className={`real-canvas ${(isDragging || isResizing) && !readOnly ? 'show-grid' : ''}`}
|
||||
>
|
||||
{checkParentVisibility() &&
|
||||
<DragContainerNested
|
||||
boxes={Object.keys(childWidgets).map((key) => ({ ...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 && (
|
||||
<div className="mx-auto mt-5 w-50 p-5">
|
||||
<center>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue