import { useMemo, useState, ReactNode } from "react"; import { useQuery } from "@tanstack/react-query"; import { useNavigate } from "@tanstack/react-router"; import { Skeleton, Alert, Table, NavLink, TextInput, Group, Text, UnstyledButton, Center } from "@mantine/core"; import { IconAlertCircle, IconChevronDown, IconChevronUp, IconSelector } from "@tabler/icons-react"; import { useReactTable, getCoreRowModel, flexRender, getFilteredRowModel, FilterFn, Row, ColumnDef, getSortedRowModel, SortingState, Column } from "@tanstack/react-table"; import classNames from "classnames"; import { headerHeight } from "./config"; import { fetchTitlesInUniverse } from "./model"; import BadgeUniverse from "./BadgeUniverse"; import BadgeSeries from "./BadgeSeries"; import BadgeFormat from "./BadgeFormat"; import classes from "./ListTitle.module.css"; import { handleSearch } from "./utils"; import PickerFormat from "./PickerFormat"; import PickerUniverse from "./PickerUniverse"; type DataRow = { id: number; name: string; series?: { id: number, name: string, no: string }; subformat_id: number; extra_universe_ids: number[]; }; const nameSearch: FilterFn = (row: Row, columnId: string, filterValue: string) => handleSearch(filterValue, row.getValue(columnId)); const seriesSearch: FilterFn = (row: Row, columnId: string, filterValue: string) => { const { name, no } = row.getValue(columnId) as { name?: string; no?: string; } ?? { name: "", no: "" }; return handleSearch(filterValue, `${name ?? ""} ${no ?? ""}`); }; const listSearch: FilterFn = (row: Row, columnId: string, filterValue: number[]) => filterValue.includes(row.getValue(columnId)); const listMultiSearch: FilterFn = (row: Row, columnId: string, filterValue: number[]) => ( (row.getValue(columnId) as number[]).length === 0 ? [ 0 ] : (row.getValue(columnId) as number[]) ) .some(subformat_id => filterValue.includes(subformat_id ?? 0)); const TextInputSearch = ({ value, setValue, label }: { value: string; setValue: (text: string) => void; label: string }) => ( { setValue(currentTarget.value); }} /> ); const SortButtonWrapper = ({ column, children }: { column: Column; children: ReactNode; }) => { const Icon = column.getCanSort() ? column.getNextSortingOrder() === "asc" ? IconSelector : column.getNextSortingOrder() === "desc" ? IconChevronDown : IconChevronUp : null; return ( {children}
{Icon && }
); }; export default ({ id }: { id: number }) => { const { isPending, isError, isSuccess, data, error } = useQuery({ queryKey: [ "titles-list", id ], queryFn: () => fetchTitlesInUniverse(id) }); const navigate = useNavigate(); const [ sorting, setSorting ] = useState([]); const columns = useMemo(() => [ { accessorKey: "subformat_id", id: "subformat_id", cell: ({ getValue }) => , header: ({ column }) => ( { column.setFilterValue(formats); }} /> ), filterFn: "listSearch" as unknown as FilterFn }, { accessorKey: "name", id: "name", cell: ({ getValue, row: { original: { id } } }) => ( { navigate({ to: "/title/$id", params: { id } }); }} className={classes.navlink} />), header: ({ column }) => ( ), filterFn: "nameSearch" as unknown as FilterFn }, { accessorKey: "series", id: "series", cell: ({ getValue }) => { const { id, name, no } = getValue() as { id?: number; name?: string; no?: string; } ?? { id: 0, name: "", no: "" }; if (!id) return null; return ( ); }, header: ({ column }) => ( ), filterFn: "seriesSearch" as unknown as FilterFn }, { accessorKey: "extra_universe_ids", id: "extra_universe_ids", cell: ({ getValue }) => (getValue() as number[]).map(id => ), header: ({ column }) => ( Crossovers extra_universe_ids) .flat() .filter((e: number, i: number, a: number[]) => a.indexOf(e) === i), 0 ] } onChange={formats => { column.setFilterValue(formats); }} /> ), filterFn: "listMultiSearch" as unknown as FilterFn } ] as ColumnDef[], [ data ]); const table = useReactTable({ columns, data, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), onSortingChange: setSorting, filterFns: { nameSearch, seriesSearch, listSearch, listMultiSearch }, state: { sorting }, debugAll: true }); if (isError) return ( }> {error.message} ); return ( {table.getHeaderGroups().map(headerGroup => ( {headerGroup.headers.map(header => {/*console.log(header.column);*/return ( {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} );})} ))} {isSuccess && table?.getRowModel()?.rows?.map(row => ( {row.getVisibleCells().map(cell => ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} ))}
); };