Fixed warnings and info pages.
This commit is contained in:
parent
bb047651ae
commit
5680b067a8
@ -1,3 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card } from 'antd'
|
||||
import useCollapseState from '../../hooks/useCollapseState'
|
||||
@ -19,6 +20,8 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder'
|
||||
|
||||
const FilamentStockInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const filamentStockId = new URLSearchParams(location.search).get(
|
||||
'filamentStockId'
|
||||
)
|
||||
@ -31,35 +34,39 @@ const FilamentStockInfo = () => {
|
||||
auditLogs: true
|
||||
}
|
||||
)
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
lock: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
return (
|
||||
<EditObjectForm
|
||||
id={filamentStockId}
|
||||
type='filamentStock'
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock,
|
||||
fetchObject
|
||||
}) => {
|
||||
const actions = {
|
||||
reload: () => {
|
||||
fetchObject()
|
||||
editFormRef?.current?.fetchObject?.()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
editFormRef?.current?.startEditing?.()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
editFormRef?.current?.cancelEditing?.()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
editFormRef?.current?.handleUpdate?.()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
style={{ height: '100%', minHeight: 0 }}
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
<Flex justify={'space-between'}>
|
||||
<Space size='middle'>
|
||||
@ -67,10 +74,10 @@ const FilamentStockInfo = () => {
|
||||
<ObjectActions
|
||||
type='filamentStock'
|
||||
id={filamentStockId}
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'Filament Stock Information' },
|
||||
{ key: 'events', label: 'Filament Stock Events' },
|
||||
@ -81,57 +88,69 @@ const FilamentStockInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={true}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<InfoCollapse
|
||||
title='Filament Stock Information'
|
||||
icon={<InfoCircleIcon />}
|
||||
active={collapseState.info}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('info', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||
collapseKey='info'
|
||||
>
|
||||
<EditObjectForm
|
||||
id={filamentStockId}
|
||||
type='filamentStock'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => (
|
||||
<ObjectInfo
|
||||
loading={loading}
|
||||
isEditing={isEditing}
|
||||
type='filamentStock'
|
||||
objectData={objectData}
|
||||
/>
|
||||
)}
|
||||
</EditObjectForm>
|
||||
</InfoCollapse>
|
||||
|
||||
</ActionHandler>
|
||||
<InfoCollapse
|
||||
title='Filament Stock Events'
|
||||
icon={<FilamentStockIcon />}
|
||||
active={collapseState.events}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('events', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('events', expanded)}
|
||||
collapseKey='events'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -141,24 +160,17 @@ const FilamentStockInfo = () => {
|
||||
/>
|
||||
)}
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
active={collapseState.notes}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('notes', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||
collapseKey='notes'
|
||||
>
|
||||
<Card>
|
||||
<NotesPanel
|
||||
_id={filamentStockId}
|
||||
type='filamentStock'
|
||||
/>
|
||||
<NotesPanel _id={filamentStockId} type='filamentStock' />
|
||||
</Card>
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='Audit Logs'
|
||||
icon={<AuditLogIcon />}
|
||||
@ -168,7 +180,7 @@ const FilamentStockInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -181,11 +193,7 @@ const FilamentStockInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -14,9 +14,7 @@ const DocumentSizes = () => {
|
||||
const [messageApi, contextHolder] = message.useMessage()
|
||||
const [newDocumentSizeOpen, setNewDocumentSizeOpen] = useState(false)
|
||||
const tableRef = useRef()
|
||||
|
||||
const [viewMode, setViewMode] = useViewMode('documentSize')
|
||||
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
useColumnVisibility('documentSize')
|
||||
|
||||
@ -85,7 +83,7 @@ const DocumentSizes = () => {
|
||||
<NewDocumentSize
|
||||
onOk={() => {
|
||||
setNewDocumentSizeOpen(false)
|
||||
messageApi.success('New note type created successfully.')
|
||||
messageApi.success('New document size created successfully.')
|
||||
tableRef.current?.reload()
|
||||
}}
|
||||
reset={!newDocumentSizeOpen}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card } from 'antd'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
@ -24,6 +25,8 @@ log.setLevel(config.logLevel)
|
||||
|
||||
const DocumentSizeInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const documentSizeId = new URLSearchParams(location.search).get(
|
||||
'documentSizeId'
|
||||
)
|
||||
@ -35,55 +38,39 @@ const DocumentSizeInfo = () => {
|
||||
auditLogs: true
|
||||
}
|
||||
)
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
lock: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
return (
|
||||
<EditObjectForm
|
||||
id={documentSizeId}
|
||||
type='documentSize'
|
||||
style={{ height: '100%' }}
|
||||
>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
startEditing,
|
||||
cancelEditing,
|
||||
handleUpdate,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock,
|
||||
fetchObject
|
||||
}) => {
|
||||
// Define actions for ActionHandler
|
||||
const actions = {
|
||||
reload: () => {
|
||||
fetchObject()
|
||||
editFormRef?.current?.fetchObject?.()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
startEditing()
|
||||
editFormRef?.current?.startEditing?.()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
cancelEditing()
|
||||
editFormRef?.current?.cancelEditing?.()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
handleUpdate()
|
||||
editFormRef?.current?.handleUpdate?.()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
style={{
|
||||
height: 'calc(var(--unit-100vh) - 155px)',
|
||||
minHeight: 0
|
||||
}}
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
<Flex justify={'space-between'}>
|
||||
<Space size='middle'>
|
||||
@ -91,13 +78,12 @@ const DocumentSizeInfo = () => {
|
||||
<ObjectActions
|
||||
type='documentSize'
|
||||
id={documentSizeId}
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'DocumentSize Information' },
|
||||
{ key: 'stocks', label: 'DocumentSize Stocks' },
|
||||
{ key: 'info', label: 'Document Size Information' },
|
||||
{ key: 'notes', label: 'Notes' },
|
||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||
]}
|
||||
@ -105,39 +91,51 @@ const DocumentSizeInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={lock?.locked || loading}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflowY: 'scroll' }}>
|
||||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<InfoCollapse
|
||||
title='Document Size Information'
|
||||
icon={<InfoCircleIcon />}
|
||||
active={collapseState.info}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('info', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||
collapseKey='info'
|
||||
>
|
||||
<EditObjectForm
|
||||
id={documentSizeId}
|
||||
type='documentSize'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => (
|
||||
<ObjectInfo
|
||||
loading={loading}
|
||||
indicator={<LoadingOutlined />}
|
||||
@ -145,22 +143,21 @@ const DocumentSizeInfo = () => {
|
||||
type='documentSize'
|
||||
objectData={objectData}
|
||||
/>
|
||||
)}
|
||||
</EditObjectForm>
|
||||
</InfoCollapse>
|
||||
|
||||
</ActionHandler>
|
||||
<InfoCollapse
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
active={collapseState.notes}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('notes', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||
collapseKey='notes'
|
||||
>
|
||||
<Card>
|
||||
<NotesPanel _id={documentSizeId} type='documentSize' />
|
||||
</Card>
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='Audit Logs'
|
||||
icon={<AuditLogIcon />}
|
||||
@ -170,7 +167,7 @@ const DocumentSizeInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -183,11 +180,7 @@ const DocumentSizeInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card } from 'antd'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
@ -25,6 +26,8 @@ log.setLevel(config.logLevel)
|
||||
|
||||
const FilamentInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const filamentId = new URLSearchParams(location.search).get('filamentId')
|
||||
const [collapseState, updateCollapseState] = useCollapseState(
|
||||
'FilamentInfo',
|
||||
@ -36,43 +39,35 @@ const FilamentInfo = () => {
|
||||
}
|
||||
)
|
||||
|
||||
return (
|
||||
<EditObjectForm id={filamentId} type='filament' style={{ height: '100%' }}>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
startEditing,
|
||||
cancelEditing,
|
||||
handleUpdate,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock,
|
||||
fetchObject
|
||||
}) => {
|
||||
// Define actions for ActionHandler
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
lock: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
const actions = {
|
||||
reload: () => {
|
||||
fetchObject()
|
||||
editFormRef?.current?.fetchObject?.()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
startEditing()
|
||||
editFormRef?.current?.startEditing?.()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
cancelEditing()
|
||||
editFormRef?.current?.cancelEditing?.()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
handleUpdate()
|
||||
editFormRef?.current?.handleUpdate?.()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
@ -87,10 +82,10 @@ const FilamentInfo = () => {
|
||||
<ObjectActions
|
||||
type='filament'
|
||||
id={filamentId}
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'Filament Information' },
|
||||
{ key: 'stocks', label: 'Filament Stocks' },
|
||||
@ -101,39 +96,53 @@ const FilamentInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={lock?.locked || loading}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflowY: 'scroll' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<InfoCollapse
|
||||
title='Filament Information'
|
||||
icon={<InfoCircleIcon />}
|
||||
active={collapseState.info}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('info', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||
collapseKey='info'
|
||||
>
|
||||
<EditObjectForm
|
||||
id={filamentId}
|
||||
type='filament'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => {
|
||||
return (
|
||||
<ObjectInfo
|
||||
loading={loading}
|
||||
indicator={<LoadingOutlined />}
|
||||
@ -141,18 +150,20 @@ const FilamentInfo = () => {
|
||||
type='filament'
|
||||
objectData={objectData}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</InfoCollapse>
|
||||
</ActionHandler>
|
||||
|
||||
<InfoCollapse
|
||||
title='Filament Stocks'
|
||||
icon={<FilamentIcon />}
|
||||
active={collapseState.stocks}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('stocks', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('stocks', expanded)}
|
||||
collapseKey='stocks'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -171,9 +182,7 @@ const FilamentInfo = () => {
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
active={collapseState.notes}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('notes', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||
collapseKey='notes'
|
||||
>
|
||||
<Card>
|
||||
@ -190,7 +199,7 @@ const FilamentInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -203,11 +212,7 @@ const FilamentInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex } from 'antd'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
@ -17,6 +18,8 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
||||
|
||||
const NoteTypeInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const noteTypeId = new URLSearchParams(location.search).get('noteTypeId')
|
||||
const [collapseState, updateCollapseState] = useCollapseState(
|
||||
'NoteTypeInfo',
|
||||
@ -25,52 +28,39 @@ const NoteTypeInfo = () => {
|
||||
auditLogs: true
|
||||
}
|
||||
)
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
lock: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
return (
|
||||
<EditObjectForm
|
||||
id={noteTypeId}
|
||||
type='noteType'
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
startEditing,
|
||||
cancelEditing,
|
||||
handleUpdate,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock,
|
||||
fetchObject
|
||||
}) => {
|
||||
// Define actions for ActionHandler
|
||||
const actions = {
|
||||
reload: () => {
|
||||
fetchObject()
|
||||
editFormRef?.current?.fetchObject?.()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
startEditing()
|
||||
editFormRef?.current?.startEditing?.()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
cancelEditing()
|
||||
editFormRef?.current?.cancelEditing?.()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
handleUpdate()
|
||||
editFormRef?.current?.handleUpdate?.()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
style={{ height: '100%', minHeight: 0 }}
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
<Flex justify={'space-between'}>
|
||||
<Space size='middle'>
|
||||
@ -78,10 +68,10 @@ const NoteTypeInfo = () => {
|
||||
<ObjectActions
|
||||
type='noteType'
|
||||
id={noteTypeId}
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'Note Type Information' },
|
||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||
@ -90,39 +80,51 @@ const NoteTypeInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={lock?.locked || loading}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<InfoCollapse
|
||||
title='Note Type Information'
|
||||
icon={<InfoCircleIcon />}
|
||||
active={collapseState.info}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('info', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||
collapseKey='info'
|
||||
>
|
||||
<EditObjectForm
|
||||
id={noteTypeId}
|
||||
type='noteType'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => (
|
||||
<ObjectInfo
|
||||
loading={loading}
|
||||
indicator={<LoadingOutlined />}
|
||||
@ -130,8 +132,10 @@ const NoteTypeInfo = () => {
|
||||
type='noteType'
|
||||
objectData={objectData}
|
||||
/>
|
||||
)}
|
||||
</EditObjectForm>
|
||||
</InfoCollapse>
|
||||
|
||||
</ActionHandler>
|
||||
<InfoCollapse
|
||||
title='Audit Logs'
|
||||
icon={<AuditLogIcon />}
|
||||
@ -141,7 +145,7 @@ const NoteTypeInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -154,11 +158,7 @@ const NoteTypeInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useContext } from 'react'
|
||||
import { useRef, useState, useContext } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card } from 'antd'
|
||||
import useCollapseState from '../../hooks/useCollapseState'
|
||||
@ -20,66 +20,56 @@ import { ApiServerContext } from '../../context/ApiServerContext'
|
||||
|
||||
const PartInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const partId = new URLSearchParams(location.search).get('partId')
|
||||
|
||||
const { fetchObjectContent } = useContext(ApiServerContext)
|
||||
|
||||
const [collapseState, updateCollapseState] = useCollapseState('PartInfo', {
|
||||
info: true,
|
||||
parts: true,
|
||||
notes: true,
|
||||
auditLogs: true
|
||||
})
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
lock: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
return (
|
||||
<EditObjectForm
|
||||
id={partId}
|
||||
type='part'
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
startEditing,
|
||||
cancelEditing,
|
||||
handleUpdate,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock,
|
||||
fetchObject
|
||||
}) => {
|
||||
const actions = {
|
||||
reload: () => {
|
||||
fetchObject()
|
||||
editFormRef?.current?.fetchObject?.()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
startEditing()
|
||||
editFormRef?.current?.startEditing?.()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
cancelEditing()
|
||||
editFormRef?.current?.cancelEditing?.()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
handleUpdate()
|
||||
editFormRef?.current?.handleUpdate?.()
|
||||
return true
|
||||
},
|
||||
download: () => {
|
||||
if (partId) {
|
||||
fetchObjectContent(partId, 'part', `${objectData.name}.stl`)
|
||||
if (partId && editFormRef?.current?.getObjectData) {
|
||||
const objectData = editFormRef.current.getObjectData()
|
||||
fetchObjectContent(partId, 'part', `${objectData?.name || 'part'}.stl`)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
style={{ height: '100%', minHeight: 0 }}
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
<Flex justify={'space-between'}>
|
||||
<Space size='middle'>
|
||||
@ -87,10 +77,10 @@ const PartInfo = () => {
|
||||
<ObjectActions
|
||||
type='part'
|
||||
id={partId}
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'Part Information' },
|
||||
{ key: 'notes', label: 'Notes' },
|
||||
@ -100,61 +90,72 @@ const PartInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={lock?.locked || loading}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<InfoCollapse
|
||||
title='Part Information'
|
||||
icon={<InfoCircleIcon />}
|
||||
active={collapseState.info}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('info', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||
collapseKey='info'
|
||||
>
|
||||
<EditObjectForm
|
||||
id={partId}
|
||||
type='part'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => (
|
||||
<ObjectInfo
|
||||
loading={loading}
|
||||
isEditing={isEditing}
|
||||
type='part'
|
||||
objectData={objectData}
|
||||
/>
|
||||
)}
|
||||
</EditObjectForm>
|
||||
</InfoCollapse>
|
||||
|
||||
</ActionHandler>
|
||||
<InfoCollapse
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
active={collapseState.notes}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('notes', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||
collapseKey='notes'
|
||||
>
|
||||
<Card>
|
||||
<NotesPanel _id={partId} type='part' />
|
||||
</Card>
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='Audit Logs'
|
||||
icon={<AuditLogIcon />}
|
||||
@ -164,7 +165,7 @@ const PartInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -177,11 +178,7 @@ const PartInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card } from 'antd'
|
||||
import useCollapseState from '../../hooks/useCollapseState'
|
||||
@ -19,6 +20,8 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
||||
|
||||
const ProductInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const productId = new URLSearchParams(location.search).get('productId')
|
||||
const [collapseState, updateCollapseState] = useCollapseState('ProductInfo', {
|
||||
info: true,
|
||||
@ -26,50 +29,39 @@ const ProductInfo = () => {
|
||||
notes: true,
|
||||
auditLogs: true
|
||||
})
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
lock: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
return (
|
||||
<EditObjectForm
|
||||
id={productId}
|
||||
type='product'
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
startEditing,
|
||||
cancelEditing,
|
||||
handleUpdate,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock,
|
||||
fetchObject
|
||||
}) => {
|
||||
const actions = {
|
||||
reload: () => {
|
||||
fetchObject()
|
||||
editFormRef?.current?.fetchObject?.()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
startEditing()
|
||||
editFormRef?.current?.startEditing?.()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
cancelEditing()
|
||||
editFormRef?.current?.cancelEditing?.()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
handleUpdate()
|
||||
editFormRef?.current?.handleUpdate?.()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
style={{ height: '100%', minHeight: 0 }}
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
<Flex justify={'space-between'}>
|
||||
<Space size='middle'>
|
||||
@ -77,10 +69,10 @@ const ProductInfo = () => {
|
||||
<ObjectActions
|
||||
type='product'
|
||||
id={productId}
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'Product Information' },
|
||||
{ key: 'parts', label: 'Product Parts' },
|
||||
@ -91,54 +83,66 @@ const ProductInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={lock?.locked || loading}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<InfoCollapse
|
||||
title='Product Information'
|
||||
icon={<InfoCircleIcon />}
|
||||
active={collapseState.info}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('info', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||
collapseKey='info'
|
||||
>
|
||||
<EditObjectForm
|
||||
id={productId}
|
||||
type='product'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => (
|
||||
<ObjectInfo
|
||||
loading={loading}
|
||||
isEditing={isEditing}
|
||||
type='product'
|
||||
objectData={objectData}
|
||||
/>
|
||||
)}
|
||||
</EditObjectForm>
|
||||
</InfoCollapse>
|
||||
|
||||
</ActionHandler>
|
||||
<InfoCollapse
|
||||
title='Product Parts'
|
||||
icon={<ProductIcon />}
|
||||
active={collapseState.parts}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('parts', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('parts', expanded)}
|
||||
collapseKey='parts'
|
||||
>
|
||||
<ObjectTable
|
||||
@ -150,21 +154,17 @@ const ProductInfo = () => {
|
||||
masterFilter={{ 'product._id': productId }}
|
||||
/>
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
active={collapseState.notes}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('notes', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||
collapseKey='notes'
|
||||
>
|
||||
<Card>
|
||||
<NotesPanel _id={productId} type='product' />
|
||||
</Card>
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='Audit Logs'
|
||||
icon={<AuditLogIcon />}
|
||||
@ -174,7 +174,7 @@ const ProductInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -187,11 +187,7 @@ const ProductInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card } from 'antd'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
@ -19,58 +20,47 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
||||
|
||||
const UserInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const userId = new URLSearchParams(location.search).get('userId')
|
||||
const [collapseState, updateCollapseState] = useCollapseState('UserInfo', {
|
||||
info: true,
|
||||
notes: true,
|
||||
auditLogs: true
|
||||
})
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
lock: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
return (
|
||||
<EditObjectForm
|
||||
id={userId}
|
||||
type='user'
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
startEditing,
|
||||
cancelEditing,
|
||||
handleUpdate,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock,
|
||||
fetchObject
|
||||
}) => {
|
||||
// Define actions for ActionHandler
|
||||
const actions = {
|
||||
reload: () => {
|
||||
fetchObject()
|
||||
editFormRef?.current?.fetchObject?.()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
startEditing()
|
||||
editFormRef?.current?.startEditing?.()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
cancelEditing()
|
||||
editFormRef?.current?.cancelEditing?.()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
handleUpdate()
|
||||
editFormRef?.current?.handleUpdate?.()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
style={{ height: '100%', minHeight: 0 }}
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
<Flex justify={'space-between'}>
|
||||
<Space size='middle'>
|
||||
@ -78,10 +68,10 @@ const UserInfo = () => {
|
||||
<ObjectActions
|
||||
type='user'
|
||||
id={userId}
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'User Information' },
|
||||
{ key: 'notes', label: 'Notes' },
|
||||
@ -91,39 +81,51 @@ const UserInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={lock?.locked || loading || true}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<InfoCollapse
|
||||
title='User Information'
|
||||
icon={<InfoCircleIcon />}
|
||||
active={collapseState.info}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('info', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||
collapseKey='info'
|
||||
>
|
||||
<EditObjectForm
|
||||
id={userId}
|
||||
type='user'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => (
|
||||
<ObjectInfo
|
||||
loading={loading}
|
||||
indicator={<LoadingOutlined />}
|
||||
@ -131,22 +133,21 @@ const UserInfo = () => {
|
||||
type='user'
|
||||
objectData={objectData}
|
||||
/>
|
||||
)}
|
||||
</EditObjectForm>
|
||||
</InfoCollapse>
|
||||
|
||||
</ActionHandler>
|
||||
<InfoCollapse
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
active={collapseState.notes}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('notes', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||
collapseKey='notes'
|
||||
>
|
||||
<Card>
|
||||
<NotesPanel _id={userId} type='user' />
|
||||
</Card>
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='Audit Logs'
|
||||
icon={<AuditLogIcon />}
|
||||
@ -156,7 +157,7 @@ const UserInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -169,11 +170,7 @@ const UserInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card } from 'antd'
|
||||
import loglevel from 'loglevel'
|
||||
@ -23,63 +24,51 @@ log.setLevel(config.logLevel)
|
||||
|
||||
const VendorInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const vendorId = new URLSearchParams(location.search).get('vendorId')
|
||||
const [collapseState, updateCollapseState] = useCollapseState('VendorInfo', {
|
||||
info: true,
|
||||
notes: true,
|
||||
auditLogs: true
|
||||
})
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
lock: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
return (
|
||||
<EditObjectForm
|
||||
id={vendorId}
|
||||
type='vendor'
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
startEditing,
|
||||
cancelEditing,
|
||||
handleFetchObject,
|
||||
handleUpdate,
|
||||
handleDelete,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock
|
||||
}) => {
|
||||
// Define actions for ActionHandler
|
||||
const actions = {
|
||||
reload: () => {
|
||||
handleFetchObject()
|
||||
editFormRef?.current?.handleFetchObject?.()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
startEditing()
|
||||
editFormRef?.current?.startEditing?.()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
cancelEditing()
|
||||
editFormRef?.current?.cancelEditing?.()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
handleUpdate()
|
||||
editFormRef?.current?.handleUpdate?.()
|
||||
return true
|
||||
},
|
||||
delete: () => {
|
||||
handleDelete()
|
||||
editFormRef?.current?.handleDelete?.()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
style={{ height: '100%', minHeight: 0 }}
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
<Flex justify={'space-between'}>
|
||||
<Space size='middle'>
|
||||
@ -87,10 +76,10 @@ const VendorInfo = () => {
|
||||
<ObjectActions
|
||||
type='vendor'
|
||||
id={vendorId}
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'Vendor Information' },
|
||||
{ key: 'notes', label: 'Notes' },
|
||||
@ -100,61 +89,72 @@ const VendorInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={lock?.locked || loading}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<InfoCollapse
|
||||
title='Vendor Information'
|
||||
icon={<InfoCircleIcon />}
|
||||
active={collapseState.info}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('info', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||
collapseKey='info'
|
||||
>
|
||||
<EditObjectForm
|
||||
id={vendorId}
|
||||
type='vendor'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => (
|
||||
<ObjectInfo
|
||||
loading={loading}
|
||||
isEditing={isEditing}
|
||||
type='vendor'
|
||||
objectData={objectData}
|
||||
/>
|
||||
)}
|
||||
</EditObjectForm>
|
||||
</InfoCollapse>
|
||||
|
||||
</ActionHandler>
|
||||
<InfoCollapse
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
active={collapseState.notes}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('notes', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||
collapseKey='notes'
|
||||
>
|
||||
<Card>
|
||||
<NotesPanel _id={vendorId} type='vendor' />
|
||||
</Card>
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='Audit Logs'
|
||||
icon={<AuditLogIcon />}
|
||||
@ -164,7 +164,7 @@ const VendorInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -177,11 +177,7 @@ const VendorInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,97 +1,82 @@
|
||||
import { useContext } from 'react'
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card, Typography } from 'antd'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
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 EditObjectForm from '../../common/EditObjectForm'
|
||||
import EditButtons from '../../common/EditButtons'
|
||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
||||
import ActionHandler from '../../common/ActionHandler'
|
||||
import loglevel from 'loglevel'
|
||||
import config from '../../../../config.js'
|
||||
import useCollapseState from '../../hooks/useCollapseState.js'
|
||||
import NotesPanel from '../../common/NotesPanel.jsx'
|
||||
import InfoCollapse from '../../common/InfoCollapse.jsx'
|
||||
import ObjectInfo from '../../common/ObjectInfo.jsx'
|
||||
import ViewButton from '../../common/ViewButton.jsx'
|
||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
||||
import GCodeFileIcon from '../../../Icons/GCodeFileIcon.jsx'
|
||||
import { ApiServerContext } from '../../context/ApiServerContext'
|
||||
import EditObjectForm from '../../common/EditObjectForm.jsx'
|
||||
import EditButtons from '../../common/EditButtons.jsx'
|
||||
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'
|
||||
import EyeIcon from '../../../Icons/EyeIcon.jsx'
|
||||
|
||||
const { Text } = Typography
|
||||
|
||||
const log = loglevel.getLogger('GCodeFileInfo')
|
||||
log.setLevel(config.logLevel)
|
||||
|
||||
const GCodeFileInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const gcodeFileId = new URLSearchParams(location.search).get('gcodeFileId')
|
||||
|
||||
const { fetchObjectContent } = useContext(ApiServerContext)
|
||||
const [collapseState, updateCollapseState] = useCollapseState(
|
||||
'gcodeFileInfo',
|
||||
'GCodeFileInfo',
|
||||
{
|
||||
info: true,
|
||||
preview: true,
|
||||
stocks: true,
|
||||
notes: true,
|
||||
auditLogs: true
|
||||
}
|
||||
)
|
||||
|
||||
return (
|
||||
<EditObjectForm
|
||||
id={gcodeFileId}
|
||||
type='gcodefile'
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
startEditing,
|
||||
cancelEditing,
|
||||
handleUpdate,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock,
|
||||
fetchObject
|
||||
}) => {
|
||||
// Define actions that can be triggered via URL, now with access to startEditing
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
locked: false,
|
||||
loading: false
|
||||
})
|
||||
|
||||
const actions = {
|
||||
reload: () => {
|
||||
fetchObject()
|
||||
editFormRef?.current.handleFetchObject()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
startEditing()
|
||||
editFormRef?.current.startEditing()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
cancelEditing()
|
||||
editFormRef?.current.cancelEditing()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
handleUpdate()
|
||||
editFormRef?.current.handleUpdate()
|
||||
return true
|
||||
},
|
||||
download: () => {
|
||||
if (gcodeFileId) {
|
||||
fetchObjectContent(
|
||||
gcodeFileId,
|
||||
'gcodeFile',
|
||||
`${objectData.name}.gcode`
|
||||
)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
style={{ height: '100%', minHeight: 0 }}
|
||||
style={{
|
||||
height: 'calc(var(--unit-100vh) - 155px)',
|
||||
minHeight: 0
|
||||
}}
|
||||
>
|
||||
<Flex justify={'space-between'}>
|
||||
<Space size='middle'>
|
||||
@ -99,10 +84,10 @@ const GCodeFileInfo = () => {
|
||||
<ObjectActions
|
||||
type='gcodeFile'
|
||||
id={gcodeFileId}
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'GCode File Information' },
|
||||
{ key: 'preview', label: 'GCode File Preview' },
|
||||
@ -113,29 +98,47 @@ const GCodeFileInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={lock?.locked || loading}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||
<div style={{ height: '100%', overflowY: 'scroll' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<EditObjectForm
|
||||
id={gcodeFileId}
|
||||
type='gcodeFile'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
console.log('Got edit form state change', state)
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => {
|
||||
return (
|
||||
<Flex vertical gap={'large'}>
|
||||
<InfoCollapse
|
||||
title='GCode File Information'
|
||||
@ -150,14 +153,14 @@ const GCodeFileInfo = () => {
|
||||
loading={loading}
|
||||
indicator={<LoadingOutlined />}
|
||||
isEditing={isEditing}
|
||||
objectData={objectData}
|
||||
type='gcodeFile'
|
||||
objectData={objectData}
|
||||
visibleProperties={{}}
|
||||
/>
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='GCode File Preview'
|
||||
icon={<GCodeFileIcon />}
|
||||
icon={<EyeIcon />}
|
||||
active={collapseState.preview}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('preview', expanded)
|
||||
@ -176,14 +179,17 @@ const GCodeFileInfo = () => {
|
||||
)}
|
||||
</Card>
|
||||
</InfoCollapse>
|
||||
</Flex>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</ActionHandler>
|
||||
|
||||
<InfoCollapse
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
active={collapseState.notes}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('notes', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||
collapseKey='notes'
|
||||
>
|
||||
<Card>
|
||||
@ -200,7 +206,7 @@ const GCodeFileInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -213,11 +219,7 @@ const GCodeFileInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,25 +1,33 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card } from 'antd'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
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 EditObjectForm from '../../common/EditObjectForm'
|
||||
import EditButtons from '../../common/EditButtons'
|
||||
import loglevel from 'loglevel'
|
||||
import config from '../../../../config.js'
|
||||
import useCollapseState from '../../hooks/useCollapseState.js'
|
||||
import NotesPanel from '../../common/NotesPanel.jsx'
|
||||
import InfoCollapse from '../../common/InfoCollapse.jsx'
|
||||
import ObjectInfo from '../../common/ObjectInfo.jsx'
|
||||
import ViewButton from '../../common/ViewButton.jsx'
|
||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
||||
import EditObjectForm from '../../common/EditObjectForm.jsx'
|
||||
import EditButtons from '../../common/EditButtons.jsx'
|
||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
||||
import ActionHandler from '../../common/ActionHandler'
|
||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon'
|
||||
import JobIcon from '../../../Icons/JobIcon'
|
||||
import AuditLogIcon from '../../../Icons/AuditLogIcon'
|
||||
import NoteIcon from '../../../Icons/NoteIcon'
|
||||
import ActionHandler from '../../common/ActionHandler.jsx'
|
||||
import ObjectActions from '../../common/ObjectActions.jsx'
|
||||
import ObjectTable from '../../common/ObjectTable.jsx'
|
||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
||||
import JobIcon from '../../../Icons/JobIcon.jsx'
|
||||
|
||||
const log = loglevel.getLogger('JobInfo')
|
||||
log.setLevel(config.logLevel)
|
||||
|
||||
const JobInfo = () => {
|
||||
const location = useLocation()
|
||||
const editFormRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const jobId = new URLSearchParams(location.search).get('jobId')
|
||||
const [collapseState, updateCollapseState] = useCollapseState('JobInfo', {
|
||||
info: true,
|
||||
@ -28,43 +36,53 @@ const JobInfo = () => {
|
||||
auditLogs: true
|
||||
})
|
||||
|
||||
return (
|
||||
<EditObjectForm
|
||||
id={jobId}
|
||||
type='job'
|
||||
style={{ height: 'calc(var(--unit-100vh) - 155px)', minHeight: 0 }}
|
||||
>
|
||||
{({
|
||||
loading,
|
||||
isEditing,
|
||||
formValid,
|
||||
objectData,
|
||||
editLoading,
|
||||
lock,
|
||||
fetchObject
|
||||
}) => {
|
||||
// Define actions that can be triggered via URL, now with access to startEditing
|
||||
const [editFormState, setEditFormState] = useState({
|
||||
isEditing: false,
|
||||
editLoading: false,
|
||||
formValid: false,
|
||||
locked: false,
|
||||
loading: false
|
||||
})
|
||||
|
||||
const actions = {
|
||||
reload: () => {
|
||||
fetchObject()
|
||||
editFormRef?.current.handleFetchObject()
|
||||
return true
|
||||
},
|
||||
edit: () => {
|
||||
editFormRef?.current.startEditing()
|
||||
return false
|
||||
},
|
||||
cancelEdit: () => {
|
||||
editFormRef?.current.cancelEditing()
|
||||
return true
|
||||
},
|
||||
finishEdit: () => {
|
||||
editFormRef?.current.handleUpdate()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionHandler actions={actions} loading={loading}>
|
||||
{({ callAction }) => (
|
||||
<>
|
||||
<Flex
|
||||
gap='large'
|
||||
vertical='true'
|
||||
style={{ height: '100%', minHeight: 0 }}
|
||||
style={{
|
||||
height: 'calc(var(--unit-100vh) - 155px)',
|
||||
minHeight: 0
|
||||
}}
|
||||
>
|
||||
<Flex justify={'space-between'}>
|
||||
<Space size='middle'>
|
||||
<Space size='small'>
|
||||
<ObjectActions type='job' id={jobId} disabled={loading} />
|
||||
<ObjectActions
|
||||
type='job'
|
||||
id={jobId}
|
||||
disabled={editFormState.loading}
|
||||
/>
|
||||
<ViewButton
|
||||
disabled={loading}
|
||||
disabled={editFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'Job Information' },
|
||||
{ key: 'subJobs', label: 'Sub Jobs' },
|
||||
@ -75,39 +93,52 @@ const JobInfo = () => {
|
||||
updateVisibleState={updateCollapseState}
|
||||
/>
|
||||
</Space>
|
||||
<LockIndicator lock={lock} />
|
||||
<LockIndicator lock={editFormState.lock} />
|
||||
</Space>
|
||||
<Space>
|
||||
<EditButtons
|
||||
isEditing={isEditing}
|
||||
isEditing={editFormState.isEditing}
|
||||
handleUpdate={() => {
|
||||
callAction('finishEdit')
|
||||
actionHandlerRef.current.callAction('finishEdit')
|
||||
}}
|
||||
cancelEditing={() => {
|
||||
callAction('cancelEdit')
|
||||
actionHandlerRef.current.callAction('cancelEdit')
|
||||
}}
|
||||
startEditing={() => {
|
||||
callAction('edit')
|
||||
actionHandlerRef.current.callAction('edit')
|
||||
}}
|
||||
editLoading={editLoading}
|
||||
formValid={formValid}
|
||||
disabled={true}
|
||||
loading={editLoading}
|
||||
editLoading={editFormState.editLoading}
|
||||
formValid={editFormState.formValid}
|
||||
disabled={editFormState.lock?.locked || editFormState.loading}
|
||||
loading={editFormState.editLoading}
|
||||
/>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||
<div style={{ height: '100%', overflowY: 'scroll' }}>
|
||||
<Flex vertical gap={'large'}>
|
||||
<ActionHandler
|
||||
actions={actions}
|
||||
loading={editFormState.loading}
|
||||
ref={actionHandlerRef}
|
||||
>
|
||||
<InfoCollapse
|
||||
title='Job Information'
|
||||
icon={<InfoCircleIcon />}
|
||||
active={collapseState.info}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('info', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||
collapseKey='info'
|
||||
>
|
||||
<EditObjectForm
|
||||
id={jobId}
|
||||
type='job'
|
||||
style={{ height: '100%' }}
|
||||
ref={editFormRef}
|
||||
onStateChange={(state) => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => (
|
||||
<ObjectInfo
|
||||
loading={loading}
|
||||
indicator={<LoadingOutlined />}
|
||||
@ -115,15 +146,16 @@ const JobInfo = () => {
|
||||
type='job'
|
||||
objectData={objectData}
|
||||
/>
|
||||
)}
|
||||
</EditObjectForm>
|
||||
</InfoCollapse>
|
||||
</ActionHandler>
|
||||
|
||||
<InfoCollapse
|
||||
title='Sub Jobs'
|
||||
icon={<JobIcon />}
|
||||
active={collapseState.subJobs}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('subJobs', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('subJobs', expanded)}
|
||||
collapseKey='subJobs'
|
||||
>
|
||||
<ObjectTable
|
||||
@ -137,9 +169,7 @@ const JobInfo = () => {
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
active={collapseState.notes}
|
||||
onToggle={(expanded) =>
|
||||
updateCollapseState('notes', expanded)
|
||||
}
|
||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||
collapseKey='notes'
|
||||
>
|
||||
<Card>
|
||||
@ -156,7 +186,7 @@ const JobInfo = () => {
|
||||
}
|
||||
collapseKey='auditLogs'
|
||||
>
|
||||
{loading ? (
|
||||
{editFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<ObjectTable
|
||||
@ -169,11 +199,7 @@ const JobInfo = () => {
|
||||
</Flex>
|
||||
</div>
|
||||
</Flex>
|
||||
)}
|
||||
</ActionHandler>
|
||||
)
|
||||
}}
|
||||
</EditObjectForm>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ const ActionHandler = forwardRef(
|
||||
ActionHandler.displayName = 'ActionHandler'
|
||||
|
||||
ActionHandler.propTypes = {
|
||||
children: PropTypes.func,
|
||||
children: PropTypes.oneOf([PropTypes.func, PropTypes.object]),
|
||||
actions: PropTypes.objectOf(PropTypes.func),
|
||||
actionParam: PropTypes.string,
|
||||
clearAfterExecute: PropTypes.bool,
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
// NoteTypeSelect.js
|
||||
import PropTypes from 'prop-types'
|
||||
import { message, Tag, Select, Space } from 'antd'
|
||||
import { useEffect, useState, useContext, useCallback } from 'react'
|
||||
import axios from 'axios'
|
||||
import { AuthContext } from '../context/AuthContext'
|
||||
import config from '../../../config'
|
||||
|
||||
const NoteTypeSelect = ({ onChange, disabled, value = null }) => {
|
||||
const [noteTypeOptions, setNoteTypeOptions] = useState([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [messageApi] = message.useMessage()
|
||||
|
||||
const { authenticated } = useContext(AuthContext)
|
||||
|
||||
const fetchNoteTypesData = useCallback(async () => {
|
||||
if (!authenticated) {
|
||||
return
|
||||
}
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`${config.backendUrl}/notetypes?active=true`,
|
||||
{
|
||||
headers: {
|
||||
Accept: 'application/json'
|
||||
},
|
||||
withCredentials: true // Important for including cookies
|
||||
}
|
||||
)
|
||||
const data = response.data
|
||||
|
||||
setNoteTypeOptions(() => {
|
||||
var options = []
|
||||
data.map((noteType) => {
|
||||
var newNoteTypeOption = {
|
||||
label: (
|
||||
<Space>
|
||||
<Tag color={noteType?.color}>{noteType.name}</Tag>
|
||||
</Space>
|
||||
),
|
||||
value: noteType._id
|
||||
}
|
||||
options.push(newNoteTypeOption)
|
||||
})
|
||||
return options
|
||||
})
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// For other errors, show a message
|
||||
messageApi.error(
|
||||
'Error fetching note types data:',
|
||||
error.response.status
|
||||
)
|
||||
} else {
|
||||
messageApi.error(
|
||||
'An unexpected error occurred. Please try again later.'
|
||||
)
|
||||
}
|
||||
}
|
||||
}, [authenticated, messageApi])
|
||||
|
||||
useEffect(() => {
|
||||
if (authenticated) {
|
||||
fetchNoteTypesData()
|
||||
}
|
||||
}, [authenticated, fetchNoteTypesData])
|
||||
|
||||
return (
|
||||
<Select
|
||||
options={noteTypeOptions}
|
||||
onChange={onChange}
|
||||
loading={loading}
|
||||
disabled={disabled}
|
||||
placeholder='Select note type'
|
||||
style={{ width: '100%' }}
|
||||
value={value}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
NoteTypeSelect.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
disabled: PropTypes.bool,
|
||||
checkable: PropTypes.bool,
|
||||
value: PropTypes.object
|
||||
}
|
||||
|
||||
export default NoteTypeSelect
|
||||
@ -28,10 +28,10 @@ import config from '../../../config'
|
||||
import { AuthContext } from '../context/AuthContext'
|
||||
import { ApiServerContext } from '../context/ApiServerContext'
|
||||
import InfoCircleIcon from '../../Icons/InfoCircleIcon'
|
||||
import NoteTypeSelect from './NoteTypeSelect'
|
||||
import IdDisplay from './IdDisplay'
|
||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||
import ExclamationOctagonIcon from '../../Icons/ExclamationOctagonIcon'
|
||||
import ObjectProperty from './ObjectProperty'
|
||||
|
||||
const { Text, Title } = Typography
|
||||
const { TextArea } = Input
|
||||
@ -621,7 +621,11 @@ const NotesPanel = ({ _id, onNewNote, type }) => {
|
||||
{ required: true, message: 'Please select a note type' }
|
||||
]}
|
||||
>
|
||||
<NoteTypeSelect />
|
||||
<ObjectProperty
|
||||
type='object'
|
||||
objectType='noteType'
|
||||
isEditing={true}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Flex>
|
||||
</Form>
|
||||
|
||||
@ -47,7 +47,7 @@ const OperationDisplay = ({
|
||||
}
|
||||
|
||||
OperationDisplay.propTypes = {
|
||||
operation: PropTypes.bool.isRequired,
|
||||
operation: PropTypes.string.isRequired,
|
||||
showIcon: PropTypes.bool,
|
||||
showText: PropTypes.bool,
|
||||
showColor: PropTypes.bool
|
||||
|
||||
@ -38,7 +38,7 @@ const ApiServerProvider = ({ children }) => {
|
||||
const subscribedCallbacksRef = useRef(new Map())
|
||||
const subscribedLockCallbacksRef = useRef(new Map())
|
||||
|
||||
const notifyLockUpdate = useCallback(
|
||||
const handleLockUpdate = useCallback(
|
||||
async (lockData) => {
|
||||
logger.debug('Notifying lock update:', lockData)
|
||||
const objectId = lockData._id || lockData.id
|
||||
@ -94,7 +94,7 @@ const ApiServerProvider = ({ children }) => {
|
||||
|
||||
newSocket.on('objectUpdate', handleObjectUpdate)
|
||||
newSocket.on('objectNew', handleObjectNew)
|
||||
newSocket.on('notify_lock_update', notifyLockUpdate)
|
||||
newSocket.on('lockUpdate', handleLockUpdate)
|
||||
|
||||
newSocket.on('disconnect', () => {
|
||||
logger.debug('Api Server disconnected')
|
||||
@ -123,7 +123,7 @@ const ApiServerProvider = ({ children }) => {
|
||||
|
||||
socketRef.current = newSocket
|
||||
}
|
||||
}, [token, authenticated, messageApi, notificationApi, notifyLockUpdate])
|
||||
}, [token, authenticated, messageApi, notificationApi, handleLockUpdate])
|
||||
|
||||
useEffect(() => {
|
||||
if (token && authenticated == true) {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
// src/contexts/PrintServerContext.js
|
||||
import { createContext, useEffect, useState, useContext, useRef } from 'react'
|
||||
import io from 'socket.io-client'
|
||||
import { message, notification } from 'antd'
|
||||
import PropTypes from 'prop-types'
|
||||
import { AuthContext } from './AuthContext'
|
||||
@ -21,47 +20,9 @@ const PrintServerProvider = ({ children }) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (token) {
|
||||
log.debug('Token is available, connecting to print server...')
|
||||
|
||||
const newSocket = io(config.printServerUrl, {
|
||||
reconnectionAttempts: 3,
|
||||
timeout: 3000,
|
||||
auth: { token: token }
|
||||
})
|
||||
|
||||
setConnecting(true)
|
||||
|
||||
newSocket.on('connect', () => {
|
||||
log.debug('Print server connected')
|
||||
setConnecting(false)
|
||||
setError(null)
|
||||
})
|
||||
|
||||
newSocket.on('disconnect', () => {
|
||||
log.debug('Print server disconnected')
|
||||
setError('Print server disconnected')
|
||||
})
|
||||
|
||||
newSocket.on('connect_error', (err) => {
|
||||
log.error('Print server connection error:', err)
|
||||
messageApi.error('Print server connection error: ' + err.message)
|
||||
setError('Print server connection error')
|
||||
})
|
||||
|
||||
newSocket.on('bridge.notification', (data) => {
|
||||
notificationApi[data.type]({
|
||||
title: data.title,
|
||||
message: data.message
|
||||
})
|
||||
})
|
||||
|
||||
newSocket.on('error', (err) => {
|
||||
log.error('Print server error:', err)
|
||||
setError('Print server error')
|
||||
})
|
||||
|
||||
socketRef.current = newSocket
|
||||
|
||||
log.debug('Token is available, connecting to print server...')
|
||||
// Clean up function
|
||||
return () => {
|
||||
if (socketRef.current) {
|
||||
|
||||
@ -29,6 +29,7 @@ export const FilamentStock = {
|
||||
],
|
||||
filters: ['_id'],
|
||||
sorters: ['createdAt', 'updatedAt'],
|
||||
group: ['filament'],
|
||||
properties: [
|
||||
{
|
||||
name: '_id',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user