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;