mirror of
https://github.com/cssgunc/compass.git
synced 2025-04-20 18:40:17 -04:00
Refactored ServiceIndex
This commit is contained in:
parent
6a454c809f
commit
571b9dd067
|
@ -1,13 +1,12 @@
|
||||||
import { PageLayout } from "@/components/PageLayout";
|
import { Bars2Icon } from "@heroicons/react/24/solid";
|
||||||
import { RowOpenAction } from "@/components/Table/RowOpenAction";
|
import { useState } from "react";
|
||||||
|
import useTagsHandler from "@/components/TagsInput/TagsHandler";
|
||||||
|
import { ColumnDef, createColumnHelper } from "@tanstack/react-table";
|
||||||
import { Table } from "@/components/Table/Table";
|
import { Table } from "@/components/Table/Table";
|
||||||
|
import { RowOpenAction } from "@/components/Table/RowOpenAction";
|
||||||
import TagsInput from "@/components/TagsInput/Index";
|
import TagsInput from "@/components/TagsInput/Index";
|
||||||
import Resource from "@/utils/models/Resource";
|
import Resource from "@/utils/models/Resource";
|
||||||
import { Bars2Icon, BookmarkIcon } from "@heroicons/react/24/solid";
|
|
||||||
import { ColumnDef, createColumnHelper } from "@tanstack/react-table";
|
|
||||||
import { useState } from "react";
|
|
||||||
import { DataPoint } from "@/components/Table/Table";
|
import { DataPoint } from "@/components/Table/Table";
|
||||||
import useTagsHandler from "@/components/TagsInput/TagsHandler";
|
|
||||||
|
|
||||||
export function ResourceTable({ resources }: { resources: Resource[] }) {
|
export function ResourceTable({ resources }: { resources: Resource[] }) {
|
||||||
const columnHelper = createColumnHelper<Resource>();
|
const columnHelper = createColumnHelper<Resource>();
|
||||||
|
@ -87,12 +86,5 @@ export function ResourceTable({ resources }: { resources: Resource[] }) {
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return <Table data={data} setData={setData} columns={columns}/>
|
||||||
<div className="min-h-screen flex flex-col">
|
|
||||||
{/* icon + title */}
|
|
||||||
<PageLayout title="Resources" icon={<BookmarkIcon />}>
|
|
||||||
<Table data={resources} setData={setData} columns={columns}/>
|
|
||||||
</PageLayout>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,125 +1,33 @@
|
||||||
// for showcasing to compass
|
import { Bars2Icon } from "@heroicons/react/24/solid";
|
||||||
|
import { SetStateAction, useState } from "react";
|
||||||
import users from "./users.json";
|
import useTagsHandler from "@/components/TagsInput/TagsHandler";
|
||||||
import {
|
import { ColumnDef, createColumnHelper } from "@tanstack/react-table";
|
||||||
Cell,
|
import { Table } from "@/components/Table/Table";
|
||||||
ColumnDef,
|
import { RowOpenAction } from "@/components/Table/RowOpenAction";
|
||||||
Row,
|
import TagsInput from "@/components/TagsInput/Index";
|
||||||
createColumnHelper,
|
|
||||||
flexRender,
|
|
||||||
getCoreRowModel,
|
|
||||||
getFilteredRowModel,
|
|
||||||
sortingFns,
|
|
||||||
useReactTable,
|
|
||||||
} from "@tanstack/react-table";
|
|
||||||
import {
|
|
||||||
ChangeEvent,
|
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
FunctionComponent,
|
|
||||||
useRef,
|
|
||||||
ChangeEventHandler,
|
|
||||||
Key,
|
|
||||||
} from "react";
|
|
||||||
import { RowOptionMenu } from "./RowOptionMenu";
|
|
||||||
import { RowOpenAction } from "./RowOpenAction";
|
|
||||||
import { TableAction } from "./TableAction";
|
|
||||||
import {
|
|
||||||
AtSymbolIcon,
|
|
||||||
Bars2Icon,
|
|
||||||
ArrowDownCircleIcon,
|
|
||||||
PlusIcon,
|
|
||||||
} from "@heroicons/react/24/solid";
|
|
||||||
import TagsInput from "../TagsInput/Index";
|
|
||||||
import { rankItem } from "@tanstack/match-sorter-utils";
|
|
||||||
import Service from "@/utils/models/Service";
|
import Service from "@/utils/models/Service";
|
||||||
|
import { DataPoint } from "@/components/Table/Table";
|
||||||
|
|
||||||
// For search
|
export const ServiceTable = ({ services }: { services: Service[] }) => {
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Rename everything to service
|
|
||||||
export const ServiceTable = ({ users }: { users: Service[] }) => {
|
|
||||||
const columnHelper = createColumnHelper<Service>();
|
const columnHelper = createColumnHelper<Service>();
|
||||||
|
const [data, setData] = useState<DataPoint[]>([...services]);
|
||||||
|
|
||||||
useEffect(() => {
|
const { presetOptions, setPresetOptions, getTagColor } = useTagsHandler([
|
||||||
const sortedUsers = [...users].sort((a, b) =>
|
|
||||||
a.visible === b.visible ? 0 : a.visible ? -1 : 1
|
|
||||||
);
|
|
||||||
setData(sortedUsers);
|
|
||||||
}, [users]);
|
|
||||||
|
|
||||||
const deleteUser = (userId: number) => {
|
|
||||||
console.log(data);
|
|
||||||
setData((currentData) =>
|
|
||||||
currentData.filter((user) => user.id !== userId)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const hideUser = (userId: number) => {
|
|
||||||
console.log(`Toggling visibility for user with ID: ${userId}`);
|
|
||||||
setData((currentData) => {
|
|
||||||
const newData = currentData
|
|
||||||
.map((user) => {
|
|
||||||
if (user.id === userId) {
|
|
||||||
return { ...user, visible: !user.visible };
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
})
|
|
||||||
.sort((a, b) =>
|
|
||||||
a.visible === b.visible ? 0 : a.visible ? -1 : 1
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log(newData);
|
|
||||||
return newData;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const [presetOptions, setPresetOptions] = useState([
|
|
||||||
"administrator",
|
"administrator",
|
||||||
"volunteer",
|
"volunteer",
|
||||||
"employee",
|
"employee",
|
||||||
]);
|
])
|
||||||
const [tagColors, setTagColors] = useState(new Map());
|
|
||||||
|
|
||||||
const getTagColor = (tag: string) => {
|
const handleRowUpdate = (updatedRow: DataPoint) => {
|
||||||
if (!tagColors.has(tag)) {
|
const dataIndex = data.findIndex((row) => row.id === updatedRow.id);
|
||||||
const colors = [
|
if (dataIndex !== -1) {
|
||||||
"bg-cyan-100",
|
const updatedData = [...data];
|
||||||
"bg-blue-100",
|
updatedData[dataIndex] = updatedRow;
|
||||||
"bg-green-100",
|
setData(updatedData);
|
||||||
"bg-yellow-100",
|
|
||||||
"bg-purple-100",
|
|
||||||
];
|
|
||||||
const randomColor =
|
|
||||||
colors[Math.floor(Math.random() * colors.length)];
|
|
||||||
setTagColors(new Map(tagColors).set(tag, randomColor));
|
|
||||||
}
|
}
|
||||||
return tagColors.get(tag);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns: ColumnDef<Service, any>[] = [
|
||||||
columnHelper.display({
|
|
||||||
id: "options",
|
|
||||||
cell: (props) => (
|
|
||||||
<RowOptionMenu
|
|
||||||
onDelete={() => {}}
|
|
||||||
onHide={() => hideUser(props.row.original.id)}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
columnHelper.accessor("name", {
|
columnHelper.accessor("name", {
|
||||||
header: () => (
|
header: () => (
|
||||||
<>
|
<>
|
||||||
|
@ -150,7 +58,14 @@ export const ServiceTable = ({ users }: { users: Service[] }) => {
|
||||||
<Bars2Icon className="inline align-top h-4" /> Program
|
<Bars2Icon className="inline align-top h-4" /> Program
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
cell: (info) => <TagsInput presetValue={info.getValue()} />,
|
cell: (info) => (
|
||||||
|
<TagsInput
|
||||||
|
presetValue={info.getValue()}
|
||||||
|
presetOptions={presetOptions}
|
||||||
|
setPresetOptions={setPresetOptions}
|
||||||
|
getTagColor={getTagColor}
|
||||||
|
/>
|
||||||
|
),
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor("requirements", {
|
columnHelper.accessor("requirements", {
|
||||||
header: () => (
|
header: () => (
|
||||||
|
@ -159,10 +74,12 @@ export const ServiceTable = ({ users }: { users: Service[] }) => {
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
cell: (info) => (
|
cell: (info) => (
|
||||||
|
// TODO: Setup different tag handler for requirements
|
||||||
<TagsInput
|
<TagsInput
|
||||||
presetValue={
|
presetValue={info.getValue()[0] !== "" ? info.getValue() : ["N/A"]}
|
||||||
info.getValue()[0] !== "" ? info.getValue() : ["N/A"]
|
presetOptions={presetOptions}
|
||||||
}
|
setPresetOptions={setPresetOptions}
|
||||||
|
getTagColor={getTagColor}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
@ -179,134 +96,5 @@ export const ServiceTable = ({ users }: { users: Service[] }) => {
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
const [data, setData] = useState<Service[]>([...users]);
|
return <Table data={data} setData={setData} columns={columns} />
|
||||||
|
|
||||||
const addUser = () => {
|
|
||||||
setData([...data]);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Searching
|
|
||||||
const [query, setQuery] = useState("");
|
|
||||||
const handleSearchChange = (e: ChangeEvent) => {
|
|
||||||
const target = e.target as HTMLInputElement;
|
|
||||||
setQuery(String(target.value));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCellChange = (e: ChangeEvent, key: Key) => {
|
|
||||||
const target = e.target as HTMLInputElement;
|
|
||||||
console.log(key);
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Filtering
|
|
||||||
|
|
||||||
// TODO: Sorting
|
|
||||||
|
|
||||||
// added this fn for editing rows
|
|
||||||
const handleRowUpdate = (updatedRow: Service) => {
|
|
||||||
const dataIndex = data.findIndex((row) => row.id === updatedRow.id);
|
|
||||||
if (dataIndex !== -1) {
|
|
||||||
const updatedData = [...data];
|
|
||||||
updatedData[dataIndex] = updatedRow;
|
|
||||||
setData(updatedData);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const table = useReactTable({
|
|
||||||
columns,
|
|
||||||
data,
|
|
||||||
filterFns: {
|
|
||||||
fuzzy: fuzzyFilter,
|
|
||||||
},
|
|
||||||
state: {
|
|
||||||
globalFilter: query,
|
|
||||||
},
|
|
||||||
onGlobalFilterChange: setQuery,
|
|
||||||
globalFilterFn: fuzzyFilter,
|
|
||||||
getCoreRowModel: getCoreRowModel(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleRowData = (row: any) => {
|
|
||||||
const rowData: any = {};
|
|
||||||
row.cells.forEach((cell: any) => {
|
|
||||||
rowData[cell.column.id] = cell.value;
|
|
||||||
});
|
|
||||||
// Use rowData object containing data from all columns for the current row
|
|
||||||
console.log(rowData);
|
|
||||||
return rowData;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col">
|
|
||||||
<div className="flex flex-row justify-end">
|
|
||||||
<TableAction query={query} handleChange={handleSearchChange} />
|
|
||||||
</div>
|
|
||||||
<table className="w-full text-xs text-left rtl:text-right">
|
|
||||||
<thead className="text-xs text-gray-500 capitalize">
|
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
|
||||||
<tr key={headerGroup.id}>
|
|
||||||
{headerGroup.headers.map((header, i) => (
|
|
||||||
<th
|
|
||||||
scope="col"
|
|
||||||
className={
|
|
||||||
"p-2 border-gray-200 border-y font-medium " +
|
|
||||||
(1 < i && i < columns.length - 1
|
|
||||||
? "border-x"
|
|
||||||
: "")
|
|
||||||
}
|
|
||||||
key={header.id}
|
|
||||||
>
|
|
||||||
{header.isPlaceholder
|
|
||||||
? null
|
|
||||||
: flexRender(
|
|
||||||
header.column.columnDef.header,
|
|
||||||
header.getContext()
|
|
||||||
)}
|
|
||||||
</th>
|
|
||||||
))}
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{table.getRowModel().rows.map((row) => {
|
|
||||||
// Individual row
|
|
||||||
const isUserVisible = row.original.visible;
|
|
||||||
const rowClassNames = `text-gray-800 border-y lowercase hover:bg-gray-50 ${
|
|
||||||
!isUserVisible ? "bg-gray-200 text-gray-500" : ""
|
|
||||||
}`;
|
|
||||||
return (
|
|
||||||
<tr className={rowClassNames} key={row.id}>
|
|
||||||
{row.getVisibleCells().map((cell, i) => (
|
|
||||||
<td
|
|
||||||
key={cell.id}
|
|
||||||
className={
|
|
||||||
"[&:nth-child(n+3)]:border-x relative first:text-left first:px-0 last:border-none"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{flexRender(
|
|
||||||
cell.column.columnDef.cell,
|
|
||||||
cell.getContext()
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
))}
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</tbody>
|
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
className="p-3 border-y border-gray-200 text-gray-600 hover:bg-gray-50"
|
|
||||||
colSpan={100}
|
|
||||||
onClick={addUser}
|
|
||||||
>
|
|
||||||
<span className="flex ml-1 text-gray-500">
|
|
||||||
<PlusIcon className="inline h-4 mr-1" />
|
|
||||||
New
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user