2025-08-22 20:28:50 +01:00

93 lines
2.6 KiB
JavaScript

import { useState, useEffect, useContext } from 'react'
import { Form, message } from 'antd'
import { ApiServerContext } from '../context/ApiServerContext'
import PropTypes from 'prop-types'
/**
* NewObjectForm is a reusable form component for creating new objects.
* It handles form validation, submission, and error handling logic.
*
* Props:
* - type: string (required)
* - formItems: array (for ObjectInfo/ObjectProperty items)
* - defaultValues: object (optional) - initial values for the form
* - children: function({
* loading, isSubmitting, handleSubmit, form, formValid, objectData, setObjectData
* }) => ReactNode
*/
const NewObjectForm = ({ type, style, defaultValues = {}, children }) => {
const [objectData, setObjectData] = useState(defaultValues)
const [submitLoading, setSubmitLoading] = useState(false)
const [formValid, setFormValid] = useState(false)
const [form] = Form.useForm()
const formUpdateValues = Form.useWatch([], form)
const [messageApi, contextHolder] = message.useMessage()
const { createObject, showError } = useContext(ApiServerContext)
// Set initial form values when defaultValues change
useEffect(() => {
if (Object.keys(defaultValues).length > 0) {
form.setFieldsValue(defaultValues)
}
}, [form, defaultValues])
// Validate form on change
useEffect(() => {
form
.validateFields({ validateOnly: true })
.then(() => setFormValid(true))
.catch(() => setFormValid(false))
}, [form, formUpdateValues])
const handleSubmit = async () => {
try {
setSubmitLoading(true)
const newObject = await createObject(type, objectData)
messageApi.success('Object created successfully')
return newObject
} catch (err) {
console.error(err)
if (err.errorFields) {
return
}
messageApi.error('Failed to create object')
showError(
`Failed to create object. Message: ${err.message}. Code: ${err.code}`,
() => handleSubmit()
)
} finally {
setSubmitLoading(false)
}
}
return (
<Form
form={form}
layout='vertical'
style={style}
onValuesChange={(values) => {
setObjectData((prev) => ({ ...prev, ...values }))
}}
>
{contextHolder}
{children({
submitLoading: submitLoading,
handleSubmit,
form,
formValid,
objectData,
setObjectData
})}
</Form>
)
}
NewObjectForm.propTypes = {
type: PropTypes.string.isRequired,
children: PropTypes.func.isRequired,
style: PropTypes.object,
defaultValues: PropTypes.object
}
export default NewObjectForm