@trail-ui/react
Version:
480 lines (477 loc) • 18.7 kB
JavaScript
import {
table_header_default
} from "./chunk-GCE2RD4S.mjs";
import {
Lozenge
} from "./chunk-5CC46WKN.mjs";
import {
_Checkbox
} from "./chunk-26XCDXWQ.mjs";
import {
_Button
} from "./chunk-YXFZGEMT.mjs";
import {
_AvatarGroup
} from "./chunk-STWU4DVS.mjs";
import {
_Avatar
} from "./chunk-OKWXKKQQ.mjs";
// src/tanstackTable/tanstackTable.tsx
import { ArrowDownIcon, ArrowUpIcon, ChevronLeftIcon, ChevronRightIcon } from "@trail-ui/icons";
import { clsx } from "@trail-ui/shared-utils";
import { commonColors } from "@trail-ui/theme";
import {
flexRender,
getCoreRowModel,
getFacetedRowModel,
getFacetedUniqueValues,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable
} from "@tanstack/react-table";
import React, { useEffect, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { createElement } from "react";
var includesString = (row, columnId, filterValue) => {
const rowValue = row.getValue(columnId);
if (typeof rowValue !== "string" || typeof filterValue !== "string") {
return false;
}
return rowValue.toLowerCase().includes(filterValue.toLowerCase());
};
var multiSelectFilter = (row, columnId, filterValue) => {
if (!Array.isArray(filterValue))
return true;
const rowValue = row.getValue(columnId);
return filterValue.includes(rowValue);
};
function TanstackTable({
columns,
data,
tableData,
showName = true,
defaultSortingHeader,
tableName,
checkBoxSelectedName,
WithoutCheckbox,
tableHeight,
showFilter = true
}) {
var _a;
const tableColumns = columns.map((column) => {
return {
id: column.id,
size: column.width,
header: () => {
switch (column.type) {
case "id":
return !WithoutCheckbox && /* @__PURE__ */ jsx("div", { className: "text-center", children: /* @__PURE__ */ jsx(
_Checkbox,
{
"aria-label": `Select All ${tableName}`,
classNames: { control: "mr-0" },
...{
isSelected: Object.keys(rowSelection).length === data.length,
isIndeterminate: Object.keys(rowSelection).length > 0 && Object.keys(rowSelection).length < data.length,
checked: Object.keys(rowSelection).length === data.length,
onChange: () => {
const allSelected = Object.keys(rowSelection).length === data.length;
const newSelection = allSelected ? {} : data.reduce((acc, row) => {
acc[row.id] = true;
return acc;
}, {});
setRowSelection(newSelection);
}
}
}
) });
default:
return column.name;
}
},
accessorKey: column.accessor,
filterFn: column.type === "text" ? multiSelectFilter : multiSelectFilter,
cell: ({ cell }) => {
switch (column.type) {
case "id":
return !WithoutCheckbox && /* @__PURE__ */ jsx("div", { className: "text-center", children: /* @__PURE__ */ jsx(
_Checkbox,
{
classNames: { control: "mr-0" },
"aria-label": `${cell.row.original[checkBoxSelectedName != null ? checkBoxSelectedName : ""]}`,
...{
isSelected: cell.row.getIsSelected(),
onChange: () => cell.row.toggleSelected()
}
}
) });
case "text":
return cell.getValue();
case "date":
return new Date(cell.getValue()).toLocaleDateString();
case "number":
return cell.getValue();
case "status":
return /* @__PURE__ */ jsx("p", { className: "w-max", children: /* @__PURE__ */ jsx(
Lozenge,
{
size: "sm",
variant: "light",
value: cell.getValue(),
color: cell.getValue() === "Completed" ? "green" : cell.getValue() === "Regression" ? "red" : "yellow"
}
) });
case "percentage":
return /* @__PURE__ */ jsx(
Lozenge,
{
size: "sm",
variant: "light",
value: `${cell.getValue()}`,
color: cell.getValue() > 0 ? "green" : cell.getValue() < 0 ? "red" : "yellow"
}
);
case "image":
return /* @__PURE__ */ jsx("figure", { className: "min-w-36", children: /* @__PURE__ */ jsx(
"img",
{
className: "h-10",
src: cell.getValue(),
style: {
objectFit: column.objectFit ? column.objectFit : "cover",
width: column.objectFit === "contain" ? "max-content" : "100%"
},
alt: ""
}
) });
case "profileImage":
return /* @__PURE__ */ jsx("figure", { children: /* @__PURE__ */ jsx(
"img",
{
className: "h-10",
src: cell.getValue(),
style: {
objectFit: column.objectFit ? column.objectFit : "cover",
width: column.objectFit === "contain" ? "max-content" : "100%"
},
alt: ""
}
) });
case "username":
return /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1 text-sm text-neutral-900", children: [
/* @__PURE__ */ jsx(
_Avatar,
{
size: "md",
is: "span",
name: cell.getValue(),
getInitials: (name) => name.toUpperCase().slice(0, 2),
showFallback: true,
color: ["green", "red", "yellow", "default", "purple", "blue"][Math.floor(Math.random() * 6)]
}
),
showName && /* @__PURE__ */ jsx("span", { id: cell.getValue(), className: "text-sm text-neutral-900", children: cell.getValue() })
] });
case "usersList":
return /* @__PURE__ */ jsx(_AvatarGroup, { size: "md", max: 2, children: (cell.getValue() || []).map((user) => /* @__PURE__ */ jsx(
_Avatar,
{
size: "md",
is: "span",
src: user.avatar,
name: user.name,
getInitials: (name) => name.toUpperCase().slice(0, 2),
showFallback: true,
color: ["green", "red", "yellow", "default", "purple", "blue"][Math.floor(Math.random() * 6)]
},
user.id
)) });
default:
return cell.getValue();
}
}
};
});
const [sorting, setSorting] = useState([]);
const [rowSelection, setRowSelection] = useState({});
const [columnFilters, setColumnFilters] = React.useState([]);
const [globalFilter, setGlobalFilter] = React.useState("");
const table = useReactTable({
enableRowSelection: true,
columns: tableColumns,
data,
defaultColumn: {
size: 100
},
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
onColumnFiltersChange: setColumnFilters,
onRowSelectionChange: setRowSelection,
onSortingChange: setSorting,
getPaginationRowModel: getPaginationRowModel(),
getFacetedRowModel: getFacetedRowModel(),
getFacetedUniqueValues: getFacetedUniqueValues(),
getFilteredRowModel: getFilteredRowModel(),
filterFns: {
includesString,
multiSelectFilter
},
state: {
sorting,
rowSelection,
columnFilters,
globalFilter
},
initialState: {
pagination: {
pageSize: tableData ? tableData : 10,
pageIndex: 0
}
}
});
const currentPage = table.getState().pagination.pageIndex + 1;
const pageCount = table.getPageCount();
const pageNumbers = [];
const maxButtonsToShow = 5;
if (pageCount <= maxButtonsToShow) {
for (let i = 1; i <= pageCount; i++) {
pageNumbers.push(i);
}
} else {
let startPage, endPage;
const middleButtonsToShow = maxButtonsToShow - 2;
const halfMiddleButtonsToShow = Math.floor(middleButtonsToShow / 2);
if (currentPage <= halfMiddleButtonsToShow + 1) {
startPage = 2;
endPage = middleButtonsToShow + 1;
} else if (currentPage + halfMiddleButtonsToShow >= pageCount) {
startPage = pageCount - middleButtonsToShow;
endPage = pageCount - 1;
} else {
startPage = currentPage - halfMiddleButtonsToShow;
endPage = currentPage + halfMiddleButtonsToShow;
}
pageNumbers.push(1);
if (startPage > 2) {
pageNumbers.push("...");
}
for (let i = startPage; i <= endPage; i++) {
pageNumbers.push(i);
}
if (endPage < pageCount - 1) {
pageNumbers.push("...");
}
pageNumbers.push(pageCount);
}
const alignRightData = [
"salesHours",
"plannedHours",
"teamSize",
"plannedVsActual",
"actualVsPlanned",
"salesVsActual",
"actualHours",
"noOfHours",
"noOfUnits",
"report",
"support",
"fixing",
"meeting",
"qualityAssurance",
"bbMeeting",
"documentation",
"training",
"offProduction",
"peerReview",
"projects",
"reported",
"perfectIssues",
"perfectIssuesPercentage"
];
const [currentSort, setCurrentSort] = useState(
defaultSortingHeader ? defaultSortingHeader : "projectName"
);
function toggleSort(header) {
const sortingHandler = header.column.getToggleSortingHandler();
if (sortingHandler) {
sortingHandler({ persist: () => {
} });
}
setCurrentSort(header.id);
}
const stateSorting = table.getState().sorting;
useEffect(() => {
const sortedHeader = table.getHeaderGroups().flatMap((headerGroup) => headerGroup.headers).find((header) => header.column.getIsSorted());
if (sortedHeader) {
setCurrentSort(sortedHeader.id);
} else {
setCurrentSort(null);
}
}, [stateSorting, table]);
const [openFilter, setOpenFilter] = useState(false);
return /* @__PURE__ */ jsxs("div", { className: "rounded", children: [
showFilter && /* @__PURE__ */ jsx(
table_header_default,
{
openFilter,
setOpenFilter,
table,
globalFilter,
setGlobalFilter,
data,
columns,
tableName
}
),
/* @__PURE__ */ jsxs("div", { className: "p-6", children: [
/* @__PURE__ */ jsx("div", { className: "h-full overflow-auto rounded border border-neutral-200", children: /* @__PURE__ */ jsx("div", { className: `${tableHeight ? tableHeight : ""}`, children: /* @__PURE__ */ jsxs("table", { className: "w-full overflow-auto bg-white ", children: [
/* @__PURE__ */ jsx("thead", { className: "sticky top-0 z-10 border-b border-b-neutral-200", children: /* @__PURE__ */ jsx("tr", { children: table.getHeaderGroups().map(
(headerGroup) => headerGroup.headers.map((header) => {
var _a2;
return /* @__PURE__ */ createElement(
"th",
{
id: header.id,
...header.id === "id" ? {
"aria-label": `Select All ${tableName}`
} : {},
"aria-sort": header.column.getIsSorted() === "asc" ? "ascending" : header.column.getIsSorted() === "desc" ? "descending" : "none",
key: header.id,
scope: "col",
colSpan: header.colSpan,
className: `${alignRightData.includes(header.id) ? "text-right" : "text-left"} ${WithoutCheckbox ? "first:auto" : "first:w-10"} h-10 min-h-10 border-r border-r-neutral-200 bg-neutral-100 p-2 text-sm font-semibold text-neutral-900 first:text-center last:border-r-0`
},
header.isPlaceholder && header.column.getIndex() === 0 ? null : header.id == "id" ? /* @__PURE__ */ jsx("span", { children: flexRender(header.column.columnDef.header, header.getContext()) }) : /* @__PURE__ */ jsx(
_Button,
{
appearance: "transparent",
className: clsx(
header.column.getCanSort() ? "cursor-pointer select-none" : "",
`${alignRightData.includes(header.id) ? "justify-end" : "justify-start"} w-full items-center px-0 text-sm font-semibold text-neutral-900`
),
onPress: () => toggleSort(header),
onKeyDown: (event) => {
if (event.key === "Enter" || event.key === " ") {
header.column.getToggleSortingHandler();
}
},
children: /* @__PURE__ */ jsxs(
"span",
{
className: `${alignRightData.includes(header.id) ? "justify-end" : "justify-between"} flex w-full items-center gap-4`,
children: [
flexRender(header.column.columnDef.header, header.getContext()),
header.column.getCanSort() && header.id !== "id" && (currentSort === header.id ? /* @__PURE__ */ jsx("span", { className: "sort-icon", children: (_a2 = {
asc: /* @__PURE__ */ jsx(
ArrowUpIcon,
{
color: commonColors.neutral[800],
width: 16,
height: 16
}
),
desc: /* @__PURE__ */ jsx(
ArrowDownIcon,
{
color: commonColors.neutral[800],
width: 16,
height: 16
}
)
}[header.column.getIsSorted()]) != null ? _a2 : null }) : null)
]
}
)
}
)
);
})
) }) }),
/* @__PURE__ */ jsx("tbody", { children: ((_a = table.getRowModel().rows) == null ? void 0 : _a.length) ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx("tr", { "data-state": row.getIsSelected() && "selected", children: row.getVisibleCells().map(
(cell) => cell.column.id === checkBoxSelectedName ? /* @__PURE__ */ jsx(
"th",
{
id: `head-${row.id}`,
className: `${alignRightData.includes(cell.column.id) ? "text-right" : "text-left"} ${WithoutCheckbox ? "first:auto" : "first:w-10"} h-10 border-b border-l border-b-neutral-200 border-l-neutral-200 !bg-neutral-50 px-2 py-2 text-sm font-normal text-neutral-900 first:border-l-0`,
children: flexRender(cell.column.columnDef.cell, cell.getContext())
},
cell.id
) : /* @__PURE__ */ jsx(
"td",
{
headers: `head-${row.id} ${cell.column.id}`,
className: `${alignRightData.includes(cell.column.id) ? "text-right" : "text-left"} ${WithoutCheckbox ? "first:auto" : "first:w-10"} h-10 border-b border-l border-b-neutral-200 border-l-neutral-200 px-2 py-2 text-sm font-normal text-neutral-900 first:border-l-0`,
children: flexRender(cell.column.columnDef.cell, cell.getContext())
},
cell.id
)
) }, row.id)) : /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: columns.length, className: "h-24 text-center", children: "No results." }) }) })
] }) }) }),
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center justify-between space-x-2 p-2", children: [
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-neutral-600", children: [
"Showing ",
table.getRowModel().rows.length,
" out of ",
data.length,
" results"
] }) }),
/* @__PURE__ */ jsx("nav", { "aria-label": "Pagination", className: "flex justify-end", children: /* @__PURE__ */ jsxs("ul", { className: "justtify-end flex gap-2", children: [
/* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
_Button,
{
className: "px-1",
"aria-label": "Previous page",
appearance: "transparent",
isDisabled: !table.getCanPreviousPage(),
onPress: () => table.previousPage(),
children: /* @__PURE__ */ jsx(
ChevronLeftIcon,
{
color: `${currentPage === 1 ? "#B0ACBB" : "#302E38"}`,
width: 24,
height: 24
}
)
}
) }),
pageNumbers.map((pageNumber, index) => /* @__PURE__ */ jsx("li", { className: "h-8 w-8", children: pageNumber === "..." ? /* @__PURE__ */ jsx("span", { children: "..." }) : /* @__PURE__ */ jsx(
"button",
{
...pageNumber === currentPage ? { "aria-current": "page" } : {},
"aria-current": pageNumber === currentPage ? "page" : void 0,
onClick: () => {
if (pageNumber !== "...") {
table.setPageIndex(pageNumber - 1);
}
},
className: `h-full w-full text-sm font-normal text-neutral-800 ${pageNumber === currentPage ? "rounded border border-purple-600 bg-purple-100" : "bg-white"} ${pageNumber !== "..." ? "underline" : ""}`,
children: pageNumber
}
) }, index)),
/* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
_Button,
{
className: "px-1",
appearance: "transparent",
isDisabled: !table.getCanNextPage(),
onPress: () => table.nextPage(),
"aria-label": "Next page",
children: /* @__PURE__ */ jsx(
ChevronRightIcon,
{
color: !table.getCanNextPage() ? "#B0ACBB" : "#302E38",
width: 24,
height: 24
}
)
}
) })
] }) })
] })
] })
] });
}
export {
TanstackTable
};