@trail-ui/react
Version:
259 lines (256 loc) • 8.13 kB
JavaScript
import {
GroupedEditableTableBody
} from "./chunk-KR7KR2VP.mjs";
import {
EditabletableFooter
} from "./chunk-CADGCYST.mjs";
import {
EditableTablePagination
} from "./chunk-IYSTD2VQ.mjs";
import {
EditableTableHeader
} from "./chunk-GUQNTN2I.mjs";
import {
FocusHandlerContextProvider
} from "./chunk-F5W73ZFA.mjs";
import {
TableContextProvider
} from "./chunk-A4IWBDSQ.mjs";
import {
dateSortingFn,
multiSelectFilter
} from "./chunk-KFZT7QCH.mjs";
// src/editable-table/grouped-editable-table.tsx
import { useState, useCallback, useEffect, useMemo, useRef } from "react";
import {
useReactTable,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
getFacetedRowModel,
getFacetedUniqueValues
} from "@tanstack/react-table";
import { twMerge } from "tailwind-merge";
import { jsx, jsxs } from "react/jsx-runtime";
function GroupedEditableTableNative({
tableId,
classNames,
tableName,
data,
columns,
isLoading,
//Save data callback
handleSaveData,
idSelector,
allowBulkGroupSelection = false,
selectAllCheckBoxName,
setTable,
setColumnFilters,
hiddenColumnIds,
isCellDisabled,
//Server pagination props
showPagination = true,
serverPagination = false,
totalCount,
currentPage = 1,
onPageChange,
currentPageSize,
onPageSizeChange,
defaultSortingHeaders,
handleSort,
globalFilter,
setGlobalFilter,
paginationSizeOptions,
//Table footer props
showTableFooter = false,
//selection
onSelectionChange
}) {
const flatData = useMemo(
() => data.flatMap(
(group) => group.data.map((o) => ({ ...o, editableTableGroupId: group.groupId }))
),
[data]
);
const [tableData, setTableData] = useState(flatData || []);
const [sorting, setSorting] = useState(defaultSortingHeaders || []);
const [tableColumnFilters, setTableColumnFilters] = useState([]);
const [rowSelection, setRowSelection] = useState({});
const tableRef = useRef(null);
const groupData = useMemo(
() => data.map((group) => ({
groupId: group.groupId,
groupName: group.groupName,
ids: group.data.map((o) => idSelector(o)),
...(group == null ? void 0 : group.description) ? { description: group.description } : {}
})),
[data]
);
const [pagination, setPagination] = useState({
pageSize: currentPageSize != null ? currentPageSize : 100,
pageIndex: currentPage - 1
});
const updateData = useCallback((rowId, accessorKey, value) => {
setTableData((prev) => {
const updatedData = [...prev];
const rowIndex = updatedData.findIndex((r) => idSelector(r) === rowId);
if (rowIndex === -1) {
return prev;
}
updatedData[rowIndex] = {
...updatedData[rowIndex],
[accessorKey]: value
};
return updatedData;
});
}, []);
const totalPages = serverPagination && totalCount && pagination.pageSize ? Math.ceil(totalCount / pagination.pageSize) : Math.ceil(tableData.length / pagination.pageSize);
const table = useReactTable({
data: tableData,
columns,
state: {
sorting,
pagination,
columnFilters: tableColumnFilters,
globalFilter,
rowSelection,
...(hiddenColumnIds == null ? void 0 : hiddenColumnIds.length) && {
columnVisibility: Object.fromEntries(hiddenColumnIds.map((col) => [col, false]))
}
},
onRowSelectionChange: (updater) => {
setRowSelection((prev) => {
const newSelection = typeof updater === "function" ? updater(prev) : updater;
return newSelection;
});
},
getRowId: idSelector,
manualPagination: serverPagination,
...serverPagination && { pageCount: totalPages },
onPaginationChange: setPagination,
manualSorting: serverPagination,
getSortedRowModel: serverPagination ? void 0 : getSortedRowModel(),
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onSortingChange: setSorting,
getFacetedRowModel: getFacetedRowModel(),
getFacetedUniqueValues: getFacetedUniqueValues(),
onColumnFiltersChange: setTableColumnFilters,
onGlobalFilterChange: setGlobalFilter,
enableSortingRemoval: false,
sortingFns: { dateSortingFn },
filterFns: { multiSelectFilter },
meta: {
updateData
}
});
useEffect(() => {
if (serverPagination && sorting.length > 0 && handleSort) {
const { id, desc } = sorting[0];
const order = desc === void 0 ? "default" /* DEFAULT */ : desc ? "desc" /* DESC */ : "asc" /* ASC */;
handleSort({ columnId: id, order });
}
}, [sorting]);
useEffect(() => {
if (onSelectionChange) {
const ids = Object.keys(rowSelection).filter((id) => rowSelection[id]);
onSelectionChange(ids);
}
}, [rowSelection]);
if (setColumnFilters) {
setColumnFilters(tableColumnFilters);
}
const totalResults = serverPagination ? totalCount != null ? totalCount : 0 : table.getFilteredRowModel().rows.length;
useEffect(() => {
setTableData(flatData);
}, [flatData]);
useEffect(() => setTable == null ? void 0 : setTable(table), [table]);
useEffect(() => {
if (serverPagination && currentPage !== void 0) {
setPagination((prev) => ({ ...prev, pageIndex: currentPage - 1 }));
}
}, [serverPagination, currentPage]);
useEffect(() => {
if (serverPagination && currentPageSize !== void 0) {
setPagination((prev) => ({ ...prev, pageSize: currentPageSize }));
}
}, [serverPagination, currentPageSize]);
return /* @__PURE__ */ jsx(
TableContextProvider,
{
handleSaveData,
idSelector,
table,
tableName,
groupData,
allowBulkGroupSelection,
tableRef,
doesRowHeaderExist: table.getAllColumns().map((col) => col.columnDef).some((col) => (col == null ? void 0 : col.columnType) === "th"),
hasFooter: showTableFooter,
serverPagination,
children: /* @__PURE__ */ jsx(FocusHandlerContextProvider, { table, groupData, children: /* @__PURE__ */ jsxs(
"div",
{
id: tableId,
className: twMerge("flex max-h-full max-w-full flex-col gap-4", classNames == null ? void 0 : classNames.wrapper),
children: [
/* @__PURE__ */ jsx(
"div",
{
className: twMerge(
"relative h-full max-h-[100%-3.5rem] overflow-auto rounded border border-neutral-200",
classNames == null ? void 0 : classNames.tableWrapper
),
children: /* @__PURE__ */ jsxs(
"table",
{
ref: tableRef,
role: "grid",
"aria-label": tableName != null ? tableName : "",
className: twMerge("w-full", classNames == null ? void 0 : classNames.table),
children: [
/* @__PURE__ */ jsx(
EditableTableHeader,
{
table,
tableName,
selectAllCheckBoxName
}
),
/* @__PURE__ */ jsx(
GroupedEditableTableBody,
{
table,
columns,
isLoading,
isCellDisabled
}
),
showTableFooter && /* @__PURE__ */ jsx(EditabletableFooter, {})
]
}
)
}
),
showPagination && /* @__PURE__ */ jsx(
EditableTablePagination,
{
totalResults,
pagination,
table,
onPageChange,
onPageSizeChange,
paginationSizeOptions
}
)
]
}
) })
}
);
}
export {
GroupedEditableTableNative
};