@@ -3,7 +3,7 @@ import { HttpError, useTranslate } from "@refinedev/core";
33import { Alert , ColorPicker , DatePicker , Form , Input , InputNumber , message , Radio , Select , Typography } from "antd" ;
44import TextArea from "antd/es/input/TextArea" ;
55import dayjs from "dayjs" ;
6- import { useEffect , useState } from "react" ;
6+ import { useEffect , useMemo , useState } from "react" ;
77import { ExtraFieldFormItem , ParsedExtras , StringifiedExtras } from "../../components/extraFields" ;
88import { MultiColorPicker } from "../../components/multiColorPicker" ;
99import { formatNumberOnUserInput , numberParser , numberParserAllowEmpty } from "../../utils/parsing" ;
@@ -42,6 +42,7 @@ export const FilamentEdit = () => {
4242 optionLabel : "name" ,
4343 pagination : { mode : "off" } ,
4444 } ) ;
45+ const watchedAllValues = Form . useWatch ( [ ] , formProps . form ) ;
4546
4647 // Add the vendor_id field to the form
4748 if ( formProps . initialValues ) {
@@ -76,8 +77,71 @@ export const FilamentEdit = () => {
7677 }
7778 } ;
7879
80+ const normalizeForCompare = ( value : unknown ) : unknown => {
81+ if ( dayjs . isDayjs ( value ) ) {
82+ return value . toISOString ( ) ;
83+ }
84+ if ( Array . isArray ( value ) ) {
85+ return value . map ( normalizeForCompare ) ;
86+ }
87+ if ( value && typeof value === "object" ) {
88+ const objectValue = value as Record < string , unknown > ;
89+ return Object . keys ( objectValue )
90+ . sort ( )
91+ . reduce < Record < string , unknown > > ( ( acc , key ) => {
92+ const normalizedValue = normalizeForCompare ( objectValue [ key ] ) ;
93+ if ( normalizedValue !== undefined ) {
94+ acc [ key ] = normalizedValue ;
95+ }
96+ return acc ;
97+ } , { } ) ;
98+ }
99+ return value ;
100+ } ;
101+
102+ const toComparableState = ( value : unknown ) : string => {
103+ const normalized = normalizeForCompare ( value ) as Record < string , unknown > | undefined ;
104+ const normalizedExtra = { ...( normalized ?. extra as Record < string , unknown > | undefined ) } ;
105+
106+ return JSON . stringify ( {
107+ name : normalized ?. name ?? "" ,
108+ vendor_id : normalized ?. vendor_id ?? null ,
109+ material : normalized ?. material ?? "" ,
110+ price : normalized ?. price ?? null ,
111+ density : normalized ?. density ?? null ,
112+ diameter : normalized ?. diameter ?? null ,
113+ weight : normalized ?. weight ?? null ,
114+ spool_weight : normalized ?. spool_weight ?? null ,
115+ settings_extruder_temp : normalized ?. settings_extruder_temp ?? null ,
116+ settings_bed_temp : normalized ?. settings_bed_temp ?? null ,
117+ article_number : normalized ?. article_number ?? "" ,
118+ external_id : normalized ?. external_id ?? "" ,
119+ comment : normalized ?. comment ?? "" ,
120+ color_hex : normalized ?. color_hex ?? "" ,
121+ multi_color_direction : normalized ?. multi_color_direction ?? "" ,
122+ multi_color_hexes : colorType === "single" ? "" : ( normalized ?. multi_color_hexes ?? "" ) ,
123+ extra : normalizedExtra ,
124+ } ) ;
125+ } ;
126+
127+ const initialComparableState = useMemo (
128+ ( ) => ( formProps . initialValues ? toComparableState ( formProps . initialValues ) : null ) ,
129+ [ formProps . initialValues , colorType ] ,
130+ ) ;
131+ const watchedComparableState = useMemo (
132+ ( ) => ( watchedAllValues ? toComparableState ( watchedAllValues ) : null ) ,
133+ [ watchedAllValues , colorType ] ,
134+ ) ;
135+ const hasFormChanges =
136+ initialComparableState !== null && watchedComparableState !== null && initialComparableState !== watchedComparableState ;
137+ const saveButtonState = {
138+ ...saveButtonProps ,
139+ type : hasFormChanges ? ( "primary" as const ) : ( "default" as const ) ,
140+ disabled : saveButtonProps . disabled || ! hasFormChanges ,
141+ } ;
142+
79143 return (
80- < Edit saveButtonProps = { saveButtonProps } >
144+ < Edit saveButtonProps = { saveButtonState } >
81145 { contextHolder }
82146 < Form { ...formProps } layout = "vertical" >
83147 < Form . Item
0 commit comments