Create internal filament from external flow done
This commit is contained in:
@@ -136,6 +136,8 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"filament_name": "Filament",
|
"filament_name": "Filament",
|
||||||
"filament": "Filament",
|
"filament": "Filament",
|
||||||
|
"filament_internal": "Internal",
|
||||||
|
"filament_external": "External",
|
||||||
"price": "Price",
|
"price": "Price",
|
||||||
"material": "Material",
|
"material": "Material",
|
||||||
"weight_to_use": "Weight",
|
"weight_to_use": "Weight",
|
||||||
@@ -163,7 +165,8 @@
|
|||||||
"initial_weight": "The initial weight of filament on the spool (net weight). Will use the weight from the filament object if not set.",
|
"initial_weight": "The initial weight of filament on the spool (net weight). Will use the weight from the filament object if not set.",
|
||||||
"spool_weight": "The weight of the spool when it is empty. Leave empty to use the value from the filament or the manufacturer.",
|
"spool_weight": "The weight of the spool when it is empty. Leave empty to use the value from the filament or the manufacturer.",
|
||||||
"location": "Where the spool is located if you have multiple locations where you store your spools.",
|
"location": "Where the spool is located if you have multiple locations where you store your spools.",
|
||||||
"lot_nr": "Manufacturer's lot number. Can be used to ensure a print has consistent color if multiple spools are used."
|
"lot_nr": "Manufacturer's lot number. Can be used to ensure a print has consistent color if multiple spools are used.",
|
||||||
|
"external_filament": "You have selected a filament from the external database. A filament object (and possibly a manufacturer object) will be created automatically when you create this spool. This can create duplicate filament objects if you have already created a filament object for this filament."
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
"create": "Create Spool",
|
"create": "Create Spool",
|
||||||
@@ -201,6 +204,7 @@
|
|||||||
"settings_extruder_temp": "Extruder Temp",
|
"settings_extruder_temp": "Extruder Temp",
|
||||||
"settings_bed_temp": "Bed Temp",
|
"settings_bed_temp": "Bed Temp",
|
||||||
"color_hex": "Color",
|
"color_hex": "Color",
|
||||||
|
"external_id": "External ID",
|
||||||
"spools": "Show Spools"
|
"spools": "Show Spools"
|
||||||
},
|
},
|
||||||
"fields_help": {
|
"fields_help": {
|
||||||
@@ -232,6 +236,7 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"empty_spool_weight": "Empty Spool Weight",
|
"empty_spool_weight": "Empty Spool Weight",
|
||||||
|
"external_id": "External ID",
|
||||||
"registered": "Registered",
|
"registered": "Registered",
|
||||||
"comment": "Comment"
|
"comment": "Comment"
|
||||||
},
|
},
|
||||||
|
|||||||
38
client/src/pages/filaments/functions.ts
Normal file
38
client/src/pages/filaments/functions.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { ExternalFilament } from "../../utils/queryExternalDB";
|
||||||
|
import { getAPIURL } from "../../utils/url";
|
||||||
|
import { getOrCreateVendorFromExternal } from "../vendors/functions";
|
||||||
|
import { IFilament } from "./model";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new internal filament given an external filament object.
|
||||||
|
* Returns the created internal filament.
|
||||||
|
*/
|
||||||
|
export async function createFilamentFromExternal(externalFilament: ExternalFilament): Promise<IFilament> {
|
||||||
|
const vendor = await getOrCreateVendorFromExternal(externalFilament.manufacturer);
|
||||||
|
|
||||||
|
const body: Omit<IFilament, "id" | "registered" | "extra"> & { vendor_id: number } = {
|
||||||
|
name: externalFilament.name,
|
||||||
|
material: externalFilament.material,
|
||||||
|
vendor_id: vendor.id,
|
||||||
|
density: externalFilament.density,
|
||||||
|
diameter: externalFilament.diameter,
|
||||||
|
weight: externalFilament.weight,
|
||||||
|
spool_weight: externalFilament.spool_weight || undefined,
|
||||||
|
color_hex: externalFilament.color_hex,
|
||||||
|
settings_extruder_temp: externalFilament.extruder_temp || undefined,
|
||||||
|
settings_bed_temp: externalFilament.bed_temp || undefined,
|
||||||
|
external_id: externalFilament.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch(getAPIURL() + "/filament", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ export interface IFilament {
|
|||||||
settings_extruder_temp?: number;
|
settings_extruder_temp?: number;
|
||||||
settings_bed_temp?: number;
|
settings_bed_temp?: number;
|
||||||
color_hex?: string;
|
color_hex?: string;
|
||||||
|
external_id?: string;
|
||||||
extra: { [key: string]: string };
|
extra: { [key: string]: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,6 +143,8 @@ export const FilamentShow: React.FC<IResourceComponentsProps> = () => {
|
|||||||
)}
|
)}
|
||||||
<Title level={5}>{t("filament.fields.article_number")}</Title>
|
<Title level={5}>{t("filament.fields.article_number")}</Title>
|
||||||
<TextField value={record?.article_number} />
|
<TextField value={record?.article_number} />
|
||||||
|
<Title level={5}>{t("filament.fields.external_id")}</Title>
|
||||||
|
<TextField value={record?.external_id} />
|
||||||
<Title level={5}>{t("filament.fields.comment")}</Title>
|
<Title level={5}>{t("filament.fields.comment")}</Title>
|
||||||
<TextField value={enrichText(record?.comment)} />
|
<TextField value={enrichText(record?.comment)} />
|
||||||
<Title level={4}>{t("settings.extra_fields.tab")}</Title>
|
<Title level={4}>{t("settings.extra_fields.tab")}</Title>
|
||||||
|
|||||||
@@ -1,7 +1,20 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { HttpError, IResourceComponentsProps, useTranslate } from "@refinedev/core";
|
import { HttpError, IResourceComponentsProps, useTranslate } from "@refinedev/core";
|
||||||
import { Create, useForm, useSelect } from "@refinedev/antd";
|
import { Create, useForm, useSelect } from "@refinedev/antd";
|
||||||
import { Form, Input, DatePicker, Select, InputNumber, Radio, Divider, Button, Typography } from "antd";
|
import {
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
DatePicker,
|
||||||
|
Select,
|
||||||
|
InputNumber,
|
||||||
|
Radio,
|
||||||
|
Divider,
|
||||||
|
Button,
|
||||||
|
Typography,
|
||||||
|
ConfigProvider,
|
||||||
|
Alert,
|
||||||
|
Space,
|
||||||
|
} from "antd";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import TextArea from "antd/es/input/TextArea";
|
import TextArea from "antd/es/input/TextArea";
|
||||||
import { IFilament } from "../filaments/model";
|
import { IFilament } from "../filaments/model";
|
||||||
@@ -14,7 +27,8 @@ import { EntityType, useGetFields } from "../../utils/queryFields";
|
|||||||
import { ExtraFieldFormItem, StringifiedExtras } from "../../components/extraFields";
|
import { ExtraFieldFormItem, StringifiedExtras } from "../../components/extraFields";
|
||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
import { getCurrencySymbol, useCurrency } from "../../utils/settings";
|
import { getCurrencySymbol, useCurrency } from "../../utils/settings";
|
||||||
import { useGetExternalDBFilaments } from "../../utils/queryExternalDB";
|
import { ExternalFilament, useGetExternalDBFilaments } from "../../utils/queryExternalDB";
|
||||||
|
import { createFilamentFromExternal } from "../filaments/functions";
|
||||||
|
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
|
|
||||||
@@ -22,6 +36,10 @@ interface CreateOrCloneProps {
|
|||||||
mode: "create" | "clone";
|
mode: "create" | "clone";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ISpoolRequest = Omit<ISpoolParsedExtras, "id" | "registered"> & {
|
||||||
|
filament_id: number | string;
|
||||||
|
};
|
||||||
|
|
||||||
function formatFilamentLabel(name: string, diameter: number, vendorName?: string, material?: string, weight?: number) {
|
function formatFilamentLabel(name: string, diameter: number, vendorName?: string, material?: string, weight?: number) {
|
||||||
const portions = [];
|
const portions = [];
|
||||||
if (vendorName) {
|
if (vendorName) {
|
||||||
@@ -36,7 +54,7 @@ function formatFilamentLabel(name: string, diameter: number, vendorName?: string
|
|||||||
if (weight) {
|
if (weight) {
|
||||||
extras.push(formatWeight(weight));
|
extras.push(formatWeight(weight));
|
||||||
}
|
}
|
||||||
return `${portions.join(" - ")} (${extras.join(" ")})`;
|
return `${portions.join(" - ")} (${extras.join(", ")})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,7 +75,7 @@ export const SpoolCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps
|
|||||||
const { form, formProps, formLoading, onFinish, redirect } = useForm<
|
const { form, formProps, formLoading, onFinish, redirect } = useForm<
|
||||||
ISpool,
|
ISpool,
|
||||||
HttpError,
|
HttpError,
|
||||||
ISpoolParsedExtras,
|
ISpoolRequest,
|
||||||
ISpoolParsedExtras
|
ISpoolParsedExtras
|
||||||
>({
|
>({
|
||||||
redirect: false,
|
redirect: false,
|
||||||
@@ -91,6 +109,17 @@ export const SpoolCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps
|
|||||||
|
|
||||||
const handleSubmit = async (redirectTo: "list" | "edit" | "create") => {
|
const handleSubmit = async (redirectTo: "list" | "edit" | "create") => {
|
||||||
const values = StringifiedExtras(await form.validateFields());
|
const values = StringifiedExtras(await form.validateFields());
|
||||||
|
if (typeof values.filament_id === "string") {
|
||||||
|
// Filament ID being a string indicates its an external filament.
|
||||||
|
// If so, we should first create the internal filament version, then create the spool(s)
|
||||||
|
const externalFilament = externalFilaments.data?.find((f) => f.id === values.filament_id);
|
||||||
|
if (!externalFilament) {
|
||||||
|
throw new Error("Unknown external filament");
|
||||||
|
}
|
||||||
|
const internalFilament = await createFilamentFromExternal(externalFilament);
|
||||||
|
values.filament_id = internalFilament.id;
|
||||||
|
}
|
||||||
|
|
||||||
if (quantity > 1) {
|
if (quantity > 1) {
|
||||||
const submit = Array(quantity).fill(values);
|
const submit = Array(quantity).fill(values);
|
||||||
// queue multiple creates this way for now Refine doesn't seem to map Arrays to createMany or multiple creates like it says it does
|
// queue multiple creates this way for now Refine doesn't seem to map Arrays to createMany or multiple creates like it says it does
|
||||||
@@ -98,7 +127,8 @@ export const SpoolCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps
|
|||||||
} else {
|
} else {
|
||||||
await onFinish(values);
|
await onFinish(values);
|
||||||
}
|
}
|
||||||
redirect(redirectTo, (values as ISpool).id);
|
|
||||||
|
redirect(redirectTo);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { queryResult: filamentsQuery } = useSelect<IFilament>({
|
const { queryResult: filamentsQuery } = useSelect<IFilament>({
|
||||||
@@ -116,7 +146,19 @@ export const SpoolCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps
|
|||||||
});
|
});
|
||||||
}, [form, extraFields.data, formProps.initialValues]);
|
}, [form, extraFields.data, formProps.initialValues]);
|
||||||
|
|
||||||
const filamentSelectInternal = filamentsQuery.data?.data.map((item) => {
|
//
|
||||||
|
// Set up the filament selection options
|
||||||
|
//
|
||||||
|
|
||||||
|
interface SelectOption {
|
||||||
|
label: string;
|
||||||
|
value: string | number;
|
||||||
|
weight?: number;
|
||||||
|
spool_weight?: number;
|
||||||
|
is_internal: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filamentSelectInternal: SelectOption[] | undefined = filamentsQuery.data?.data.map((item) => {
|
||||||
return {
|
return {
|
||||||
label: formatFilamentLabel(
|
label: formatFilamentLabel(
|
||||||
item.name ?? `ID ${item.id}`,
|
item.name ?? `ID ${item.id}`,
|
||||||
@@ -128,61 +170,71 @@ export const SpoolCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps
|
|||||||
value: item.id,
|
value: item.id,
|
||||||
weight: item.weight,
|
weight: item.weight,
|
||||||
spool_weight: item.spool_weight,
|
spool_weight: item.spool_weight,
|
||||||
|
is_internal: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
filamentSelectInternal?.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
|
filamentSelectInternal?.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
|
||||||
|
|
||||||
const filamentSelectExternal = externalFilaments.data?.map((item) => {
|
const filamentSelectExternal: SelectOption[] | undefined = externalFilaments.data?.map((item) => {
|
||||||
return {
|
return {
|
||||||
label: formatFilamentLabel(item.name, item.diameter, item.manufacturer, item.material, item.weight),
|
label: formatFilamentLabel(item.name, item.diameter, item.manufacturer, item.material, item.weight),
|
||||||
value: item.id,
|
value: item.id,
|
||||||
weight: item.weight,
|
weight: item.weight,
|
||||||
spool_weight: item.spool_weight,
|
spool_weight: item.spool_weight || undefined,
|
||||||
|
is_internal: false,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
filamentSelectExternal?.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
|
filamentSelectExternal?.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
|
||||||
|
|
||||||
const filamentSelectOptions = [
|
const filamentSelectOptions = [
|
||||||
{
|
{
|
||||||
title: "Internal",
|
label: <span>{t("spool.fields.filament_internal")}</span>,
|
||||||
label: <span>Internal</span>,
|
|
||||||
options: filamentSelectInternal ?? [],
|
options: filamentSelectInternal ?? [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "External",
|
label: <span>{t("spool.fields.filament_external")}</span>,
|
||||||
label: <span>External</span>,
|
|
||||||
options: filamentSelectExternal ?? [],
|
options: filamentSelectExternal ?? [],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const selectedFilamentID: number | string | undefined = Form.useWatch("filament_id", form);
|
||||||
|
let selectedFilament: SelectOption | null = null;
|
||||||
|
// selectedFilamentID is a number of it's an internal filament, and a string of it's an external filament.
|
||||||
|
if (typeof selectedFilamentID === "number") {
|
||||||
|
selectedFilament =
|
||||||
|
filamentSelectInternal?.find((obj) => {
|
||||||
|
return obj.value === selectedFilamentID;
|
||||||
|
}) ?? null;
|
||||||
|
} else if (typeof selectedFilamentID === "string") {
|
||||||
|
selectedFilament =
|
||||||
|
filamentSelectExternal?.find((obj) => {
|
||||||
|
return obj.value === selectedFilamentID;
|
||||||
|
}) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Weight calculations
|
||||||
|
//
|
||||||
|
|
||||||
const [weightToEnter, setWeightToEnter] = useState(1);
|
const [weightToEnter, setWeightToEnter] = useState(1);
|
||||||
const [usedWeight, setUsedWeight] = useState(0);
|
const [usedWeight, setUsedWeight] = useState(0);
|
||||||
|
|
||||||
const selectedFilamentID = Form.useWatch("filament_id", form);
|
React.useEffect(() => {
|
||||||
const selectedFilament = filamentSelectInternal?.find((obj) => {
|
|
||||||
return obj.value === selectedFilamentID;
|
|
||||||
});
|
|
||||||
|
|
||||||
const filamentChange = (newID: number) => {
|
|
||||||
const newSelectedFilament = filamentSelectInternal?.find((obj) => {
|
|
||||||
return obj.value === newID;
|
|
||||||
});
|
|
||||||
|
|
||||||
const initial_weight = initialWeightValue ?? 0;
|
const initial_weight = initialWeightValue ?? 0;
|
||||||
const spool_weight = spoolWeightValue ?? 0;
|
const spool_weight = spoolWeightValue ?? 0;
|
||||||
|
|
||||||
const newFilamentWeight = newSelectedFilament?.weight || 0;
|
const newFilamentWeight = selectedFilament?.weight || 0;
|
||||||
const newSpoolWeight = newSelectedFilament?.spool_weight || 0;
|
const newSpoolWeight = selectedFilament?.spool_weight || 0;
|
||||||
|
|
||||||
const currentCalculatedFilamentWeight = getTotalWeightFromFilament();
|
const currentCalculatedFilamentWeight = selectedFilament ? calcTotalWeight(selectedFilament) : 0;
|
||||||
if ((initial_weight === 0 || initial_weight === currentCalculatedFilamentWeight) && newFilamentWeight > 0) {
|
if (newFilamentWeight > 0) {
|
||||||
form.setFieldValue("initial_weight", newFilamentWeight);
|
form.setFieldValue("initial_weight", newFilamentWeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((spool_weight === 0 || spool_weight === (selectedFilament?.spool_weight ?? 0)) && newSpoolWeight > 0) {
|
if (newSpoolWeight > 0) {
|
||||||
form.setFieldValue("spool_weight", newSpoolWeight);
|
form.setFieldValue("spool_weight", newSpoolWeight);
|
||||||
}
|
}
|
||||||
};
|
}, [selectedFilament]);
|
||||||
|
|
||||||
const weightChange = (weight: number) => {
|
const weightChange = (weight: number) => {
|
||||||
setUsedWeight(weight);
|
setUsedWeight(weight);
|
||||||
@@ -222,9 +274,9 @@ export const SpoolCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps
|
|||||||
return net_weight + spool_weight;
|
return net_weight + spool_weight;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTotalWeightFromFilament = (): number => {
|
function calcTotalWeight(filament: SelectOption): number {
|
||||||
return (selectedFilament?.weight ?? 0) + (selectedFilament?.spool_weight ?? 0);
|
return (filament.weight ?? 0) + (filament.spool_weight ?? 0);
|
||||||
};
|
}
|
||||||
|
|
||||||
const getMeasuredWeight = (): number => {
|
const getMeasuredWeight = (): number => {
|
||||||
const grossWeight = getGrossWeight();
|
const grossWeight = getGrossWeight();
|
||||||
@@ -343,11 +395,11 @@ export const SpoolCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps
|
|||||||
filterOption={(input, option) =>
|
filterOption={(input, option) =>
|
||||||
typeof option?.label === "string" && selectSearchMatches(input, option?.label)
|
typeof option?.label === "string" && selectSearchMatches(input, option?.label)
|
||||||
}
|
}
|
||||||
onChange={(value) => {
|
|
||||||
filamentChange(value);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{selectedFilament?.is_internal === false && (
|
||||||
|
<Alert message={t("spool.fields_help.external_filament")} type="info" />
|
||||||
|
)}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("spool.fields.price")}
|
label={t("spool.fields.price")}
|
||||||
help={t("spool.fields_help.price")}
|
help={t("spool.fields_help.price")}
|
||||||
|
|||||||
48
client/src/pages/vendors/functions.ts
vendored
Normal file
48
client/src/pages/vendors/functions.ts
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { getAPIURL } from "../../utils/url";
|
||||||
|
import { IVendor } from "./model";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a vendor given its external ID.
|
||||||
|
*/
|
||||||
|
export async function getVendorByExternalID(external_id: string): Promise<IVendor | null> {
|
||||||
|
// Make a search using GET and query params
|
||||||
|
const response = await fetch(`${getAPIURL()}/vendor?${new URLSearchParams({ external_id })}`);
|
||||||
|
if (!response.ok) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data: IVendor[] = await response.json();
|
||||||
|
if (data.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new internal filament given an external filament object.
|
||||||
|
* Returns the created internal filament.
|
||||||
|
*/
|
||||||
|
export async function getOrCreateVendorFromExternal(vendor_external_id: string): Promise<IVendor> {
|
||||||
|
const existingVendor = await getVendorByExternalID(vendor_external_id);
|
||||||
|
if (existingVendor) {
|
||||||
|
return existingVendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const body: Omit<IVendor, "id" | "registered" | "extra"> = {
|
||||||
|
name: vendor_external_id,
|
||||||
|
external_id: vendor_external_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch(getAPIURL() + "/vendor", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
1
client/src/pages/vendors/model.tsx
vendored
1
client/src/pages/vendors/model.tsx
vendored
@@ -4,6 +4,7 @@ export interface IVendor {
|
|||||||
name: string;
|
name: string;
|
||||||
comment?: string;
|
comment?: string;
|
||||||
empty_spool_weight?: number;
|
empty_spool_weight?: number;
|
||||||
|
external_id?: string;
|
||||||
extra: { [key: string]: string };
|
extra: { [key: string]: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
client/src/pages/vendors/show.tsx
vendored
2
client/src/pages/vendors/show.tsx
vendored
@@ -44,6 +44,8 @@ export const VendorShow: React.FC<IResourceComponentsProps> = () => {
|
|||||||
<TextField value={enrichText(record?.comment)} />
|
<TextField value={enrichText(record?.comment)} />
|
||||||
<Title level={5}>{t("vendor.fields.empty_spool_weight")}</Title>
|
<Title level={5}>{t("vendor.fields.empty_spool_weight")}</Title>
|
||||||
<TextField value={record?.empty_spool_weight} />
|
<TextField value={record?.empty_spool_weight} />
|
||||||
|
<Title level={5}>{t("vendor.fields.external_id")}</Title>
|
||||||
|
<TextField value={record?.external_id} />
|
||||||
<Title level={4}>{t("settings.extra_fields.tab")}</Title>
|
<Title level={4}>{t("settings.extra_fields.tab")}</Title>
|
||||||
{extraFields?.data?.map((field, index) => (
|
{extraFields?.data?.map((field, index) => (
|
||||||
<ExtraFieldDisplay key={index} field={field} value={record?.extra[field.key]} />
|
<ExtraFieldDisplay key={index} field={field} value={record?.extra[field.key]} />
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { getAPIURL } from "./url";
|
import { getAPIURL } from "./url";
|
||||||
|
|
||||||
interface ExternalFilament {
|
export interface ExternalFilament {
|
||||||
id: string;
|
id: string;
|
||||||
manufacturer: string;
|
manufacturer: string;
|
||||||
name: string;
|
name: string;
|
||||||
material: string;
|
material: string;
|
||||||
density: number | null;
|
density: number;
|
||||||
weight: number;
|
weight: number;
|
||||||
spool_weight: number | null;
|
spool_weight: number | null;
|
||||||
diameter: number;
|
diameter: number;
|
||||||
@@ -15,7 +15,7 @@ interface ExternalFilament {
|
|||||||
bed_temp: number | null;
|
bed_temp: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExternalMaterial {
|
export interface ExternalMaterial {
|
||||||
material: string;
|
material: string;
|
||||||
density: number;
|
density: number;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user