diff --git a/frontend/src/metadata/components/popover/groupbys-popover/groupbys/groupby-item.js b/frontend/src/metadata/components/popover/groupbys-popover/groupbys/groupby-item.js
index e8cc5f0c0d..b434dcce39 100644
--- a/frontend/src/metadata/components/popover/groupbys-popover/groupbys/groupby-item.js
+++ b/frontend/src/metadata/components/popover/groupbys-popover/groupbys/groupby-item.js
@@ -21,7 +21,7 @@ const GroupbyItem = ({ showDragBtn, index, readOnly, groupby, columns, onDelete,
const [dropPosition, setDropPosition] = useState(null);
- const [, drag] = useDrag({
+ const [, drag, preview] = useDrag({
type: 'sfMetadataGroupbyItem',
item: () => ({
idx: index,
@@ -54,7 +54,7 @@ const GroupbyItem = ({ showDragBtn, index, readOnly, groupby, columns, onDelete,
})
});
- const dragDropRef = drag(drop(ref));
+ drop(preview(ref));
const column = useMemo(() => {
return getColumnByKey(columns, groupby.column_key);
@@ -160,7 +160,7 @@ const GroupbyItem = ({ showDragBtn, index, readOnly, groupby, columns, onDelete,
return (
+
)}
diff --git a/frontend/src/metadata/components/popover/options-popover/option/index.css b/frontend/src/metadata/components/popover/options-popover/option/index.css
index 310cf6f8f7..5f83cb5f26 100644
--- a/frontend/src/metadata/components/popover/options-popover/option/index.css
+++ b/frontend/src/metadata/components/popover/options-popover/option/index.css
@@ -49,19 +49,28 @@
fill: #212529;
}
-.sf-metadata-edit-option-container.sf-metadata-edit-option-can-drop {
- border-bottom: 1px solid #666;
-}
-
-.sf-metadata-edit-option-container.sf-metadata-edit-option-can-drop-top::before {
+.sf-metadata-edit-option-container.sf-metadata-edit-option-drop-over-top::before {
content: '';
- width: 100%;
- height: 1px;
- background: #666;
- display: block;
position: absolute;
top: 0;
left: 0;
+ width: 100%;
+ height: 2px;
+ background-color: rgb(200, 220, 240);
+ border-radius: 2px;
+ z-index: 1;
+}
+
+.sf-metadata-edit-option-container.sf-metadata-edit-option-drop-over-bottom::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 2px;
+ background-color: rgb(200, 220, 240);
+ border-radius: 2px;
+ z-index: 1;
}
.sf-metadata-edit-option-container.sf-metadata-edit-deleting-option,
diff --git a/frontend/src/metadata/components/popover/options-popover/option/index.js b/frontend/src/metadata/components/popover/options-popover/option/index.js
index 4a181d0a1d..ecdb5ae916 100644
--- a/frontend/src/metadata/components/popover/options-popover/option/index.js
+++ b/frontend/src/metadata/components/popover/options-popover/option/index.js
@@ -1,4 +1,4 @@
-import React, { useCallback } from 'react';
+import React, { useCallback, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { useDrag, useDrop } from 'react-dnd';
import classnames from 'classnames';
@@ -9,74 +9,50 @@ import Name from './name';
import './index.css';
-// const dragSource = {
-// beginDrag: props => {
-// return { idx: props.index, data: props.option, mode: 'sfMetadataSingleSelectOption' };
-// },
-// endDrag(props, monitor) {
-// const optionSource = monitor.getItem();
-// const didDrop = monitor.didDrop();
-// let optionTarget = {};
-// if (!didDrop) {
-// return { optionSource, optionTarget };
-// }
-// },
-// isDragging(props, monitor) {
-// const { index, dragged } = props;
-// const { idx } = dragged;
-// return idx > index;
-// }
-// };
-
-// const dragCollect = (connect, monitor) => ({
-// connectDragSource: connect.dragSource(),
-// connectDragPreview: connect.dragPreview(),
-// isDragging: monitor.isDragging()
-// });
-
-// const dropTarget = {
-// drop(props, monitor) {
-// const optionSource = monitor.getItem();
-// const { index: targetIdx } = props;
-// if (targetIdx !== optionSource.idx) {
-// const optionTarget = { idx: targetIdx, data: props.option };
-// props.onMove(optionSource, optionTarget);
-// }
-// }
-// };
-
-// const dropCollect = (connect, monitor) => ({
-// connectDropTarget: connect.dropTarget(),
-// isOver: monitor.isOver(),
-// canDrop: monitor.canDrop(),
-// dragged: monitor.getItem()
-// });
-
const Option = ({
isViewing, isDeleting, isEditing, isPredefined,
- option,
- onDelete: propsDelete, onUpdate,
+ option, index,
+ onDelete: propsDelete, onUpdate, onMove,
onMouseLeave, onMouseEnter: propsMouseEnter, onToggleFreeze, onOpenNameEditor, onCloseNameEditor,
}) => {
- const [{ isDragging }, drag] = useDrag({
+ const ref = useRef(null);
+ const [dropPosition, setDropPosition] = useState(null);
+
+ const [, drag, preview] = useDrag({
type: 'sfMetadataSingleSelectOption',
item: () => ({
- idx: option.id,
+ idx: index,
data: option,
}),
- collect: (monitor) => ({
- isDragging: monitor.isDragging(),
- }),
});
const [{ isOver, canDrop }, drop] = useDrop({
accept: 'sfMetadataSingleSelectOption',
+ hover: (item, monitor) => {
+ if (!ref.current) return;
+
+ const hoverBoundingRect = ref.current.getBoundingClientRect();
+ const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
+ const clientOffset = monitor.getClientOffset();
+ const hoverClientY = clientOffset.y - hoverBoundingRect.top;
+
+ const newPosition = hoverClientY < hoverMiddleY ? 'top' : 'bottom';
+ setDropPosition(newPosition);
+ },
+ drop: (item) => {
+ if (item.idx === index) return;
+ if (item.idx === index - 1 && dropPosition === 'top') return;
+ if (item.idx === index + 1 && dropPosition === 'bottom') return;
+ onMove(item, { idx: index, data: option });
+ },
collect: (monitor) => ({
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
})
});
+ drop(preview(ref));
+
const onDelete = useCallback((event) => {
event.nativeEvent.stopImmediatePropagation();
propsDelete(option.id);
@@ -88,11 +64,11 @@ const Option = ({
return (
drag(drop(node))}
+ ref={ref}
className={classnames('sf-metadata-edit-option-container', {
- 'sf-metadata-edit-option-can-drop': isOver && canDrop && !isDragging,
'sf-metadata-edit-deleting-option': isDeleting,
- 'sf-metadata-edit-option-can-drop-top': isOver && canDrop && isDragging,
+ 'sf-metadata-edit-option-drop-over-top': isOver && canDrop && dropPosition === 'top',
+ 'sf-metadata-edit-option-drop-over-bottom': isOver && canDrop && dropPosition === 'bottom',
'sf-metadata-edit-option-viewing': isViewing,
'sf-metadata-edit-option-editing': isEditing,
'sf-metadata-edit-option-disabled': isPredefined,
@@ -100,7 +76,7 @@ const Option = ({
onMouseEnter={() => onMouseEnter()}
onMouseLeave={onMouseLeave}
>
-
+
@@ -125,7 +101,6 @@ const Option = ({
};
Option.propTypes = {
- // normal
option: PropTypes.object,
index: PropTypes.number,
isPredefined: PropTypes.bool,
@@ -140,14 +115,6 @@ Option.propTypes = {
onToggleFreeze: PropTypes.func,
onOpenNameEditor: PropTypes.func.isRequired,
onCloseNameEditor: PropTypes.func.isRequired,
-
- // // drag
- // isOver: PropTypes.bool,
- // canDrop: PropTypes.bool,
- // dragged: PropTypes.object,
- // connectDragSource: PropTypes.func.isRequired,
- // connectDropTarget: PropTypes.func.isRequired,
- // connectDragPreview: PropTypes.func.isRequired,
};
export default Option;