import { useCallback, useContext, useEffect, useMemo } from 'react';
import { useBlockLayout, useColumnOrder, useResizeColumns, useTable } from 'react-table';
import { Tooltip } from '@chakra-ui/react';
import {
closestCenter,
DndContext,
KeyboardSensor,
PointerSensor,
TouchSensor,
useSensor,
useSensors,
} from '@dnd-kit/core';
import {
horizontalListSortingStrategy,
SortableContext,
sortableKeyboardCoordinates,
} from '@dnd-kit/sortable';
import PropTypes from 'prop-types';
import { TableSettingsContext } from '../../common/context/TableSettingsContext';
import { useLocalStorage } from '../../common/hooks/useLocalStorage';
import { tooltipDelayFast } from '../../ontimeConfig';
import SortableCell from './tableElements/SortableCell';
import TableSettings from './tableElements/TableSettings';
import BlockRow from './tableRows/BlockRow';
import DelayRow from './tableRows/DelayRow';
import EventRow from './tableRows/EventRow';
import { makeColumns } from './columns';
import { defaultColumnOrder, defaultHiddenColumns } from './defaults';
import style from './Table.module.scss';
export default function OntimeTable({ tableData, userFields, selectedId, handleUpdate }) {
const { followSelected, showSettings } = useContext(TableSettingsContext);
const [columnOrder, saveColumnOrder] = useLocalStorage('table-order', defaultColumnOrder);
const [columnSize, saveColumnSize] = useLocalStorage('table-sizes', {});
const [hiddenColumns, saveHiddenColumns] = useLocalStorage('table-hidden', defaultHiddenColumns);
const columns = useMemo(() => makeColumns(columnSize, userFields), [columnSize, userFields]);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
setColumnOrder,
allColumns,
setHiddenColumns,
toggleHideAllColumns,
state,
} = useTable(
{
columns,
data: tableData,
initialState: {
hiddenColumns: hiddenColumns,
},
handleUpdate,
},
useColumnOrder,
useBlockLayout,
useResizeColumns
);
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: {
delay: 100,
tolerance: 50,
},
}),
useSensor(TouchSensor, {
activationConstraint: {
delay: 100,
tolerance: 50,
},
}),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
);
const handleResetReordering = useCallback(() => {
console.log('called reset', defaultColumnOrder)
saveColumnOrder(defaultColumnOrder);
setColumnOrder(defaultColumnOrder);
}, [saveColumnOrder, setColumnOrder]);
const handleResetResizing = useCallback(() => {
saveColumnSize({});
}, [saveColumnSize]);
const handleResetToggles = useCallback(() => {
setHiddenColumns(defaultHiddenColumns);
saveHiddenColumns(defaultHiddenColumns);
}, [saveHiddenColumns, setHiddenColumns]);
const clearToggles = useCallback(() => {
toggleHideAllColumns(false);
saveHiddenColumns([]);
}, [saveHiddenColumns, toggleHideAllColumns]);
const handleOnDragEnd = useCallback((event) => {
const { delta, active, over } = event;
// cancel if delta y is greater than 200
if (delta.y > 200) return;
const cols = [...columnOrder];
// get index of from
const fromIndex = cols.findIndex((i) => i === active.id);
// get index of to
const toIndex = cols.findIndex((i) => i === over.id);
if (toIndex === -1) {
return;
}
// reorder
const [reorderedItem] = cols.splice(fromIndex, 1);
cols.splice(toIndex, 0, reorderedItem);
saveColumnOrder(cols);
setColumnOrder(cols);
}, [columnOrder, saveColumnOrder, setColumnOrder]);
// save hidden columns object to local storage
useEffect(() => {
saveHiddenColumns(state.hiddenColumns);
}, [saveHiddenColumns, state.hiddenColumns]);
// save column sizes to local storage
useEffect(() => {
// property changes from title of column to null on resize end
if (state.columnResizing?.isResizingColumn !== null) {
return;
}
const cols = state.columnResizing.columnWidths;
saveColumnSize((prev) => ({ ...prev, ...cols }));
}, [saveColumnSize, state.columnResizing]);
// scroll to active cue
useEffect(() => {
if (followSelected) {
const el = document.getElementById(selectedId);
if (el) {
el.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'nearest',
});
}
}
}, [followSelected, selectedId]);
// keep order of events
let eventIndex = 0;
// keep delay (ms)
let cumulativeDelay = 0;
return (
<>
{showSettings && (
|
|
|---|