sorting and filter functionality

This commit is contained in:
Nick A 2025-04-03 21:37:08 -04:00
parent bdc6600a3f
commit 2c5fd0ea76
4 changed files with 54 additions and 13 deletions

View File

@ -1,4 +1,3 @@
// FilterBox.tsx
import { useState } from "react"; import { useState } from "react";
import { ChevronDownIcon } from "@heroicons/react/24/solid"; import { ChevronDownIcon } from "@heroicons/react/24/solid";
import { ContainsDropdown } from "./ContainsDropdown"; import { ContainsDropdown } from "./ContainsDropdown";

View File

@ -118,6 +118,9 @@ export default function ResourceTable({
</Tag> </Tag>
</div> </div>
), ),
meta: {
filterVariant: "select",
}
}), }),
columnHelper.accessor("summary", { columnHelper.accessor("summary", {
header: () => ( header: () => (

View File

@ -5,17 +5,13 @@ import {
getCoreRowModel, getCoreRowModel,
flexRender, flexRender,
createColumnHelper, createColumnHelper,
getFilteredRowModel,
ColumnFiltersState,
getSortedRowModel,
SortingState,
} from "@tanstack/react-table"; } from "@tanstack/react-table";
import { import { ChangeEvent, useState, Dispatch, SetStateAction } from "react";
ChangeEvent,
useState,
useEffect,
Key,
Dispatch,
SetStateAction,
} from "react";
import { TableAction } from "./TableAction"; import { TableAction } from "./TableAction";
import { PlusIcon } from "@heroicons/react/24/solid";
import { rankItem } from "@tanstack/match-sorter-utils"; import { rankItem } from "@tanstack/match-sorter-utils";
import { RowOptionMenu } from "./RowOptionMenu"; import { RowOptionMenu } from "./RowOptionMenu";
import DataPoint from "@/utils/models/DataPoint"; import DataPoint from "@/utils/models/DataPoint";
@ -81,7 +77,8 @@ export default function Table<T extends DataPoint>({
createEndpoint, createEndpoint,
isAdmin = false, isAdmin = false,
}: TableProps<T>) { }: TableProps<T>) {
console.log(data); const [filters, setFilters] = useState<ColumnFiltersState>([]);
const [sorting, setSorting] = useState<SortingState>([]);
const columnHelper = createColumnHelper<T>(); const columnHelper = createColumnHelper<T>();
@ -166,10 +163,16 @@ export default function Table<T extends DataPoint>({
}, },
state: { state: {
globalFilter: query, globalFilter: query,
columnFilters: filters,
sorting,
}, },
onGlobalFilterChange: setQuery, onGlobalFilterChange: setQuery,
globalFilterFn: fuzzyFilter, globalFilterFn: fuzzyFilter,
getCoreRowModel: getCoreRowModel(), getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getSortedRowModel: getSortedRowModel(),
onColumnFiltersChange: setFilters,
onSortingChange: setSorting,
}); });
return ( return (
@ -185,12 +188,24 @@ export default function Table<T extends DataPoint>({
<th <th
scope="col" scope="col"
className={ className={
"p-2 border-gray-200 border-y font-medium " + "p-2 border-gray-200 border-y font-medium cursor-pointer select-none" +
(1 < i && i < columns.length - 1 (1 < i && i < columns.length - 1
? "border-x" ? "border-x"
: "") : "")
} }
key={header.id} key={header.id}
onClick={header.column.getToggleSortingHandler()}
title={
header.column.getCanSort()
? header.column.getNextSortingOrder() ===
"asc"
? "Sort ascending"
: header.column.getNextSortingOrder() ===
"desc"
? "Sort descending"
: "Clear sort"
: undefined
}
> >
{header.isPlaceholder {header.isPlaceholder
? null ? null
@ -198,6 +213,14 @@ export default function Table<T extends DataPoint>({
header.column.columnDef.header, header.column.columnDef.header,
header.getContext() header.getContext()
)} )}
{{
asc: "🔼",
desc: "🔽",
}[header.column.getIsSorted() as string] ??
null}
{header.column.getCanFilter() && (
<Filter column={header.column} />
)}
</th> </th>
))} ))}
</tr> </tr>
@ -266,3 +289,19 @@ export default function Table<T extends DataPoint>({
</div> </div>
); );
} }
function Filter({ column }: { column: any }) {
return (
<div>
<input
type="text"
value={(column.getFilterValue() ?? "") as string}
onChange={(e) => {
column.setFilterValue(e.target.value);
}}
placeholder="Search..."
className="border border-gray-300 rounded p-1"
/>
</div>
);
}

View File

@ -1,7 +1,7 @@
// TableAction.tsx // TableAction.tsx
import { MagnifyingGlassIcon } from "@heroicons/react/24/solid"; import { MagnifyingGlassIcon } from "@heroicons/react/24/solid";
import { ChangeEventHandler, FunctionComponent, useRef, useState } from "react"; import { ChangeEventHandler, FunctionComponent, useRef, useState } from "react";
import { FilterBox } from "../FilterBox"; import { FilterBox } from "../FilterBox/FilterBox";
type TableActionProps = { type TableActionProps = {
query: string; query: string;