Client: Now uses server side sorting

Still some stuff left to do #98
This commit is contained in:
Donkie
2023-09-07 21:24:40 +02:00
parent 826fde6967
commit f62f9d899b
9 changed files with 387 additions and 323 deletions

View File

@@ -5,54 +5,59 @@ import { Table, Space, Button, Dropdown } from "antd";
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import { IFilament } from "./model";
import { genericSorter, typeSorters } from "../../utils/sorting";
import { genericFilterer, typeFilters } from "../../utils/filtering";
import { EditOutlined, FilterOutlined } from "@ant-design/icons";
import { TableState, useInitialTableState, useStoreInitialState } from "../../utils/saveload";
import {
DateColumn,
FilteredColumn,
FilteredQueryColumn,
NumberColumn,
RichColumn,
SortedColumn,
SpoolIconColumn,
} from "../../components/column";
import {
useSpoolmanArticleNumbers,
useSpoolmanFilamentNames,
useSpoolmanMaterials,
useSpoolmanVendors,
} from "../../components/otherModels";
dayjs.extend(utc);
interface IFilamentCollapsed extends Omit<IFilament, "vendor"> {
vendor_name: string | null;
"vendor.name": string | null;
}
const namespace = "filamentList-v2";
export const FilamentList: React.FC<IResourceComponentsProps> = () => {
const t = useTranslate();
// Load initial state
const initialState = useInitialTableState("filamentList");
const initialState = useInitialTableState(namespace);
// Fetch data from the API
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent, setPageSize } =
useTable<IFilament>({
syncWithLocation: false,
pagination: {
mode: "off", // Perform pagination in antd's Table instead. Otherwise client-side sorting/filtering doesn't work.
current: initialState.pagination.current,
pageSize: initialState.pagination.pageSize,
},
sorters: {
mode: "off", // Disable server-side sorting
initial: initialState.sorters,
},
filters: {
mode: "off", // Disable server-side filtering
initial: initialState.filters,
},
});
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent } = useTable<IFilament>({
syncWithLocation: false,
pagination: {
mode: "server",
current: initialState.pagination.current,
pageSize: initialState.pagination.pageSize,
},
sorters: {
mode: "server",
initial: initialState.sorters,
},
filters: {
mode: "server",
initial: initialState.filters,
},
});
// Create state for the columns to show
const allColumns: (keyof IFilamentCollapsed & string)[] = [
"id",
"vendor_name",
"vendor.name",
"name",
"material",
"price",
@@ -72,10 +77,6 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
const [showColumns, setShowColumns] = React.useState<string[]>(initialState.showColumns ?? defaultColumns);
// Type the sorters and filters
const typedSorters = typeSorters<IFilamentCollapsed>(sorters);
const typedFilters = typeFilters<IFilamentCollapsed>(filters);
// Store state in local storage
const tableState: TableState = {
sorters,
@@ -83,7 +84,7 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
pagination: { current, pageSize },
showColumns,
};
useStoreInitialState("filamentList", tableState);
useStoreInitialState(namespace, tableState);
// Collapse the dataSource to a mutable list and add a filament_name field
const dataSource: IFilamentCollapsed[] = React.useMemo(
@@ -95,17 +96,14 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
} else {
vendor_name = null;
}
return { ...element, vendor_name };
return { ...element, "vendor.name": vendor_name };
}),
[tableProps.dataSource]
);
// Filter and sort the dataSource
const filteredDataSource = React.useMemo(() => {
const filtered = dataSource.filter(genericFilterer(typedFilters));
filtered.sort(genericSorter(typedSorters));
return filtered;
}, [dataSource, typedFilters, typedSorters]);
if (tableProps.pagination) {
tableProps.pagination.showSizeChanger = true;
}
return (
<List
@@ -148,31 +146,20 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
</>
)}
>
<Table
{...tableProps}
dataSource={filteredDataSource}
pagination={{
showSizeChanger: true,
current: current,
pageSize: pageSize,
onChange: (page, pageSize) => {
setCurrent(page);
setPageSize(pageSize);
},
}}
rowKey="id"
>
<Table {...tableProps} dataSource={dataSource} rowKey="id">
{SortedColumn({
id: "id",
i18ncat: "filament",
dataSource,
tableState,
})}
{FilteredColumn({
id: "vendor_name",
i18ncat: "filament",
{FilteredQueryColumn({
id: "vendor.name",
i18nkey: "filament.fields.vendor_name",
dataSource,
tableState,
filterValueQuery: useSpoolmanVendors(),
allowMultipleFilters: false,
})}
{SpoolIconColumn({
id: "name",
@@ -180,12 +167,16 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
color: (record: IFilamentCollapsed) => record.color_hex,
dataSource,
tableState,
filterValueQuery: useSpoolmanFilamentNames(),
allowMultipleFilters: false,
})}
{FilteredColumn({
{FilteredQueryColumn({
id: "material",
i18ncat: "filament",
dataSource,
tableState,
filterValueQuery: useSpoolmanMaterials(),
allowMultipleFilters: false,
})}
{SortedColumn({
id: "price",
@@ -225,11 +216,13 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
dataSource,
tableState,
})}
{FilteredColumn({
{FilteredQueryColumn({
id: "article_number",
i18ncat: "filament",
dataSource,
tableState,
filterValueQuery: useSpoolmanArticleNumbers(),
allowMultipleFilters: false,
})}
{NumberColumn({
id: "settings_extruder_temp",