2022-05-24 10:19:33 +00:00
|
|
|
/* eslint-disable import/no-named-as-default */
|
2021-05-09 18:06:11 +00:00
|
|
|
import React, { useCallback, useState, useEffect } from 'react';
|
|
|
|
|
import { useDrop, useDragLayer } from 'react-dnd';
|
2022-02-03 09:15:40 +00:00
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
2021-05-09 18:06:11 +00:00
|
|
|
import { ItemTypes } from './ItemTypes';
|
|
|
|
|
import { DraggableBox } from './DraggableBox';
|
|
|
|
|
import { snapToGrid as doSnapToGrid } from './snapToGrid';
|
|
|
|
|
import update from 'immutability-helper';
|
2022-06-02 06:21:52 +00:00
|
|
|
import { componentTypes } from './WidgetManager/components';
|
2021-05-09 18:06:11 +00:00
|
|
|
import { computeComponentName } from '@/_helpers/utils';
|
2022-05-11 09:13:13 +00:00
|
|
|
import produce from 'immer';
|
2021-05-09 18:06:11 +00:00
|
|
|
|
|
|
|
|
export const SubContainer = ({
|
|
|
|
|
mode,
|
|
|
|
|
snapToGrid,
|
|
|
|
|
onComponentClick,
|
|
|
|
|
onEvent,
|
|
|
|
|
appDefinition,
|
|
|
|
|
appDefinitionChanged,
|
|
|
|
|
currentState,
|
|
|
|
|
onComponentOptionChanged,
|
|
|
|
|
onComponentOptionsChanged,
|
|
|
|
|
appLoading,
|
|
|
|
|
zoomLevel,
|
|
|
|
|
parent,
|
|
|
|
|
parentRef,
|
2022-02-06 13:15:38 +00:00
|
|
|
setSelectedComponent,
|
2021-06-04 14:51:36 +00:00
|
|
|
deviceWindowWidth,
|
|
|
|
|
selectedComponent,
|
2021-08-30 13:23:58 +00:00
|
|
|
currentLayout,
|
2021-09-21 13:48:28 +00:00
|
|
|
removeComponent,
|
2021-11-23 07:59:22 +00:00
|
|
|
darkMode,
|
2021-12-10 03:13:05 +00:00
|
|
|
containerCanvasWidth,
|
2022-01-14 08:27:31 +00:00
|
|
|
readOnly,
|
|
|
|
|
customResolvables,
|
|
|
|
|
parentComponent,
|
|
|
|
|
listViewItemOptions,
|
2022-02-03 07:07:34 +00:00
|
|
|
onComponentHover,
|
|
|
|
|
hoveredComponent,
|
2022-05-11 09:13:13 +00:00
|
|
|
selectedComponents,
|
2021-05-09 18:06:11 +00:00
|
|
|
}) => {
|
2022-03-10 11:51:46 +00:00
|
|
|
const [_containerCanvasWidth, setContainerCanvasWidth] = useState(0);
|
2021-11-23 07:59:22 +00:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2022-03-17 12:46:28 +00:00
|
|
|
if (parentRef.current) {
|
|
|
|
|
const canvasWidth = getContainerCanvasWidth();
|
|
|
|
|
setContainerCanvasWidth(canvasWidth);
|
|
|
|
|
}
|
2022-03-10 11:51:46 +00:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2022-03-17 12:46:28 +00:00
|
|
|
}, [parentRef, getContainerCanvasWidth()]);
|
2021-11-23 07:59:22 +00:00
|
|
|
|
2021-05-09 18:06:11 +00:00
|
|
|
zoomLevel = zoomLevel || 1;
|
|
|
|
|
|
2021-09-21 13:48:28 +00:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2021-05-09 18:06:11 +00:00
|
|
|
const allComponents = appDefinition ? appDefinition.components : {};
|
|
|
|
|
|
2021-09-21 13:48:28 +00:00
|
|
|
let childComponents = [];
|
2021-05-09 18:06:11 +00:00
|
|
|
|
|
|
|
|
Object.keys(allComponents).forEach((key) => {
|
2021-09-21 13:48:28 +00:00
|
|
|
if (allComponents[key].parent === parent) {
|
2022-01-14 08:27:31 +00:00
|
|
|
childComponents[key] = { ...allComponents[key], component: { ...allComponents[key]['component'], parent } };
|
2021-05-09 18:06:11 +00:00
|
|
|
}
|
2021-09-21 13:48:28 +00:00
|
|
|
});
|
2021-05-09 18:06:11 +00:00
|
|
|
|
|
|
|
|
const [boxes, setBoxes] = useState(allComponents);
|
|
|
|
|
const [isDragging, setIsDragging] = useState(false);
|
|
|
|
|
const [isResizing, setIsResizing] = useState(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setBoxes(allComponents);
|
|
|
|
|
}, [allComponents]);
|
|
|
|
|
|
|
|
|
|
const moveBox = useCallback(
|
|
|
|
|
(id, left, top) => {
|
|
|
|
|
setBoxes(
|
|
|
|
|
update(boxes, {
|
|
|
|
|
[id]: {
|
2021-09-21 13:48:28 +00:00
|
|
|
$merge: { left, top },
|
|
|
|
|
},
|
2021-05-09 18:06:11 +00:00
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
[boxes]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2021-09-21 13:48:28 +00:00
|
|
|
if (appDefinitionChanged) {
|
2021-05-09 18:06:11 +00:00
|
|
|
appDefinitionChanged({ ...appDefinition, components: boxes });
|
|
|
|
|
}
|
2021-09-21 13:48:28 +00:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2021-05-09 18:06:11 +00:00
|
|
|
}, [boxes]);
|
|
|
|
|
|
2021-05-11 17:47:39 +00:00
|
|
|
const { draggingState } = useDragLayer((monitor) => {
|
2021-05-15 15:09:37 +00:00
|
|
|
// TODO: Need to move to a performant version of the block below
|
2021-09-21 13:48:28 +00:00
|
|
|
if (monitor.getItem()) {
|
|
|
|
|
if (monitor.getItem().id === undefined) {
|
|
|
|
|
if (parentRef.current) {
|
2021-05-15 15:09:37 +00:00
|
|
|
const currentOffset = monitor.getSourceClientOffset();
|
2021-09-21 13:48:28 +00:00
|
|
|
if (currentOffset) {
|
|
|
|
|
const canvasBoundingRect = parentRef.current
|
|
|
|
|
.getElementsByClassName('real-canvas')[0]
|
|
|
|
|
.getBoundingClientRect();
|
|
|
|
|
if (
|
|
|
|
|
currentOffset.x > canvasBoundingRect.x &&
|
|
|
|
|
currentOffset.x < canvasBoundingRect.x + canvasBoundingRect.width
|
|
|
|
|
) {
|
|
|
|
|
return { draggingState: true };
|
2021-05-15 15:09:37 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-21 13:48:28 +00:00
|
|
|
if (monitor.isDragging() && monitor.getItem().parent) {
|
|
|
|
|
if (monitor.getItem().parent === parent) {
|
|
|
|
|
return { draggingState: true };
|
|
|
|
|
} else {
|
|
|
|
|
return { draggingState: false };
|
2021-05-11 17:47:39 +00:00
|
|
|
}
|
2021-09-21 13:48:28 +00:00
|
|
|
} else {
|
|
|
|
|
return { draggingState: false };
|
2021-05-11 17:47:39 +00:00
|
|
|
}
|
|
|
|
|
});
|
2021-05-09 18:06:11 +00:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setIsDragging(draggingState);
|
|
|
|
|
}, [draggingState]);
|
|
|
|
|
|
2021-11-16 11:44:09 +00:00
|
|
|
function convertXToPercentage(x, canvasWidth) {
|
|
|
|
|
return (x * 100) / canvasWidth;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function convertXFromPercentage(x, canvasWidth) {
|
|
|
|
|
return (x * canvasWidth) / 100;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-09 18:06:11 +00:00
|
|
|
const [, drop] = useDrop(
|
|
|
|
|
() => ({
|
|
|
|
|
accept: ItemTypes.BOX,
|
|
|
|
|
drop(item, monitor) {
|
|
|
|
|
let componentData = {};
|
|
|
|
|
let componentMeta = {};
|
|
|
|
|
let id = item.id;
|
|
|
|
|
|
|
|
|
|
let left = 0;
|
|
|
|
|
let top = 0;
|
|
|
|
|
|
2021-06-04 14:51:36 +00:00
|
|
|
let layouts = item['layouts'];
|
|
|
|
|
const currentLayoutOptions = layouts ? layouts[item.currentLayout] : {};
|
|
|
|
|
|
2021-05-09 18:06:11 +00:00
|
|
|
const canvasBoundingRect = parentRef.current.getElementsByClassName('real-canvas')[0].getBoundingClientRect();
|
|
|
|
|
|
|
|
|
|
// Component already exists and this is just a reposition event
|
|
|
|
|
if (id) {
|
|
|
|
|
const delta = monitor.getDifferenceFromInitialOffset();
|
|
|
|
|
componentData = item.component;
|
2021-11-16 11:44:09 +00:00
|
|
|
left = Math.round(convertXFromPercentage(currentLayoutOptions.left, canvasBoundingRect.width) + delta.x);
|
2021-06-04 14:51:36 +00:00
|
|
|
top = Math.round(currentLayoutOptions.top + delta.y);
|
|
|
|
|
|
|
|
|
|
if (snapToGrid) {
|
2021-11-16 11:44:09 +00:00
|
|
|
[left, top] = doSnapToGrid(canvasBoundingRect.width, left, top);
|
2021-06-04 14:51:36 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 11:44:09 +00:00
|
|
|
left = convertXToPercentage(left, canvasBoundingRect.width);
|
|
|
|
|
|
2021-09-21 13:48:28 +00:00
|
|
|
let newBoxes = {
|
2021-06-04 14:51:36 +00:00
|
|
|
...boxes,
|
|
|
|
|
[id]: {
|
|
|
|
|
...boxes[id],
|
|
|
|
|
parent: parent,
|
2021-09-21 13:48:28 +00:00
|
|
|
layouts: {
|
2021-06-04 14:51:36 +00:00
|
|
|
...boxes[id]['layouts'],
|
|
|
|
|
[item.currentLayout]: {
|
|
|
|
|
...boxes[id]['layouts'][item.currentLayout],
|
|
|
|
|
top: top,
|
|
|
|
|
left: left,
|
2021-09-21 13:48:28 +00:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-06-04 14:51:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
setBoxes(newBoxes);
|
2021-05-09 18:06:11 +00:00
|
|
|
} else {
|
|
|
|
|
// This is a new component
|
|
|
|
|
componentMeta = componentTypes.find((component) => component.component === item.component.component);
|
|
|
|
|
componentData = JSON.parse(JSON.stringify(componentMeta));
|
|
|
|
|
componentData.name = computeComponentName(componentData.component, boxes);
|
|
|
|
|
|
|
|
|
|
const offsetFromTopOfWindow = canvasBoundingRect.top;
|
|
|
|
|
const offsetFromLeftOfWindow = canvasBoundingRect.left;
|
|
|
|
|
const currentOffset = monitor.getSourceClientOffset();
|
2022-02-06 13:15:38 +00:00
|
|
|
const initialClientOffset = monitor.getInitialClientOffset();
|
|
|
|
|
const delta = monitor.getDifferenceFromInitialOffset();
|
2021-05-09 18:06:11 +00:00
|
|
|
|
2021-09-21 13:48:28 +00:00
|
|
|
left = Math.round(currentOffset.x + currentOffset.x * (1 - zoomLevel) - offsetFromLeftOfWindow);
|
2022-02-06 13:15:38 +00:00
|
|
|
top = Math.round(
|
|
|
|
|
initialClientOffset.y - 10 + delta.y + initialClientOffset.y * (1 - zoomLevel) - offsetFromTopOfWindow
|
|
|
|
|
);
|
2021-05-09 18:06:11 +00:00
|
|
|
|
|
|
|
|
id = uuidv4();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 11:44:09 +00:00
|
|
|
const subContainerWidth = canvasBoundingRect.width;
|
2021-05-09 18:06:11 +00:00
|
|
|
if (snapToGrid) {
|
2021-11-16 11:44:09 +00:00
|
|
|
[left, top] = doSnapToGrid(subContainerWidth, left, top);
|
2021-05-09 18:06:11 +00:00
|
|
|
}
|
|
|
|
|
|
2021-09-21 13:48:28 +00:00
|
|
|
if (item.currentLayout === 'mobile') {
|
2021-06-04 14:51:36 +00:00
|
|
|
componentData.definition.others.showOnDesktop.value = false;
|
|
|
|
|
componentData.definition.others.showOnMobile.value = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 11:44:09 +00:00
|
|
|
// convert the left offset to percentage
|
|
|
|
|
left = (left * 100) / subContainerWidth;
|
|
|
|
|
|
2021-12-10 03:13:05 +00:00
|
|
|
const width = (componentMeta.defaultSize.width * 100) / 43;
|
2021-11-16 11:44:09 +00:00
|
|
|
|
2021-05-09 18:06:11 +00:00
|
|
|
setBoxes({
|
|
|
|
|
...boxes,
|
|
|
|
|
[id]: {
|
|
|
|
|
component: componentData,
|
2021-11-22 16:11:26 +00:00
|
|
|
parent: parentRef.current.id,
|
2021-06-04 14:51:36 +00:00
|
|
|
layouts: {
|
2021-09-21 13:48:28 +00:00
|
|
|
[item.currentLayout]: {
|
2021-06-04 14:51:36 +00:00
|
|
|
top: top,
|
|
|
|
|
left: left,
|
2021-11-16 11:44:09 +00:00
|
|
|
width: width,
|
2021-06-04 14:51:36 +00:00
|
|
|
height: componentMeta.defaultSize.height,
|
2021-09-21 13:48:28 +00:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-05-09 18:06:11 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return undefined;
|
2021-09-21 13:48:28 +00:00
|
|
|
},
|
2021-05-09 18:06:11 +00:00
|
|
|
}),
|
|
|
|
|
[moveBox]
|
|
|
|
|
);
|
|
|
|
|
|
2021-11-16 11:44:09 +00:00
|
|
|
function getContainerCanvasWidth() {
|
2021-11-23 07:59:22 +00:00
|
|
|
if (containerCanvasWidth !== undefined) {
|
|
|
|
|
return containerCanvasWidth;
|
|
|
|
|
}
|
2021-11-16 11:44:09 +00:00
|
|
|
let width = 0;
|
|
|
|
|
if (parentRef.current) {
|
2021-11-23 07:59:22 +00:00
|
|
|
const realCanvas = parentRef.current.getElementsByClassName('real-canvas')[0];
|
|
|
|
|
if (realCanvas) {
|
|
|
|
|
const canvasBoundingRect = realCanvas.getBoundingClientRect();
|
|
|
|
|
width = canvasBoundingRect.width;
|
|
|
|
|
}
|
2021-11-16 11:44:09 +00:00
|
|
|
}
|
2021-11-23 07:59:22 +00:00
|
|
|
|
2021-11-16 11:44:09 +00:00
|
|
|
return width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onDragStop(e, componentId, direction, currentLayout) {
|
|
|
|
|
const canvasWidth = getContainerCanvasWidth();
|
|
|
|
|
const nodeBounds = direction.node.getBoundingClientRect();
|
|
|
|
|
|
|
|
|
|
const canvasBounds = parentRef.current.getElementsByClassName('real-canvas')[0].getBoundingClientRect();
|
|
|
|
|
|
|
|
|
|
// Computing the left offset
|
|
|
|
|
const leftOffset = nodeBounds.x - canvasBounds.x;
|
2022-05-11 09:13:13 +00:00
|
|
|
const currentLeftOffset = boxes[componentId].layouts[currentLayout].left;
|
|
|
|
|
const leftDiff = currentLeftOffset - convertXToPercentage(leftOffset, canvasWidth);
|
2021-11-16 11:44:09 +00:00
|
|
|
|
2022-05-11 09:13:13 +00:00
|
|
|
const topDiff = boxes[componentId].layouts[currentLayout].top - (nodeBounds.y - canvasBounds.y);
|
2021-11-16 11:44:09 +00:00
|
|
|
|
2022-05-11 09:13:13 +00:00
|
|
|
let newBoxes = { ...boxes };
|
|
|
|
|
|
|
|
|
|
if (selectedComponents) {
|
|
|
|
|
for (const selectedComponent of selectedComponents) {
|
|
|
|
|
newBoxes = produce(newBoxes, (draft) => {
|
|
|
|
|
const topOffset = draft[selectedComponent.id].layouts[currentLayout].top;
|
|
|
|
|
const leftOffset = draft[selectedComponent.id].layouts[currentLayout].left;
|
|
|
|
|
|
|
|
|
|
draft[selectedComponent.id].layouts[currentLayout].top = topOffset - topDiff;
|
|
|
|
|
draft[selectedComponent.id].layouts[currentLayout].left = leftOffset - leftDiff;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-16 11:44:09 +00:00
|
|
|
|
|
|
|
|
setBoxes(newBoxes);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 05:19:05 +00:00
|
|
|
function onResizeStop(id, e, direction, ref, d, position) {
|
2021-05-09 18:06:11 +00:00
|
|
|
const deltaWidth = d.width;
|
|
|
|
|
const deltaHeight = d.height;
|
|
|
|
|
|
2021-05-26 05:19:05 +00:00
|
|
|
let { x, y } = position;
|
|
|
|
|
|
2021-06-04 14:51:36 +00:00
|
|
|
const defaultData = {
|
|
|
|
|
top: 100,
|
|
|
|
|
left: 0,
|
|
|
|
|
width: 445,
|
2021-09-21 13:48:28 +00:00
|
|
|
height: 500,
|
2021-06-04 14:51:36 +00:00
|
|
|
};
|
|
|
|
|
|
2021-09-21 13:48:28 +00:00
|
|
|
let { left, top, width, height } = boxes[id]['layouts'][currentLayout] || defaultData;
|
|
|
|
|
|
2021-11-16 11:44:09 +00:00
|
|
|
const canvasBoundingRect = parentRef.current.getElementsByClassName('real-canvas')[0].getBoundingClientRect();
|
|
|
|
|
const subContainerWidth = canvasBoundingRect.width;
|
|
|
|
|
|
2021-05-26 05:19:05 +00:00
|
|
|
top = y;
|
2021-11-16 11:44:09 +00:00
|
|
|
left = (x * 100) / subContainerWidth;
|
2021-05-26 05:19:05 +00:00
|
|
|
|
2021-11-16 11:44:09 +00:00
|
|
|
width = width + (deltaWidth * 43) / subContainerWidth;
|
2021-09-21 13:48:28 +00:00
|
|
|
height = height + deltaHeight;
|
2021-05-26 05:19:05 +00:00
|
|
|
|
2021-09-21 13:48:28 +00:00
|
|
|
let newBoxes = {
|
2021-06-04 14:51:36 +00:00
|
|
|
...boxes,
|
|
|
|
|
[id]: {
|
|
|
|
|
...boxes[id],
|
2021-09-21 13:48:28 +00:00
|
|
|
layouts: {
|
2021-06-04 14:51:36 +00:00
|
|
|
...boxes[id]['layouts'],
|
|
|
|
|
[currentLayout]: {
|
|
|
|
|
...boxes[id]['layouts'][currentLayout],
|
2021-09-21 13:48:28 +00:00
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
top,
|
|
|
|
|
left,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-06-04 14:51:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
setBoxes(newBoxes);
|
2021-05-09 18:06:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function paramUpdated(id, param, value) {
|
|
|
|
|
if (Object.keys(value).length > 0) {
|
|
|
|
|
setBoxes(
|
|
|
|
|
update(boxes, {
|
|
|
|
|
[id]: {
|
|
|
|
|
$merge: {
|
|
|
|
|
component: {
|
|
|
|
|
...boxes[id].component,
|
|
|
|
|
definition: {
|
|
|
|
|
...boxes[id].component.definition,
|
|
|
|
|
properties: {
|
|
|
|
|
...boxes[id].component.definition.properties,
|
2021-09-21 13:48:28 +00:00
|
|
|
[param]: value,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-05-09 18:06:11 +00:00
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 11:44:09 +00:00
|
|
|
const styles = {
|
|
|
|
|
width: '100%',
|
|
|
|
|
height: '100%',
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
backgroundSize: `${getContainerCanvasWidth() / 43}px 10px`,
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-14 08:27:31 +00:00
|
|
|
function onComponentOptionChangedForSubcontainer(component, optionName, value, extraProps) {
|
2022-02-02 09:06:12 +00:00
|
|
|
if (parentComponent?.component === 'Listview') {
|
2022-01-28 07:52:55 +00:00
|
|
|
let newData = currentState.components[parentComponent.name]?.data || [];
|
|
|
|
|
newData[listViewItemOptions.index] = {
|
|
|
|
|
...newData[listViewItemOptions.index],
|
|
|
|
|
[component.name]: {
|
|
|
|
|
...(newData[listViewItemOptions.index] ? newData[listViewItemOptions.index][component.name] : {}),
|
|
|
|
|
[optionName]: value,
|
|
|
|
|
},
|
|
|
|
|
};
|
2022-02-28 11:58:56 +00:00
|
|
|
return onComponentOptionChanged(parentComponent, 'data', newData);
|
2022-01-28 07:52:55 +00:00
|
|
|
} else {
|
2022-02-28 11:58:56 +00:00
|
|
|
return onComponentOptionChanged(component, optionName, value, extraProps);
|
2022-01-28 07:52:55 +00:00
|
|
|
}
|
2022-01-14 08:27:31 +00:00
|
|
|
}
|
|
|
|
|
|
2022-01-31 11:18:58 +00:00
|
|
|
function customRemoveComponent(component) {
|
|
|
|
|
const componentName = appDefinition.components[component.id]['component'].name;
|
|
|
|
|
removeComponent(component);
|
|
|
|
|
if (parentComponent.component === 'Listview') {
|
|
|
|
|
const currentData = currentState.components[parentComponent.name]?.data || [];
|
|
|
|
|
const newData = currentData.map((widget) => {
|
|
|
|
|
delete widget[componentName];
|
|
|
|
|
return widget;
|
|
|
|
|
});
|
|
|
|
|
onComponentOptionChanged(parentComponent, 'data', newData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-09 18:06:11 +00:00
|
|
|
return (
|
2021-12-10 03:13:05 +00:00
|
|
|
<div
|
|
|
|
|
ref={drop}
|
|
|
|
|
style={styles}
|
|
|
|
|
id={`canvas-${parent}`}
|
2022-01-14 08:27:31 +00:00
|
|
|
className={`real-canvas ${(isDragging || isResizing) && !readOnly ? ' show-grid' : ''}`}
|
2021-12-10 03:13:05 +00:00
|
|
|
>
|
2022-02-21 18:04:02 +00:00
|
|
|
{Object.keys(childComponents).map((key) => (
|
2021-05-09 18:06:11 +00:00
|
|
|
<DraggableBox
|
|
|
|
|
onComponentClick={onComponentClick}
|
|
|
|
|
onEvent={onEvent}
|
2022-01-14 08:27:31 +00:00
|
|
|
onComponentOptionChanged={onComponentOptionChangedForSubcontainer}
|
2021-05-09 18:06:11 +00:00
|
|
|
onComponentOptionsChanged={onComponentOptionsChanged}
|
|
|
|
|
key={key}
|
|
|
|
|
currentState={currentState}
|
|
|
|
|
onResizeStop={onResizeStop}
|
2021-11-16 11:44:09 +00:00
|
|
|
onDragStop={onDragStop}
|
2021-05-09 18:06:11 +00:00
|
|
|
paramUpdated={paramUpdated}
|
|
|
|
|
id={key}
|
2022-01-14 08:27:31 +00:00
|
|
|
extraProps={{ listviewItemIndex: listViewItemOptions?.index }}
|
|
|
|
|
allComponents={allComponents}
|
|
|
|
|
{...childComponents[key]}
|
2021-05-10 11:36:33 +00:00
|
|
|
mode={mode}
|
2021-05-09 18:06:11 +00:00
|
|
|
resizingStatusChanged={(status) => setIsResizing(status)}
|
2021-11-16 11:44:09 +00:00
|
|
|
draggingStatusChanged={(status) => setIsDragging(status)}
|
2021-05-09 18:06:11 +00:00
|
|
|
inCanvas={true}
|
|
|
|
|
zoomLevel={zoomLevel}
|
2022-02-06 13:15:38 +00:00
|
|
|
setSelectedComponent={setSelectedComponent}
|
2021-06-04 14:51:36 +00:00
|
|
|
currentLayout={currentLayout}
|
2021-09-19 09:13:17 +00:00
|
|
|
selectedComponent={selectedComponent}
|
2021-06-04 14:51:36 +00:00
|
|
|
deviceWindowWidth={deviceWindowWidth}
|
2022-05-11 14:40:48 +00:00
|
|
|
isSelectedComponent={mode === 'edit' ? selectedComponents.find((component) => component.id === key) : false}
|
2022-01-31 11:18:58 +00:00
|
|
|
removeComponent={customRemoveComponent}
|
2022-03-10 11:51:46 +00:00
|
|
|
canvasWidth={_containerCanvasWidth}
|
2022-01-14 08:27:31 +00:00
|
|
|
readOnly={readOnly}
|
2022-02-03 02:55:15 +00:00
|
|
|
darkMode={darkMode}
|
2022-01-14 08:27:31 +00:00
|
|
|
customResolvables={customResolvables}
|
2022-02-03 07:07:34 +00:00
|
|
|
onComponentHover={onComponentHover}
|
|
|
|
|
hoveredComponent={hoveredComponent}
|
2022-02-02 09:06:12 +00:00
|
|
|
parentId={parentComponent?.name}
|
2022-05-11 09:13:13 +00:00
|
|
|
isMultipleComponentsSelected={selectedComponents?.length > 1 ? true : false}
|
2021-11-22 16:11:26 +00:00
|
|
|
containerProps={{
|
|
|
|
|
mode,
|
|
|
|
|
snapToGrid,
|
|
|
|
|
onComponentClick,
|
|
|
|
|
onEvent,
|
|
|
|
|
appDefinition,
|
|
|
|
|
appDefinitionChanged,
|
|
|
|
|
currentState,
|
|
|
|
|
onComponentOptionChanged,
|
|
|
|
|
onComponentOptionsChanged,
|
|
|
|
|
appLoading,
|
|
|
|
|
zoomLevel,
|
2022-02-06 13:15:38 +00:00
|
|
|
setSelectedComponent,
|
2021-11-22 16:11:26 +00:00
|
|
|
removeComponent,
|
|
|
|
|
currentLayout,
|
|
|
|
|
deviceWindowWidth,
|
2022-05-18 13:03:04 +00:00
|
|
|
selectedComponents,
|
2021-11-22 16:11:26 +00:00
|
|
|
darkMode,
|
2022-01-14 08:27:31 +00:00
|
|
|
readOnly,
|
2022-02-03 07:07:34 +00:00
|
|
|
onComponentHover,
|
|
|
|
|
hoveredComponent,
|
2021-11-22 16:11:26 +00:00
|
|
|
}}
|
2021-05-09 18:06:11 +00:00
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
|
|
{Object.keys(boxes).length === 0 && !appLoading && !isDragging && (
|
|
|
|
|
<div className="mx-auto mt-5 w-50 p-5 bg-light no-components-box">
|
2021-10-08 06:03:24 +00:00
|
|
|
<center className="text-muted">
|
2021-10-11 15:15:58 +00:00
|
|
|
Drag components from the right sidebar and drop here. Check out our{' '}
|
|
|
|
|
<a href="https://docs.tooljet.io/docs/tutorial/adding-widget" target="_blank" rel="noreferrer">
|
|
|
|
|
guide
|
|
|
|
|
</a>{' '}
|
|
|
|
|
on adding widgets.
|
2021-10-08 06:03:24 +00:00
|
|
|
</center>
|
2021-05-09 18:06:11 +00:00
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{appLoading && (
|
|
|
|
|
<div className="mx-auto mt-5 w-50 p-5">
|
|
|
|
|
<center>
|
|
|
|
|
<div className="progress progress-sm w-50">
|
|
|
|
|
<div className="progress-bar progress-bar-indeterminate"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</center>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|