Added a basic web UI

This commit is contained in:
Donkie
2023-05-10 21:11:10 +02:00
parent 1c59e0efd5
commit 0269518175
39 changed files with 10950 additions and 1 deletions

View File

@@ -0,0 +1,133 @@
import React from "react";
import { IResourceComponentsProps } from "@refinedev/core";
import { Create, useForm } from "@refinedev/antd";
import { Form, Input, DatePicker, Select, InputNumber } from "antd";
import dayjs from "dayjs";
import TextArea from "antd/es/input/TextArea";
export const FilamentCreate: React.FC<IResourceComponentsProps> = () => {
const { formProps, saveButtonProps, queryResult } = useForm();
return (
<Create saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item
label="Name"
help="Filament name, to distinguish this filament type among others from the same vendor. Should contain the color for example."
name={["name"]}
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Vendor"
name={["vendor", "name"]}
rules={[
{
required: false,
},
]}
>
{/* <Select {...vendorSelectProps} /> */}
</Form.Item>
<Form.Item
label="Material"
help="E.g. PLA, ABS, PETG, etc."
name={["material"]}
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Price"
help="Price of a full spool in the system configured currency."
name={["price"]}
rules={[
{
required: false,
},
]}
>
<InputNumber min={0} />
</Form.Item>
<Form.Item
label="Density"
name={["density"]}
rules={[
{
required: true,
},
]}
>
<InputNumber min={0} addonAfter="g/cm³" />
</Form.Item>
<Form.Item
label="Diameter"
name={["diameter"]}
rules={[
{
required: true,
},
]}
>
<InputNumber min={0} addonAfter="mm" />
</Form.Item>
<Form.Item
label="Weight"
help="The filament weight of a full spool (net weight)."
name={["weight"]}
rules={[
{
required: false,
},
]}
>
<InputNumber min={0} addonAfter="g" />
</Form.Item>
<Form.Item
label="Spool Weight"
help="The weight of an empty spool."
name={["spool_weight"]}
rules={[
{
required: false,
},
]}
>
<InputNumber min={0} addonAfter="g" />
</Form.Item>
<Form.Item
label="Article Number"
name={["article_number"]}
help="E.g. EAN, UPC, etc."
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Comment"
name={["comment"]}
rules={[
{
required: false,
},
]}
>
<TextArea maxLength={1024} />
</Form.Item>
</Form>
</Create>
);
};

View File

@@ -0,0 +1,160 @@
import React from "react";
import { IResourceComponentsProps } from "@refinedev/core";
import { Edit, useForm } from "@refinedev/antd";
import { Form, Input, DatePicker, Select, InputNumber } from "antd";
import dayjs from "dayjs";
import TextArea from "antd/es/input/TextArea";
export const FilamentEdit: React.FC<IResourceComponentsProps> = () => {
const { formProps, saveButtonProps, queryResult } = useForm();
const filamentData = queryResult?.data?.data;
return (
<Edit saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item
label="Id"
name={["id"]}
rules={[
{
required: true,
},
]}
>
<Input readOnly disabled />
</Form.Item>
<Form.Item
label="Registered"
name={["registered"]}
rules={[
{
required: true,
},
]}
getValueProps={(value) => ({
value: value ? dayjs(value) : undefined,
})}
>
<DatePicker disabled format="lll" />
</Form.Item>
<Form.Item
label="Name"
help="Filament name, to distinguish this filament type among others from the same vendor. Should contain the color for example."
name={["name"]}
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Vendor"
name={["vendor", "name"]}
rules={[
{
required: false,
},
]}
>
{/* <Select {...vendorSelectProps} /> */}
</Form.Item>
<Form.Item
label="Material"
help="E.g. PLA, ABS, PETG, etc."
name={["material"]}
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Price"
help="Price of a full spool in the system configured currency."
name={["price"]}
rules={[
{
required: false,
},
]}
>
<InputNumber min={0} />
</Form.Item>
<Form.Item
label="Density"
name={["density"]}
rules={[
{
required: true,
},
]}
>
<InputNumber min={0} addonAfter="g/cm³" />
</Form.Item>
<Form.Item
label="Diameter"
name={["diameter"]}
rules={[
{
required: true,
},
]}
>
<InputNumber min={0} addonAfter="mm" />
</Form.Item>
<Form.Item
label="Weight"
help="The filament weight of a full spool (net weight)."
name={["weight"]}
rules={[
{
required: false,
},
]}
>
<InputNumber min={0} addonAfter="g" />
</Form.Item>
<Form.Item
label="Spool Weight"
help="The weight of an empty spool."
name={["spool_weight"]}
rules={[
{
required: false,
},
]}
>
<InputNumber min={0} addonAfter="g" />
</Form.Item>
<Form.Item
label="Article Number"
name={["article_number"]}
help="E.g. EAN, UPC, etc."
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Comment"
name={["comment"]}
rules={[
{
required: false,
},
]}
>
<TextArea maxLength={1024} />
</Form.Item>
</Form>
</Edit>
);
};

View File

@@ -0,0 +1,4 @@
export { FilamentCreate } from "./create";
export { FilamentEdit } from "./edit";
export { FilamentList } from "./list";
export { FilamentShow } from "./show";

View File

@@ -0,0 +1,106 @@
import React from "react";
import { IResourceComponentsProps, BaseRecord } from "@refinedev/core";
import {
useTable,
List,
EditButton,
ShowButton,
DateField,
NumberField,
} from "@refinedev/antd";
import { Table, Space } from "antd";
export const FilamentList: React.FC<IResourceComponentsProps> = () => {
const { tableProps } = useTable({
syncWithLocation: true,
});
return (
<List>
<Table {...tableProps} rowKey="id">
<Table.Column dataIndex="id" title="Id" />
<Table.Column dataIndex={["vendor", "name"]} title="Vendor" />
<Table.Column dataIndex="name" title="Name" />
<Table.Column dataIndex="material" title="Material" />
<Table.Column dataIndex="price" title="Price" />
<Table.Column
dataIndex="density"
title="Density"
render={(value: any) => (
<NumberField
value={value}
options={{
unitDisplay: "short",
unit: "gram",
style: "unit",
maximumFractionDigits: 2,
}}
/>
)}
/>
<Table.Column
dataIndex="diameter"
title="Diameter"
render={(value: any) => (
<NumberField
value={value}
options={{
unitDisplay: "short",
unit: "millimeter",
style: "unit",
maximumFractionDigits: 2,
}}
/>
)}
/>
<Table.Column
dataIndex="weight"
title="Weight"
render={(value: any) => (
<NumberField
value={value}
options={{
unitDisplay: "short",
unit: "gram",
style: "unit",
maximumFractionDigits: 1,
}}
/>
)}
/>
<Table.Column
dataIndex="spool_weight"
title="Spool Weight"
render={(value: any) => (
<NumberField
value={value}
options={{
unitDisplay: "short",
unit: "gram",
style: "unit",
maximumFractionDigits: 1,
}}
/>
)}
/>
<Table.Column dataIndex="article_number" title="Article Number" />
<Table.Column
dataIndex={["registered"]}
title="Registered"
render={(value: any) => <DateField value={value} />}
/>
<Table.Column dataIndex={["comment"]} title="Comment" />
<Table.Column
title="Actions"
dataIndex="actions"
render={(_, record: BaseRecord) => (
<Space>
<EditButton hideText size="small" recordItemId={record.id} />
<ShowButton hideText size="small" recordItemId={record.id} />
</Space>
)}
/>
</Table>
</List>
);
};

View File

@@ -0,0 +1,80 @@
import React from "react";
import { IResourceComponentsProps, useShow } from "@refinedev/core";
import {
Show,
NumberField,
DateField,
TagField,
TextField,
} from "@refinedev/antd";
import { Typography } from "antd";
const { Title } = Typography;
export const FilamentShow: React.FC<IResourceComponentsProps> = () => {
const { queryResult } = useShow();
const { data, isLoading } = queryResult;
const record = data?.data;
return (
<Show isLoading={isLoading}>
<Title level={5}>Id</Title>
<NumberField value={record?.id ?? ""} />
<Title level={5}>Registered</Title>
<DateField value={record?.registered} format="lll" />
<Title level={5}>Name</Title>
<TextField value={record?.name} />
<Title level={5}>Vendor</Title>
{/* {vendorIsLoading ? <>Loading...</> : <>{vendorData?.data?.id}</>} */}
<Title level={5}>Material</Title>
<TextField value={record?.material} />
<Title level={5}>Price</Title>
<NumberField value={record?.price ?? ""} />
<Title level={5}>Density</Title>
<NumberField
value={record?.density ?? ""}
options={{
unitDisplay: "short",
unit: "gram",
style: "unit",
maximumFractionDigits: 2,
}}
/>
<Title level={5}>Diameter</Title>
<NumberField
value={record?.diameter ?? ""}
options={{
unitDisplay: "short",
unit: "millimeter",
style: "unit",
maximumFractionDigits: 2,
}}
/>
<Title level={5}>Weight</Title>
<NumberField
value={record?.weight ?? ""}
options={{
unitDisplay: "short",
unit: "gram",
style: "unit",
maximumFractionDigits: 1,
}}
/>
<Title level={5}>Spool Weight</Title>
<NumberField
value={record?.spool_weight ?? ""}
options={{
unitDisplay: "short",
unit: "gram",
style: "unit",
maximumFractionDigits: 1,
}}
/>
<Title level={5}>Article Number</Title>
<TextField value={record?.article_number} />
<Title level={5}>Comment</Title>
<TextField value={record?.comment} />
</Show>
);
};

View File

@@ -0,0 +1,100 @@
import React from "react";
import { IResourceComponentsProps } from "@refinedev/core";
import { Create, useForm } from "@refinedev/antd";
import { Form, Input, DatePicker, Select, InputNumber } from "antd";
import dayjs from "dayjs";
import TextArea from "antd/es/input/TextArea";
export const SpoolCreate: React.FC<IResourceComponentsProps> = () => {
const { formProps, saveButtonProps, queryResult } = useForm();
return (
<Create saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item
label="First Used"
name={["first_used"]}
rules={[
{
required: false,
},
]}
getValueProps={(value) => ({
value: value ? dayjs(value) : undefined,
})}
>
<DatePicker format="lll" />
</Form.Item>
<Form.Item
label="Last Used"
name={["last_used"]}
rules={[
{
required: false,
},
]}
getValueProps={(value) => ({
value: value ? dayjs(value) : undefined,
})}
>
<DatePicker format="lll" />
</Form.Item>
<Form.Item
label="Filament"
name={["filament", "name"]}
rules={[
{
required: true,
},
]}
>
{/* <Select {...filamentSelectProps} /> */}
</Form.Item>
<Form.Item
label="Used Weight"
name={["used_weight"]}
rules={[
{
required: true,
},
]}
>
<InputNumber min={0} addonAfter="g" />
</Form.Item>
<Form.Item
label="Location"
name={["location"]}
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Lot Nr"
name={["lot_nr"]}
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Comment"
name={["comment"]}
rules={[
{
required: false,
},
]}
>
<TextArea maxLength={1024} />
</Form.Item>
</Form>
</Create>
);
};

View File

@@ -0,0 +1,127 @@
import React from "react";
import { IResourceComponentsProps } from "@refinedev/core";
import { Edit, useForm } from "@refinedev/antd";
import { Form, Input, DatePicker, Select, InputNumber } from "antd";
import dayjs from "dayjs";
import TextArea from "antd/es/input/TextArea";
export const SpoolEdit: React.FC<IResourceComponentsProps> = () => {
const { formProps, saveButtonProps, queryResult } = useForm();
const spoolData = queryResult?.data?.data;
return (
<Edit saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item
label="Id"
name={["id"]}
rules={[
{
required: true,
},
]}
>
<Input readOnly disabled />
</Form.Item>
<Form.Item
label="Registered"
name={["registered"]}
rules={[
{
required: true,
},
]}
getValueProps={(value) => ({
value: value ? dayjs(value) : undefined,
})}
>
<DatePicker disabled format="lll" />
</Form.Item>
<Form.Item
label="First Used"
name={["first_used"]}
rules={[
{
required: true,
},
]}
getValueProps={(value) => ({
value: value ? dayjs(value) : undefined,
})}
>
<DatePicker format="lll" />
</Form.Item>
<Form.Item
label="Last Used"
name={["last_used"]}
rules={[
{
required: true,
},
]}
getValueProps={(value) => ({
value: value ? dayjs(value) : undefined,
})}
>
<DatePicker format="lll" />
</Form.Item>
<Form.Item
label="Filament"
name={["filament", "name"]}
rules={[
{
required: true,
},
]}
>
{/* <Select {...filamentSelectProps} /> */}
</Form.Item>
<Form.Item
label="Used Weight"
name={["used_weight"]}
rules={[
{
required: true,
},
]}
>
<Input min={0} addonAfter="g" />
</Form.Item>
<Form.Item
label="Location"
name={["location"]}
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Lot Nr"
name={["lot_nr"]}
rules={[
{
required: false,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Comment"
name={["comment"]}
rules={[
{
required: false,
},
]}
>
<TextArea maxLength={1024} />
</Form.Item>
</Form>
</Edit>
);
};

View File

@@ -0,0 +1,4 @@
export { SpoolCreate } from "./create";
export { SpoolEdit } from "./edit";
export { SpoolList } from "./list";
export { SpoolShow } from "./show";

View File

@@ -0,0 +1,68 @@
import React from "react";
import { IResourceComponentsProps, BaseRecord } from "@refinedev/core";
import {
useTable,
List,
EditButton,
ShowButton,
DateField,
NumberField,
} from "@refinedev/antd";
import { Table, Space } from "antd";
export const SpoolList: React.FC<IResourceComponentsProps> = () => {
const { tableProps } = useTable({
syncWithLocation: true,
});
return (
<List>
<Table {...tableProps} rowKey="id">
<Table.Column dataIndex="id" title="Id" />
<Table.Column
dataIndex={["filament", "vendor", "name"]}
title="Vendor"
/>
<Table.Column dataIndex={["filament", "name"]} title="Filament Name" />
<Table.Column
dataIndex="remaining_weight"
title="Estimated Remaining Weight"
render={(value: any) => (
<NumberField
value={value}
options={{
unitDisplay: "short",
unit: "gram",
style: "unit",
maximumFractionDigits: 1,
}}
/>
)}
/>
<Table.Column
dataIndex={["first_used"]}
title="First Used"
render={(value: any) => <DateField value={value} format="lll" />}
/>
<Table.Column
dataIndex={["last_used"]}
title="Last Used"
render={(value: any) => <DateField value={value} format="lll" />}
/>
<Table.Column dataIndex="location" title="Location" />
<Table.Column dataIndex="lot_nr" title="Lot Nr" />
<Table.Column dataIndex={["comment"]} title="Comment" />
<Table.Column
title="Actions"
dataIndex="actions"
render={(_, record: BaseRecord) => (
<Space>
<EditButton hideText size="small" recordItemId={record.id} />
<ShowButton hideText size="small" recordItemId={record.id} />
</Space>
)}
/>
</Table>
</List>
);
};

View File

@@ -0,0 +1,64 @@
import React from "react";
import { IResourceComponentsProps, useShow } from "@refinedev/core";
import {
Show,
NumberField,
DateField,
TagField,
TextField,
} from "@refinedev/antd";
import { Typography } from "antd";
const { Title } = Typography;
export const SpoolShow: React.FC<IResourceComponentsProps> = () => {
const { queryResult } = useShow();
const { data, isLoading } = queryResult;
const record = data?.data;
return (
<Show isLoading={isLoading}>
<Title level={5}>Id</Title>
<NumberField value={record?.id ?? ""} />
<Title level={5}>Registered</Title>
<DateField value={record?.registered} format="lll" />
<Title level={5}>First Used</Title>
<DateField value={record?.first_used} format="lll" />
<Title level={5}>Last Used</Title>
<DateField value={record?.last_used} format="lll" />
<Title level={5}>Filament</Title>
{/* {filamentIsLoading ? (
<>Loading...</>
) : (
<>{filamentData?.data?.id}</>
)} */}
<Title level={5}>Remaining Weight</Title>
<NumberField
value={record?.remaining_weight ?? ""}
options={{
unitDisplay: "short",
unit: "gram",
style: "unit",
maximumFractionDigits: 1,
}}
/>
<Title level={5}>Used Weight</Title>
<NumberField
value={record?.used_weight ?? ""}
options={{
unitDisplay: "short",
unit: "gram",
style: "unit",
maximumFractionDigits: 1,
}}
/>
<Title level={5}>Location</Title>
<TextField value={record?.location} />
<Title level={5}>Lot Nr</Title>
<TextField value={record?.lot_nr} />
<Title level={5}>Comment</Title>
<TextField value={record?.comment} />
</Show>
);
};

39
client/src/pages/vendors/create.tsx vendored Normal file
View File

@@ -0,0 +1,39 @@
import React from "react";
import { IResourceComponentsProps } from "@refinedev/core";
import { Create, useForm } from "@refinedev/antd";
import { Form, Input, DatePicker } from "antd";
import dayjs from "dayjs";
import TextArea from "antd/es/input/TextArea";
export const VendorCreate: React.FC<IResourceComponentsProps> = () => {
const { formProps, saveButtonProps, queryResult } = useForm();
return (
<Create saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item
label="Name"
name={["name"]}
rules={[
{
required: true,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Comment"
name={["comment"]}
rules={[
{
required: false,
},
]}
>
<TextArea maxLength={1024} />
</Form.Item>
</Form>
</Create>
);
};

66
client/src/pages/vendors/edit.tsx vendored Normal file
View File

@@ -0,0 +1,66 @@
import React from "react";
import { IResourceComponentsProps } from "@refinedev/core";
import { Edit, useForm } from "@refinedev/antd";
import { Form, Input, DatePicker } from "antd";
import dayjs from "dayjs";
import TextArea from "antd/es/input/TextArea";
export const VendorEdit: React.FC<IResourceComponentsProps> = () => {
const { formProps, saveButtonProps, queryResult } = useForm();
const vendorData = queryResult?.data?.data;
return (
<Edit saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item
label="Id"
name={["id"]}
rules={[
{
required: true,
},
]}
>
<Input readOnly disabled />
</Form.Item>
<Form.Item
label="Registered"
name={["registered"]}
rules={[
{
required: true,
},
]}
getValueProps={(value) => ({
value: value ? dayjs(value) : undefined,
})}
>
<DatePicker disabled format="lll" />
</Form.Item>
<Form.Item
label="Name"
name={["name"]}
rules={[
{
required: true,
},
]}
>
<Input maxLength={64} />
</Form.Item>
<Form.Item
label="Comment"
name={["comment"]}
rules={[
{
required: false,
},
]}
>
<TextArea maxLength={1024} />
</Form.Item>
</Form>
</Edit>
);
};

4
client/src/pages/vendors/index.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
export { VendorCreate } from "./create";
export { VendorEdit } from "./edit";
export { VendorList } from "./list";
export { VendorShow } from "./show";

41
client/src/pages/vendors/list.tsx vendored Normal file
View File

@@ -0,0 +1,41 @@
import React from "react";
import { IResourceComponentsProps, BaseRecord } from "@refinedev/core";
import {
useTable,
List,
EditButton,
ShowButton,
DateField,
} from "@refinedev/antd";
import { Table, Space } from "antd";
export const VendorList: React.FC<IResourceComponentsProps> = () => {
const { tableProps } = useTable({
syncWithLocation: true,
});
return (
<List>
<Table {...tableProps} rowKey="id">
<Table.Column dataIndex="id" title="Id" />
<Table.Column dataIndex="name" title="Name" />
<Table.Column
dataIndex={["registered"]}
title="Registered"
render={(value: any) => <DateField value={value} format="lll" />}
/>
<Table.Column dataIndex={["comment"]} title="Comment" />
<Table.Column
title="Actions"
dataIndex="actions"
render={(_, record: BaseRecord) => (
<Space>
<EditButton hideText size="small" recordItemId={record.id} />
<ShowButton hideText size="small" recordItemId={record.id} />
</Space>
)}
/>
</Table>
</List>
);
};

32
client/src/pages/vendors/show.tsx vendored Normal file
View File

@@ -0,0 +1,32 @@
import React from "react";
import { IResourceComponentsProps, useShow } from "@refinedev/core";
import {
Show,
NumberField,
DateField,
TagField,
TextField,
} from "@refinedev/antd";
import { Typography } from "antd";
const { Title } = Typography;
export const VendorShow: React.FC<IResourceComponentsProps> = () => {
const { queryResult } = useShow();
const { data, isLoading } = queryResult;
const record = data?.data;
return (
<Show isLoading={isLoading}>
<Title level={5}>Id</Title>
<NumberField value={record?.id ?? ""} />
<Title level={5}>Registered</Title>
<DateField value={record?.registered} format="lll" />
<Title level={5}>Name</Title>
<TextField value={record?.name} />
<Title level={5}>Comment</Title>
<TextField value={record?.comment} />
</Show>
);
};