`;
+
+exports[`AnalyticalTable test drag and drop of a draggable column 1`] = `
+
+
+
+ Test
+
+
+
+
+
+
+
+
+
+
+ 40
+
+
+
+
+ Fra
+
+
+
+
+ MAR
+
+
+
+
+ 28
+
+
+
+
+
+
+ 20
+
+
+
+
+ bla
+
+
+
+
+ Nei
+
+
+
+
+ 50
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/packages/main/src/components/AnalyticalTable/demo/demo.stories.tsx b/packages/main/src/components/AnalyticalTable/demo/demo.stories.tsx
index bdb2594787b..f6721ae0b45 100644
--- a/packages/main/src/components/AnalyticalTable/demo/demo.stories.tsx
+++ b/packages/main/src/components/AnalyticalTable/demo/demo.stories.tsx
@@ -79,6 +79,7 @@ export const defaultTable = () => {
groupBy={array('groupBy', [])}
rowHeight={number('rowHeight', 60)}
selectedRowKey={text('selectedRowKey', `row_5`)}
+ onColumnsReordered={action('onColumnsReordered')}
/>
);
diff --git a/packages/main/src/components/AnalyticalTable/hooks/useDragAndDrop.ts b/packages/main/src/components/AnalyticalTable/hooks/useDragAndDrop.ts
new file mode 100644
index 00000000000..850c2929890
--- /dev/null
+++ b/packages/main/src/components/AnalyticalTable/hooks/useDragAndDrop.ts
@@ -0,0 +1,57 @@
+import { useCallback, useRef, useState } from 'react';
+
+const getColumnId = (column) => {
+ return typeof column.accessor === 'string' ? column.accessor : column.id;
+};
+
+export const useDragAndDrop = (props, setColumnOrder, columnOrder, isBeingResized, onColumnsOrderChanged) => {
+ const [dragOver, setDragOver] = useState('');
+
+ const handleDragStart = useCallback(
+ (e) => {
+ if (isBeingResized) {
+ e.preventDefault();
+ return;
+ }
+ e.dataTransfer.setData('colId', e.currentTarget.id);
+ },
+ [isBeingResized]
+ );
+
+ const handleDragOver = useCallback((e) => {
+ e.preventDefault();
+ }, []);
+
+ const handleDragEnter = useCallback((e) => {
+ setDragOver(e.currentTarget.id);
+ }, []);
+
+ const handleOnDrop = useCallback(
+ (e) => {
+ setDragOver('');
+
+ const droppedColId = e.currentTarget.id;
+ const draggedColId = e.dataTransfer.getData('colId');
+ if (droppedColId === draggedColId) return;
+
+ const internalColumnOrder = columnOrder.length > 0 ? columnOrder : props.columns.map((col) => getColumnId(col));
+ const droppedColIdx = internalColumnOrder.findIndex((col) => col === droppedColId);
+ const draggedColIdx = internalColumnOrder.findIndex((col) => col === draggedColId);
+
+ const tempCols = [...internalColumnOrder];
+ tempCols.splice(droppedColIdx, 0, tempCols.splice(draggedColIdx, 1)[0]);
+ setColumnOrder(tempCols);
+
+ const newOrderedColumns = [...props.columns];
+ newOrderedColumns.splice(droppedColIdx, 0, newOrderedColumns.splice(draggedColIdx, 1)[0]);
+ onColumnsOrderChanged(e.currentTarget, props.columns[draggedColIdx], newOrderedColumns);
+ },
+ [columnOrder]
+ );
+
+ const handleOnDragEnd = useCallback(() => {
+ setDragOver('');
+ }, [dragOver]);
+
+ return [dragOver, handleDragEnter, handleDragStart, handleDragOver, handleOnDrop, handleOnDragEnd];
+};
diff --git a/packages/main/src/components/AnalyticalTable/hooks/useResizeColumns.ts b/packages/main/src/components/AnalyticalTable/hooks/useResizeColumns.ts
index 912a783e068..7c92b397267 100644
--- a/packages/main/src/components/AnalyticalTable/hooks/useResizeColumns.ts
+++ b/packages/main/src/components/AnalyticalTable/hooks/useResizeColumns.ts
@@ -12,5 +12,13 @@ export const useResizeColumns = () => {
[setResizedColumns, resizedColumns]
);
- return [resizedColumns, onColumnSizeChanged];
+ const [isBeingResized, setBeingResized] = useState(false);
+ const onColumnBeingResized = useCallback(
+ ({ value }) => {
+ setBeingResized(value);
+ },
+ [setBeingResized]
+ );
+
+ return [resizedColumns, onColumnSizeChanged, isBeingResized, onColumnBeingResized];
};
diff --git a/packages/main/src/components/AnalyticalTable/hooks/useTableHeaderStyling.ts b/packages/main/src/components/AnalyticalTable/hooks/useTableHeaderStyling.ts
index 41d74883eb2..07ac953bc7e 100644
--- a/packages/main/src/components/AnalyticalTable/hooks/useTableHeaderStyling.ts
+++ b/packages/main/src/components/AnalyticalTable/hooks/useTableHeaderStyling.ts
@@ -1,16 +1,17 @@
import { useCallback } from 'react';
-export const useTableHeaderStyling = (classes, onColumnSizeChanged) =>
+export const useTableHeaderStyling = (classes, onColumnSizeChanged, onColumnBeingResized) =>
useCallback(
(instance) => {
instance.getHeaderProps.push((column) => {
return {
className: classes.th,
onColumnSizeChanged,
+ onColumnBeingResized,
column
};
});
return instance;
},
- [classes.th, onColumnSizeChanged]
+ [classes.th, onColumnSizeChanged, onColumnBeingResized]
);
diff --git a/packages/main/src/components/AnalyticalTable/index.tsx b/packages/main/src/components/AnalyticalTable/index.tsx
index 02be28a0d7f..36380a29fb3 100644
--- a/packages/main/src/components/AnalyticalTable/index.tsx
+++ b/packages/main/src/components/AnalyticalTable/index.tsx
@@ -15,7 +15,7 @@ import React, {
useMemo
} from 'react';
import { createUseStyles, useTheme } from 'react-jss';
-import { useExpanded, useFilters, useGroupBy, useSortBy, useTable } from 'react-table';
+import { useExpanded, useFilters, useGroupBy, useSortBy, useTable, useColumnOrder } from 'react-table';
import { CommonProps } from '../../interfaces/CommonProps';
import { JSSTheme } from '../../interfaces/JSSTheme';
import styles from './AnayticalTable.jss';
@@ -37,6 +37,7 @@ import { useWindowResize } from './hooks/useWindowResize';
import { makeTemplateColumns } from './hooks/utils';
import { TitleBar } from './TitleBar';
import { VirtualTableBody } from './virtualization/VirtualTableBody';
+import { useDragAndDrop } from './hooks/useDragAndDrop';
export interface ColumnConfiguration {
accessor?: string;
@@ -85,6 +86,7 @@ export interface TableProps extends CommonProps {
groupable?: boolean;
groupBy?: string[];
selectable?: boolean;
+ columnOrder?: object[];
// events
@@ -92,6 +94,7 @@ export interface TableProps extends CommonProps {
onGroup?: (e?: Event) => void;
onRowSelected?: (e?: Event) => any;
onRowExpandChange?: (e?: Event) => any;
+ onColumnsReordered?: (e?: Event) => void;
/**
* additional options which will be passed to [react-table“s useTable hook](https://github.com/tannerlinsley/react-table/blob/master/docs/api.md#table-options)
*/
@@ -134,6 +137,7 @@ const AnalyticalTable: FC
= forwardRef((props: TableProps, ref: Ref<
selectedRowKey,
LoadingComponent,
onRowExpandChange,
+ onColumnsReordered,
noDataText,
NoDataComponent,
visibleRows,
@@ -146,12 +150,12 @@ const AnalyticalTable: FC = forwardRef((props: TableProps, ref: Ref<
const classes = useStyles({ rowHeight: props.rowHeight });
const [selectedRowPath, onRowClicked] = useRowSelection(onRowSelected, selectedRowKey);
- const [resizedColumns, onColumnSizeChanged] = useResizeColumns();
+ const [resizedColumns, onColumnSizeChanged, isBeingResized, onColumnBeingResized] = useResizeColumns();
const [analyticalTableRef, reactWindowRef] = useTableScrollHandles(ref);
const getSubRows = useCallback((row) => row[subRowsKey] || [], [subRowsKey]);
- const { getTableProps, headerGroups, rows, prepareRow, setState, state: tableState } = useTable(
+ const { getTableProps, headerGroups, rows, prepareRow, setState, state: tableState, setColumnOrder } = useTable(
{
columns,
data,
@@ -161,11 +165,12 @@ const AnalyticalTable: FC = forwardRef((props: TableProps, ref: Ref<
},
useFilters,
useGroupBy,
+ useColumnOrder,
useSortBy,
useExpanded,
useTableStyling(classes),
useTableHeaderGroupStyling(classes, resizedColumns),
- useTableHeaderStyling(classes, onColumnSizeChanged),
+ useTableHeaderStyling(classes, onColumnSizeChanged, onColumnBeingResized),
useTableRowStyling(
classes,
resizedColumns,
@@ -248,7 +253,26 @@ const AnalyticalTable: FC = forwardRef((props: TableProps, ref: Ref<
[tableState.groupBy, onGroup]
);
+ const onColumnsOrderChanged = useCallback(
+ (target, column, columnsNewOrder) => {
+ onColumnsReordered(
+ Event.of(null, target, {
+ columnsNewOrder,
+ column
+ })
+ );
+ },
+ [tableState.columnOrder, onColumnsReordered]
+ );
+
const [headerRef, tableWidth] = useWindowResize();
+ const [dragOver, handleDragEnter, handleDragStart, handleDragOver, handleOnDrop, handleOnDragEnd] = useDragAndDrop(
+ props,
+ setColumnOrder,
+ tableState.columnOrder,
+ isBeingResized,
+ onColumnsOrderChanged
+ );
return (
@@ -265,6 +289,7 @@ const AnalyticalTable: FC
= forwardRef((props: TableProps, ref: Ref<
{headerGroup.headers.map((column, index) => (
= forwardRef((props: TableProps, ref: Ref<
filterable={props.filterable}
onSort={props.onSort}
onGroupBy={onGroupByChanged}
+ onDragStart={handleDragStart}
+ onDragOver={handleDragOver}
+ onDrop={handleOnDrop}
+ onDragEnter={handleDragEnter}
+ onDragEnd={handleOnDragEnd}
+ dragOver={column.id === dragOver}
+ column={column}
+ isDraggable={!isTreeTable}
>
{column.render('Header')}
@@ -341,6 +374,7 @@ AnalyticalTable.defaultProps = {
subRowsKey: 'subRows',
onGroup: () => {},
onRowExpandChange: () => {},
+ onColumnsReordered: () => {},
isTreeTable: false,
alternateRowColor: false
};
diff --git a/packages/main/src/components/FilterBar/demo.stories.tsx b/packages/main/src/components/FilterBar/demo.stories.tsx
index def4dd45270..fe682ffec0e 100644
--- a/packages/main/src/components/FilterBar/demo.stories.tsx
+++ b/packages/main/src/components/FilterBar/demo.stories.tsx
@@ -11,8 +11,14 @@ import { VariantManagement } from '@ui5/webcomponents-react/lib/VariantManagemen
import { action } from '@storybook/addon-actions';
import notes from './FilterBar.md';
-const variantItems = [{ label: 'Variant 1', key: '1' }, { label: 'Variant 2', key: '2' }];
-const filterItems = [{ text: 'Text 1', key: '1' }, { text: 'Text 2', key: '2' }];
+const variantItems = [
+ { label: 'Variant 1', key: '1' },
+ { label: 'Variant 2', key: '2' }
+];
+const filterItems = [
+ { text: 'Text 1', key: '1' },
+ { text: 'Text 2', key: '2' }
+];
const renderVariants = () => {
return (
diff --git a/packages/main/src/components/VariantManagement/demo.stories.tsx b/packages/main/src/components/VariantManagement/demo.stories.tsx
index 79fb98a4b57..743a5648e4f 100644
--- a/packages/main/src/components/VariantManagement/demo.stories.tsx
+++ b/packages/main/src/components/VariantManagement/demo.stories.tsx
@@ -6,7 +6,10 @@ import { TitleLevel } from '@ui5/webcomponents-react/lib/TitleLevel';
import { VariantManagement } from '@ui5/webcomponents-react/lib/VariantManagement';
import notes from './VariantManagement.md';
-const variantItems = [{ label: 'Variant 1', key: '1' }, { label: 'Variant 2', key: '2' }];
+const variantItems = [
+ { label: 'Variant 1', key: '1' },
+ { label: 'Variant 2', key: '2' }
+];
export const renderStory = () => (