From 722f4b4c48b9e49509a47e5a23f1ce45dbe9999d Mon Sep 17 00:00:00 2001 From: Karolis Ramanauskas Date: Wed, 30 Oct 2024 19:54:05 +0200 Subject: [PATCH] fix(explorer): type-based sorting (#3340) --- .changeset/dirty-lemons-complain.md | 5 ++++ .../[worldAddress]/explore/TablesViewer.tsx | 23 +++++++--------- .../explore/utils/typeSortingFn.ts | 26 +++++++++++++++++++ .../(explorer)/queries/useTableDataQuery.ts | 9 ++++--- 4 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 .changeset/dirty-lemons-complain.md create mode 100644 packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/utils/typeSortingFn.ts diff --git a/.changeset/dirty-lemons-complain.md b/.changeset/dirty-lemons-complain.md new file mode 100644 index 0000000000..c6a8e6bbf7 --- /dev/null +++ b/.changeset/dirty-lemons-complain.md @@ -0,0 +1,5 @@ +--- +"@latticexyz/explorer": patch +--- + +The columns in the Explore tab table are now sorted correctly according to their types. diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/TablesViewer.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/TablesViewer.tsx index 5f6303fc55..1b9340228b 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/TablesViewer.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/TablesViewer.tsx @@ -18,30 +18,26 @@ import { Button } from "../../../../../../components/ui/Button"; import { Input } from "../../../../../../components/ui/Input"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../../../../../../components/ui/Table"; import { cn } from "../../../../../../utils"; -import { TableData, useTableDataQuery } from "../../../../queries/useTableDataQuery"; +import { TData, TDataRow, useTableDataQuery } from "../../../../queries/useTableDataQuery"; import { EditableTableCell } from "./EditableTableCell"; +import { typeSortingFn } from "./utils/typeSortingFn"; const initialSortingState: SortingState = []; -const initialRows: TableData["rows"] = []; +const initialRows: TData["rows"] = []; export function TablesViewer({ table, query }: { table?: TableType; query?: string }) { - const { - data: tableData, - isLoading: isTableDataLoading, - isFetched, - isError, - error, - } = useTableDataQuery({ table, query }); - const isLoading = isTableDataLoading || !isFetched; - + const { data: tableData, isLoading: isTDataLoading, isFetched, isError, error } = useTableDataQuery({ table, query }); + const isLoading = isTDataLoading || !isFetched; const [globalFilter, setGlobalFilter] = useQueryState("filter", parseAsString.withDefault("")); const [sorting, setSorting] = useQueryState("sort", parseAsJson().withDefault(initialSortingState)); - const tableColumns: ColumnDef>[] = useMemo(() => { + const tableColumns: ColumnDef[] = useMemo(() => { if (!table || !tableData) return []; return tableData.columns.map((name) => { - const type = table?.schema[name]?.type; + const schema = table?.schema[name]; + const type = schema?.type; + return { accessorKey: name, header: ({ column }) => { @@ -57,6 +53,7 @@ export function TablesViewer({ table, query }: { table?: TableType; query?: stri ); }, + sortingFn: (rowA, rowB, columnId) => typeSortingFn(rowA, rowB, columnId, type), cell: ({ row }) => { const namespace = table?.namespace; const keySchema = getKeySchema(table); diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/utils/typeSortingFn.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/utils/typeSortingFn.ts new file mode 100644 index 0000000000..ed3a0ae105 --- /dev/null +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/utils/typeSortingFn.ts @@ -0,0 +1,26 @@ +import { bigIntSort } from "@latticexyz/common/utils"; +import { AbiType } from "@latticexyz/config"; +import { Row } from "@tanstack/react-table"; +import { TDataRow } from "../../../../../queries/useTableDataQuery"; + +export function typeSortingFn(rowA: Row, rowB: Row, columnId: string, type?: AbiType) { + const a = rowA.getValue(columnId); + const b = rowB.getValue(columnId); + + if (type?.startsWith("uint") || type?.startsWith("int")) { + const aBig = BigInt(a?.toString() || "0"); + const bBig = BigInt(b?.toString() || "0"); + return bigIntSort(aBig, bBig); + } + + if (typeof a === "bigint" || typeof b === "bigint") { + const aBig = BigInt(a?.toString() || "0"); + const bBig = BigInt(b?.toString() || "0"); + return bigIntSort(aBig, bBig); + } + + if (a == null) return 1; + if (b == null) return -1; + + return a < b ? -1 : a > b ? 1 : 0; +} diff --git a/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts b/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts index 38c112d42b..2527343345 100644 --- a/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts +++ b/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts @@ -11,9 +11,10 @@ type Props = { query: string | undefined; }; -export type TableData = { +export type TDataRow = Record; +export type TData = { columns: string[]; - rows: Record[]; + rows: TDataRow[]; }; export function useTableDataQuery({ table, query }: Props) { @@ -21,7 +22,7 @@ export function useTableDataQuery({ table, query }: Props) { const { id: chainId } = useChain(); const decodedQuery = decodeURIComponent(query ?? ""); - return useQuery({ + return useQuery({ queryKey: ["tableData", chainName, worldAddress, decodedQuery], queryFn: async () => { const indexer = indexerForChainId(chainId); @@ -45,7 +46,7 @@ export function useTableDataQuery({ table, query }: Props) { return data; }, - select: (data: DozerResponse): TableData | undefined => { + select: (data: DozerResponse): TData | undefined => { if (!table || !data?.result?.[0]) return undefined; const result = data.result[0];