mirror of
https://github.com/cssgunc/compass.git
synced 2025-04-10 06:10:17 -04:00
Merge pull request #30 from cssgunc/andy-GEN-97-table-search
This commit is contained in:
commit
d94f4fddd6
|
@ -3,16 +3,20 @@
|
||||||
import usersImport from "./users.json";
|
import usersImport from "./users.json";
|
||||||
import {
|
import {
|
||||||
ColumnDef,
|
ColumnDef,
|
||||||
|
Row,
|
||||||
createColumnHelper,
|
createColumnHelper,
|
||||||
flexRender,
|
flexRender,
|
||||||
getCoreRowModel,
|
getCoreRowModel,
|
||||||
|
getFilteredRowModel,
|
||||||
|
sortingFns,
|
||||||
useReactTable,
|
useReactTable,
|
||||||
} from "@tanstack/react-table";
|
} from "@tanstack/react-table";
|
||||||
import { useState, useEffect } from "react";
|
import { ChangeEvent, useState, useEffect } from "react";
|
||||||
import { RowOptionMenu } from "./RowOptionMenu";
|
import { RowOptionMenu } from "./RowOptionMenu";
|
||||||
import { RowOpenAction } from "./RowOpenAction";
|
import { RowOpenAction } from "./RowOpenAction";
|
||||||
import { TableAction } from "./TableAction";
|
import { TableAction } from "./TableAction";
|
||||||
import { Bars2Icon, AtSymbolIcon, HashtagIcon, ArrowDownCircleIcon } from "@heroicons/react/24/solid";
|
import { Bars2Icon, AtSymbolIcon, HashtagIcon, ArrowDownCircleIcon } from "@heroicons/react/24/solid";
|
||||||
|
import { rankItem } from "@tanstack/match-sorter-utils";
|
||||||
|
|
||||||
const usersExample = usersImport as unknown as User[];
|
const usersExample = usersImport as unknown as User[];
|
||||||
|
|
||||||
|
@ -28,6 +32,17 @@ type User = {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For search
|
||||||
|
const fuzzyFilter = (row: Row<any>, columnId: string, value: any, addMeta: (meta: any) => void) => {
|
||||||
|
// Rank the item
|
||||||
|
const itemRank = rankItem(row.getValue(columnId), value)
|
||||||
|
|
||||||
|
// Store the ranking info
|
||||||
|
addMeta(itemRank)
|
||||||
|
|
||||||
|
// Return if the item should be filtered in/out
|
||||||
|
return itemRank.passed
|
||||||
|
}
|
||||||
|
|
||||||
export const Table = () => {
|
export const Table = () => {
|
||||||
const columnHelper = createColumnHelper<User>();
|
const columnHelper = createColumnHelper<User>();
|
||||||
|
@ -43,7 +58,7 @@ export const Table = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideUser = (userId: number) => {
|
const hideUser = (userId: number) => {
|
||||||
console.log(`Toggling visibility for user with ID: ${userId}`);
|
console.log(`Toggling visibility for user with ID: ${userId}`);
|
||||||
setData(currentData => {
|
setData(currentData => {
|
||||||
const newData = currentData.map(user => {
|
const newData = currentData.map(user => {
|
||||||
if (user.id === userId) {
|
if (user.id === userId) {
|
||||||
|
@ -51,12 +66,12 @@ export const Table = () => {
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
}).sort((a, b) => a.visible === b.visible ? 0 : a.visible ? -1 : 1);
|
}).sort((a, b) => a.visible === b.visible ? 0 : a.visible ? -1 : 1);
|
||||||
|
|
||||||
console.log(newData);
|
console.log(newData);
|
||||||
return newData;
|
return newData;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
id: "options",
|
id: "options",
|
||||||
|
@ -82,16 +97,35 @@ export const Table = () => {
|
||||||
|
|
||||||
const [data, setData] = useState<User[]>([...usersExample]);
|
const [data, setData] = useState<User[]>([...usersExample]);
|
||||||
|
|
||||||
|
// Searching
|
||||||
|
const [query, setQuery] = useState("");
|
||||||
|
const handleSearchChange = (e: ChangeEvent) => {
|
||||||
|
const target = e.target as HTMLInputElement;
|
||||||
|
setQuery(String(target.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Filtering
|
||||||
|
// TODO: Sorting
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
columns,
|
columns,
|
||||||
data,
|
data,
|
||||||
|
filterFns: {
|
||||||
|
fuzzy: fuzzyFilter
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
globalFilter: query,
|
||||||
|
},
|
||||||
|
onGlobalFilterChange: setQuery,
|
||||||
|
globalFilterFn: fuzzyFilter,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
getFilteredRowModel: getFilteredRowModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="flex flex-row justify-end">
|
<div className="flex flex-row justify-end">
|
||||||
<TableAction />
|
<TableAction query={query} handleChange={handleSearchChange} />
|
||||||
</div>
|
</div>
|
||||||
<table className="w-full text-xs text-left rtl:text-right">
|
<table className="w-full text-xs text-left rtl:text-right">
|
||||||
<thead className="text-xs text-gray-500 capitalize">
|
<thead className="text-xs text-gray-500 capitalize">
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
|
/** The actions (Filter, Sort, Search) at the top of the table. */
|
||||||
import { MagnifyingGlassIcon } from "@heroicons/react/24/solid";
|
import { MagnifyingGlassIcon } from "@heroicons/react/24/solid";
|
||||||
import { useRef, useState } from "react";
|
import { ChangeEventHandler, Dispatch, FunctionComponent, SetStateAction, useRef, useState } from "react";
|
||||||
|
|
||||||
export const TableAction = () => {
|
type TableActionProps = {
|
||||||
|
query: string
|
||||||
|
handleChange: ChangeEventHandler<HTMLInputElement>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TableAction: FunctionComponent<TableActionProps> = ({query, handleChange}) => {
|
||||||
const searchInput = useRef<HTMLInputElement>(null);
|
const searchInput = useRef<HTMLInputElement>(null);
|
||||||
const [searchActive, setSearchActive] = useState(false);
|
const [searchActive, setSearchActive] = useState(false);
|
||||||
|
|
||||||
const activateSearch = () => {
|
const activateSearch = () => {
|
||||||
setSearchActive(true);
|
setSearchActive(true);
|
||||||
if (searchInput.current === null) { return; }
|
if (searchInput.current === null) { return; }
|
||||||
|
@ -30,7 +37,10 @@ export const TableAction = () => {
|
||||||
className={"outline-none transition-all duration-300 " + (searchActive ? "w-48" : "w-0")}
|
className={"outline-none transition-all duration-300 " + (searchActive ? "w-48" : "w-0")}
|
||||||
type="text"
|
type="text"
|
||||||
name="search"
|
name="search"
|
||||||
placeholder="Type to search..." />
|
placeholder="Type to search..."
|
||||||
|
value={query ?? ""}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
21
compass/package-lock.json
generated
21
compass/package-lock.json
generated
|
@ -9,6 +9,7 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^2.1.1",
|
"@heroicons/react": "^2.1.1",
|
||||||
|
"@tanstack/match-sorter-utils": "^8.15.1",
|
||||||
"@tanstack/react-table": "^8.15.0",
|
"@tanstack/react-table": "^8.15.0",
|
||||||
"next": "13.5.6",
|
"next": "13.5.6",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
|
@ -402,6 +403,21 @@
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tanstack/match-sorter-utils": {
|
||||||
|
"version": "8.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.15.1.tgz",
|
||||||
|
"integrity": "sha512-PnVV3d2poenUM31ZbZi/yXkBu3J7kd5k2u51CGwwNojag451AjTH9N6n41yjXz2fpLeewleyLBmNS6+HcGDlXw==",
|
||||||
|
"dependencies": {
|
||||||
|
"remove-accents": "0.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/tannerlinsley"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tanstack/react-table": {
|
"node_modules/@tanstack/react-table": {
|
||||||
"version": "8.15.0",
|
"version": "8.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.15.0.tgz",
|
||||||
|
@ -3556,6 +3572,11 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/remove-accents": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
|
||||||
|
"integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A=="
|
||||||
|
},
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.8",
|
"version": "1.22.8",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "compass",
|
"name": "compass",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
@ -11,6 +10,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^2.1.1",
|
"@heroicons/react": "^2.1.1",
|
||||||
|
"@tanstack/match-sorter-utils": "^8.15.1",
|
||||||
"@tanstack/react-table": "^8.15.0",
|
"@tanstack/react-table": "^8.15.0",
|
||||||
"next": "13.5.6",
|
"next": "13.5.6",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user