Fixed selected filament re-rendering too much

This commit is contained in:
Donkie
2024-05-15 19:40:34 +02:00
parent 69bb3cec77
commit 090cbadf3b
3 changed files with 90 additions and 60 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useMemo, 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 { import {
@@ -85,10 +85,32 @@ export const SpoolCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps
// //
// Set up the filament selection options // Set up the filament selection options
// //
const { options: filamentOptions, getById, allExternalFilaments } = useGetFilamentSelectOptions(); const {
options: filamentOptions,
internalSelectOptions,
externalSelectOptions,
allExternalFilaments,
} = useGetFilamentSelectOptions();
const selectedFilamentID = Form.useWatch("filament_id", form); const selectedFilamentID = Form.useWatch("filament_id", form);
const selectedFilament = getById(selectedFilamentID); const selectedFilament = useMemo(() => {
// id is a number of it's an internal filament, and a string of it's an external filament.
if (typeof selectedFilamentID === "number") {
return (
internalSelectOptions?.find((obj) => {
return obj.value === selectedFilamentID;
}) ?? null
);
} else if (typeof selectedFilamentID === "string") {
return (
externalSelectOptions?.find((obj) => {
return obj.value === selectedFilamentID;
}) ?? null
);
} else {
return null;
}
}, [selectedFilamentID, internalSelectOptions, externalSelectOptions]);
// //
// Submit handler // Submit handler
@@ -96,8 +118,7 @@ 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());
const selectOption = getById(values.filament_id); if (selectedFilament?.is_internal === false) {
if (selectOption?.is_internal === false) {
// Filament ID being a string indicates its an external filament. // 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) // If so, we should first create the internal filament version, then create the spool(s)
const externalFilament = allExternalFilaments?.find((f) => f.id === values.filament_id); const externalFilament = allExternalFilaments?.find((f) => f.id === values.filament_id);

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useMemo, useState } from "react";
import { HttpError, IResourceComponentsProps, useTranslate } from "@refinedev/core"; import { HttpError, IResourceComponentsProps, useTranslate } from "@refinedev/core";
import { Edit, useForm, useSelect } from "@refinedev/antd"; import { Edit, useForm, useSelect } from "@refinedev/antd";
import { Form, Input, DatePicker, Select, InputNumber, Radio, Divider, Alert, Typography } from "antd"; import { Form, Input, DatePicker, Select, InputNumber, Radio, Divider, Alert, Typography } from "antd";
@@ -46,10 +46,6 @@ export const SpoolEdit: React.FC<IResourceComponentsProps> = () => {
const initialWeightValue = Form.useWatch("initial_weight", form); const initialWeightValue = Form.useWatch("initial_weight", form);
const spoolWeightValue = Form.useWatch("spool_weight", form); const spoolWeightValue = Form.useWatch("spool_weight", form);
// Get filament selection options
const { queryResult } = useSelect<IFilament>({
resource: "filament",
});
// Add the filament_id field to the form // Add the filament_id field to the form
if (formProps.initialValues) { if (formProps.initialValues) {
@@ -62,10 +58,32 @@ export const SpoolEdit: React.FC<IResourceComponentsProps> = () => {
// //
// Set up the filament selection options // Set up the filament selection options
// //
const { options: filamentOptions, getById, allExternalFilaments } = useGetFilamentSelectOptions(); const {
options: filamentOptions,
internalSelectOptions,
externalSelectOptions,
allExternalFilaments,
} = useGetFilamentSelectOptions();
const selectedFilamentID = Form.useWatch("filament_id", form); const selectedFilamentID = Form.useWatch("filament_id", form);
const selectedFilament = getById(selectedFilamentID); const selectedFilament = useMemo(() => {
// id is a number of it's an internal filament, and a string of it's an external filament.
if (typeof selectedFilamentID === "number") {
return (
internalSelectOptions?.find((obj) => {
return obj.value === selectedFilamentID;
}) ?? null
);
} else if (typeof selectedFilamentID === "string") {
return (
externalSelectOptions?.find((obj) => {
return obj.value === selectedFilamentID;
}) ?? null
);
} else {
return null;
}
}, [selectedFilamentID, internalSelectOptions, externalSelectOptions]);
// Override the form's onFinish method to stringify the extra fields // Override the form's onFinish method to stringify the extra fields
const originalOnFinish = formProps.onFinish; const originalOnFinish = formProps.onFinish;
@@ -73,8 +91,7 @@ export const SpoolEdit: React.FC<IResourceComponentsProps> = () => {
if (allValues !== undefined && allValues !== null) { if (allValues !== undefined && allValues !== null) {
// Lot of stupidity here to make types work // Lot of stupidity here to make types work
const values = StringifiedExtras<ISpoolRequest>(allValues); const values = StringifiedExtras<ISpoolRequest>(allValues);
const selectOption = getById(values.filament_id); if (selectedFilament?.is_internal === false) {
if (selectOption?.is_internal === false) {
// Filament ID being a string indicates its an external filament. // Filament ID being a string indicates its an external filament.
// If so, we should first create the internal filament version, then edit the spool // If so, we should first create the internal filament version, then edit the spool
const externalFilament = allExternalFilaments?.find((f) => f.id === values.filament_id); const externalFilament = allExternalFilaments?.find((f) => f.id === values.filament_id);
@@ -103,6 +120,7 @@ export const SpoolEdit: React.FC<IResourceComponentsProps> = () => {
React.useEffect(() => { React.useEffect(() => {
const newFilamentWeight = selectedFilament?.weight || 0; const newFilamentWeight = selectedFilament?.weight || 0;
const newSpoolWeight = selectedFilament?.spool_weight || 0; const newSpoolWeight = selectedFilament?.spool_weight || 0;
console.log("selectedFilament", selectedFilament, newFilamentWeight, newSpoolWeight);
if (newFilamentWeight > 0) { if (newFilamentWeight > 0) {
form.setFieldValue("initial_weight", newFilamentWeight); form.setFieldValue("initial_weight", newFilamentWeight);
} }

View File

@@ -4,6 +4,7 @@ import { getAPIURL } from "../../utils/url";
import { ISpool } from "./model"; import { ISpool } from "./model";
import { IFilament } from "../filaments/model"; import { IFilament } from "../filaments/model";
import { useGetExternalDBFilaments } from "../../utils/queryExternalDB"; import { useGetExternalDBFilaments } from "../../utils/queryExternalDB";
import { useMemo } from "react";
export async function setSpoolArchived(spool: ISpool, archived: boolean) { export async function setSpoolArchived(spool: ISpool, archived: boolean) {
const init: RequestInit = { const init: RequestInit = {
@@ -62,36 +63,42 @@ export function useGetFilamentSelectOptions() {
const externalFilaments = useGetExternalDBFilaments(); const externalFilaments = useGetExternalDBFilaments();
// Format and sort internal filament options // Format and sort internal filament options
const filamentSelectInternal: SelectOption[] = const filamentSelectInternal: SelectOption[] = useMemo(() => {
internalFilaments.data?.data.map((item) => { const data =
return { internalFilaments.data?.data.map((item) => {
label: formatFilamentLabel( return {
item.name ?? `ID ${item.id}`, label: formatFilamentLabel(
item.diameter, item.name ?? `ID ${item.id}`,
item.vendor?.name, item.diameter,
item.material, item.vendor?.name,
item.weight item.material,
), item.weight
value: item.id, ),
weight: item.weight, value: item.id,
spool_weight: item.spool_weight, weight: item.weight,
is_internal: true, spool_weight: item.spool_weight,
}; is_internal: true,
}) ?? []; };
filamentSelectInternal.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" })); }) ?? [];
data.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
return data;
}, [internalFilaments.data?.data]);
// Format and sort external filament options // Format and sort external filament options
const filamentSelectExternal: SelectOption[] = const filamentSelectExternal: SelectOption[] = useMemo(() => {
externalFilaments.data?.map((item) => { const data =
return { externalFilaments.data?.map((item) => {
label: formatFilamentLabel(item.name, item.diameter, item.manufacturer, item.material, item.weight), return {
value: item.id, label: formatFilamentLabel(item.name, item.diameter, item.manufacturer, item.material, item.weight),
weight: item.weight, value: item.id,
spool_weight: item.spool_weight || undefined, weight: item.weight,
is_internal: false, spool_weight: item.spool_weight || undefined,
}; is_internal: false,
}) ?? []; };
filamentSelectExternal.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" })); }) ?? [];
data.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
return data;
}, [externalFilaments.data]);
return { return {
options: [ options: [
@@ -104,24 +111,8 @@ export function useGetFilamentSelectOptions() {
options: filamentSelectExternal, options: filamentSelectExternal,
}, },
], ],
getById: (id: number | string | null) => { internalSelectOptions: filamentSelectInternal,
// id is a number of it's an internal filament, and a string of it's an external filament. externalSelectOptions: filamentSelectExternal,
if (typeof id === "number") {
return (
filamentSelectInternal?.find((obj) => {
return obj.value === id;
}) ?? null
);
} else if (typeof id === "string") {
return (
filamentSelectExternal?.find((obj) => {
return obj.value === id;
}) ?? null
);
} else {
return null;
}
},
allExternalFilaments: externalFilaments.data, allExternalFilaments: externalFilaments.data,
}; };
} }