diff --git a/frontend/src/Editor/Components/Table/Table.jsx b/frontend/src/Editor/Components/Table/Table.jsx index 75466ad130..1e28042129 100644 --- a/frontend/src/Editor/Components/Table/Table.jsx +++ b/frontend/src/Editor/Components/Table/Table.jsx @@ -11,6 +11,7 @@ import { useBlockLayout, useResizeColumns, useRowSelect, + useColumnOrder, } from 'react-table'; import cx from 'classnames'; import { resolveReferences, validateWidget } from '@/_helpers/utils'; @@ -28,6 +29,7 @@ import generateActionsData from './columns/actions'; import autogenerateColumns from './columns/autogenerateColumns'; import IndeterminateCheckbox from './IndeterminateCheckbox'; import { useTranslation } from 'react-i18next'; +import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; // eslint-disable-next-line import/no-unresolved import { IconEyeOff } from '@tabler/icons'; import * as XLSX from 'xlsx/xlsx.mjs'; @@ -86,6 +88,22 @@ export function Table({ disabledSort, } = loadPropertiesAndStyles(properties, styles, darkMode, component); + const getItemStyle = ({ isDragging, isDropAnimating }, draggableStyle) => ({ + ...draggableStyle, + userSelect: 'none', + background: isDragging ? 'rgba(77, 114, 250, 0.2)' : '', + top: 'auto', + borderRadius: '4px', + ...(isDragging && { + marginLeft: '-120px', + display: 'flex', + alignItems: 'center', + paddingLeft: '10px', + height: '30px', + }), + ...(!isDragging && { transform: 'translate(0,0)', width: '100%' }), + ...(isDropAnimating && { transitionDuration: '0.001s' }), + }); const { t } = useTranslation(); const [tableDetails, dispatch] = useReducer(reducer, initialState()); @@ -340,12 +358,13 @@ export function Table({ setAllFilters, preGlobalFilteredRows, setGlobalFilter, + allColumns, + setColumnOrder, state: { pageIndex, globalFilter }, exportData, selectedFlatRows, globalFilteredRows, getToggleHideAllColumnsProps, - allColumns, } = useTable( { autoResetPage: false, @@ -363,6 +382,7 @@ export function Table({ disableSortBy: disabledSort, manualSortBy: serverSideSort, }, + useColumnOrder, useFilters, useGlobalFilter, useSortBy, @@ -393,6 +413,7 @@ export function Table({ ]); } ); + const currentColOrder = React.useRef(); const sortOptions = useMemo(() => { if (state?.sortBy?.length === 0) { @@ -609,27 +630,75 @@ export function Table({ {headerGroups.map((headerGroup, index) => ( - - {headerGroup.headers.map((column, index) => ( - - {column.render('Header')} - -
{ - e.preventDefault(); - e.stopPropagation(); - }} - draggable="true" - {...column.getResizerProps()} - className={`resizer ${column.isResizing ? 'isResizing' : ''}`} - /> - - ))} -
+ {headerGroup.headers.map((column, index) => ( + + {(provided, snapshot) => { + return ( + + ); + }} + + ))} + + )} + + ))} diff --git a/frontend/src/_styles/theme.scss b/frontend/src/_styles/theme.scss index 780d545a65..57c0a968bf 100644 --- a/frontend/src/_styles/theme.scss +++ b/frontend/src/_styles/theme.scss @@ -1902,8 +1902,8 @@ button { border-right: 5px solid transparent; border-top: 5px solid #767676; border-bottom: 5px solid transparent; - left: 6px; - top: 8px; + left: 0px; + top: 7px; } .sort-asc:after { @@ -1911,8 +1911,8 @@ button { border-right: 5px solid transparent; border-top: 0px solid transparent; border-bottom: 5px solid #767676; - left: 6px; - bottom: 8px; + left: 0px; + top: 7px; } } @@ -3441,6 +3441,9 @@ input:focus-visible { .gui-select-wrappper .select-search__input { height: 30px; } +.table thead th { + display: flex !important; +} .theme-dark .input-group-text, .theme-dark .markdown>table thead th,
-
{ + currentColOrder.current = allColumns?.map((o) => o.id); + }} + onDragUpdate={(dragUpdateObj) => { + const colOrder = [...currentColOrder.current]; + const sIndex = dragUpdateObj.source.index; + const dIndex = dragUpdateObj.destination && dragUpdateObj.destination.index; + + if (typeof sIndex === 'number' && typeof dIndex === 'number') { + colOrder.splice(sIndex, 1); + colOrder.splice(dIndex, 0, dragUpdateObj.draggableId); + setColumnOrder(colOrder); + } + }} + > + + {(droppableProvided, snapshot) => ( +
+
+ {column.render('Header')} +
+
{ + e.preventDefault(); + e.stopPropagation(); + }} + draggable="true" + {...column.getResizerProps()} + className={`resizer ${column.isResizing ? 'isResizing' : ''}`} + /> +