Refactor object form.

This commit is contained in:
Tom Butcher 2025-08-31 21:29:46 +01:00
parent 4d01a6a04f
commit aee3370b6d
21 changed files with 581 additions and 663 deletions

View File

@ -20,7 +20,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder'
const FilamentStockInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const filamentStockId = new URLSearchParams(location.search).get(
'filamentStockId'
@ -34,7 +34,7 @@ const FilamentStockInfo = () => {
auditLogs: true
}
)
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -44,19 +44,19 @@ const FilamentStockInfo = () => {
const actions = {
reload: () => {
editFormRef?.current?.fetchObject?.()
objectFormRef?.current?.fetchObject?.()
return true
},
edit: () => {
editFormRef?.current?.startEditing?.()
objectFormRef?.current?.startEditing?.()
return false
},
cancelEdit: () => {
editFormRef?.current?.cancelEditing?.()
objectFormRef?.current?.cancelEditing?.()
return true
},
finishEdit: () => {
editFormRef?.current?.handleUpdate?.()
objectFormRef?.current?.handleUpdate?.()
return true
}
}
@ -74,10 +74,10 @@ const FilamentStockInfo = () => {
<ObjectActions
type='filamentStock'
id={filamentStockId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Filament Stock Information' },
{ key: 'events', label: 'Filament Stock Events' },
@ -88,11 +88,11 @@ const FilamentStockInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -102,10 +102,10 @@ const FilamentStockInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -113,7 +113,7 @@ const FilamentStockInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -127,7 +127,7 @@ const FilamentStockInfo = () => {
id={filamentStockId}
type='filamentStock'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -150,7 +150,7 @@ const FilamentStockInfo = () => {
onToggle={(expanded) => updateCollapseState('events', expanded)}
collapseKey='events'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
@ -180,7 +180,7 @@ const FilamentStockInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -25,7 +25,7 @@ log.setLevel(config.logLevel)
const DocumentSizeInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const documentSizeId = new URLSearchParams(location.search).get(
'documentSizeId'
@ -38,7 +38,7 @@ const DocumentSizeInfo = () => {
auditLogs: true
}
)
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -48,19 +48,19 @@ const DocumentSizeInfo = () => {
const actions = {
reload: () => {
editFormRef?.current?.fetchObject?.()
objectFormRef?.current?.fetchObject?.()
return true
},
edit: () => {
editFormRef?.current?.startEditing?.()
objectFormRef?.current?.startEditing?.()
return false
},
cancelEdit: () => {
editFormRef?.current?.cancelEditing?.()
objectFormRef?.current?.cancelEditing?.()
return true
},
finishEdit: () => {
editFormRef?.current?.handleUpdate?.()
objectFormRef?.current?.handleUpdate?.()
return true
}
}
@ -78,10 +78,10 @@ const DocumentSizeInfo = () => {
<ObjectActions
type='documentSize'
id={documentSizeId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Document Size Information' },
{ key: 'notes', label: 'Notes' },
@ -91,11 +91,11 @@ const DocumentSizeInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -105,10 +105,10 @@ const DocumentSizeInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -116,7 +116,7 @@ const DocumentSizeInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -130,7 +130,7 @@ const DocumentSizeInfo = () => {
id={documentSizeId}
type='documentSize'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -167,7 +167,7 @@ const DocumentSizeInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -21,7 +21,7 @@ log.setLevel(config.logLevel)
const DocumentTemplateDesign = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const documentTemplateId = new URLSearchParams(location.search).get(
'documentTemplateId'
@ -36,7 +36,7 @@ const DocumentTemplateDesign = () => {
}
)
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -46,19 +46,19 @@ const DocumentTemplateDesign = () => {
const actions = {
reload: () => {
editFormRef?.current.handleFetchObject()
objectFormRef?.current.handleFetchObject()
return true
},
edit: () => {
editFormRef?.current.startEditing()
objectFormRef?.current.startEditing()
return false
},
cancelEdit: () => {
editFormRef?.current.cancelEditing()
objectFormRef?.current.cancelEditing()
return true
},
finishEdit: () => {
editFormRef?.current.handleUpdate()
objectFormRef?.current.handleUpdate()
return true
}
}
@ -78,11 +78,11 @@ const DocumentTemplateDesign = () => {
<ObjectActions
type='documentTemplate'
id={documentTemplateId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
visibleActions={{ edit: false }}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{
key: 'preview',
@ -99,11 +99,11 @@ const DocumentTemplateDesign = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -113,10 +113,10 @@ const DocumentTemplateDesign = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -125,14 +125,14 @@ const DocumentTemplateDesign = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={documentTemplateId}
type='documentTemplate'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
console.log('Got edit form state change', state)
setEditFormState((prev) => ({ ...prev, ...state }))

View File

@ -25,7 +25,7 @@ log.setLevel(config.logLevel)
const DocumentTemplateInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const documentTemplateId = new URLSearchParams(location.search).get(
'documentTemplateId'
@ -40,7 +40,7 @@ const DocumentTemplateInfo = () => {
}
)
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -50,19 +50,19 @@ const DocumentTemplateInfo = () => {
const actions = {
reload: () => {
editFormRef?.current.handleFetchObject()
objectFormRef?.current.handleFetchObject()
return true
},
edit: () => {
editFormRef?.current.startEditing()
objectFormRef?.current.startEditing()
return false
},
cancelEdit: () => {
editFormRef?.current.cancelEditing()
objectFormRef?.current.cancelEditing()
return true
},
finishEdit: () => {
editFormRef?.current.handleUpdate()
objectFormRef?.current.handleUpdate()
return true
}
}
@ -83,10 +83,10 @@ const DocumentTemplateInfo = () => {
<ObjectActions
type='documentTemplate'
id={documentTemplateId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'DocumentTemplate Information' },
{ key: 'notes', label: 'Notes' },
@ -96,11 +96,11 @@ const DocumentTemplateInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -110,10 +110,10 @@ const DocumentTemplateInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -122,7 +122,7 @@ const DocumentTemplateInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -136,7 +136,7 @@ const DocumentTemplateInfo = () => {
id={documentTemplateId}
type='documentTemplate'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
console.log('Got edit form state change', state)
setEditFormState((prev) => ({ ...prev, ...state }))
@ -182,7 +182,7 @@ const DocumentTemplateInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -26,7 +26,7 @@ log.setLevel(config.logLevel)
const FilamentInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const filamentId = new URLSearchParams(location.search).get('filamentId')
const [collapseState, updateCollapseState] = useCollapseState(
@ -39,7 +39,7 @@ const FilamentInfo = () => {
}
)
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -49,19 +49,19 @@ const FilamentInfo = () => {
const actions = {
reload: () => {
editFormRef?.current?.fetchObject?.()
objectFormRef?.current?.fetchObject?.()
return true
},
edit: () => {
editFormRef?.current?.startEditing?.()
objectFormRef?.current?.startEditing?.()
return false
},
cancelEdit: () => {
editFormRef?.current?.cancelEditing?.()
objectFormRef?.current?.cancelEditing?.()
return true
},
finishEdit: () => {
editFormRef?.current?.handleUpdate?.()
objectFormRef?.current?.handleUpdate?.()
return true
}
}
@ -82,10 +82,10 @@ const FilamentInfo = () => {
<ObjectActions
type='filament'
id={filamentId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Filament Information' },
{ key: 'stocks', label: 'Filament Stocks' },
@ -96,11 +96,11 @@ const FilamentInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -110,10 +110,10 @@ const FilamentInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -122,7 +122,7 @@ const FilamentInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -136,7 +136,7 @@ const FilamentInfo = () => {
id={filamentId}
type='filament'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -163,7 +163,7 @@ const FilamentInfo = () => {
onToggle={(expanded) => updateCollapseState('stocks', expanded)}
collapseKey='stocks'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
@ -199,7 +199,7 @@ const FilamentInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -1,19 +1,9 @@
import PropTypes from 'prop-types'
import { useState } from 'react'
import { useMediaQuery } from 'react-responsive'
import { Typography, Flex, Steps, Divider } from 'antd'
import ObjectInfo from '../../common/ObjectInfo'
import NewObjectForm from '../../common/NewObjectForm'
import NewObjectButtons from '../../common/NewObjectButtons'
const { Title } = Typography
import WizardView from '../../common/WizardView'
const NewFilament = ({ onOk }) => {
const [currentStep, setCurrentStep] = useState(0)
const isMobile = useMediaQuery({ maxWidth: 768 })
return (
<NewObjectForm type={'filament'}>
{({ handleSubmit, submitLoading, objectData, formValid }) => {
@ -66,43 +56,16 @@ const NewFilament = ({ onOk }) => {
}
]
return (
<Flex gap='middle'>
{!isMobile && (
<div style={{ minWidth: '160px' }}>
<Steps
current={currentStep}
items={steps}
direction='vertical'
style={{ width: 'fit-content' }}
/>
</div>
)}
{!isMobile && (
<Divider type='vertical' style={{ height: 'unset' }} />
)}
<Flex vertical gap='middle' style={{ flexGrow: 1 }}>
<Title level={2} style={{ margin: 0 }}>
New Filament
</Title>
<div style={{ minHeight: '260px', marginBottom: 8 }}>
{steps[currentStep].content}
</div>
<NewObjectButtons
currentStep={currentStep}
totalSteps={steps.length}
onPrevious={() => setCurrentStep((prev) => prev - 1)}
onNext={() => setCurrentStep((prev) => prev + 1)}
<WizardView
steps={steps}
loading={submitLoading}
formValid={formValid}
title='New Filament'
onSubmit={() => {
handleSubmit()
onOk()
}}
formValid={formValid}
submitLoading={submitLoading}
/>
</Flex>
</Flex>
)
}}
</NewObjectForm>

View File

@ -26,7 +26,7 @@ log.setLevel(config.logLevel)
const HostInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const hostId = new URLSearchParams(location.search).get('hostId')
const [collapseState, updateCollapseState] = useCollapseState('HostInfo', {
@ -37,7 +37,7 @@ const HostInfo = () => {
})
const [hostOTPOpen, setHostOTPOpen] = useState(false)
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -47,7 +47,7 @@ const HostInfo = () => {
const actions = {
reload: () => {
editFormRef?.current.handleFetchObject()
objectFormRef?.current.handleFetchObject()
return true
},
hostOTP: () => {
@ -55,15 +55,15 @@ const HostInfo = () => {
return true
},
edit: () => {
editFormRef?.current.startEditing()
objectFormRef?.current.startEditing()
return false
},
cancelEdit: () => {
editFormRef?.current.cancelEditing()
objectFormRef?.current.cancelEditing()
return true
},
finishEdit: () => {
editFormRef?.current.handleUpdate()
objectFormRef?.current.handleUpdate()
return true
}
}
@ -84,10 +84,10 @@ const HostInfo = () => {
<ObjectActions
type='host'
id={hostId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Host Information' },
{ key: 'notes', label: 'Notes' },
@ -97,11 +97,11 @@ const HostInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -111,10 +111,10 @@ const HostInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -123,7 +123,7 @@ const HostInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -137,7 +137,7 @@ const HostInfo = () => {
id={hostId}
type='host'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
console.log('Got edit form state change', state)
setEditFormState((prev) => ({ ...prev, ...state }))
@ -179,7 +179,7 @@ const HostInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -1,279 +1,80 @@
import PropTypes from 'prop-types'
import { useState, useEffect } from 'react'
import axios from 'axios'
import {
Form,
Input,
Button,
message,
Select,
Flex,
Steps,
Divider,
Upload,
Descriptions
} from 'antd'
import { UploadOutlined } from '@ant-design/icons'
import VendorSelect from '../../common/VendorSelect'
import ObjectInfo from '../../common/ObjectInfo'
import NewObjectForm from '../../common/NewObjectForm'
import WizardView from '../../common/WizardView'
import config from '../../../../config'
const initialNewMaterialForm = {
name: '',
vendor: { id: null, name: '' },
category: '',
image: null,
url: '',
barcode: ''
}
const NewMaterial = ({ onSuccess }) => {
const [messageApi, contextHolder] = message.useMessage()
const [newMaterialLoading, setNewMaterialLoading] = useState(false)
const [currentStep, setCurrentStep] = useState(0)
const [nextEnabled, setNextEnabled] = useState(false)
const [newMaterialForm] = Form.useForm()
const [newMaterialFormValues, setNewMaterialFormValues] = useState(
initialNewMaterialForm
)
const [imageList, setImageList] = useState([])
const newMaterialFormUpdateValues = Form.useWatch([], newMaterialForm)
useEffect(() => {
newMaterialForm
.validateFields({
validateOnly: true
})
.then(() => setNextEnabled(true))
.catch(() => setNextEnabled(false))
}, [newMaterialForm, newMaterialFormUpdateValues])
const summaryItems = [
const NewMaterial = ({ onOk }) => {
return (
<NewObjectForm type={'material'}>
{({ handleSubmit, submitLoading, objectData, formValid }) => {
const steps = [
{
key: 'name',
label: 'Name',
children: newMaterialFormValues.name
},
{
key: 'vendor',
label: 'Vendor',
children: newMaterialFormValues.vendor.name
},
{
key: 'category',
label: 'Category',
children: newMaterialFormValues.category
},
{
key: 'image',
label: 'Image',
children: newMaterialFormValues.image && (
<img
src={newMaterialFormValues.image}
style={{ width: 128 }}
alt='Material'
title: 'Required',
key: 'required',
content: (
<ObjectInfo
type='material'
column={1}
bordered={false}
isEditing={true}
required={true}
objectData={objectData}
/>
)
},
{
key: 'url',
label: 'URL',
children: newMaterialFormValues.url
},
{
key: 'barcode',
label: 'Barcode',
children: newMaterialFormValues.barcode
}
]
const handleNewMaterial = async () => {
setNewMaterialLoading(true)
try {
await axios.post(
`${config.backendUrl}/materials`,
newMaterialFormValues,
{
withCredentials: true
}
)
messageApi.success('New material created successfully.')
onSuccess()
} catch (error) {
messageApi.error('Error creating new material: ' + error.message)
} finally {
setNewMaterialLoading(false)
}
}
const getBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = (error) => reject(error)
})
}
const handleImageUpload = async ({ file, fileList }) => {
if (fileList.length === 0) {
setImageList(fileList)
newMaterialForm.setFieldsValue({ image: '' })
return
}
const base64 = await getBase64(file)
setNewMaterialFormValues((prevValues) => ({
...prevValues,
image: base64
}))
fileList[0].name = 'Material Image'
setImageList(fileList)
newMaterialForm.setFieldsValue({ image: base64 })
}
const steps = [
{
title: 'Details',
key: 'details',
title: 'Optional',
key: 'optional',
content: (
<>
<Form.Item
label='Name'
name='name'
rules={[
{
required: true,
message: 'Please enter a name.'
}
]}
>
<Input />
</Form.Item>
<Form.Item
label='Vendor'
name='vendor'
rules={[
{
required: true,
message: 'Please select a vendor.'
}
]}
>
<VendorSelect />
</Form.Item>
<Form.Item
label='Category'
name='category'
rules={[{ required: true, message: 'Please select a category' }]}
>
<Select>
<Select.Option value='Raw Material'>Raw Material</Select.Option>
<Select.Option value='Component'>Component</Select.Option>
<Select.Option value='Consumable'>Consumable</Select.Option>
<Select.Option value='Tool'>Tool</Select.Option>
<Select.Option value='Packaging'>Packaging</Select.Option>
</Select>
</Form.Item>
</>
)
},
{
title: 'Additional Info',
key: 'additional',
content: (
<>
<Form.Item label='Image' name='image'>
<Upload
listType='picture'
maxCount={1}
fileList={imageList}
onChange={handleImageUpload}
beforeUpload={() => false}
>
<Button icon={<UploadOutlined />}>Upload Image</Button>
</Upload>
</Form.Item>
<Form.Item label='URL' name='url'>
<Input />
</Form.Item>
<Form.Item label='Barcode' name='barcode'>
<Input />
</Form.Item>
</>
<ObjectInfo
type='material'
column={1}
bordered={false}
isEditing={true}
required={false}
objectData={objectData}
/>
)
},
{
title: 'Summary',
key: 'summary',
content: (
<>
<Descriptions
title='Material Details'
bordered
<ObjectInfo
type='material'
column={1}
items={summaryItems}
bordered={false}
visibleProperties={{
_id: false,
createdAt: false,
updatedAt: false
}}
isEditing={false}
objectData={objectData}
/>
</>
)
}
]
return (
<>
{contextHolder}
<Form
form={newMaterialForm}
layout='vertical'
onValuesChange={(changedValues) => {
setNewMaterialFormValues((prevValues) => ({
...prevValues,
...changedValues
}))
<WizardView
steps={steps}
loading={submitLoading}
formValid={formValid}
title='New Material'
onSubmit={() => {
handleSubmit()
onOk()
}}
>
<Steps
current={currentStep}
items={steps.map((item) => ({ title: item.title }))}
style={{ marginBottom: 24 }}
/>
<div style={{ minHeight: 200 }}>{steps[currentStep].content}</div>
<Divider />
<Flex justify='space-between'>
<Button
disabled={currentStep === 0}
onClick={() => setCurrentStep((prev) => prev - 1)}
>
Previous
</Button>
{currentStep < steps.length - 1 ? (
<Button
type='primary'
disabled={!nextEnabled}
onClick={() => setCurrentStep((prev) => prev + 1)}
>
Next
</Button>
) : (
<Button
type='primary'
loading={newMaterialLoading}
onClick={handleNewMaterial}
>
Create Material
</Button>
)}
</Flex>
</Form>
</>
)
}}
</NewObjectForm>
)
}
NewMaterial.propTypes = {
onSuccess: PropTypes.func.isRequired
onOk: PropTypes.func.isRequired,
reset: PropTypes.bool
}
export default NewMaterial

View File

@ -1,18 +1,9 @@
import PropTypes from 'prop-types'
import { useState } from 'react'
import { useMediaQuery } from 'react-responsive'
import { Typography, Flex, Steps, Divider } from 'antd'
import ObjectInfo from '../../common/ObjectInfo'
import NewObjectForm from '../../common/NewObjectForm'
import NewObjectButtons from '../../common/NewObjectButtons'
const { Title } = Typography
import WizardView from '../../common/WizardView'
const NewNoteType = ({ onOk }) => {
const [currentStep, setCurrentStep] = useState(0)
const isMobile = useMediaQuery({ maxWidth: 768 })
return (
<NewObjectForm
type={'noteType'}
@ -70,43 +61,16 @@ const NewNoteType = ({ onOk }) => {
}
]
return (
<Flex gap='middle'>
{!isMobile && (
<div style={{ minWidth: '160px' }}>
<Steps
current={currentStep}
items={steps}
direction='vertical'
style={{ width: 'fit-content' }}
/>
</div>
)}
{!isMobile && (
<Divider type='vertical' style={{ height: 'unset' }} />
)}
<Flex vertical gap='middle' style={{ flexGrow: 1 }}>
<Title level={2} style={{ margin: 0 }}>
New Note Type
</Title>
<div style={{ minHeight: '260px', marginBottom: 8 }}>
{steps[currentStep].content}
</div>
<NewObjectButtons
currentStep={currentStep}
totalSteps={steps.length}
onPrevious={() => setCurrentStep((prev) => prev - 1)}
onNext={() => setCurrentStep((prev) => prev + 1)}
<WizardView
steps={steps}
loading={submitLoading}
formValid={formValid}
title='New Note Type'
onSubmit={() => {
handleSubmit()
onOk()
}}
formValid={formValid}
submitLoading={submitLoading}
/>
</Flex>
</Flex>
)
}}
</NewObjectForm>

View File

@ -18,7 +18,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
const NoteTypeInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const noteTypeId = new URLSearchParams(location.search).get('noteTypeId')
const [collapseState, updateCollapseState] = useCollapseState(
@ -28,7 +28,7 @@ const NoteTypeInfo = () => {
auditLogs: true
}
)
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -38,19 +38,19 @@ const NoteTypeInfo = () => {
const actions = {
reload: () => {
editFormRef?.current?.fetchObject?.()
objectFormRef?.current?.fetchObject?.()
return true
},
edit: () => {
editFormRef?.current?.startEditing?.()
objectFormRef?.current?.startEditing?.()
return false
},
cancelEdit: () => {
editFormRef?.current?.cancelEditing?.()
objectFormRef?.current?.cancelEditing?.()
return true
},
finishEdit: () => {
editFormRef?.current?.handleUpdate?.()
objectFormRef?.current?.handleUpdate?.()
return true
}
}
@ -68,10 +68,10 @@ const NoteTypeInfo = () => {
<ObjectActions
type='noteType'
id={noteTypeId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Note Type Information' },
{ key: 'auditLogs', label: 'Audit Logs' }
@ -80,11 +80,11 @@ const NoteTypeInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -94,10 +94,10 @@ const NoteTypeInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -105,7 +105,7 @@ const NoteTypeInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -119,7 +119,7 @@ const NoteTypeInfo = () => {
id={noteTypeId}
type='noteType'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -145,7 +145,7 @@ const NoteTypeInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -0,0 +1,51 @@
import PropTypes from 'prop-types'
import ObjectInfo from '../../common/ObjectInfo'
import NewObjectForm from '../../common/NewObjectForm'
import WizardView from '../../common/WizardView'
const NewNote = ({ onOk, defaultValues = {} }) => {
return (
<NewObjectForm type={'note'} defaultValues={defaultValues}>
{({ handleSubmit, submitLoading, objectData, formValid }) => {
const steps = [
{
title: 'Required',
key: 'required',
content: (
<ObjectInfo
type='note'
column={1}
visibleProperties={{ 'parent._id': false }}
bordered={false}
isEditing={true}
required={true}
objectData={objectData}
/>
)
}
]
return (
<WizardView
steps={steps}
showSteps={false}
loading={submitLoading}
formValid={formValid}
title='New Note'
onSubmit={() => {
handleSubmit()
onOk()
}}
/>
)
}}
</NewObjectForm>
)
}
NewNote.propTypes = {
onOk: PropTypes.func.isRequired,
reset: PropTypes.bool,
defaultValues: PropTypes.object
}
export default NewNote

View File

@ -0,0 +1,184 @@
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Space, Flex, Card } from 'antd'
import loglevel from 'loglevel'
import config from '../../../../config'
import useCollapseState from '../../hooks/useCollapseState'
import NotesPanel from '../../common/NotesPanel'
import InfoCollapse from '../../common/InfoCollapse'
import ObjectInfo from '../../common/ObjectInfo'
import ViewButton from '../../common/ViewButton'
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
import NoteIcon from '../../../Icons/NoteIcon.jsx'
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
import ObjectForm from '../../common/ObjectForm'
import EditButtons from '../../common/EditButtons'
import LockIndicator from '../../common/LockIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
const log = loglevel.getLogger('NoteInfo')
log.setLevel(config.logLevel)
const NoteInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const noteId = new URLSearchParams(location.search).get('noteId')
const [collapseState, updateCollapseState] = useCollapseState('NoteInfo', {
info: true,
notes: true,
auditLogs: true
})
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
lock: null,
loading: false
})
const actions = {
reload: () => {
objectFormRef?.current?.handleFetchObject?.()
return true
},
edit: () => {
objectFormRef?.current?.startEditing?.()
return false
},
cancelEdit: () => {
objectFormRef?.current?.cancelEditing?.()
return true
},
finishEdit: () => {
objectFormRef?.current?.handleUpdate?.()
return true
},
delete: () => {
objectFormRef?.current?.handleDelete?.()
return true
}
}
return (
<>
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Space size='middle'>
<Space size='small'>
<ObjectActions
type='note'
id={noteId}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Note Information' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
cancelEditing={() => {
actionHandlerRef.current.callAction('cancelEdit')
}}
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
<div style={{ height: '100%', overflow: 'auto' }}>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Note Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={noteId}
type='note'
style={{ height: '100%' }}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='note'
objectData={objectData}
/>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={noteId} type='note' />
</Card>
</InfoCollapse>
<InfoCollapse
title='Audit Logs'
icon={<AuditLogIcon />}
active={collapseState.auditLogs}
onToggle={(expanded) =>
updateCollapseState('auditLogs', expanded)
}
collapseKey='auditLogs'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': noteId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</div>
</Flex>
</>
)
}
export default NoteInfo

View File

@ -20,7 +20,7 @@ import { ApiServerContext } from '../../context/ApiServerContext'
const PartInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const partId = new URLSearchParams(location.search).get('partId')
const { fetchObjectContent } = useContext(ApiServerContext)
@ -30,7 +30,7 @@ const PartInfo = () => {
notes: true,
auditLogs: true
})
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -40,24 +40,24 @@ const PartInfo = () => {
const actions = {
reload: () => {
editFormRef?.current?.fetchObject?.()
objectFormRef?.current?.fetchObject?.()
return true
},
edit: () => {
editFormRef?.current?.startEditing?.()
objectFormRef?.current?.startEditing?.()
return false
},
cancelEdit: () => {
editFormRef?.current?.cancelEditing?.()
objectFormRef?.current?.cancelEditing?.()
return true
},
finishEdit: () => {
editFormRef?.current?.handleUpdate?.()
objectFormRef?.current?.handleUpdate?.()
return true
},
download: () => {
if (partId && editFormRef?.current?.getObjectData) {
const objectData = editFormRef.current.getObjectData()
if (partId && objectFormRef?.current?.getObjectData) {
const objectData = objectFormRef.current.getObjectData()
fetchObjectContent(partId, 'part', `${objectData?.name || 'part'}.stl`)
return true
}
@ -77,10 +77,10 @@ const PartInfo = () => {
<ObjectActions
type='part'
id={partId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Part Information' },
{ key: 'notes', label: 'Notes' },
@ -90,11 +90,11 @@ const PartInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -104,10 +104,10 @@ const PartInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -115,7 +115,7 @@ const PartInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -129,7 +129,7 @@ const PartInfo = () => {
id={partId}
type='part'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -165,7 +165,7 @@ const PartInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -21,7 +21,6 @@ import {
import { DeleteOutlined, EyeOutlined } from '@ant-design/icons'
import { AuthContext } from '../../context/AuthContext'
import PartIcon from '../../../Icons/PartIcon'
import { StlViewer } from 'react-stl-viewer'
import VendorSelect from '../../common/VendorSelect'
import config from '../../../../config'
@ -482,15 +481,7 @@ const NewProduct = ({ onOk, reset }) => {
>
<Flex style={{ minWidth: '100%', minHeight: '80vh' }}>
{previewFile && !isPreviewLoading ? (
<div style={{ flexGrow: 1 }}>
<StlViewer
url={fileUrls[previewFile.uid]}
orbitControls
shadows
style={{ height: '80vh', width: '100%' }}
modelProps={{ color: '#008675' }}
/>
</div>
<div style={{ flexGrow: 1 }}></div>
) : (
<div
style={{

View File

@ -20,7 +20,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
const ProductInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const productId = new URLSearchParams(location.search).get('productId')
const [collapseState, updateCollapseState] = useCollapseState('ProductInfo', {
@ -29,7 +29,7 @@ const ProductInfo = () => {
notes: true,
auditLogs: true
})
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -39,19 +39,19 @@ const ProductInfo = () => {
const actions = {
reload: () => {
editFormRef?.current?.fetchObject?.()
objectFormRef?.current?.fetchObject?.()
return true
},
edit: () => {
editFormRef?.current?.startEditing?.()
objectFormRef?.current?.startEditing?.()
return false
},
cancelEdit: () => {
editFormRef?.current?.cancelEditing?.()
objectFormRef?.current?.cancelEditing?.()
return true
},
finishEdit: () => {
editFormRef?.current?.handleUpdate?.()
objectFormRef?.current?.handleUpdate?.()
return true
}
}
@ -69,10 +69,10 @@ const ProductInfo = () => {
<ObjectActions
type='product'
id={productId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Product Information' },
{ key: 'parts', label: 'Product Parts' },
@ -83,11 +83,11 @@ const ProductInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -97,10 +97,10 @@ const ProductInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -108,7 +108,7 @@ const ProductInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -122,7 +122,7 @@ const ProductInfo = () => {
id={productId}
type='product'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -174,7 +174,7 @@ const ProductInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -20,7 +20,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
const UserInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const userId = new URLSearchParams(location.search).get('userId')
const [collapseState, updateCollapseState] = useCollapseState('UserInfo', {
@ -28,7 +28,7 @@ const UserInfo = () => {
notes: true,
auditLogs: true
})
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -38,19 +38,19 @@ const UserInfo = () => {
const actions = {
reload: () => {
editFormRef?.current?.fetchObject?.()
objectFormRef?.current?.fetchObject?.()
return true
},
edit: () => {
editFormRef?.current?.startEditing?.()
objectFormRef?.current?.startEditing?.()
return false
},
cancelEdit: () => {
editFormRef?.current?.cancelEditing?.()
objectFormRef?.current?.cancelEditing?.()
return true
},
finishEdit: () => {
editFormRef?.current?.handleUpdate?.()
objectFormRef?.current?.handleUpdate?.()
return true
}
}
@ -68,10 +68,10 @@ const UserInfo = () => {
<ObjectActions
type='user'
id={userId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'User Information' },
{ key: 'notes', label: 'Notes' },
@ -81,11 +81,11 @@ const UserInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -95,10 +95,10 @@ const UserInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -106,7 +106,7 @@ const UserInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -120,7 +120,7 @@ const UserInfo = () => {
id={userId}
type='user'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -157,7 +157,7 @@ const UserInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -1,18 +1,9 @@
import PropTypes from 'prop-types'
import { useState } from 'react'
import { useMediaQuery } from 'react-responsive'
import { Typography, Flex, Steps, Divider } from 'antd'
import ObjectInfo from '../../common/ObjectInfo'
import NewObjectForm from '../../common/NewObjectForm'
import NewObjectButtons from '../../common/NewObjectButtons'
const { Title } = Typography
import WizardView from '../../common/WizardView'
const NewVendor = ({ onOk }) => {
const [currentStep, setCurrentStep] = useState(0)
const isMobile = useMediaQuery({ maxWidth: 768 })
return (
<NewObjectForm type={'vendor'}>
{({ handleSubmit, submitLoading, objectData, formValid }) => {
@ -65,43 +56,16 @@ const NewVendor = ({ onOk }) => {
}
]
return (
<Flex gap='middle'>
{!isMobile && (
<div style={{ minWidth: '160px' }}>
<Steps
current={currentStep}
items={steps}
direction='vertical'
style={{ width: 'fit-content' }}
/>
</div>
)}
{!isMobile && (
<Divider type='vertical' style={{ height: 'unset' }} />
)}
<Flex vertical gap='middle' style={{ flexGrow: 1 }}>
<Title level={2} style={{ margin: 0 }}>
New Vendor
</Title>
<div style={{ minHeight: '260px', marginBottom: 8 }}>
{steps[currentStep].content}
</div>
<NewObjectButtons
currentStep={currentStep}
totalSteps={steps.length}
onPrevious={() => setCurrentStep((prev) => prev - 1)}
onNext={() => setCurrentStep((prev) => prev + 1)}
<WizardView
steps={steps}
loading={submitLoading}
formValid={formValid}
title='New Vendor'
onSubmit={() => {
handleSubmit()
onOk()
}}
formValid={formValid}
submitLoading={submitLoading}
/>
</Flex>
</Flex>
)
}}
</NewObjectForm>

View File

@ -24,7 +24,7 @@ log.setLevel(config.logLevel)
const VendorInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const vendorId = new URLSearchParams(location.search).get('vendorId')
const [collapseState, updateCollapseState] = useCollapseState('VendorInfo', {
@ -32,7 +32,7 @@ const VendorInfo = () => {
notes: true,
auditLogs: true
})
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -42,23 +42,23 @@ const VendorInfo = () => {
const actions = {
reload: () => {
editFormRef?.current?.handleFetchObject?.()
objectFormRef?.current?.handleFetchObject?.()
return true
},
edit: () => {
editFormRef?.current?.startEditing?.()
objectFormRef?.current?.startEditing?.()
return false
},
cancelEdit: () => {
editFormRef?.current?.cancelEditing?.()
objectFormRef?.current?.cancelEditing?.()
return true
},
finishEdit: () => {
editFormRef?.current?.handleUpdate?.()
objectFormRef?.current?.handleUpdate?.()
return true
},
delete: () => {
editFormRef?.current?.handleDelete?.()
objectFormRef?.current?.handleDelete?.()
return true
}
}
@ -76,10 +76,10 @@ const VendorInfo = () => {
<ObjectActions
type='vendor'
id={vendorId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Vendor Information' },
{ key: 'notes', label: 'Notes' },
@ -89,11 +89,11 @@ const VendorInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -103,10 +103,10 @@ const VendorInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -114,7 +114,7 @@ const VendorInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -128,7 +128,7 @@ const VendorInfo = () => {
id={vendorId}
type='vendor'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -164,7 +164,7 @@ const VendorInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -28,7 +28,7 @@ log.setLevel(config.logLevel)
const GCodeFileInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const gcodeFileId = new URLSearchParams(location.search).get('gcodeFileId')
const [collapseState, updateCollapseState] = useCollapseState(
@ -41,7 +41,7 @@ const GCodeFileInfo = () => {
}
)
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -51,19 +51,19 @@ const GCodeFileInfo = () => {
const actions = {
reload: () => {
editFormRef?.current.handleFetchObject()
objectFormRef?.current.handleFetchObject()
return true
},
edit: () => {
editFormRef?.current.startEditing()
objectFormRef?.current.startEditing()
return false
},
cancelEdit: () => {
editFormRef?.current.cancelEditing()
objectFormRef?.current.cancelEditing()
return true
},
finishEdit: () => {
editFormRef?.current.handleUpdate()
objectFormRef?.current.handleUpdate()
return true
}
}
@ -84,10 +84,10 @@ const GCodeFileInfo = () => {
<ObjectActions
type='gcodeFile'
id={gcodeFileId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'GCode File Information' },
{ key: 'preview', label: 'GCode File Preview' },
@ -98,11 +98,11 @@ const GCodeFileInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -112,10 +112,10 @@ const GCodeFileInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -124,14 +124,14 @@ const GCodeFileInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={gcodeFileId}
type='gcodeFile'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
console.log('Got edit form state change', state)
setEditFormState((prev) => ({ ...prev, ...state }))
@ -206,7 +206,7 @@ const GCodeFileInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -26,7 +26,7 @@ log.setLevel(config.logLevel)
const JobInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const jobId = new URLSearchParams(location.search).get('jobId')
const [collapseState, updateCollapseState] = useCollapseState('JobInfo', {
@ -36,7 +36,7 @@ const JobInfo = () => {
auditLogs: true
})
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -46,19 +46,19 @@ const JobInfo = () => {
const actions = {
reload: () => {
editFormRef?.current.handleFetchObject()
objectFormRef?.current.handleFetchObject()
return true
},
edit: () => {
editFormRef?.current.startEditing()
objectFormRef?.current.startEditing()
return false
},
cancelEdit: () => {
editFormRef?.current.cancelEditing()
objectFormRef?.current.cancelEditing()
return true
},
finishEdit: () => {
editFormRef?.current.handleUpdate()
objectFormRef?.current.handleUpdate()
return true
}
}
@ -79,10 +79,10 @@ const JobInfo = () => {
<ObjectActions
type='job'
id={jobId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Job Information' },
{ key: 'subJobs', label: 'Sub Jobs' },
@ -93,11 +93,11 @@ const JobInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -107,10 +107,10 @@ const JobInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -119,7 +119,7 @@ const JobInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -133,7 +133,7 @@ const JobInfo = () => {
id={jobId}
type='job'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -186,7 +186,7 @@ const JobInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable

View File

@ -25,7 +25,7 @@ log.setLevel(config.logLevel)
const PrinterInfo = () => {
const location = useLocation()
const editFormRef = useRef(null)
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const printerId = new URLSearchParams(location.search).get('printerId')
const [collapseState, updateCollapseState] = useCollapseState('PrinterInfo', {
@ -35,7 +35,7 @@ const PrinterInfo = () => {
auditLogs: true
})
const [editFormState, setEditFormState] = useState({
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
@ -45,20 +45,20 @@ const PrinterInfo = () => {
const actions = {
reload: () => {
editFormRef?.current.handleFetchObject()
objectFormRef?.current.handleFetchObject()
return true
},
edit: () => {
editFormRef?.current.startEditing()
objectFormRef?.current.startEditing()
console.log('CALLING START EDITING')
return false
},
cancelEdit: () => {
editFormRef?.current.cancelEditing()
objectFormRef?.current.cancelEditing()
return true
},
finishEdit: () => {
editFormRef?.current.handleUpdate()
objectFormRef?.current.handleUpdate()
return true
}
}
@ -79,10 +79,10 @@ const PrinterInfo = () => {
<ObjectActions
type='printer'
id={printerId}
disabled={editFormState.loading}
disabled={objectFormState.loading}
/>
<ViewButton
disabled={editFormState.loading}
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Printer Information' },
{ key: 'notes', label: 'Notes' },
@ -92,11 +92,11 @@ const PrinterInfo = () => {
updateVisibleState={updateCollapseState}
/>
</Space>
<LockIndicator lock={editFormState.lock} />
<LockIndicator lock={objectFormState.lock} />
</Space>
<Space>
<EditButtons
isEditing={editFormState.isEditing}
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
@ -106,10 +106,10 @@ const PrinterInfo = () => {
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={editFormState.editLoading}
formValid={editFormState.formValid}
disabled={editFormState.lock?.locked || editFormState.loading}
loading={editFormState.editLoading}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={objectFormState.lock?.locked || objectFormState.loading}
loading={objectFormState.editLoading}
/>
</Space>
</Flex>
@ -118,7 +118,7 @@ const PrinterInfo = () => {
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={editFormState.loading}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
@ -132,7 +132,7 @@ const PrinterInfo = () => {
id={printerId}
type='printer'
style={{ height: '100%' }}
ref={editFormRef}
ref={objectFormRef}
onStateChange={(state) => {
console.log('Got edit form state change', state)
setEditFormState((prev) => ({ ...prev, ...state }))
@ -174,7 +174,7 @@ const PrinterInfo = () => {
}
collapseKey='auditLogs'
>
{editFormState.loading ? (
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable