From b2879a1ddbf99dcc0d068aee5851df701cde53ba Mon Sep 17 00:00:00 2001 From: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com> Date: Fri, 8 Jul 2022 17:23:47 +0530 Subject: [PATCH] [Feature]: Re-Order Events (#3381) * Re-Order Events * Changed logic in reorder events --- .../src/Editor/Inspector/EventManager.jsx | 204 +++++++++++++----- frontend/src/Editor/Inspector/Inspector.jsx | 12 +- frontend/src/_hooks/useDraggableInPortal.js | 31 +++ 3 files changed, 190 insertions(+), 57 deletions(-) create mode 100644 frontend/src/_hooks/useDraggableInPortal.js diff --git a/frontend/src/Editor/Inspector/EventManager.jsx b/frontend/src/Editor/Inspector/EventManager.jsx index b1226c9690..8cc45c2177 100644 --- a/frontend/src/Editor/Inspector/EventManager.jsx +++ b/frontend/src/Editor/Inspector/EventManager.jsx @@ -4,6 +4,8 @@ import OverlayTrigger from 'react-bootstrap/OverlayTrigger'; import Popover from 'react-bootstrap/Popover'; import { CodeHinter } from '../CodeBuilder/CodeHinter'; import { GotoApp } from './ActionConfigurationPanels/GotoApp'; +import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; +import useDraggableInPortal from '@/_hooks/useDraggableInPortal'; import _ from 'lodash'; import { componentTypes } from '../WidgetManager/components'; import Select from '@/_ui/Select'; @@ -603,62 +605,156 @@ export const EventManager = ({ ); } - function renderHandlers(events) { - return events.map((event, index) => { - const actionMeta = ActionTypes.find((action) => action.id === event.actionId); - const rowClassName = `row g-0 border-bottom pb-2 pt-2 px-2 ${focusedEventIndex === index ? ' bg-azure-lt' : ''}`; + const reorderEvents = (startIndex, endIndex) => { + const result = [...component.component.definition.events]; + const [removed] = result.splice(startIndex, 1); + result.splice(endIndex, 0, removed); + eventsChanged(result, true); + }; - return ( -
- setFocusedEventIndex(null)} - onToggle={(showing) => { - if (showing) { - setFocusedEventIndex(index); - } else { - setFocusedEventIndex(null); - } - if (typeof popOverCallback === 'function') popOverCallback(showing); - }} - > -
-
-
-
- {componentMeta.events[event.eventId]['displayName']} -
-
- {actionMeta.name} -
-
- { - e.stopPropagation(); - removeHandler(index); - }} - data-cy="delete-button" - > - - - - -
-
-
+ const onDragEnd = ({ source, destination }) => { + if (!destination || source?.index === destination?.index) { + return; + } + reorderEvents(source.index, destination.index); + }; + + const renderDraggable = useDraggableInPortal(); + + const renderHandlers = (events) => { + return ( + { + onDragEnd(result); + }} + className="w-100" + > + + {({ innerRef, droppableProps, placeholder }) => ( +
+ {events.map((event, index) => { + const actionMeta = ActionTypes.find((action) => action.id === event.actionId); + const rowClassName = `card-body p-0 ${focusedEventIndex === index ? ' bg-azure-lt' : ''}`; + return ( + + {renderDraggable((provided, snapshot) => { + if (snapshot.isDragging && focusedEventIndex !== null) { + setFocusedEventIndex(null); + document.body.click(); // Hack: Close overlay while dragging + } + return ( + setFocusedEventIndex(null)} + onToggle={(showing) => { + if (showing) { + setFocusedEventIndex(index); + } else { + setFocusedEventIndex(null); + } + if (typeof popOverCallback === 'function') popOverCallback(showing); + }} + > +
+
+
+
+
+ + + + + + + + +
+
+ {componentMeta.events[event.eventId]['displayName']} +
+
+ + {actionMeta.name} + +
+
+ { + e.stopPropagation(); + removeHandler(index); + }} + data-cy="delete-button" + > + + + + +
+
+
+
+
+
+ ); + })} +
+ ); + })} + {placeholder}
- -
- ); - }); - } + )} + + + ); + }; const events = component.component.definition.events || []; const componentName = componentMeta.name ? componentMeta.name : 'query'; diff --git a/frontend/src/Editor/Inspector/Inspector.jsx b/frontend/src/Editor/Inspector/Inspector.jsx index 872c2ecf64..f56bc2fc02 100644 --- a/frontend/src/Editor/Inspector/Inspector.jsx +++ b/frontend/src/Editor/Inspector/Inspector.jsx @@ -212,9 +212,15 @@ export const Inspector = ({ componentDefinitionChanged(newComponent); } - function eventsChanged(newEvents) { - let newDefinition = { ...component.component.definition }; - newDefinition.events = newEvents; + function eventsChanged(newEvents, isReordered = false) { + let newDefinition; + if (isReordered) { + newDefinition = { ...component.component }; + newDefinition.definition.events = newEvents; + } else { + newDefinition = { ...component.component.definition }; + newDefinition.events = newEvents; + } let newComponent = { ...component, diff --git a/frontend/src/_hooks/useDraggableInPortal.js b/frontend/src/_hooks/useDraggableInPortal.js new file mode 100644 index 0000000000..4ef18a16ac --- /dev/null +++ b/frontend/src/_hooks/useDraggableInPortal.js @@ -0,0 +1,31 @@ +import { useRef, useEffect } from 'react'; +import { createPortal } from 'react-dom'; + +const useDraggableInPortal = () => { + const self = useRef({}).current; + + useEffect(() => { + const div = document.createElement('div'); + div.style.position = 'absolute'; + div.style.pointerEvents = 'none'; + div.style.top = '0'; + div.style.width = '100%'; + div.style.height = '100%'; + self.elt = div; + document.body.appendChild(div); + return () => { + document.body.removeChild(div); + }; + }, [self]); + + return (render) => + (provided, ...args) => { + const element = render(provided, ...args); + if (provided.draggableProps.style.position === 'fixed') { + return createPortal(element, self.elt); + } + return element; + }; +}; + +export default useDraggableInPortal;