diff --git a/frontend/src/metadata/views/table/table-main/records-header/cell/index.css b/frontend/src/metadata/views/table/table-main/records-header/cell/index.css index 1460e6f194..04ce4b8d56 100644 --- a/frontend/src/metadata/views/table/table-main/records-header/cell/index.css +++ b/frontend/src/metadata/views/table/table-main/records-header/cell/index.css @@ -8,10 +8,38 @@ transform: scale(.8); } +.sf-metadata-record-header-cell .sf-metadata-result-table-cell.column.name-column { + cursor: default; +} + .sf-metadata-record-header-cell .rdg-can-drop > .sf-metadata-result-table-cell.column { cursor: move; } .sf-metadata-record-header-cell .rdg-dropping > .sf-metadata-result-table-cell.column { background: #ececec; + position: relative; +} + +.sf-metadata-record-header-cell .rdg-dropping-position > .sf-metadata-result-table-cell.column::before { + content: ''; + position: absolute; + top: 10%; + height: 80%; + width: 1px; + background-color: #2d7ff9; + border-radius: 50%; + z-index: 1; +} + +.sf-metadata-record-header-cell .rdg-dropping-position-left > .sf-metadata-result-table-cell.column::before { + left: -1px; +} + +.sf-metadata-record-header-cell .rdg-dropping-position-right > .sf-metadata-result-table-cell.column::before { + right: -1px; +} + +.sf-metadata-record-header-cell .rdg-dropping-position-none > .sf-metadata-result-table-cell.column::before { + display: none; } diff --git a/frontend/src/metadata/views/table/table-main/records-header/cell/index.js b/frontend/src/metadata/views/table/table-main/records-header/cell/index.js index 8f5fab0569..ac5ffb42f4 100644 --- a/frontend/src/metadata/views/table/table-main/records-header/cell/index.js +++ b/frontend/src/metadata/views/table/table-main/records-header/cell/index.js @@ -2,98 +2,36 @@ import React, { useRef, useCallback, useMemo } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { UncontrolledTooltip } from 'reactstrap'; -import { DragSource, DropTarget } from 'react-dnd'; import { Icon } from '@seafile/sf-metadata-ui-component'; import ResizeColumnHandle from './resize-column-handle'; import DropdownMenu from './dropdown-menu'; import { gettext } from '../../../../../../utils/constants'; -import { COLUMNS_ICON_CONFIG, COLUMNS_ICON_NAME, EVENT_BUS_TYPE } from '../../../../../constants'; +import { COLUMNS_ICON_CONFIG, COLUMNS_ICON_NAME, EVENT_BUS_TYPE, PRIVATE_COLUMN_KEY } from '../../../../../constants'; import './index.css'; - -const dragSource = { - beginDrag: props => { - return { key: props.column.key, column: props.column }; - }, - endDrag(props, monitor) { - const source = monitor.getItem(); - const didDrop = monitor.didDrop(); - let target = {}; - if (!didDrop) { - return { source, target }; - } - }, - isDragging(props) { - const { column, dragged } = props; - const { key } = dragged; - return key === column.key; - } -}; - -const dropTarget = { - hover(props, monitor, component) { - // This is fired very often and lets you perform side effects. - if (!window.sfMetadataBody) return; - let defaultColumnWidth = 200; - const offsetX = monitor.getClientOffset().x; - const width = document.querySelector('.sf-metadata-wrapper')?.clientWidth; - const left = window.innerWidth - width; - if (width <= 800) { - defaultColumnWidth = 20; - } - if (offsetX > window.innerWidth - defaultColumnWidth) { - window.sfMetadataBody.scrollToRight(); - } else if (offsetX < props.frozenColumnsWidth + defaultColumnWidth + left) { - window.sfMetadataBody.scrollToLeft(); - } else { - window.sfMetadataBody.clearHorizontalScroll(); - } - }, - drop(props, monitor) { - const source = monitor.getItem(); - const { column: targetColumn } = props; - if (targetColumn.key !== source.key && source.column.frozen === targetColumn.frozen) { - let target = { key: targetColumn.key }; - props.onMove(source, target); - window.sfMetadataBody.clearHorizontalScroll(); - } - } -}; - -const dragCollect = (connect, monitor) => ({ - connectDragSource: connect.dragSource(), - connectDragPreview: connect.dragPreview(), - isDragging: monitor.isDragging(), -}); - -const dropCollect = (connect, monitor) => ({ - connectDropTarget: connect.dropTarget(), - isOver: monitor.isOver(), - canDrop: monitor.canDrop(), - dragged: monitor.getItem(), -}); - const Cell = ({ - isOver, - isDragging, - canDrop, - connectDragSource, - connectDragPreview, - connectDropTarget, frozen, groupOffsetLeft, isLastFrozenCell, height, isHideTriangle, column, + columnIndex, style: propsStyle, + draggingColumnKey, + draggingColumnIndex, + dragOverColumnKey, view, + frozenColumnsWidth, renameColumn, deleteColumn, modifyColumnData, modifyLocalColumnWidth, modifyColumnWidth, + onMove, + updateDraggingKey, + updateDragOverKey, }) => { const headerCellRef = useRef(null); @@ -120,14 +58,14 @@ const Cell = ({ return right - left; }, []); - const onDrag = useCallback((e) => { + const onDraggingColumnWidth = useCallback((e) => { const width = getWidthFromMouseEvent(e); if (width > 0) { modifyLocalColumnWidth(column, width); } }, [column, getWidthFromMouseEvent, modifyLocalColumnWidth]); - const onDragEnd = useCallback((e) => { + const handleColumnWidth = useCallback((e) => { const width = getWidthFromMouseEvent(e); if (width > 0) { modifyColumnWidth(column, Math.max(width, 50)); @@ -143,12 +81,65 @@ const Cell = ({ event.stopPropagation(); }, []); + const onDragStart = useCallback((event) => { + const dragData = JSON.stringify({ type: 'sf-metadata-view-header-order', column_key: column.key, column }); + event.dataTransfer.effectAllowed = 'move'; + event.dataTransfer.setData('application/drag-sf-metadata-view-header-order', dragData); + updateDraggingKey(column.key); + }, [column, updateDraggingKey]); + + const onDragEnter = useCallback(() => { + updateDragOverKey(column.key); + }, [column, updateDragOverKey]); + + const onDragLeave = useCallback(() => { + updateDragOverKey(null); + }, [updateDragOverKey]); + + const onDragOver = useCallback((event) => { + event.preventDefault(); + event.dataTransfer.dropEffect = 'move'; + updateDragOverKey(column.key); + if (!window.sfMetadataBody) return; + let defaultColumnWidth = 200; + const offsetX = event.clientX; + const width = document.querySelector('.sf-metadata-wrapper')?.clientWidth; + const left = window.innerWidth - width; + if (width <= 800) { + defaultColumnWidth = 20; + } + if (offsetX > window.innerWidth - defaultColumnWidth) { + window.sfMetadataBody.scrollToRight(); + } else if (offsetX < frozenColumnsWidth + defaultColumnWidth + left) { + window.sfMetadataBody.scrollToLeft(); + } else { + window.sfMetadataBody.clearHorizontalScroll(); + } + }, [column, frozenColumnsWidth, updateDragOverKey]); + + const onDrop = useCallback((event) => { + event.stopPropagation(); + let dragData = event.dataTransfer.getData('application/drag-sf-metadata-view-header-order'); + if (!dragData) return false; + dragData = JSON.parse(dragData); + if (dragData.type !== 'sf-metadata-view-header-order' || !dragData.column_key) return false; + if (dragData.column_key !== column.key && dragData.column.frozen === column.frozen) { + onMove && onMove({ key: dragData.column_key }, { key: column.key }); + } + }, [column, onMove]); + + const onDragEnd = useCallback(() => { + updateDraggingKey(null); + updateDragOverKey(null); + }, [updateDraggingKey, updateDragOverKey]); + const { key, name, type } = column; const headerIconTooltip = COLUMNS_ICON_NAME[type]; const canModifyColumnOrder = window.sfMetadataContext.canModifyColumnOrder(); + const isNameColumn = key === PRIVATE_COLUMN_KEY.FILE_NAME; const cell = (
)} -