Client: Added show/hide columns feature

This commit is contained in:
Donkie
2023-07-13 19:12:38 +02:00
parent 257c8b55ac
commit e5ef306aa2
6 changed files with 559 additions and 392 deletions

View File

@@ -5,32 +5,28 @@ import {
List,
EditButton,
ShowButton,
DateField,
TextField,
CloneButton,
} from "@refinedev/antd";
import { Table, Space, Button, Row, Col } from "antd";
import { NumberFieldUnit } from "../../components/numberField";
import { Table, Space, Button, Dropdown } from "antd";
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import {
genericSorter,
getSortOrderForField,
typeSorters,
} from "../../utils/sorting";
import {
genericFilterer,
getFiltersForField,
typeFilters,
useListFiltersForField,
} from "../../utils/filtering";
import { genericSorter, typeSorters } from "../../utils/sorting";
import { genericFilterer, typeFilters } from "../../utils/filtering";
import { ISpool } from "./model";
import {
TableState,
useInitialTableState,
useStoreInitialState,
} from "../../utils/saveload";
import Icon, { FilterOutlined } from "@ant-design/icons";
import { ReactComponent as SpoolIcon } from "../../icon_spool.svg";
import { EditOutlined, FilterOutlined } from "@ant-design/icons";
import {
DateColumn,
FilteredColumn,
NumberColumn,
SortedColumn,
SpoolIconColumn,
} from "../../components/column";
import i18n from "../../i18n";
dayjs.extend(utc);
@@ -70,16 +66,34 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
},
});
// Create state for the columns to show
const allColumns: (keyof ISpoolCollapsed & string)[] = [
"id",
"filament_name",
"used_weight",
"remaining_weight",
"location",
"lot_nr",
"first_used",
"last_used",
"comment",
];
const [showColumns, setShowColumns] = React.useState<string[]>(
initialState.showColumns ?? allColumns
);
// Type the sorters and filters
const typedSorters = typeSorters<ISpoolCollapsed>(sorters);
const typedFilters = typeFilters<ISpoolCollapsed>(filters);
// Store state in local storage
useStoreInitialState("spoolList", {
const tableState: TableState = {
sorters,
filters,
pagination: { current, pageSize },
});
showColumns,
};
useStoreInitialState("spoolList", tableState);
// Collapse the dataSource to a mutable list and add a filament_name field
const dataSource: ISpoolCollapsed[] = React.useMemo(
@@ -119,6 +133,28 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
>
Clear Filters
</Button>
<Dropdown
trigger={["click"]}
menu={{
items: allColumns.map((column) => ({
key: column,
label: i18n.t(`spools.fields.${column}`),
})),
selectedKeys: showColumns,
selectable: true,
multiple: true,
onDeselect: (keys) => {
setShowColumns(keys.selectedKeys);
},
onSelect: (keys) => {
setShowColumns(keys.selectedKeys);
},
}}
>
<Button type="primary" icon={<EditOutlined />}>
Hide Columns
</Button>
</Dropdown>
{defaultButtons}
</>
)}
@@ -137,138 +173,67 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
}}
rowKey="id"
>
<Table.Column
dataIndex="id"
title="Id"
sorter={true}
sortOrder={getSortOrderForField(typedSorters, "id")}
/>
<Table.Column
dataIndex="filament_name"
title="Filament"
sorter={true}
sortOrder={getSortOrderForField(typedSorters, "filament_name")}
filters={useListFiltersForField(dataSource, "filament_name")}
filteredValue={getFiltersForField(typedFilters, "filament_name")}
render={(value, record: ISpool) => {
return {
props: {
style: {
paddingLeft: 0,
paddingTop: 0,
paddingBottom: 0,
},
},
children: (
<Row wrap={false} justify="space-around" align="middle">
{record.filament.color_hex && (
<Col flex="none">
<Icon
component={SpoolIcon}
style={{
color: "#" + record.filament.color_hex,
fontSize: 42,
marginRight: 0,
}}
/>
</Col>
)}
<Col flex="auto">{value}</Col>
</Row>
),
};
}}
/>
<Table.Column
dataIndex="used_weight"
title="Used Weight"
sorter={true}
sortOrder={getSortOrderForField(typedSorters, "used_weight")}
render={(value) => {
return (
<NumberFieldUnit
value={value}
unit="g"
options={{
maximumFractionDigits: 1,
}}
/>
);
}}
/>
<Table.Column
dataIndex="remaining_weight"
title="Estimated Remaining Weight"
sorter={true}
sortOrder={getSortOrderForField(typedSorters, "remaining_weight")}
render={(value) => {
if (value === null || value === undefined) {
return <TextField value="Unknown" />;
}
return (
<NumberFieldUnit
value={Math.max(value, 0)}
unit="g"
options={{
maximumFractionDigits: 1,
}}
/>
);
}}
/>
<Table.Column
dataIndex="location"
title="Location"
sorter={true}
sortOrder={getSortOrderForField(typedSorters, "location")}
filters={useListFiltersForField(dataSource, "location")}
filteredValue={getFiltersForField(typedFilters, "location")}
/>
<Table.Column
dataIndex="lot_nr"
title="Lot Nr"
sorter={true}
sortOrder={getSortOrderForField(typedSorters, "lot_nr")}
filters={useListFiltersForField(dataSource, "lot_nr")}
filteredValue={getFiltersForField(typedFilters, "lot_nr")}
/>
<Table.Column
dataIndex={["first_used"]}
title="First Used"
sorter={true}
sortOrder={getSortOrderForField(typedSorters, "first_used")}
render={(value) => (
<DateField
hidden={!value}
value={dayjs.utc(value).local()}
title={dayjs.utc(value).local().format()}
format="YYYY-MM-DD HH:mm:ss"
/>
)}
/>
<Table.Column
dataIndex={["last_used"]}
title="Last Used"
sorter={true}
sortOrder={getSortOrderForField(typedSorters, "last_used")}
render={(value) => (
<DateField
hidden={!value}
value={dayjs.utc(value).local()}
title={dayjs.utc(value).local().format()}
format="YYYY-MM-DD HH:mm:ss"
/>
)}
/>
<Table.Column
dataIndex={["comment"]}
title="Comment"
sorter={true}
sortOrder={getSortOrderForField(typedSorters, "comment")}
/>
{SortedColumn({
id: "id",
title: "Id",
dataSource,
tableState,
})}
{SpoolIconColumn({
id: "filament_name",
title: "Filament",
color: (record: ISpoolCollapsed) => record.filament.color_hex,
dataSource,
tableState,
})}
{NumberColumn({
id: "used_weight",
title: "Used Weight",
unit: "g",
decimals: 1,
dataSource,
tableState,
})}
{NumberColumn({
id: "remaining_weight",
title: "Estimated Remaining Weight",
unit: "g",
decimals: 1,
dataSource,
tableState,
})}
{FilteredColumn({
id: "location",
title: "Location",
dataSource,
tableState,
})}
{FilteredColumn({
id: "lot_nr",
title: "Lot Nr",
dataSource,
tableState,
})}
{DateColumn({
id: "first_used",
title: "First Used",
dataSource,
tableState,
})}
{DateColumn({
id: "last_used",
title: "Last Used",
dataSource,
tableState,
})}
{SortedColumn({
id: "comment",
title: "Comment",
dataSource,
tableState,
})}
<Table.Column
title="Actions"
dataIndex="actions"
render={(_, record: BaseRecord) => (
<Space>
<EditButton