2022-06-06 15:58:17 +10:00
|
|
|
import React, { useMemo, useState, Suspense } from "react";
|
2022-05-19 16:37:56 +10:00
|
|
|
import { useAtom, useSetAtom } from "jotai";
|
2022-05-30 12:48:27 +10:00
|
|
|
import { useDebouncedCallback, useThrottledCallback } from "use-debounce";
|
2022-05-19 16:37:56 +10:00
|
|
|
import { DndProvider } from "react-dnd";
|
|
|
|
|
import { HTML5Backend } from "react-dnd-html5-backend";
|
2022-06-03 18:17:27 +10:00
|
|
|
import { findIndex } from "lodash-es";
|
2022-05-19 16:37:56 +10:00
|
|
|
|
2022-10-14 16:15:41 +11:00
|
|
|
import {
|
|
|
|
|
createColumnHelper,
|
|
|
|
|
flexRender,
|
|
|
|
|
getCoreRowModel,
|
|
|
|
|
useReactTable,
|
|
|
|
|
} from "@tanstack/react-table";
|
|
|
|
|
|
|
|
|
|
import { TOP_BAR_HEIGHT } from "@src/layouts/Navigation/TopBar";
|
|
|
|
|
import { TABLE_TOOLBAR_HEIGHT } from "@src/components/TableToolbar";
|
|
|
|
|
import { StyledTable } from "./Styled/StyledTable";
|
|
|
|
|
import { StyledRow } from "./Styled/StyledRow";
|
|
|
|
|
import ColumnHeaderComponent from "./Column";
|
|
|
|
|
|
2022-05-27 15:10:06 +10:00
|
|
|
import { LinearProgress } from "@mui/material";
|
2022-05-19 16:37:56 +10:00
|
|
|
|
|
|
|
|
import TableContainer, { OUT_OF_ORDER_MARGIN } from "./TableContainer";
|
2022-05-27 15:10:06 +10:00
|
|
|
import ColumnHeader, { COLUMN_HEADER_HEIGHT } from "./ColumnHeader";
|
2022-05-19 16:37:56 +10:00
|
|
|
import FinalColumnHeader from "./FinalColumnHeader";
|
|
|
|
|
import FinalColumn from "./formatters/FinalColumn";
|
2022-10-14 16:15:41 +11:00
|
|
|
// import TableRow from "./TableRow";
|
2022-05-27 15:10:06 +10:00
|
|
|
import EmptyState from "@src/components/EmptyState";
|
2022-05-19 16:37:56 +10:00
|
|
|
// import BulkActions from "./BulkActions";
|
2022-05-27 15:10:06 +10:00
|
|
|
import AddRow from "@src/components/TableToolbar/AddRow";
|
2022-06-02 14:55:47 +10:00
|
|
|
import { AddRow as AddRowIcon } from "@src/assets/icons";
|
2022-06-06 15:58:17 +10:00
|
|
|
import Loading from "@src/components/Loading";
|
|
|
|
|
import ContextMenu from "./ContextMenu";
|
2022-05-19 16:37:56 +10:00
|
|
|
|
|
|
|
|
import {
|
2022-07-18 14:40:46 +10:00
|
|
|
projectScope,
|
2022-05-19 16:37:56 +10:00
|
|
|
userRolesAtom,
|
|
|
|
|
userSettingsAtom,
|
2022-07-18 14:40:46 +10:00
|
|
|
} from "@src/atoms/projectScope";
|
2022-05-19 16:37:56 +10:00
|
|
|
import {
|
|
|
|
|
tableScope,
|
|
|
|
|
tableIdAtom,
|
|
|
|
|
tableSettingsAtom,
|
|
|
|
|
tableSchemaAtom,
|
|
|
|
|
tableColumnsOrderedAtom,
|
|
|
|
|
tableRowsAtom,
|
2022-05-30 12:48:27 +10:00
|
|
|
tableNextPageAtom,
|
2022-05-19 16:37:56 +10:00
|
|
|
tablePageAtom,
|
|
|
|
|
updateColumnAtom,
|
|
|
|
|
updateFieldAtom,
|
2022-06-02 17:36:30 +10:00
|
|
|
selectedCellAtom,
|
2022-05-19 16:37:56 +10:00
|
|
|
} from "@src/atoms/tableScope";
|
|
|
|
|
|
2022-05-24 20:34:28 +10:00
|
|
|
import { getFieldType, getFieldProp } from "@src/components/fields";
|
2022-05-19 16:37:56 +10:00
|
|
|
import { FieldType } from "@src/constants/fields";
|
|
|
|
|
import { formatSubTableName } from "@src/utils/table";
|
2022-10-14 16:15:41 +11:00
|
|
|
import { TableRow, ColumnConfig } from "@src/types/table";
|
|
|
|
|
import { StyledCell } from "./Styled/StyledCell";
|
2022-05-19 16:37:56 +10:00
|
|
|
|
|
|
|
|
export const DEFAULT_ROW_HEIGHT = 41;
|
2022-06-13 16:02:38 +10:00
|
|
|
export const DEFAULT_COL_WIDTH = 150;
|
|
|
|
|
export const MAX_COL_WIDTH = 380;
|
2022-05-19 16:37:56 +10:00
|
|
|
|
2022-10-14 16:15:41 +11:00
|
|
|
declare module "@tanstack/table-core" {
|
|
|
|
|
interface ColumnMeta<TData, TValue> extends ColumnConfig {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const columnHelper = createColumnHelper<TableRow>();
|
|
|
|
|
const getRowId = (row: TableRow) => row._rowy_ref.path || row._rowy_ref.id;
|
2022-05-19 16:37:56 +10:00
|
|
|
|
2022-10-14 16:15:41 +11:00
|
|
|
export default function TableComponent() {
|
2022-07-18 14:40:46 +10:00
|
|
|
const [userRoles] = useAtom(userRolesAtom, projectScope);
|
|
|
|
|
const [userSettings] = useAtom(userSettingsAtom, projectScope);
|
2022-05-19 16:37:56 +10:00
|
|
|
|
|
|
|
|
const [tableId] = useAtom(tableIdAtom, tableScope);
|
|
|
|
|
const [tableSettings] = useAtom(tableSettingsAtom, tableScope);
|
|
|
|
|
const [tableSchema] = useAtom(tableSchemaAtom, tableScope);
|
|
|
|
|
const [tableColumnsOrdered] = useAtom(tableColumnsOrderedAtom, tableScope);
|
|
|
|
|
const [tableRows] = useAtom(tableRowsAtom, tableScope);
|
2022-05-30 12:48:27 +10:00
|
|
|
const [tableNextPage] = useAtom(tableNextPageAtom, tableScope);
|
|
|
|
|
const setTablePage = useSetAtom(tablePageAtom, tableScope);
|
2022-06-03 18:17:27 +10:00
|
|
|
const [selectedCell, setSelectedCell] = useAtom(selectedCellAtom, tableScope);
|
2022-05-19 16:37:56 +10:00
|
|
|
|
|
|
|
|
const updateColumn = useSetAtom(updateColumnAtom, tableScope);
|
|
|
|
|
const updateField = useSetAtom(updateFieldAtom, tableScope);
|
|
|
|
|
|
2022-10-14 16:15:41 +11:00
|
|
|
const canAddColumn = userRoles.includes("ADMIN");
|
2022-05-19 16:37:56 +10:00
|
|
|
const userDocHiddenFields =
|
|
|
|
|
userSettings.tables?.[formatSubTableName(tableId)]?.hiddenFields;
|
|
|
|
|
|
2022-10-14 16:15:41 +11:00
|
|
|
// Get column defs from table schema
|
|
|
|
|
// Also add end column for admins
|
2022-05-19 16:37:56 +10:00
|
|
|
const columns = useMemo(() => {
|
2022-10-14 16:15:41 +11:00
|
|
|
const _columns = tableColumnsOrdered
|
|
|
|
|
// .filter((column) => {
|
|
|
|
|
// if (column.hidden) return false;
|
|
|
|
|
// if (
|
|
|
|
|
// Array.isArray(userDocHiddenFields) &&
|
|
|
|
|
// userDocHiddenFields.includes(column.key)
|
|
|
|
|
// )
|
|
|
|
|
// return false;
|
|
|
|
|
// return true;
|
|
|
|
|
// })
|
|
|
|
|
.map((columnConfig) =>
|
|
|
|
|
columnHelper.accessor(columnConfig.fieldName, {
|
|
|
|
|
meta: columnConfig,
|
|
|
|
|
// draggable: true,
|
|
|
|
|
// resizable: true,
|
|
|
|
|
// frozen: columnConfig.fixed,
|
|
|
|
|
// headerRenderer: ColumnHeader,
|
|
|
|
|
// formatter:
|
|
|
|
|
// getFieldProp("TableCell", getFieldType(columnConfig)) ??
|
|
|
|
|
// function InDev() {
|
|
|
|
|
// return null;
|
|
|
|
|
// },
|
|
|
|
|
// editor:
|
|
|
|
|
// getFieldProp("TableEditor", getFieldType(columnConfig)) ??
|
|
|
|
|
// function InDev() {
|
|
|
|
|
// return null;
|
|
|
|
|
// },
|
|
|
|
|
// ...columnConfig,
|
|
|
|
|
// editable:
|
|
|
|
|
// tableSettings.readOnly && !userRoles.includes("ADMIN")
|
|
|
|
|
// ? false
|
|
|
|
|
// : columnConfig.editable ?? true,
|
|
|
|
|
// width: columnConfig.width ?? DEFAULT_COL_WIDTH,
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// if (canAddColumn || !tableSettings.readOnly) {
|
|
|
|
|
// _columns.push({
|
|
|
|
|
// isNew: true,
|
|
|
|
|
// key: "new",
|
|
|
|
|
// fieldName: "_rowy_new",
|
|
|
|
|
// name: "Add column",
|
|
|
|
|
// type: FieldType.last,
|
|
|
|
|
// index: _columns.length ?? 0,
|
|
|
|
|
// width: 154,
|
|
|
|
|
// headerRenderer: FinalColumnHeader,
|
|
|
|
|
// headerCellClass: "final-column-header",
|
|
|
|
|
// cellClass: "final-column-cell",
|
|
|
|
|
// formatter: FinalColumn,
|
|
|
|
|
// editable: false,
|
|
|
|
|
// });
|
|
|
|
|
// }
|
2022-05-19 16:37:56 +10:00
|
|
|
|
|
|
|
|
return _columns;
|
|
|
|
|
}, [
|
|
|
|
|
tableColumnsOrdered,
|
2022-10-14 16:15:41 +11:00
|
|
|
// userDocHiddenFields,
|
|
|
|
|
// tableSettings.readOnly,
|
|
|
|
|
// canAddColumn,
|
2022-05-19 16:37:56 +10:00
|
|
|
]);
|
2022-06-03 18:17:27 +10:00
|
|
|
|
2022-10-14 16:15:41 +11:00
|
|
|
const table = useReactTable({
|
|
|
|
|
data: tableRows,
|
|
|
|
|
columns,
|
|
|
|
|
getCoreRowModel: getCoreRowModel(),
|
|
|
|
|
getRowId,
|
|
|
|
|
columnResizeMode: "onChange",
|
|
|
|
|
// debugRows: true,
|
|
|
|
|
});
|
|
|
|
|
console.log(table);
|
2022-05-30 17:49:20 +10:00
|
|
|
|
2022-10-14 16:15:41 +11:00
|
|
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {};
|
2022-05-19 16:37:56 +10:00
|
|
|
|
|
|
|
|
return (
|
2022-10-14 16:15:41 +11:00
|
|
|
<>
|
|
|
|
|
<StyledTable
|
|
|
|
|
role="grid"
|
|
|
|
|
style={{ width: table.getTotalSize(), userSelect: "none" }}
|
|
|
|
|
onKeyDown={handleKeyDown}
|
|
|
|
|
>
|
|
|
|
|
<div className="thead" style={{ position: "sticky", top: 0 }}>
|
|
|
|
|
{table.getHeaderGroups().map((headerGroup) => (
|
|
|
|
|
<StyledRow key={headerGroup.id} role="row">
|
|
|
|
|
{headerGroup.headers.map((header) => (
|
|
|
|
|
<ColumnHeaderComponent
|
|
|
|
|
key={header.id}
|
|
|
|
|
label={header.column.columnDef.meta?.name || header.id}
|
|
|
|
|
type={header.column.columnDef.meta?.type}
|
|
|
|
|
style={{ width: header.getSize() }}
|
|
|
|
|
>
|
|
|
|
|
{/* <div
|
|
|
|
|
{...{
|
|
|
|
|
onMouseDown: header.getResizeHandler(),
|
|
|
|
|
onTouchStart: header.getResizeHandler(),
|
|
|
|
|
className: `resizer ${
|
|
|
|
|
header.column.getIsResizing() ? "isResizing" : ""
|
|
|
|
|
}`,
|
|
|
|
|
// style: {
|
|
|
|
|
// transform:
|
|
|
|
|
// columnResizeMode === 'onEnd' &&
|
|
|
|
|
// header.column.getIsResizing()
|
|
|
|
|
// ? `translateX(${
|
|
|
|
|
// table.getState().columnSizingInfo.deltaOffset
|
|
|
|
|
// }px)`
|
|
|
|
|
// : '',
|
|
|
|
|
// },
|
|
|
|
|
}}
|
|
|
|
|
/> */}
|
|
|
|
|
</ColumnHeaderComponent>
|
|
|
|
|
))}
|
|
|
|
|
</StyledRow>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="tbody">
|
|
|
|
|
{table.getRowModel().rows.map((row) => (
|
|
|
|
|
<StyledRow key={row.id} role="row">
|
|
|
|
|
{row.getVisibleCells().map((cell) => (
|
|
|
|
|
<StyledCell
|
|
|
|
|
key={cell.id}
|
|
|
|
|
style={{ width: cell.column.getSize() }}
|
|
|
|
|
>
|
|
|
|
|
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
|
|
|
<button>f</button>
|
|
|
|
|
</StyledCell>
|
|
|
|
|
))}
|
|
|
|
|
</StyledRow>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</StyledTable>
|
|
|
|
|
</>
|
2022-05-19 16:37:56 +10:00
|
|
|
);
|
|
|
|
|
}
|