mirror of
https://github.com/apache/superset.git
synced 2026-04-16 22:55:52 +00:00
feat: add drag and drop column rearrangement for table viz (#19381)
This commit is contained in:
@@ -29,6 +29,7 @@ import {
|
||||
usePagination,
|
||||
useSortBy,
|
||||
useGlobalFilter,
|
||||
useColumnOrder,
|
||||
PluginHook,
|
||||
TableOptions,
|
||||
FilterType,
|
||||
@@ -64,6 +65,7 @@ export interface DataTableProps<D extends object> extends TableOptions<D> {
|
||||
sticky?: boolean;
|
||||
rowCount: number;
|
||||
wrapperRef?: MutableRefObject<HTMLDivElement>;
|
||||
onColumnOrderChange: () => void;
|
||||
}
|
||||
|
||||
export interface RenderHTMLCellProps extends HTMLProps<HTMLTableCellElement> {
|
||||
@@ -95,12 +97,14 @@ export default typedMemo(function DataTable<D extends object>({
|
||||
hooks,
|
||||
serverPagination,
|
||||
wrapperRef: userWrapperRef,
|
||||
onColumnOrderChange,
|
||||
...moreUseTableOptions
|
||||
}: DataTableProps<D>): JSX.Element {
|
||||
const tableHooks: PluginHook<D>[] = [
|
||||
useGlobalFilter,
|
||||
useSortBy,
|
||||
usePagination,
|
||||
useColumnOrder,
|
||||
doSticky ? useSticky : [],
|
||||
hooks || [],
|
||||
].flat();
|
||||
@@ -172,6 +176,8 @@ export default typedMemo(function DataTable<D extends object>({
|
||||
setGlobalFilter,
|
||||
setPageSize: setPageSize_,
|
||||
wrapStickyTable,
|
||||
setColumnOrder,
|
||||
allColumns,
|
||||
state: { pageIndex, pageSize, globalFilter: filterValue, sticky = {} },
|
||||
} = useTable<D>(
|
||||
{
|
||||
@@ -211,6 +217,33 @@ export default typedMemo(function DataTable<D extends object>({
|
||||
|
||||
const shouldRenderFooter = columns.some(x => !!x.Footer);
|
||||
|
||||
let columnBeingDragged = -1;
|
||||
|
||||
const onDragStart = (e: React.DragEvent) => {
|
||||
const el = e.target as HTMLTableCellElement;
|
||||
columnBeingDragged = allColumns.findIndex(
|
||||
col => col.id === el.dataset.columnName,
|
||||
);
|
||||
e.dataTransfer.setData('text/plain', `${columnBeingDragged}`);
|
||||
};
|
||||
|
||||
const onDrop = (e: React.DragEvent) => {
|
||||
const el = e.target as HTMLTableCellElement;
|
||||
const newPosition = allColumns.findIndex(
|
||||
col => col.id === el.dataset.columnName,
|
||||
);
|
||||
|
||||
if (newPosition !== -1) {
|
||||
const currentCols = allColumns.map(c => c.id);
|
||||
const colToBeMoved = currentCols.splice(columnBeingDragged, 1);
|
||||
currentCols.splice(newPosition, 0, colToBeMoved[0]);
|
||||
setColumnOrder(currentCols);
|
||||
// toggle value in TableChart to trigger column width recalc
|
||||
onColumnOrderChange();
|
||||
}
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
const renderTable = () => (
|
||||
<table {...getTableProps({ className: tableClassName })}>
|
||||
<thead>
|
||||
@@ -223,6 +256,8 @@ export default typedMemo(function DataTable<D extends object>({
|
||||
column.render('Header', {
|
||||
key: column.id,
|
||||
...column.getSortByToggleProps(),
|
||||
onDragStart,
|
||||
onDrop,
|
||||
}),
|
||||
)}
|
||||
</tr>
|
||||
|
||||
@@ -350,6 +350,7 @@ function useInstance<D extends object>(instance: TableInstance<D>) {
|
||||
data,
|
||||
page,
|
||||
rows,
|
||||
allColumns,
|
||||
getTableSize = () => undefined,
|
||||
} = instance;
|
||||
|
||||
@@ -370,7 +371,7 @@ function useInstance<D extends object>(instance: TableInstance<D>) {
|
||||
useMountedMemo(getTableSize, [getTableSize]) || sticky;
|
||||
// only change of data should trigger re-render
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const table = useMemo(renderer, [page, rows]);
|
||||
const table = useMemo(renderer, [page, rows, allColumns]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!width || !height) {
|
||||
|
||||
@@ -36,6 +36,8 @@ import {
|
||||
UseSortByState,
|
||||
UseTableHooks,
|
||||
UseSortByHooks,
|
||||
UseColumnOrderState,
|
||||
UseColumnOrderInstanceProps,
|
||||
Renderer,
|
||||
HeaderProps,
|
||||
TableFooterProps,
|
||||
@@ -64,6 +66,7 @@ declare module 'react-table' {
|
||||
UseRowSelectInstanceProps<D>,
|
||||
UseRowStateInstanceProps<D>,
|
||||
UseSortByInstanceProps<D>,
|
||||
UseColumnOrderInstanceProps<D>,
|
||||
UseStickyInstanceProps {}
|
||||
|
||||
export interface TableState<D extends object>
|
||||
@@ -73,6 +76,7 @@ declare module 'react-table' {
|
||||
UsePaginationState<D>,
|
||||
UseRowSelectState<D>,
|
||||
UseSortByState<D>,
|
||||
UseColumnOrderState<D>,
|
||||
UseStickyState {}
|
||||
|
||||
// Typing from @types/react-table is incomplete
|
||||
@@ -82,12 +86,19 @@ declare module 'react-table' {
|
||||
onClick?: React.MouseEventHandler;
|
||||
}
|
||||
|
||||
interface TableRearrangeColumnsProps {
|
||||
onDragStart: (e: React.DragEvent) => void;
|
||||
onDrop: (e: React.DragEvent) => void;
|
||||
}
|
||||
|
||||
export interface ColumnInterface<D extends object>
|
||||
extends UseGlobalFiltersColumnOptions<D>,
|
||||
UseSortByColumnOptions<D> {
|
||||
// must define as a new property because it's not possible to override
|
||||
// the existing `Header` renderer option
|
||||
Header?: Renderer<TableSortByToggleProps & HeaderProps<D>>;
|
||||
Header?: Renderer<
|
||||
TableSortByToggleProps & HeaderProps<D> & TableRearrangeColumnsProps
|
||||
>;
|
||||
Footer?: Renderer<TableFooterProps<D>>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user