@@ -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",
|
||||
|
||||
@@ -4,14 +4,12 @@ import { useTable, List, EditButton, ShowButton, CloneButton } from "@refinedev/
|
||||
import { Table, Space, Button, Dropdown, Modal } from "antd";
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import { genericSorter, typeSorters } from "../../utils/sorting";
|
||||
import { genericFilterer, typeFilters } from "../../utils/filtering";
|
||||
import { ISpool } from "./model";
|
||||
import { TableState, useInitialTableState, useSavedState, useStoreInitialState } from "../../utils/saveload";
|
||||
import { EditOutlined, FilterOutlined, InboxOutlined, ToTopOutlined } from "@ant-design/icons";
|
||||
import {
|
||||
DateColumn,
|
||||
FilteredColumn,
|
||||
FilteredQueryColumn,
|
||||
NumberColumn,
|
||||
RichColumn,
|
||||
SortedColumn,
|
||||
@@ -19,55 +17,62 @@ import {
|
||||
} from "../../components/column";
|
||||
import { setSpoolArchived } from "./functions";
|
||||
import SelectAndPrint from "../../components/selectAndPrintDialog";
|
||||
import {
|
||||
useSpoolmanFilamentFullNames,
|
||||
useSpoolmanLocations,
|
||||
useSpoolmanLotNumbers,
|
||||
useSpoolmanMaterials,
|
||||
} from "../../components/otherModels";
|
||||
|
||||
dayjs.extend(utc);
|
||||
|
||||
const { confirm } = Modal;
|
||||
|
||||
interface ISpoolCollapsed extends ISpool {
|
||||
filament_name: string;
|
||||
filament_material?: string;
|
||||
"filament.name": string;
|
||||
"filament.material"?: string;
|
||||
}
|
||||
|
||||
const namespace = "spoolList-v2";
|
||||
|
||||
export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
||||
const t = useTranslate();
|
||||
const invalidate = useInvalidate();
|
||||
|
||||
// Load initial state
|
||||
const initialState = useInitialTableState("spoolList");
|
||||
const initialState = useInitialTableState(namespace);
|
||||
|
||||
// State for the switch to show archived spools
|
||||
const [showArchived, setShowArchived] = useSavedState("spoolList-showArchived", false);
|
||||
|
||||
// Fetch data from the API
|
||||
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent, setPageSize } =
|
||||
useTable<ISpool>({
|
||||
meta: {
|
||||
queryParams: {
|
||||
["allow_archived"]: showArchived,
|
||||
},
|
||||
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent } = useTable<ISpool>({
|
||||
meta: {
|
||||
queryParams: {
|
||||
["allow_archived"]: showArchived,
|
||||
},
|
||||
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,
|
||||
},
|
||||
});
|
||||
},
|
||||
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 ISpoolCollapsed & string)[] = [
|
||||
"id",
|
||||
"filament_name",
|
||||
"filament_material",
|
||||
"filament.name",
|
||||
"filament.material",
|
||||
"used_weight",
|
||||
"remaining_weight",
|
||||
"used_length",
|
||||
@@ -91,7 +96,7 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
||||
pagination: { current, pageSize },
|
||||
showColumns,
|
||||
};
|
||||
useStoreInitialState("spoolList", tableState);
|
||||
useStoreInitialState(namespace, tableState);
|
||||
|
||||
// Collapse the dataSource to a mutable list and add a filament_name field
|
||||
const dataSource: ISpoolCollapsed[] = React.useMemo(
|
||||
@@ -105,8 +110,8 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
||||
}
|
||||
return {
|
||||
...element,
|
||||
filament_name,
|
||||
filament_material: element.filament.material,
|
||||
"filament.name": filament_name,
|
||||
"filament.material": element.filament.material,
|
||||
};
|
||||
}),
|
||||
[tableProps.dataSource]
|
||||
@@ -143,6 +148,10 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
||||
}
|
||||
};
|
||||
|
||||
if (tableProps.pagination) {
|
||||
tableProps.pagination.showSizeChanger = true;
|
||||
}
|
||||
|
||||
return (
|
||||
<List
|
||||
headerButtons={({ defaultButtons }) => (
|
||||
@@ -219,17 +228,21 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
||||
tableState,
|
||||
})}
|
||||
{SpoolIconColumn({
|
||||
id: "filament_name",
|
||||
i18ncat: "spool",
|
||||
id: "filament.name",
|
||||
i18nkey: "spool.fields.filament_name",
|
||||
color: (record: ISpoolCollapsed) => record.filament.color_hex,
|
||||
dataSource,
|
||||
tableState,
|
||||
filterValueQuery: useSpoolmanFilamentFullNames(),
|
||||
allowMultipleFilters: false,
|
||||
})}
|
||||
{FilteredColumn({
|
||||
id: "filament_material",
|
||||
i18ncat: "spool",
|
||||
{FilteredQueryColumn({
|
||||
id: "filament.material",
|
||||
i18nkey: "spool.fields.material",
|
||||
dataSource,
|
||||
tableState,
|
||||
filterValueQuery: useSpoolmanMaterials(),
|
||||
allowMultipleFilters: false,
|
||||
})}
|
||||
{NumberColumn({
|
||||
id: "used_weight",
|
||||
@@ -265,17 +278,21 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
||||
dataSource,
|
||||
tableState,
|
||||
})}
|
||||
{FilteredColumn({
|
||||
{FilteredQueryColumn({
|
||||
id: "location",
|
||||
i18ncat: "spool",
|
||||
dataSource,
|
||||
tableState,
|
||||
filterValueQuery: useSpoolmanLocations(),
|
||||
allowMultipleFilters: false,
|
||||
})}
|
||||
{FilteredColumn({
|
||||
{FilteredQueryColumn({
|
||||
id: "lot_nr",
|
||||
i18ncat: "spool",
|
||||
dataSource,
|
||||
tableState,
|
||||
filterValueQuery: useSpoolmanLotNumbers(),
|
||||
allowMultipleFilters: false,
|
||||
})}
|
||||
{DateColumn({
|
||||
id: "first_used",
|
||||
|
||||
69
client/src/pages/vendors/list.tsx
vendored
69
client/src/pages/vendors/list.tsx
vendored
@@ -4,8 +4,6 @@ import { useTable, List, EditButton, ShowButton, CloneButton } from "@refinedev/
|
||||
import { Table, Space, Button, Dropdown } from "antd";
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import { genericSorter, typeSorters } from "../../utils/sorting";
|
||||
import { genericFilterer, typeFilters } from "../../utils/filtering";
|
||||
import { IVendor } from "./model";
|
||||
import { TableState, useInitialTableState, useStoreInitialState } from "../../utils/saveload";
|
||||
import { EditOutlined, FilterOutlined } from "@ant-design/icons";
|
||||
@@ -13,39 +11,36 @@ import { DateColumn, RichColumn, SortedColumn } from "../../components/column";
|
||||
|
||||
dayjs.extend(utc);
|
||||
|
||||
const namespace = "vendorList-v2";
|
||||
|
||||
export const VendorList: React.FC<IResourceComponentsProps> = () => {
|
||||
const t = useTranslate();
|
||||
|
||||
// Load initial state
|
||||
const initialState = useInitialTableState("vendorList");
|
||||
const initialState = useInitialTableState(namespace);
|
||||
|
||||
// Fetch data from the API
|
||||
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent, setPageSize } =
|
||||
useTable<IVendor>({
|
||||
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<IVendor>({
|
||||
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 IVendor & string)[] = ["id", "name", "registered", "comment"];
|
||||
const [showColumns, setShowColumns] = React.useState<string[]>(initialState.showColumns ?? allColumns);
|
||||
|
||||
// Type the sorters and filters
|
||||
const typedSorters = typeSorters<IVendor>(sorters);
|
||||
const typedFilters = typeFilters<IVendor>(filters);
|
||||
|
||||
// Store state in local storage
|
||||
const tableState: TableState = {
|
||||
sorters,
|
||||
@@ -53,7 +48,7 @@ export const VendorList: React.FC<IResourceComponentsProps> = () => {
|
||||
pagination: { current, pageSize },
|
||||
showColumns,
|
||||
};
|
||||
useStoreInitialState("vendorList", tableState);
|
||||
useStoreInitialState(namespace, tableState);
|
||||
|
||||
// Collapse the dataSource to a mutable list
|
||||
const dataSource: IVendor[] = React.useMemo(
|
||||
@@ -61,12 +56,9 @@ export const VendorList: React.FC<IResourceComponentsProps> = () => {
|
||||
[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
|
||||
@@ -109,20 +101,7 @@ export const VendorList: 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: "vendor",
|
||||
|
||||
Reference in New Issue
Block a user