From f0403b3afb61fc5bc930e1359c0e081c4b9f875f Mon Sep 17 00:00:00 2001 From: Donkie Date: Thu, 6 Jul 2023 15:36:10 +0200 Subject: [PATCH] Client: Filament table is now sortable Can only sort by 1 column for now --- client/src/pages/filaments/list.tsx | 53 ++++++++++++++++++++---- client/src/pages/filaments/model.tsx | 3 +- client/src/utils/sorting.ts | 61 ++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 client/src/utils/sorting.ts diff --git a/client/src/pages/filaments/list.tsx b/client/src/pages/filaments/list.tsx index 0e04394..3a3804e 100644 --- a/client/src/pages/filaments/list.tsx +++ b/client/src/pages/filaments/list.tsx @@ -12,29 +12,56 @@ import { Table, Space } from "antd"; import { NumberFieldUnit } from "../../components/numberField"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; +import { IFilament } from "./model"; +import { genericSorter } from "../../utils/sorting"; dayjs.extend(utc); export const FilamentList: React.FC = () => { - const { tableProps } = useTable({ + const { tableProps, sorters } = useTable({ syncWithLocation: true, pagination: { mode: "client", pageSize: 20, }, + sorters: { + mode: "off", // Disable server-side sorting + initial: [ + { + field: "id", + order: "asc", + }, + ], + }, }); + // Copy dataSource to avoid mutating the original + const dataSource = [...(tableProps.dataSource || [])]; + + // Sort dataSource by the sorters + dataSource.sort(genericSorter(sorters)); + return ( - - - - - - +
+ + + + + ( = () => { ( = () => { { if (value === null || value === undefined) { return <>; @@ -79,6 +108,7 @@ export const FilamentList: React.FC = () => { { if (value === null || value === undefined) { return <>; @@ -94,10 +124,15 @@ export const FilamentList: React.FC = () => { ); }} /> - + ( = () => { /> )} /> - + { + for (const sorter of sorters) { + const aValue = a[sorter.field]; + const bValue = b[sorter.field]; + if (aValue === bValue) { + continue; + } + // Send empty fields to the bottom + if (aValue === undefined || aValue === null) { + return 1; + } + if (bValue === undefined || bValue === null) { + return -1; + } + // Perform sorting based on type of the fields + if (typeof aValue === "string" && typeof bValue === "string") { + // Try to sort them as dates if possible + const aDate = new Date(aValue); + const bDate = new Date(bValue); + if (!isNaN(aDate.getTime()) && !isNaN(bDate.getTime())) { + return sorter.order === "asc" + ? aDate.getTime() - bDate.getTime() + : bDate.getTime() - aDate.getTime(); + } + + return sorter.order === "asc" + ? aValue.localeCompare(bValue) + : bValue.localeCompare(aValue); + } + if (typeof aValue === "number" && typeof bValue === "number") { + return sorter.order === "asc" ? aValue - bValue : bValue - aValue; + } + if (typeof aValue === "boolean" && typeof bValue === "boolean") { + return sorter.order === "asc" ? +aValue - +bValue : +bValue - +aValue; + } + if (aValue instanceof Date && bValue instanceof Date) { + return sorter.order === "asc" + ? aValue.getTime() - bValue.getTime() + : bValue.getTime() - aValue.getTime(); + } + if (typeof aValue === "object" && typeof bValue === "object") { + return sorter.order === "asc" + ? JSON.stringify(aValue).localeCompare(JSON.stringify(bValue)) + : JSON.stringify(bValue).localeCompare(JSON.stringify(aValue)); + } + } + return 0; + }; +}