Skip to content

Commit

Permalink
Ability to select multiple widgets from canvas and change their posit…
Browse files Browse the repository at this point in the history
…ion (ToolJet#2979)

* Better canvas

* fixes sets the active node to the selected widget on the editor

* removing selectedComponent and fixing currentTab msg alignment for inspector

* useKeyHooks custom hotkey hook

* handles escape key on editor

* handles delete for multiple widgets

* removes unwanted comments

* fixes: all the widgets are deleted at once, in a single action

* hide delete button from widegt config handler when multiple components are selected

* fixes delete button width for long chars

* Revert "fixes delete button width for long chars"

This reverts commit 79dadfa.

* fixes display config handler for selected widgets on layout/container widgets

* subcontainer layer dnd improvement for multi-widget

Co-authored-by: arpitnath <arpitnath42@gmail.com>
  • Loading branch information
Navaneeth-pk and arpitnath authored May 11, 2022
1 parent 4b9f49e commit e8ca5cb
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 81 deletions.
27 changes: 15 additions & 12 deletions frontend/src/Editor/ConfigHandle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const ConfigHandle = function ConfigHandle({
position,
widgetTop,
widgetHeight,
isMultipleComponentsSelected = false,
}) {
return (
<div
Expand All @@ -24,7 +25,7 @@ export const ConfigHandle = function ConfigHandle({
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
setSelectedComponent(id, component);
setSelectedComponent(id, component, e.shiftKey);
}}
role="button"
>
Expand All @@ -37,17 +38,19 @@ export const ConfigHandle = function ConfigHandle({
/>
<span>{component.name}</span>
</div>
<div className="delete-part">
<img
style={{ cursor: 'pointer', marginLeft: '5px' }}
src="/assets/images/icons/trash-light.svg"
width="12"
role="button"
height="12"
draggable="false"
onClick={() => removeComponent({ id })}
/>
</div>
{!isMultipleComponentsSelected && (
<div className="delete-part">
<img
style={{ cursor: 'pointer', marginLeft: '5px' }}
src="/assets/images/icons/trash-light.svg"
width="12"
role="button"
height="12"
draggable="false"
onClick={() => removeComponent({ id })}
/>
</div>
)}
</span>
</div>
);
Expand Down
44 changes: 23 additions & 21 deletions frontend/src/Editor/Container.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-named-as-default */
import React, { useCallback, useState, useEffect, useRef } from 'react';
import cx from 'classnames';
import { v4 as uuidv4 } from 'uuid';
Expand All @@ -14,6 +15,7 @@ import { commentsService } from '@/_services';
import config from 'config';
import Spinner from '@/_ui/Spinner';
import { useHotkeys } from 'react-hotkeys-hook';
import produce from 'immer';

export const Container = ({
canvasWidth,
Expand All @@ -33,7 +35,7 @@ export const Container = ({
currentLayout,
removeComponent,
deviceWindowWidth,
selectedComponent,
selectedComponents,
darkMode,
showComments,
appVersionsId,
Expand Down Expand Up @@ -211,7 +213,7 @@ export const Container = ({
);

function onDragStop(e, componentId, direction, currentLayout) {
const id = componentId ? componentId : uuidv4();
// const id = componentId ? componentId : uuidv4();

// Get the width of the canvas
const canvasBounds = document.getElementsByClassName('real-canvas')[0].getBoundingClientRect();
Expand All @@ -220,25 +222,24 @@ export const Container = ({

// Computing the left offset
const leftOffset = nodeBounds.x - canvasBounds.x;
const left = convertXToPercentage(leftOffset, canvasWidth);
const currentLeftOffset = boxes[componentId].layouts[currentLayout].left;
const leftDiff = currentLeftOffset - convertXToPercentage(leftOffset, canvasWidth);

// Computing the top offset
const top = nodeBounds.y - canvasBounds.y;
// const currentTopOffset = boxes[componentId].layouts[currentLayout].top;
const topDiff = boxes[componentId].layouts[currentLayout].top - (nodeBounds.y - canvasBounds.y);

let newBoxes = {
...boxes,
[id]: {
...boxes[id],
layouts: {
...boxes[id]['layouts'],
[currentLayout]: {
...boxes[id]['layouts'][currentLayout],
top: top,
left: left,
},
},
},
};
let newBoxes = { ...boxes };

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;
});
}

setBoxes(newBoxes);
}
Expand Down Expand Up @@ -310,7 +311,7 @@ export const Container = ({
}
}

React.useEffect(() => {}, [selectedComponent]);
React.useEffect(() => {}, [selectedComponents]);

const handleAddThread = async (e) => {
e.stopPropogation && e.stopPropogation();
Expand Down Expand Up @@ -466,10 +467,11 @@ export const Container = ({
removeComponent={removeComponent}
currentLayout={currentLayout}
deviceWindowWidth={deviceWindowWidth}
isSelectedComponent={selectedComponent ? selectedComponent.id === key : false}
isSelectedComponent={selectedComponents.find((component) => component.id === key)}
darkMode={darkMode}
onComponentHover={onComponentHover}
hoveredComponent={hoveredComponent}
isMultipleComponentsSelected={selectedComponents?.length > 1 ? true : false}
dataQueries={dataQueries}
containerProps={{
mode,
Expand All @@ -487,7 +489,7 @@ export const Container = ({
removeComponent,
currentLayout,
deviceWindowWidth,
selectedComponent,
selectedComponents,
darkMode,
onComponentHover,
hoveredComponent,
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/Editor/DraggableBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const DraggableBox = function DraggableBox({
parentId,
hoveredComponent,
onComponentHover,
isMultipleComponentsSelected,
dataQueries,
}) {
const [isResizing, setResizing] = useState(false);
Expand Down Expand Up @@ -220,7 +221,7 @@ export const DraggableBox = function DraggableBox({
mouseOver || isResizing || isDragging2 || isSelectedComponent ? 'resizer-active' : ''
} `}
onResize={() => setResizing(true)}
onDrag={(e) => {
onDrag={(e, direction) => {
e.preventDefault();
e.stopImmediatePropagation();
if (!isDragging2) {
Expand Down Expand Up @@ -252,7 +253,10 @@ export const DraggableBox = function DraggableBox({
position={currentLayoutOptions.top < 15 ? 'bottom' : 'top'}
widgetTop={currentLayoutOptions.top}
widgetHeight={currentLayoutOptions.height}
setSelectedComponent={(id, component) => setSelectedComponent(id, component)}
setSelectedComponent={(id, component, multiSelect) =>
setSelectedComponent(id, component, multiSelect)
}
isMultipleComponentsSelected={isMultipleComponentsSelected}
/>
)}
<ErrorBoundary showFallback={mode === 'edit'}>
Expand Down
Loading

0 comments on commit e8ca5cb

Please sign in to comment.