Compare commits

...

3 Commits

Author SHA1 Message Date
f2ccec483f Refactor invoice, payment, tax record, and stock components to utilize getModelByName for master filters
Some checks failed
farmcontrol/farmcontrol-ui/pipeline/head There was a failure building this commit
- Updated multiple components including InvoiceInfo, PaymentInfo, TaxRecordInfo, and various stock-related components to use getModelByName for constructing master filters.
- Improved code consistency and readability by replacing hardcoded parent ID references with dynamic model prefixes.
- Cleaned up unnecessary whitespace and optimized component structure for better maintainability.
2026-08-19 16:40:10 +01:00
ee038d08c3 Add CodeDiffViewer and DiffLabel components for enhanced code comparison
- Introduced CodeDiffViewer component utilizing @codemirror/merge for visual code diffs.
- Added DiffLabel component to display code change statistics and trigger the CodeDiffViewer modal.
- Updated PropertyChanges component to integrate DiffLabel for code property changes.
- Enhanced styling for code diff display with new CSS classes.
- Updated package.json and lock files to include @codemirror/merge dependency.
2026-08-19 16:40:04 +01:00
d8c13426d1 Refactor text display components to use ElipsisText for improved overflow handling
- Introduced a new ElipsisText component to manage text overflow and truncation more effectively.
- Replaced instances of the Text component with ElipsisText across various components including AddressDisplay, EmailDisplay, and FileList for consistent text handling.
- Updated styles in multiple components to ensure proper layout and responsiveness when displaying long text.
2026-08-19 15:12:55 +01:00
97 changed files with 3739 additions and 3019 deletions

View File

@ -330,6 +330,28 @@ code {
padding: 0 !important;
}
.iddisplay > *:first-child {
min-width: 0;
flex: 0 1 auto;
max-width: 100%;
overflow: hidden;
}
.iddisplay .ant-btn {
flex-shrink: 0;
}
.miscid > *:first-child {
min-width: 0;
flex: 0 1 auto;
max-width: 100%;
overflow: hidden;
}
.miscid .ant-btn {
flex-shrink: 0;
}
.ant-popover-inner:has(.spotlight-tooltip) {
padding: 0 !important;
}
@ -1139,3 +1161,150 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
.filter-sidebar-field-select .ant-select-selector {
width: max-content !important;
}
.elipsis-text-wrapper.ant-typography {
display: block;
min-width: 0;
max-width: 100%;
width: auto;
overflow: hidden;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}
.elipsis-text-wrapper.ant-typography .elipsis-text {
display: flex;
flex-direction: row;
align-items: baseline;
width: 100%;
max-width: 100%;
min-width: 0;
position: relative;
overflow: hidden;
white-space: pre;
}
.elipsis-text-wrapper.ant-typography code.elipsis-text-measure,
.elipsis-text-wrapper.ant-typography code.elipsis-text-full,
.elipsis-text-wrapper.ant-typography code.elipsis-text-truncated {
margin: 0;
box-sizing: border-box;
}
.elipsis-text-measure {
position: absolute;
visibility: hidden;
pointer-events: none;
white-space: pre;
}
.elipsis-text-full {
display: none;
position: absolute;
left: 0;
top: 0;
width: max-content;
max-width: 100%;
min-width: 0;
overflow: hidden;
white-space: pre;
}
.elipsis-text:not(.is-truncated) .elipsis-text-full {
display: inline-block;
}
.elipsis-text.is-truncated .elipsis-text-full {
display: none;
}
.elipsis-text:not(.is-truncated) .elipsis-text-truncated .elipsis-text-dots {
display: none;
}
.elipsis-text:not(.is-truncated) .elipsis-text-truncated {
visibility: hidden;
}
.elipsis-text-truncated {
display: flex;
flex: 1 1 0;
align-items: baseline;
min-width: 0;
width: 100%;
max-width: 100%;
overflow: hidden;
white-space: pre;
}
.elipsis-text-wrapper.ant-typography code.elipsis-text-truncated {
display: flex;
}
.elipsis-text-start,
.elipsis-text-end {
flex: 1 1 0;
min-width: 0;
overflow: hidden;
white-space: pre;
}
.elipsis-text-start {
mask-image: linear-gradient(
to right,
#000 0%,
#000 calc(100% - 0.8em),
transparent 100%
);
-webkit-mask-image: linear-gradient(
to right,
#000 0%,
#000 calc(100% - 0.8em),
transparent 100%
);
}
.elipsis-text-end {
display: flex;
justify-content: flex-end;
mask-image: linear-gradient(
to left,
#000 0%,
#000 calc(100% - 0.8em),
transparent 100%
);
-webkit-mask-image: linear-gradient(
to left,
#000 0%,
#000 calc(100% - 0.8em),
transparent 100%
);
}
.elipsis-text-end-inner {
flex: 0 0 auto;
white-space: pre;
}
.elipsis-text-dots {
flex: 0 0 auto;
user-select: none;
}
.code-diff-viewer {
height: 70vh;
border: 1px solid #85858541;
}
.code-diff-viewer .cm-mergeView {
height: 100%;
overflow: auto;
}
.diff-label-square {
width: 7px;
height: 7px;
background-color: #85858541;
border-radius: 2px;
}

View File

@ -23,6 +23,7 @@
"@codemirror/lang-xml": "^6.1.0",
"@codemirror/lang-yaml": "^6.1.2",
"@codemirror/language": "6.12.1",
"@codemirror/merge": "^6.12.2",
"@codemirror/state": "6.7.1",
"@codemirror/theme-one-dark": "^6.1.3",
"@codemirror/view": "6.39.12",
@ -238,6 +239,8 @@
"@codemirror/lint": ["@codemirror/lint@6.9.3", "", { "dependencies": { "@codemirror/state": "6.7.1", "@codemirror/view": "6.39.12", "crelt": "1.0.6" } }, "sha512-y3YkYhdnhjDBAe0VIA0c4wVoFOvnp8CnAvfLqi0TqotIv92wIlAAP7HELOpLBsKwjAX6W92rSflA6an/2zBvXw=="],
"@codemirror/merge": ["@codemirror/merge@6.12.2", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/highlight": "^1.0.0", "style-mod": "^4.1.0" } }, "sha512-V8JvyAPjHbPupqP7BeMcsdsYCbyPij74jxIbaIJDORI+VZzW44zFmon8bF+oxGWvOKhcRmkiUMXd8MxHr3YA2w=="],
"@codemirror/search": ["@codemirror/search@6.6.0", "", { "dependencies": { "@codemirror/state": "6.7.1", "@codemirror/view": "6.39.12", "crelt": "1.0.7" } }, "sha512-koFuNXcDvyyotWcgOnZGmY7LZqEOXZaaxD/j6n18TCLx2/9HieZJ5H6hs1g8FiRxBD0DNfs0nXn17g872RmYdw=="],
"@codemirror/state": ["@codemirror/state@6.7.1", "", { "dependencies": { "@marijn/find-cluster-break": "1.0.3" } }, "sha512-9QzNDgE4EYDnAHfrTlR2lwiPciiOymLtwKK+8yHQzCc7GXhAP9xdEbEJFy2IWB1j9UGUl9BsgMmTo/ImA02T7A=="],

View File

@ -27,6 +27,7 @@
"@codemirror/lang-xml": "^6.1.0",
"@codemirror/lang-yaml": "^6.1.2",
"@codemirror/language": "6.12.1",
"@codemirror/merge": "^6.12.2",
"@codemirror/state": "6.7.1",
"@codemirror/theme-one-dark": "^6.1.3",
"@codemirror/view": "6.39.12",

14
pnpm-lock.yaml generated
View File

@ -70,6 +70,9 @@ importers:
'@codemirror/language':
specifier: 6.12.1
version: 6.12.1
'@codemirror/merge':
specifier: ^6.12.2
version: 6.12.2
'@codemirror/state':
specifier: 6.7.1
version: 6.7.1
@ -611,6 +614,9 @@ packages:
'@codemirror/lint@6.9.3':
resolution: {integrity: sha512-y3YkYhdnhjDBAe0VIA0c4wVoFOvnp8CnAvfLqi0TqotIv92wIlAAP7HELOpLBsKwjAX6W92rSflA6an/2zBvXw==}
'@codemirror/merge@6.12.2':
resolution: {integrity: sha512-V8JvyAPjHbPupqP7BeMcsdsYCbyPij74jxIbaIJDORI+VZzW44zFmon8bF+oxGWvOKhcRmkiUMXd8MxHr3YA2w==}
'@codemirror/search@6.6.0':
resolution: {integrity: sha512-koFuNXcDvyyotWcgOnZGmY7LZqEOXZaaxD/j6n18TCLx2/9HieZJ5H6hs1g8FiRxBD0DNfs0nXn17g872RmYdw==}
@ -7047,6 +7053,14 @@ snapshots:
'@codemirror/view': 6.39.12
crelt: 1.0.6
'@codemirror/merge@6.12.2':
dependencies:
'@codemirror/language': 6.12.1
'@codemirror/state': 6.7.1
'@codemirror/view': 6.39.12
'@lezer/highlight': 1.2.3
style-mod: 4.1.3
'@codemirror/search@6.6.0':
dependencies:
'@codemirror/state': 6.7.1

View File

@ -26,7 +26,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelProperty } from '../../../../database/ObjectModels.js'
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
import OrderItemIcon from '../../../Icons/OrderItemIcon.jsx'
import ShipmentIcon from '../../../Icons/ShipmentIcon.jsx'
@ -38,7 +38,6 @@ const InvoiceInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -82,215 +81,218 @@ const InvoiceInfo = () => {
delete: () => {
objectFormRef?.current?.handleDelete?.()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='invoice'
id={invoiceId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Invoice Information' },
{ key: 'invoiceOrderItems', label: 'Invoice Order Items' },
{ key: 'invoiceShipments', label: 'Invoice Shipments' },
{ key: 'payments', label: 'Payments' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='invoice'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='invoice'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='invoice'
id={invoiceId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Invoice Information' },
{ key: 'invoiceOrderItems', label: 'Invoice Order Items' },
{ key: 'invoiceShipments', label: 'Invoice Shipments' },
{ key: 'payments', label: 'Payments' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='invoice'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='invoice'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={invoiceId}
objectType='invoice'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={invoiceId}
type='invoice'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Invoice Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='invoice'
labelWidth='225px'
objectData={objectData}
visibleProperties={{
invoiceOrderItems: false,
invoiceShipments: false
}}
/>
</InfoCollapse>
<InfoCollapse
title='Invoice Order Items'
icon={<OrderItemIcon />}
active={collapseState.invoiceOrderItems}
onToggle={(expanded) =>
updateCollapseState('invoiceOrderItems', expanded)
}
collapseKey='invoiceOrderItems'
>
<ObjectProperty
{...getModelProperty('invoice', 'invoiceOrderItems')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
size='medium'
/>
</InfoCollapse>
<InfoCollapse
title='Invoice Shipments'
icon={<ShipmentIcon />}
active={collapseState.invoiceShipments}
onToggle={(expanded) =>
updateCollapseState('invoiceShipments', expanded)
}
collapseKey='invoiceShipments'
>
<ObjectProperty
{...getModelProperty('invoice', 'invoiceShipments')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
size='medium'
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Payments'
icon={<PaymentIcon />}
active={collapseState.payments}
onToggle={(expanded) => updateCollapseState('payments', expanded)}
collapseKey='payments'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='payment'
masterFilter={{ 'invoice._id': invoiceId }}
visibleColumns={{ invoice: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={invoiceId} type='invoice' />
</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': invoiceId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={invoiceId}
objectType='invoice'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={invoiceId}
type='invoice'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Invoice Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='invoice'
labelWidth='225px'
objectData={objectData}
visibleProperties={{
invoiceOrderItems: false,
invoiceShipments: false
}}
/>
</InfoCollapse>
<InfoCollapse
title='Invoice Order Items'
icon={<OrderItemIcon />}
active={collapseState.invoiceOrderItems}
onToggle={(expanded) =>
updateCollapseState('invoiceOrderItems', expanded)
}
collapseKey='invoiceOrderItems'
>
<ObjectProperty
{...getModelProperty('invoice', 'invoiceOrderItems')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
size='medium'
/>
</InfoCollapse>
<InfoCollapse
title='Invoice Shipments'
icon={<ShipmentIcon />}
active={collapseState.invoiceShipments}
onToggle={(expanded) =>
updateCollapseState('invoiceShipments', expanded)
}
collapseKey='invoiceShipments'
>
<ObjectProperty
{...getModelProperty('invoice', 'invoiceShipments')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
size='medium'
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Payments'
icon={<PaymentIcon />}
active={collapseState.payments}
onToggle={(expanded) => updateCollapseState('payments', expanded)}
collapseKey='payments'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='payment'
masterFilter={{ invoice: getModelByName('invoice').prefix + ':' + invoiceId }}
visibleColumns={{ invoice: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={invoiceId} type='invoice' />
</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:
getModelByName('invoice').prefix +
':' +
invoiceId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -23,6 +23,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('PaymentInfo')
@ -33,7 +34,6 @@ const PaymentInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -74,157 +74,160 @@ const PaymentInfo = () => {
delete: () => {
objectFormRef?.current?.handleDelete?.()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='payment'
id={paymentId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Payment Information' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='payment'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='payment'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='payment'
id={paymentId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Payment Information' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='payment'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='payment'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={paymentId}
objectType='payment'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={paymentId}
type='payment'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Payment Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='payment'
labelWidth='225px'
objectData={objectData}
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={paymentId} type='payment' />
</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': paymentId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={paymentId}
objectType='payment'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={paymentId}
type='payment'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Payment Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='payment'
labelWidth='225px'
objectData={objectData}
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={paymentId} type='payment' />
</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:
getModelByName('payment').prefix +
':' +
paymentId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -21,6 +21,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('TaxRecordInfo')
@ -199,8 +200,13 @@ const TaxRecordInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': taxRecordId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('taxRecord').prefix +
':' +
taxRecordId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -22,6 +22,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder'
import DocumentPrintButton from '../../common/DocumentPrintButton'
import UserNotifierToggle from '../../common/UserNotifierToggle'
import ScrollBox from '../../common/ScrollBox'
import { getModelByName } from '../../../../database/ObjectModels.js'
import HistoryDisplay from '../../common/HistoryDisplay'
const FilamentStockInfo = () => {
@ -186,7 +187,7 @@ const FilamentStockInfo = () => {
) : (
<ObjectTable
type='stockEvent'
masterFilter={{ 'parent._id': filamentStockId }}
masterFilter={{ parent: getModelByName('filamentStock').prefix + ':' + filamentStockId }}
visibleColumns={{ parent: false }}
/>
)}
@ -234,8 +235,13 @@ const FilamentStockInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': filamentStockId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('filamentStock').prefix +
':' +
filamentStockId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -21,6 +21,7 @@ import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('OrderItemInfo')
@ -205,8 +206,13 @@ const OrderItemInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': orderItemId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('orderItem').prefix +
':' +
orderItemId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -25,6 +25,7 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import HistoryDisplay from '../../common/HistoryDisplay.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import PartStockIcon from '../../../Icons/PartStockIcon.jsx'
const log = loglevel.getLogger('PartStockInfo')
@ -204,7 +205,7 @@ const PartStockInfo = () => {
) : (
<ObjectTable
type='stockEvent'
masterFilter={{ 'parent._id': partStockId }}
masterFilter={{ parent: getModelByName('partStock').prefix + ':' + partStockId }}
visibleColumns={{ parent: false }}
/>
)}
@ -255,8 +256,13 @@ const PartStockInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': partStockId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('partStock').prefix +
':' +
partStockId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -10,7 +10,7 @@ import InfoCollapse from '../../common/InfoCollapse.jsx'
import ObjectInfo from '../../common/ObjectInfo.jsx'
import ObjectProperty from '../../common/ObjectProperty.jsx'
import ViewButton from '../../common/ViewButton.jsx'
import { getModelProperty } from '../../../../database/ObjectModels.js'
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
import NoteIcon from '../../../Icons/NoteIcon.jsx'
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
@ -39,7 +39,6 @@ const ProductStockInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -88,217 +87,220 @@ const ProductStockInfo = () => {
delete: () => {
objectFormRef?.current.handleDelete?.()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='productStock'
id={productStockId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Product Stock Information' },
{ key: 'partStocks', label: 'Part Stocks' },
{ key: 'events', label: 'Product Stock Events' },
{ key: 'history', label: 'Product Stock History' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='productStock'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='productStock'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='productStock'
id={productStockId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Product Stock Information' },
{ key: 'partStocks', label: 'Part Stocks' },
{ key: 'events', label: 'Product Stock Events' },
{ key: 'history', label: 'Product Stock History' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='productStock'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='productStock'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={productStockId}
objectType='productStock'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={productStockId}
type='productStock'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Product Stock Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='productStock'
objectData={objectData}
labelWidth='175px'
visibleProperties={{ partStocks: false }}
/>
</InfoCollapse>
<InfoCollapse
title='Part Stocks'
icon={<PartStockIcon />}
active={collapseState.partStocks}
onToggle={(expanded) =>
updateCollapseState('partStocks', expanded)
}
collapseKey='partStocks'
>
<ObjectProperty
{...getModelProperty('productStock', 'partStocks')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
size='medium'
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Product Stock Events'
icon={<ProductStockIcon />}
active={collapseState.events}
onToggle={(expanded) => updateCollapseState('events', expanded)}
collapseKey='events'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='stockEvent'
masterFilter={{ 'parent._id': productStockId }}
visibleColumns={{ parent: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Product Stock History'
icon={<GraphIcon />}
active={collapseState.history}
onToggle={(expanded) => updateCollapseState('history', expanded)}
collapseKey='history'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<HistoryDisplay
history={objectFormState.objectData?.history || []}
objectType='productStock'
chartType='line'
loading={objectFormState.loading}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={productStockId} type='productStock' />
</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': productStockId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={productStockId}
objectType='productStock'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={productStockId}
type='productStock'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Product Stock Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='productStock'
objectData={objectData}
labelWidth='175px'
visibleProperties={{ partStocks: false }}
/>
</InfoCollapse>
<InfoCollapse
title='Part Stocks'
icon={<PartStockIcon />}
active={collapseState.partStocks}
onToggle={(expanded) =>
updateCollapseState('partStocks', expanded)
}
collapseKey='partStocks'
>
<ObjectProperty
{...getModelProperty('productStock', 'partStocks')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
size='medium'
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Product Stock Events'
icon={<ProductStockIcon />}
active={collapseState.events}
onToggle={(expanded) => updateCollapseState('events', expanded)}
collapseKey='events'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='stockEvent'
masterFilter={{ parent: getModelByName('productStock').prefix + ':' + productStockId }}
visibleColumns={{ parent: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Product Stock History'
icon={<GraphIcon />}
active={collapseState.history}
onToggle={(expanded) => updateCollapseState('history', expanded)}
collapseKey='history'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<HistoryDisplay
history={objectFormState.objectData?.history || []}
objectType='productStock'
chartType='line'
loading={objectFormState.loading}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={productStockId} type='productStock' />
</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:
getModelByName('productStock').prefix +
':' +
productStockId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -27,6 +27,7 @@ import ScrollBox from '../../common/ScrollBox.jsx'
import OrderItemsIcon from '../../../Icons/OrderItemIcon.jsx'
import ShipmentIcon from '../../../Icons/ShipmentIcon.jsx'
import InvoiceIcon from '../../../Icons/InvoiceIcon.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import StockEventIcon from '../../../Icons/StockEventIcon.jsx'
const log = loglevel.getLogger('PurchaseOrderInfo')
@ -39,7 +40,6 @@ const PurchaseOrderInfo = () => {
const shipmentsTableRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -92,244 +92,247 @@ const PurchaseOrderInfo = () => {
delete: () => {
objectFormRef?.current?.handleDelete?.()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='purchaseOrder'
id={purchaseOrderId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Purchase Order Information' },
{ key: 'orderItems', label: 'Order Items' },
{ key: 'shipments', label: 'Shipments' },
{ key: 'invoices', label: 'Invoices' },
{ key: 'stockEvents', label: 'Stock Events' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='purchaseOrder'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='purchaseOrder'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='purchaseOrder'
id={purchaseOrderId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Purchase Order Information' },
{ key: 'orderItems', label: 'Order Items' },
{ key: 'shipments', label: 'Shipments' },
{ key: 'invoices', label: 'Invoices' },
{ key: 'stockEvents', label: 'Stock Events' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='purchaseOrder'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='purchaseOrder'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={purchaseOrderId}
objectType='purchaseOrder'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={purchaseOrderId}
type='purchaseOrder'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Purchase Order Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='purchaseOrder'
labelWidth='225px'
objectData={objectData}
visibleProperties={{
items: false
}}
/>
</InfoCollapse>
<InfoCollapse
title='Purchase Order Items'
icon={<OrderItemsIcon />}
active={collapseState.orderItems}
onToggle={(expanded) =>
updateCollapseState('orderItems', expanded)
}
collapseKey='orderItems'
>
<ObjectTable
type='orderItem'
masterFilter={{
'order._id': purchaseOrderId,
orderType: 'purchaseOrder'
}}
visibleColumns={{ order: false }}
ref={orderItemsTableRef}
/>
</InfoCollapse>
<InfoCollapse
title='Shipments'
icon={<ShipmentIcon />}
active={collapseState.shipments}
onToggle={(expanded) =>
updateCollapseState('shipments', expanded)
}
collapseKey='shipments'
>
<ObjectTable
type='shipment'
masterFilter={{
'order._id': purchaseOrderId,
orderType: 'purchaseOrder'
}}
visibleColumns={{ order: false }}
ref={shipmentsTableRef}
/>
</InfoCollapse>
<InfoCollapse
title='Invoices'
icon={<InvoiceIcon />}
active={collapseState.invoices}
onToggle={(expanded) =>
updateCollapseState('invoices', expanded)
}
collapseKey='invoices'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='invoice'
masterFilter={{
'order._id': purchaseOrderId,
orderType: 'purchaseOrder'
}}
visibleColumns={{ order: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Stock Events'
icon={<StockEventIcon />}
active={collapseState.stockEvents}
onToggle={(expanded) =>
updateCollapseState('stockEvents', expanded)
}
collapseKey='stockEvents'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='stockEvent'
masterFilter={{
'owner._id': purchaseOrderId
}}
/>
)}
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={purchaseOrderId} type='purchaseOrder' />
</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': purchaseOrderId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={purchaseOrderId}
objectType='purchaseOrder'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={purchaseOrderId}
type='purchaseOrder'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Purchase Order Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='purchaseOrder'
labelWidth='225px'
objectData={objectData}
visibleProperties={{
items: false
}}
/>
</InfoCollapse>
<InfoCollapse
title='Purchase Order Items'
icon={<OrderItemsIcon />}
active={collapseState.orderItems}
onToggle={(expanded) =>
updateCollapseState('orderItems', expanded)
}
collapseKey='orderItems'
>
<ObjectTable
type='orderItem'
masterFilter={{
order: getModelByName('purchaseOrder').prefix + ':' + purchaseOrderId,
orderType: 'purchaseOrder'
}}
visibleColumns={{ order: false }}
ref={orderItemsTableRef}
/>
</InfoCollapse>
<InfoCollapse
title='Shipments'
icon={<ShipmentIcon />}
active={collapseState.shipments}
onToggle={(expanded) =>
updateCollapseState('shipments', expanded)
}
collapseKey='shipments'
>
<ObjectTable
type='shipment'
masterFilter={{
order: getModelByName('purchaseOrder').prefix + ':' + purchaseOrderId,
orderType: 'purchaseOrder'
}}
visibleColumns={{ order: false }}
ref={shipmentsTableRef}
/>
</InfoCollapse>
<InfoCollapse
title='Invoices'
icon={<InvoiceIcon />}
active={collapseState.invoices}
onToggle={(expanded) =>
updateCollapseState('invoices', expanded)
}
collapseKey='invoices'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='invoice'
masterFilter={{
order: getModelByName('purchaseOrder').prefix + ':' + purchaseOrderId,
orderType: 'purchaseOrder'
}}
visibleColumns={{ order: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Stock Events'
icon={<StockEventIcon />}
active={collapseState.stockEvents}
onToggle={(expanded) =>
updateCollapseState('stockEvents', expanded)
}
collapseKey='stockEvents'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='stockEvent'
masterFilter={{
owner: getModelByName('purchaseOrder').prefix + ':' + purchaseOrderId
}}
/>
)}
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={purchaseOrderId} type='purchaseOrder' />
</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:
getModelByName('purchaseOrder').prefix +
':' +
purchaseOrderId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -27,6 +27,7 @@ import NewOrderItem from '../OrderItems/NewOrderItem.jsx'
import NewShipment from './NewShipment.jsx'
import PostPurchaseOrder from '../PurchaseOrders/PostPurchaseOrder.jsx'
import AcknowledgePurchaseOrder from '../PurchaseOrders/AcknowledgePurchaseOrder.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ShipmentIcon from '../../../Icons/ShipmentIcon.jsx'
const log = loglevel.getLogger('PurchaseOrderInfo')
@ -227,7 +228,7 @@ const PurchaseOrderInfo = () => {
<ObjectTable
type='orderItem'
masterFilter={{
'order._id': purchaseOrderId,
order: getModelByName('purchaseOrder').prefix + ':' + purchaseOrderId,
orderType: 'purchaseOrder'
}}
visibleColumns={{ order: false }}
@ -246,7 +247,7 @@ const PurchaseOrderInfo = () => {
<ObjectTable
type='shipment'
masterFilter={{
'order._id': purchaseOrderId,
order: getModelByName('purchaseOrder').prefix + ':' + purchaseOrderId,
orderType: 'purchaseOrder'
}}
visibleColumns={{ order: false }}
@ -282,8 +283,13 @@ const PurchaseOrderInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': purchaseOrderId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('purchaseOrder').prefix +
':' +
purchaseOrderId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -24,6 +24,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import OrderItemIcon from '../../../Icons/OrderItemIcon.jsx'
const log = loglevel.getLogger('ShipmentInfo')
@ -34,7 +35,6 @@ const ShipmentInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -77,179 +77,182 @@ const ShipmentInfo = () => {
delete: () => {
objectFormRef?.current?.handleDelete?.()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='shipment'
id={shipmentId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Shipment Information' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='shipment'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='shipment'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='shipment'
id={shipmentId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Shipment Information' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='shipment'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='shipment'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={shipmentId}
objectType='shipment'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={shipmentId}
type='shipment'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Shipment Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='shipment'
objectData={objectData}
visibleProperties={{
items: false
}}
labelWidth='175px'
/>
</InfoCollapse>
<InfoCollapse
title='Shipment Order Items'
icon={<OrderItemIcon />}
active={collapseState.orderItems}
onToggle={(expanded) =>
updateCollapseState('orderItems', expanded)
}
collapseKey='orderItems'
>
<ObjectTable
type='orderItem'
masterFilter={{ 'shipment._id': shipmentId }}
visibleColumns={{
shipment: false,
order: false,
orderType: false
}}
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={shipmentId} type='shipment' />
</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': shipmentId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={shipmentId}
objectType='shipment'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={shipmentId}
type='shipment'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Shipment Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='shipment'
objectData={objectData}
visibleProperties={{
items: false
}}
labelWidth='175px'
/>
</InfoCollapse>
<InfoCollapse
title='Shipment Order Items'
icon={<OrderItemIcon />}
active={collapseState.orderItems}
onToggle={(expanded) =>
updateCollapseState('orderItems', expanded)
}
collapseKey='orderItems'
>
<ObjectTable
type='orderItem'
masterFilter={{ shipment: getModelByName('shipment').prefix + ':' + shipmentId }}
visibleColumns={{
shipment: false,
order: false,
orderType: false
}}
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={shipmentId} type='shipment' />
</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:
getModelByName('shipment').prefix +
':' +
shipmentId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -22,6 +22,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('StockAuditInfo')
@ -211,8 +212,13 @@ const StockAuditInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': stockAuditId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('stockAudit').prefix +
':' +
stockAuditId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -22,6 +22,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('StockLocationInfo')
@ -209,8 +210,13 @@ const StockLocationInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': stockLocationId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('stockLocation').prefix +
':' +
stockLocationId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -8,7 +8,7 @@ import InfoCollapse from '../../common/InfoCollapse.jsx'
import ObjectInfo from '../../common/ObjectInfo.jsx'
import ObjectProperty from '../../common/ObjectProperty.jsx'
import ViewButton from '../../common/ViewButton.jsx'
import { getModelProperty } from '../../../../database/ObjectModels.js'
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
import NoteIcon from '../../../Icons/NoteIcon.jsx'
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
@ -31,7 +31,6 @@ const StockTransferInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -78,178 +77,181 @@ const StockTransferInfo = () => {
delete: () => {
objectFormRef?.current.handleDelete?.()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='stockTransfer'
id={stockTransferId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Transfer' },
{ key: 'lines', label: 'Lines' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='stockTransfer'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='stockTransfer'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='stockTransfer'
id={stockTransferId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Transfer' },
{ key: 'lines', label: 'Lines' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='stockTransfer'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='stockTransfer'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={stockTransferId}
objectType='stockTransfer'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={stockTransferId}
type='stockTransfer'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Stock transfer'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='stockTransfer'
objectData={objectData}
labelWidth='175px'
visibleProperties={{ lines: false }}
/>
</InfoCollapse>
<InfoCollapse
title='Lines'
icon={<StockTransferIcon />}
active={collapseState.lines}
onToggle={(expanded) =>
updateCollapseState('lines', expanded)
}
collapseKey='lines'
>
<ObjectProperty
{...getModelProperty('stockTransfer', 'lines')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
size='medium'
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={stockTransferId} type='stockTransfer' />
</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': stockTransferId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={stockTransferId}
objectType='stockTransfer'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={stockTransferId}
type='stockTransfer'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Stock transfer'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='stockTransfer'
objectData={objectData}
labelWidth='175px'
visibleProperties={{ lines: false }}
/>
</InfoCollapse>
<InfoCollapse
title='Lines'
icon={<StockTransferIcon />}
active={collapseState.lines}
onToggle={(expanded) =>
updateCollapseState('lines', expanded)
}
collapseKey='lines'
>
<ObjectProperty
{...getModelProperty('stockTransfer', 'lines')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
size='medium'
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={stockTransferId} type='stockTransfer' />
</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:
getModelByName('stockTransfer').prefix +
':' +
stockTransferId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -19,6 +19,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const AppPasswordInfo = () => {
@ -26,7 +27,6 @@ const AppPasswordInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -70,132 +70,135 @@ const AppPasswordInfo = () => {
}
return (
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='appPassword'
id={appPasswordId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'App Password Information' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='appPassword'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='appPassword'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='appPassword'
id={appPasswordId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'App Password Information' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='appPassword'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='appPassword'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={appPasswordId}
objectType='appPassword'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='App Password Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={appPasswordId}
type='appPassword'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='appPassword'
objectData={objectData}
/>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<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': appPasswordId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={appPasswordId}
objectType='appPassword'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='App Password Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={appPasswordId}
type='appPassword'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='appPassword'
objectData={objectData}
/>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Audit Logs'
icon={<AuditLogIcon />}
active={collapseState.auditLogs}
onToggle={(expanded) => updateCollapseState('auditLogs', expanded)}
collapseKey='auditLogs'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='auditLog'
masterFilter={{
parent:
getModelByName('appPassword').prefix +
':' +
appPasswordId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -6,6 +6,7 @@ import CloudIcon from '../../../Icons/CloudIcon'
import HostIcon from '../../../Icons/HostIcon'
import ReloadIcon from '../../../Icons/ReloadIcon'
import HProgress from '../../common/HProgress'
import ElipsisText from '../../common/ElipsisText'
import CheckCircleIcon from '../../../Icons/CheckCircleIcon'
import XMarkCircleIcon from '../../../Icons/XMarkCircleIcon'
@ -143,9 +144,9 @@ const UpdateStage = ({ stage, status, percent, detail }) => {
style={{ flex: 1, margin: 0 }}
/>
{detail && (
<Text type='secondary' ellipsis style={{ minWidth: 0 }}>
<ElipsisText type='secondary' style={{ minWidth: 0 }}>
{detail}
</Text>
</ElipsisText>
)}
</Flex>
)}

View File

@ -21,6 +21,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('CourierServiceInfo')
@ -201,8 +202,13 @@ const CourierServiceInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': courierServiceId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('courierService').prefix +
':' +
courierServiceId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -22,6 +22,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import CourierServiceIcon from '../../../Icons/CourierServiceIcon.jsx'
const log = loglevel.getLogger('CourierInfo')
@ -186,10 +187,10 @@ const CourierInfo = () => {
) : (
<ObjectTable
type='courierService'
masterFilter={{ 'courier._id': courierId }}
masterFilter={{ courier: getModelByName('courier').prefix + ':' + courierId }}
visibleColumns={{
courier: false,
'courier._id': false
courier: false
}}
/>
)}
@ -219,8 +220,13 @@ const CourierInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': courierId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('courier').prefix +
':' +
courierId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -22,6 +22,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('DocumentJobInfo')
@ -199,8 +200,13 @@ const DocumentJobInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': documentJobId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('documentJob').prefix +
':' +
documentJobId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -22,6 +22,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('DocumentPrinterInfo')
@ -213,8 +214,13 @@ const DocumentPrinterInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': documentPrinterId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('documentPrinter').prefix +
':' +
documentPrinterId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -22,6 +22,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('DocumentSizeInfo')
@ -200,8 +201,13 @@ const DocumentSizeInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': documentSizeId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('documentSize').prefix +
':' +
documentSizeId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -22,6 +22,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('DocumentTemplateInfo')
@ -214,8 +215,13 @@ const DocumentTemplateInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': documentTemplateId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('documentTemplate').prefix +
':' +
documentTemplateId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -19,6 +19,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const FilamentSkuInfo = () => {
@ -196,8 +197,13 @@ const FilamentSkuInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': filamentSkuId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('filamentSku').prefix +
':' +
filamentSkuId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -25,6 +25,7 @@ import FilamentIcon from '../../../Icons/FilamentIcon.jsx'
import FilamentSkuIcon from '../../../Icons/FilamentSkuIcon.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
const log = loglevel.getLogger('FilamentInfo')
@ -214,7 +215,7 @@ const FilamentInfo = () => {
<ObjectTable
ref={filamentSkusTableRef}
type='filamentSku'
masterFilter={{ filament: filamentId }}
masterFilter={{ filament: getModelByName('filament').prefix + ':' + filamentId }}
visibleColumns={{ filament: false }}
/>
)}
@ -232,7 +233,7 @@ const FilamentInfo = () => {
) : (
<ObjectTable
type='filamentStock'
masterFilter={{ filament: filamentId }}
masterFilter={{ filament: getModelByName('filament').prefix + ':' + filamentId }}
visibleColumns={{
filament: false,
startingWeight: false
@ -265,8 +266,13 @@ const FilamentInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': filamentId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('filament').prefix +
':' +
filamentId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -28,7 +28,7 @@ import { ApiServerContext } from '../../context/ApiServerContext.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import JsonObjectIcon from '../../../Icons/JsonObjectIcon.jsx'
import ObjectProperty from '../../common/ObjectProperty.jsx'
import { getModelProperty } from '../../../../database/ObjectModels.js'
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
const log = loglevel.getLogger('FileInfo')
log.setLevel(config.logLevel)
@ -250,8 +250,13 @@ const FileInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': fileId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('file').prefix +
':' +
fileId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -25,6 +25,7 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import PrinterIcon from '../../../Icons/PrinterIcon.jsx'
import DocumentPrinterIcon from '../../../Icons/DocumentPrinterIcon.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('HostInfo')
@ -35,7 +36,6 @@ const HostInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -81,198 +81,201 @@ const HostInfo = () => {
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='host'
id={hostId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Host Information' },
{ key: 'printers', label: 'Printers' },
{ key: 'documentPrinters', label: 'Document Printers' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='host'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='host'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='host'
id={hostId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Host Information' },
{ key: 'printers', label: 'Printers' },
{ key: 'documentPrinters', label: 'Document Printers' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='host'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='host'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={hostId}
objectType='host'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Host Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={hostId}
type='host'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => {
return (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='host'
objectData={objectData}
labelWidth='175px'
/>
)
}}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Printers'
icon={<PrinterIcon />}
active={collapseState.printers}
onToggle={(expanded) => updateCollapseState('printers', expanded)}
collapseKey='printers'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='printer'
masterFilter={{ 'host._id': hostId }}
visibleColumns={{
host: false,
'host._id': false
}}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Document Printers'
icon={<DocumentPrinterIcon />}
active={collapseState.documentPrinters}
onToggle={(expanded) =>
updateCollapseState('documentPrinters', expanded)
}
collapseKey='documentPrinters'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='documentPrinter'
masterFilter={{ 'host._id': hostId }}
visibleColumns={{
host: false,
'host._id': false
}}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={hostId} type='host' />
</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': hostId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={hostId}
objectType='host'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Host Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={hostId}
type='host'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => {
return (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='host'
objectData={objectData}
labelWidth='175px'
/>
)
}}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Printers'
icon={<PrinterIcon />}
active={collapseState.printers}
onToggle={(expanded) => updateCollapseState('printers', expanded)}
collapseKey='printers'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='printer'
masterFilter={{ host: getModelByName('host').prefix + ':' + hostId }}
visibleColumns={{
host: false,
host: false
}}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Document Printers'
icon={<DocumentPrinterIcon />}
active={collapseState.documentPrinters}
onToggle={(expanded) =>
updateCollapseState('documentPrinters', expanded)
}
collapseKey='documentPrinters'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='documentPrinter'
masterFilter={{ host: getModelByName('host').prefix + ':' + hostId }}
visibleColumns={{
host: false,
host: false
}}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={hostId} type='host' />
</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:
getModelByName('host').prefix +
':' +
hostId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -21,6 +21,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('MaterialInfo')
@ -199,8 +200,13 @@ const MaterialInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': materialId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('material').prefix +
':' +
materialId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -18,6 +18,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const NoteTypeInfo = () => {
@ -177,8 +178,13 @@ const NoteTypeInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': noteTypeId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('noteType').prefix +
':' +
noteTypeId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -15,7 +15,7 @@ const NewNote = ({ onOk, defaultValues = {} }) => {
<ObjectInfo
type='note'
column={1}
visibleProperties={{ 'parent._id': false }}
visibleProperties={{ parent: false }}
bordered={false}
isEditing={true}
required={true}

View File

@ -25,7 +25,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelProperty } from '../../../../database/ObjectModels.js'
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
const log = loglevel.getLogger('NoteInfo')
log.setLevel(config.logLevel)
@ -228,8 +228,13 @@ const NoteInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': noteId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('note').prefix +
':' +
noteId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -19,6 +19,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const PartSkuInfo = () => {
@ -191,8 +192,13 @@ const PartSkuInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': partSkuId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('partSku').prefix +
':' +
partSkuId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -21,6 +21,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import PartSkuIcon from '../../../Icons/PartSkuIcon.jsx'
const PartInfo = () => {
@ -30,7 +31,6 @@ const PartInfo = () => {
const partId = new URLSearchParams(location.search).get('partId')
const partSkusTableRef = useRef()
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -70,166 +70,165 @@ const PartInfo = () => {
}
return (
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='part'
id={partId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Part Information' },
{ key: 'partSkus', label: 'Part SKUs' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='part'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='part'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='part'
id={partId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Part Information' },
{ key: 'partSkus', label: 'Part SKUs' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='part'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='part'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<Space>
<EditButtons
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={partId}
objectType='part'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={partId}
type='part'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
cancelEditing={() => {
actionHandlerRef.current.callAction('cancelEdit')
}}
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={
objectFormState.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={partId}
objectType='part'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={partId}
type='part'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<InfoCollapse
title='Part Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='part'
objectData={objectData}
/>
</InfoCollapse>
)}
</ObjectForm>
<InfoCollapse
title='Part SKUs'
icon={<PartSkuIcon />}
active={collapseState.partSkus}
onToggle={(expanded) =>
updateCollapseState('partSkus', expanded)
}
collapseKey='partSkus'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
ref={partSkusTableRef}
type='partSku'
masterFilter={{ part: partId }}
visibleColumns={{ part: false }}
{({ loading, isEditing, objectData }) => (
<InfoCollapse
title='Part Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='part'
objectData={objectData}
/>
)}
</InfoCollapse>
</ActionHandler>
</InfoCollapse>
)}
</ObjectForm>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={partId} type='part' />
</Card>
</InfoCollapse>
<InfoCollapse
title='Audit Logs'
icon={<AuditLogIcon />}
active={collapseState.auditLogs}
onToggle={(expanded) =>
updateCollapseState('auditLogs', expanded)
}
collapseKey='auditLogs'
title='Part SKUs'
icon={<PartSkuIcon />}
active={collapseState.partSkus}
onToggle={(expanded) => updateCollapseState('partSkus', expanded)}
collapseKey='partSkus'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': partId }}
visibleColumns={{ _id: false, 'parent._id': false }}
ref={partSkusTableRef}
type='partSku'
masterFilter={{ part: getModelByName('part').prefix + ':' + partId }}
visibleColumns={{ part: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={partId} type='part' />
</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:
getModelByName('part').prefix +
':' +
partId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -19,6 +19,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const ProductCategoryInfo = () => {
@ -196,8 +197,13 @@ const ProductCategoryInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': productCategoryId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('productCategory').prefix +
':' +
productCategoryId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -21,7 +21,7 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import ObjectProperty from '../../common/ObjectProperty.jsx'
import { getModelProperty } from '../../../../database/ObjectModels.js'
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
import PartIcon from '../../../Icons/PartIcon.jsx'
const ProductSkuInfo = () => {
@ -224,8 +224,13 @@ const ProductSkuInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': productSkuId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('productSku').prefix +
':' +
productSkuId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -21,6 +21,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ProductSkuIcon from '../../../Icons/ProductSkuIcon.jsx'
const ProductInfo = () => {
@ -36,7 +37,6 @@ const ProductInfo = () => {
})
const productSkusTableRef = useRef()
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -70,169 +70,172 @@ const ProductInfo = () => {
}
return (
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='product'
id={productId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Product Information' },
{ key: 'productSkus', label: 'Product SKUs' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='product'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='product'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='product'
id={productId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Product Information' },
{ key: 'productSkus', label: 'Product SKUs' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='product'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='product'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={productId}
objectType='product'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={productId}
type='product'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Product Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='product'
objectData={objectData}
/>
</InfoCollapse>
<InfoCollapse
title='Product SKUs'
icon={<ProductSkuIcon />}
active={collapseState.productSkus}
onToggle={(expanded) =>
updateCollapseState('productSkus', expanded)
}
collapseKey='productSkus'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
ref={productSkusTableRef}
type='productSku'
masterFilter={{ product: productId }}
visibleColumns={{ product: false }}
/>
)}
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={productId} type='product' />
</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': productId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={productId}
objectType='product'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={productId}
type='product'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Product Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='product'
objectData={objectData}
/>
</InfoCollapse>
<InfoCollapse
title='Product SKUs'
icon={<ProductSkuIcon />}
active={collapseState.productSkus}
onToggle={(expanded) =>
updateCollapseState('productSkus', expanded)
}
collapseKey='productSkus'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
ref={productSkusTableRef}
type='productSku'
masterFilter={{ product: getModelByName('product').prefix + ':' + productId }}
visibleColumns={{ product: false }}
/>
)}
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={productId} type='product' />
</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:
getModelByName('product').prefix +
':' +
productId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -21,6 +21,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('TaxRateInfo')
@ -196,8 +197,13 @@ const TaxRateInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': taxRateId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('taxRate').prefix +
':' +
taxRateId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -23,7 +23,7 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import ObjectProperty from '../../common/ObjectProperty.jsx'
import { getModelProperty } from '../../../../database/ObjectModels.js'
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
import { useMediaQuery } from 'react-responsive'
const UserInfo = () => {
@ -206,7 +206,7 @@ const UserInfo = () => {
) : (
<ObjectTable
type='appPassword'
masterFilter={{ user: userId }}
masterFilter={{ user: getModelByName('user').prefix + ':' + userId }}
visibleColumns={{ user: false }}
ref={appPasswordsTableRef}
/>
@ -227,9 +227,7 @@ const UserInfo = () => {
title='Audit Logs'
icon={<AuditLogIcon />}
active={collapseState.auditLogs}
onToggle={(expanded) =>
updateCollapseState('auditLogs', expanded)
}
onToggle={(expanded) => updateCollapseState('auditLogs', expanded)}
collapseKey='auditLogs'
>
{objectFormState.loading ? (
@ -237,8 +235,13 @@ const UserInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': userId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('user').prefix +
':' +
userId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -21,6 +21,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('VendorInfo')
@ -196,8 +197,13 @@ const VendorInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': vendorId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('vendor').prefix +
':' +
vendorId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -27,6 +27,7 @@ import SettingsIcon from '../../../Icons/SettingsIcon'
import UserNotifierToggle from '../../common/UserNotifierToggle'
import ViewButton from '../../common/ViewButton'
import useCollapseState from '../../hooks/useCollapseState'
import { getModelByName } from '../../../../database/ObjectModels.js'
import {
FILAMENT_PROFILE_BED_TEMPERATURE_PROPERTIES,
FILAMENT_PROFILE_COMPATIBILITY_PROPERTIES,
@ -160,7 +161,9 @@ const FilamentProfileInfo = () => {
<Space>
<EditButtons
isEditing={objectFormState.isEditing}
handleUpdate={() => actionHandlerRef.current.callAction('finishEdit')}
handleUpdate={() =>
actionHandlerRef.current.callAction('finishEdit')
}
cancelEditing={() =>
actionHandlerRef.current.callAction('cancelEdit')
}
@ -533,8 +536,13 @@ const FilamentProfileInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': filamentProfileId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('filamentProfile').prefix +
':' +
filamentProfileId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -24,7 +24,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelProperty } from '../../../../database/ObjectModels.js'
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
import PartIcon from '../../../Icons/PartIcon.jsx'
const log = loglevel.getLogger('GCodeFileInfo')
@ -235,8 +235,13 @@ const GCodeFileInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': gcodeFileId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('gcodeFile').prefix +
':' +
gcodeFileId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -4,6 +4,7 @@ import WizardView from '../../common/WizardView'
import { ApiServerContext } from '../../context/ApiServerContext'
import { Descriptions, Flex, Typography } from 'antd'
import ObjectTable from '../../common/ObjectTable'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ObjectProperty from '../../common/ObjectProperty'
const { Text } = Typography
const DeployJob = ({
@ -26,7 +27,7 @@ const DeployJob = ({
while (hasMore == true) {
const subJobsPage = await fetchObjects('subJob', {
page: currentPage,
filter: { 'job._id': job._id }
filter: { job: job._id }
})
subJobs = [...subJobs, ...subJobsPage.data]
if (subJobsPage.data.length >= 25) {
@ -150,7 +151,7 @@ const DeployJob = ({
printer: false,
job: false
}}
masterFilter={{ 'job._id': job?._id }}
masterFilter={{ job: getModelByName('job').prefix + ':' + job?._id }}
size={'small'}
showActions={!slicerIntegration}
/>

View File

@ -24,6 +24,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import JobIcon from '../../../Icons/JobIcon.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('JobInfo')
@ -34,7 +35,6 @@ const JobInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -74,169 +74,172 @@ const JobInfo = () => {
finishEdit: () => {
objectFormRef?.current.handleUpdate()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='job'
id={jobId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Job Information' },
{ key: 'subJobs', label: 'Sub Jobs' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='job'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='job'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='job'
id={jobId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Job Information' },
{ key: 'subJobs', label: 'Sub Jobs' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='job'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='job'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={jobId}
objectType='job'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Job Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={jobId}
type='job'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='job'
objectData={objectData}
/>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Sub Jobs'
icon={<JobIcon />}
active={collapseState.subJobs}
onToggle={(expanded) => updateCollapseState('subJobs', expanded)}
collapseKey='subJobs'
>
<ObjectTable
type='subJob'
masterFilter={{ 'job._id': jobId }}
visibleColumns={{ 'job._id': false }}
/>
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={jobId} type='job' />
</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': jobId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={jobId}
objectType='job'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Job Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={jobId}
type='job'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='job'
objectData={objectData}
/>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Sub Jobs'
icon={<JobIcon />}
active={collapseState.subJobs}
onToggle={(expanded) => updateCollapseState('subJobs', expanded)}
collapseKey='subJobs'
>
<ObjectTable
type='subJob'
masterFilter={{ job: getModelByName('job').prefix + ':' + jobId }}
visibleColumns={{ job: false }}
/>
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={jobId} type='job' />
</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:
getModelByName('job').prefix +
':' +
jobId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -26,7 +26,7 @@ import UserNotifierToggle from '../../common/UserNotifierToggle'
import ViewButton from '../../common/ViewButton'
import useCollapseState from '../../hooks/useCollapseState'
import ObjectProperty from '../../common/ObjectProperty'
import { getModelProperty } from '../../../../database/ObjectModels'
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels'
import GCodeFileIcon from '../../../Icons/GCodeFileIcon'
import SettingsIcon from '../../../Icons/SettingsIcon'
import ExclamationOctagonIcon from '../../../Icons/ExclamationOctagonIcon'
@ -133,7 +133,9 @@ const PrinterProfileInfo = () => {
<Space>
<EditButtons
isEditing={objectFormState.isEditing}
handleUpdate={() => actionHandlerRef.current.callAction('finishEdit')}
handleUpdate={() =>
actionHandlerRef.current.callAction('finishEdit')
}
cancelEditing={() =>
actionHandlerRef.current.callAction('cancelEdit')
}
@ -385,8 +387,13 @@ const PrinterProfileInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': printerProfileId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('printerProfile').prefix +
':' +
printerProfileId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -24,6 +24,7 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import PrinterProfileIcon from '../../../Icons/PrinterProfileIcon.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
const log = loglevel.getLogger('PrinterInfo')
log.setLevel(config.logLevel)
@ -34,7 +35,6 @@ const PrinterInfo = () => {
const profilesTableRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
const printerId = new URLSearchParams(location.search).get('printerId')
const [collapseState, updateCollapseState] = useCollapseState('PrinterInfo', {
@ -75,188 +75,191 @@ const PrinterInfo = () => {
finishEdit: () => {
objectFormRef?.current.handleUpdate()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='printer'
id={printerId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Printer Information' },
{ key: 'profiles', label: 'Printer Profiles' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='printer'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='printer'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='printer'
id={printerId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Printer Information' },
{ key: 'profiles', label: 'Printer Profiles' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='printer'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='printer'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={printerId}
objectType='printer'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Printer Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={printerId}
type='printer'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='printer'
objectData={objectData}
labelWidth='175px'
visibleProperties={{
currentFilamentStock: false,
'currentFilamentStock._id': false,
currentJob: false,
'currentJob._id': false,
currentSubJob: false,
'currentSubJob._id': false,
alerts: false,
pendingSlicerUploads: false
}}
/>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Printer Profiles'
icon={<PrinterProfileIcon />}
active={collapseState.profiles}
onToggle={(expanded) => updateCollapseState('profiles', expanded)}
collapseKey='profiles'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
ref={profilesTableRef}
type='printerProfile'
masterFilter={{ printer: printerId }}
visibleColumns={{
printer: false,
'printer._id': false
}}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={printerId} type='printer' />
</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': printerId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={printerId}
objectType='printer'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Printer Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={printerId}
type='printer'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='printer'
objectData={objectData}
labelWidth='175px'
visibleProperties={{
currentFilamentStock: false,
'currentFilamentStock._id': false,
currentJob: false,
'currentJob._id': false,
currentSubJob: false,
'currentSubJob._id': false,
alerts: false,
pendingSlicerUploads: false
}}
/>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Printer Profiles'
icon={<PrinterProfileIcon />}
active={collapseState.profiles}
onToggle={(expanded) => updateCollapseState('profiles', expanded)}
collapseKey='profiles'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
ref={profilesTableRef}
type='printerProfile'
masterFilter={{ printer: getModelByName('printer').prefix + ':' + printerId }}
visibleColumns={{
printer: false,
'printer._id': false
}}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={printerId} type='printer' />
</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:
getModelByName('printer').prefix +
':' +
printerId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -21,6 +21,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import StockEventIcon from '../../../Icons/StockEventIcon.jsx'
const SubJobInfo = () => {
@ -173,9 +174,9 @@ const SubJobInfo = () => {
) : (
<ObjectTable
type='stockEvent'
masterFilter={{ 'owner._id': subJobId }}
masterFilter={{ owner: getModelByName('subJob').prefix + ':' + subJobId }}
visibleColumns={{
'owner._id': false,
owner: false,
'owner.type': false,
owner: false
}}
@ -207,8 +208,13 @@ const SubJobInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': subJobId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('subJob').prefix +
':' +
subJobId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -21,6 +21,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('ClientInfo')
@ -196,8 +197,13 @@ const ClientInfo = () => {
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': clientId }}
visibleColumns={{ _id: false, 'parent._id': false }}
masterFilter={{
parent:
getModelByName('client').prefix +
':' +
clientId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>

View File

@ -23,6 +23,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
const log = loglevel.getLogger('ListingVarientInfo')
log.setLevel(config.logLevel)
@ -32,7 +33,6 @@ const ListingVarientInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -77,151 +77,154 @@ const ListingVarientInfo = () => {
delete: () => {
objectFormRef?.current?.handleDelete?.()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='listingVarient'
id={listingVarientId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Listing Varient Information' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='listingVarient'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='listingVarient'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='listingVarient'
id={listingVarientId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Listing Varient Information' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='listingVarient'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='listingVarient'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={listingVarientId}
objectType='listingVarient'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={listingVarientId}
type='listingVarient'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Listing Varient Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='listingVarient'
objectData={objectData}
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={listingVarientId} type='listingVarient' />
</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': listingVarientId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={listingVarientId}
objectType='listingVarient'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={listingVarientId}
type='listingVarient'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Listing Varient Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='listingVarient'
objectData={objectData}
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={listingVarientId} type='listingVarient' />
</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:
getModelByName('listingVarient').prefix +
':' +
listingVarientId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -23,6 +23,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import ScrollBox from '../../common/ScrollBox.jsx'
const log = loglevel.getLogger('ListingInfo')
@ -34,7 +35,6 @@ const ListingInfo = () => {
const listingVarientsTableRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -75,171 +75,174 @@ const ListingInfo = () => {
delete: () => {
objectFormRef?.current?.handleDelete?.()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='listing'
id={listingId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Listing Information' },
{ key: 'listingVarients', label: 'Listing Varients' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='listing'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='listing'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='listing'
id={listingId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Listing Information' },
{ key: 'listingVarients', label: 'Listing Varients' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='listing'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='listing'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={listingId}
objectType='listing'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={listingId}
type='listing'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Listing Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='listing'
labelWidth={165}
objectData={objectData}
/>
</InfoCollapse>
<InfoCollapse
title='Listing Varients'
icon={<ListingVarientIcon />}
active={collapseState.listingVarients}
onToggle={(expanded) =>
updateCollapseState('listingVarients', expanded)
}
collapseKey='listingVarients'
>
<ObjectTable
type='listingVarient'
masterFilter={{
'listing._id': listingId
}}
visibleColumns={{ listing: false }}
ref={listingVarientsTableRef}
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={listingId} type='listing' />
</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': listingId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={listingId}
objectType='listing'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={listingId}
type='listing'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Listing Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='listing'
labelWidth={165}
objectData={objectData}
/>
</InfoCollapse>
<InfoCollapse
title='Listing Varients'
icon={<ListingVarientIcon />}
active={collapseState.listingVarients}
onToggle={(expanded) =>
updateCollapseState('listingVarients', expanded)
}
collapseKey='listingVarients'
>
<ObjectTable
type='listingVarient'
masterFilter={{
listing: getModelByName('listing').prefix + ':' + listingId
}}
visibleColumns={{ listing: false }}
ref={listingVarientsTableRef}
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={listingId} type='listing' />
</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:
getModelByName('listing').prefix +
':' +
listingId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -1,4 +1,4 @@
import { useContext, useRef, useState , useEffect} from 'react'
import { useContext, useRef, useState, useEffect } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, message, Space } from 'antd'
import loglevel from 'loglevel'
@ -25,6 +25,7 @@ import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { ApiServerContext } from '../../context/ApiServerContext.jsx'
import { ElectronContext } from '../../context/ElectronContext.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import {
buildMarketplaceAuthState,
storeMarketplaceAuthState
@ -38,7 +39,6 @@ const MarketplaceInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -148,144 +148,147 @@ const MarketplaceInfo = () => {
}
return (
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='marketplace'
id={marketplaceId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Marketplace Information' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='marketplace'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='marketplace'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='marketplace'
id={marketplaceId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Marketplace Information' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='marketplace'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='marketplace'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={marketplaceId}
objectType='marketplace'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Marketplace Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={marketplaceId}
type='marketplace'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='marketplace'
labelWidth={215}
objectData={objectData}
/>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={marketplaceId} type='marketplace' />
</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': marketplaceId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={marketplaceId}
objectType='marketplace'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Marketplace Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={marketplaceId}
type='marketplace'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<ObjectInfo
loading={loading}
isEditing={isEditing}
type='marketplace'
labelWidth={215}
objectData={objectData}
/>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={marketplaceId} type='marketplace' />
</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:
getModelByName('marketplace').prefix +
':' +
marketplaceId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -27,6 +27,7 @@ import ScrollBox from '../../common/ScrollBox.jsx'
import OrderItemsIcon from '../../../Icons/OrderItemIcon.jsx'
import ShipmentIcon from '../../../Icons/ShipmentIcon.jsx'
import InvoiceIcon from '../../../Icons/InvoiceIcon.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import StockEventIcon from '../../../Icons/StockEventIcon.jsx'
const log = loglevel.getLogger('SalesOrderInfo')
@ -39,7 +40,6 @@ const SalesOrderInfo = () => {
const shipmentsTableRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
@ -90,244 +90,247 @@ const SalesOrderInfo = () => {
delete: () => {
objectFormRef?.current?.handleDelete?.()
return true
},
}
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<Space size='small'>
<Space size='small'>
<ObjectActions
type='salesOrder'
id={salesOrderId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Sales Order Information' },
{ key: 'orderItems', label: 'Order Items' },
{ key: 'shipments', label: 'Shipments' },
{ key: 'invoices', label: 'Invoices' },
{ key: 'stockEvents', label: 'Stock Events' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='salesOrder'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='salesOrder'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
<ObjectActions
type='salesOrder'
id={salesOrderId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Sales Order Information' },
{ key: 'orderItems', label: 'Order Items' },
{ key: 'shipments', label: 'Shipments' },
{ key: 'invoices', label: 'Invoices' },
{ key: 'stockEvents', label: 'Stock Events' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='salesOrder'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='salesOrder'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={salesOrderId}
objectType='salesOrder'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={salesOrderId}
type='salesOrder'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Sales Order Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='salesOrder'
labelWidth='225px'
objectData={objectData}
visibleProperties={{
items: false
}}
/>
</InfoCollapse>
<InfoCollapse
title='Sales Order Items'
icon={<OrderItemsIcon />}
active={collapseState.orderItems}
onToggle={(expanded) =>
updateCollapseState('orderItems', expanded)
}
collapseKey='orderItems'
>
<ObjectTable
type='orderItem'
masterFilter={{
'order._id': salesOrderId,
orderType: 'salesOrder'
}}
visibleColumns={{ order: false }}
ref={orderItemsTableRef}
/>
</InfoCollapse>
<InfoCollapse
title='Shipments'
icon={<ShipmentIcon />}
active={collapseState.shipments}
onToggle={(expanded) =>
updateCollapseState('shipments', expanded)
}
collapseKey='shipments'
>
<ObjectTable
type='shipment'
masterFilter={{
'order._id': salesOrderId,
orderType: 'salesOrder'
}}
visibleColumns={{ order: false }}
ref={shipmentsTableRef}
/>
</InfoCollapse>
<InfoCollapse
title='Invoices'
icon={<InvoiceIcon />}
active={collapseState.invoices}
onToggle={(expanded) =>
updateCollapseState('invoices', expanded)
}
collapseKey='invoices'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='invoice'
masterFilter={{
'order._id': salesOrderId,
orderType: 'salesOrder'
}}
visibleColumns={{ order: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Stock Events'
icon={<StockEventIcon />}
active={collapseState.stockEvents}
onToggle={(expanded) =>
updateCollapseState('stockEvents', expanded)
}
collapseKey='stockEvents'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='stockEvent'
masterFilter={{
'owner._id': salesOrderId
}}
/>
)}
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={salesOrderId} type='salesOrder' />
</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': salesOrderId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</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.beingEditedByOther ||
objectFormState.loading ||
objectFormState.editDisabled
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={salesOrderId}
objectType='salesOrder'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<ObjectForm
id={salesOrderId}
type='salesOrder'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex vertical gap={'large'}>
<InfoCollapse
title='Sales Order Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) =>
updateCollapseState('info', expanded)
}
collapseKey='info'
>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='salesOrder'
labelWidth='225px'
objectData={objectData}
visibleProperties={{
items: false
}}
/>
</InfoCollapse>
<InfoCollapse
title='Sales Order Items'
icon={<OrderItemsIcon />}
active={collapseState.orderItems}
onToggle={(expanded) =>
updateCollapseState('orderItems', expanded)
}
collapseKey='orderItems'
>
<ObjectTable
type='orderItem'
masterFilter={{
order: getModelByName('salesOrder').prefix + ':' + salesOrderId,
orderType: 'salesOrder'
}}
visibleColumns={{ order: false }}
ref={orderItemsTableRef}
/>
</InfoCollapse>
<InfoCollapse
title='Shipments'
icon={<ShipmentIcon />}
active={collapseState.shipments}
onToggle={(expanded) =>
updateCollapseState('shipments', expanded)
}
collapseKey='shipments'
>
<ObjectTable
type='shipment'
masterFilter={{
order: getModelByName('salesOrder').prefix + ':' + salesOrderId,
orderType: 'salesOrder'
}}
visibleColumns={{ order: false }}
ref={shipmentsTableRef}
/>
</InfoCollapse>
<InfoCollapse
title='Invoices'
icon={<InvoiceIcon />}
active={collapseState.invoices}
onToggle={(expanded) =>
updateCollapseState('invoices', expanded)
}
collapseKey='invoices'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='invoice'
masterFilter={{
order: getModelByName('salesOrder').prefix + ':' + salesOrderId,
orderType: 'salesOrder'
}}
visibleColumns={{ order: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Stock Events'
icon={<StockEventIcon />}
active={collapseState.stockEvents}
onToggle={(expanded) =>
updateCollapseState('stockEvents', expanded)
}
collapseKey='stockEvents'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='stockEvent'
masterFilter={{
owner: getModelByName('salesOrder').prefix + ':' + salesOrderId
}}
/>
)}
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={salesOrderId} type='salesOrder' />
</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:
getModelByName('salesOrder').prefix +
':' +
salesOrderId
}}
visibleColumns={{ _id: false, parent: false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
)
}

View File

@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
import { Flex, Typography, Input } from 'antd'
import CountryDisplay from './CountryDisplay'
import CountrySelect from './CountrySelect'
import ElipsisText from './ElipsisText'
const { Text } = Typography
@ -50,9 +51,9 @@ const AddressDisplay = ({
{isCountry ? (
<CountryDisplay countryCode={fieldValue} />
) : (
<Text ellipsis alt={label}>
<ElipsisText alt={label}>
{fieldValue}
</Text>
</ElipsisText>
)}
</Flex>
)

View File

@ -22,6 +22,64 @@ import { Button, Modal, Typography } from 'antd'
const { Link } = Typography
export function toEditorCode(code, language = 'javascript') {
if (code == null) return ''
if (typeof code === 'object' && language === 'json') {
return JSON.stringify(code, null, 2)
}
return String(code)
}
export function getCodeLanguageExtension(
language = 'javascript',
autoCompleteObject = null
) {
const lang = Array.isArray(language) ? language[0] : language
switch (String(lang || 'javascript').toLowerCase()) {
case 'javascript':
case 'js':
return javascript()
case 'python':
case 'py':
return python()
case 'json':
return json()
case 'xml':
return xml()
case 'fctemplatelang':
case 'ejs':
return fcTemplateLang({ autoCompleteObject })
case 'html':
return html()
case 'css':
return css()
case 'markdown':
case 'md':
return markdown()
case 'sql':
return sql()
case 'java':
return java()
case 'cpp':
case 'c++':
case 'c':
return cpp()
case 'rust':
case 'rs':
return rust()
case 'go':
return go()
case 'php':
return php()
case 'yaml':
case 'yml':
return yaml()
default:
return javascript()
}
}
export default function CodeBlockEditor({
code = '',
language = 'javascript',
@ -37,57 +95,12 @@ export default function CodeBlockEditor({
}) {
const { isDarkMode } = useThemeContext()
const [codeMirrorOpen, setCodeMirrorOpen] = useState(false)
var editorCode = code
const editorCode = toEditorCode(code, language)
if (typeof code == 'object' && language == 'json') {
editorCode = JSON.stringify(code, null, 2)
}
// Map language to CodeMirror extension
const languageExtension = useMemo(() => {
switch (language.toLowerCase()) {
case 'javascript':
case 'js':
return javascript()
case 'python':
case 'py':
return python()
case 'json':
return json()
case 'xml':
return xml()
case 'fctemplatelang':
case 'ejs':
return fcTemplateLang({ autoCompleteObject })
case 'html':
return html()
case 'css':
return css()
case 'markdown':
case 'md':
return markdown()
case 'sql':
return sql()
case 'java':
return java()
case 'cpp':
case 'c++':
case 'c':
return cpp()
case 'rust':
case 'rs':
return rust()
case 'go':
return go()
case 'php':
return php()
case 'yaml':
case 'yml':
return yaml()
default:
return javascript() // Default fallback
}
}, [language, autoCompleteObject])
const languageExtension = useMemo(
() => getCodeLanguageExtension(language, autoCompleteObject),
[language, autoCompleteObject]
)
const handleOnChange = (value) => {
if (typeof code == 'object' && language == 'json') {

View File

@ -0,0 +1,85 @@
import { useLayoutEffect, useMemo, useRef } from 'react'
import PropTypes from 'prop-types'
import { MergeView } from '@codemirror/merge'
import { EditorState } from '@codemirror/state'
import { EditorView } from '@codemirror/view'
import { oneDark } from '@codemirror/theme-one-dark'
import { basicSetup } from 'codemirror'
import { useThemeContext } from '../context/ThemeContext'
import {
getCodeLanguageExtension,
toEditorCode
} from './CodeBlockEditor'
export default function CodeDiffViewer({
oldCode = '',
newCode = '',
language = 'javascript'
}) {
const { isDarkMode } = useThemeContext()
const parentRef = useRef(null)
const oldDoc = toEditorCode(oldCode, language)
const newDoc = toEditorCode(newCode, language)
const languageExtension = useMemo(
() => getCodeLanguageExtension(language),
[language]
)
useLayoutEffect(() => {
if (!parentRef.current) return
const editorTheme = EditorView.theme({
'&': {
fontSize: '14px',
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", monospace'
}
})
const sharedExtensions = [
basicSetup,
languageExtension,
editorTheme,
EditorView.editable.of(false),
EditorState.readOnly.of(true),
...(isDarkMode ? [oneDark] : [])
]
const view = new MergeView({
a: {
doc: oldDoc,
extensions: sharedExtensions
},
b: {
doc: newDoc,
extensions: sharedExtensions
},
parent: parentRef.current,
highlightChanges: true,
gutter: true,
collapseUnchanged: { margin: 3, minSize: 6 }
})
return () => {
view.destroy()
}
}, [oldDoc, newDoc, languageExtension, isDarkMode])
return (
<div
ref={parentRef}
className={
isDarkMode ? 'code-diff-viewer is-dark' : 'code-diff-viewer'
}
/>
)
}
CodeDiffViewer.propTypes = {
oldCode: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
newCode: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
language: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string)
])
}

View File

@ -1,9 +1,8 @@
import PropTypes from 'prop-types'
import { Flex, Typography } from 'antd'
import { Flex } from 'antd'
import Flag from './Flag'
import countries from '../../../database/Countries'
const { Text } = Typography
import ElipsisText from './ElipsisText'
const CountryDisplay = ({ countryCode }) => {
const country = countries.find((c) => c.code === countryCode)
@ -17,7 +16,7 @@ const CountryDisplay = ({ countryCode }) => {
gap={'small'}
align='center'
className='country-display'
style={{ minWidth: 0 }}
style={{ minWidth: 0, width: '100%' }}
>
<Flag
code={country.code}
@ -25,8 +24,8 @@ const CountryDisplay = ({ countryCode }) => {
hasBorder={true}
borderRadius={5}
/>
<div style={{ minWidth: 0 }}>
<Text ellipsis>{country.name}</Text>
<div style={{ minWidth: 0, flex: 1, overflow: 'hidden' }}>
<ElipsisText>{country.name}</ElipsisText>
</div>
</Flex>
)

View File

@ -1,9 +1,8 @@
import { Select, Flex, Typography } from 'antd'
import { Select, Flex } from 'antd'
import PropTypes from 'prop-types'
import Flag from './Flag'
import countries from '../../../database/Countries'
const { Text } = Typography
import ElipsisText from './ElipsisText'
const CountrySelect = ({
value,
@ -30,7 +29,7 @@ const CountrySelect = ({
label: (
<Flex gap='small' align='center' className='country-display'>
<Flag code={country.code} size='small' borderRadius={3} />
<Text elipsis>{country.name}</Text>
<ElipsisText>{country.name}</ElipsisText>
</Flex>
)
}))}

View File

@ -22,6 +22,7 @@ import { Header } from 'antd/es/layout/layout'
import { useMediaQuery } from 'react-responsive'
import KeyboardShortcut from './KeyboardShortcut'
import UserProfilePopover from './UserProfilePopover'
import ElipsisText from './ElipsisText'
import FarmControlLogo from '../../Logos/FarmControlLogo'
import FarmControlLogoSmall from '../../Logos/FarmControlLogoSmall'
@ -194,19 +195,17 @@ const DashboardNavigation = () => {
}}
>
{selectedMenuItem.icon}
<Text
ellipsis
<ElipsisText
style={{
minWidth: 0, // CRUCIAL for flex children
maxWidth: '100%', // Responsive
minWidth: 0,
maxWidth: '100%',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
flex: 1 // Take available space, shrink as needed
flex: 1
}}
>
{selectedMenuItem.label}
</Text>
</ElipsisText>
</Flex>
)}
<div style={{ flexGrow: 1 }}>

View File

@ -0,0 +1,116 @@
import { useMemo, useState } from 'react'
import PropTypes from 'prop-types'
import { Button, Modal, Typography, theme, Flex } from 'antd'
import { presentableDiff } from '@codemirror/merge'
import CodeDiffViewer from './CodeDiffViewer'
import { toEditorCode } from './CodeBlockEditor'
const { Link, Text } = Typography
const SQUARE_COUNT = 10
const countLines = (str) => {
if (!str) return 0
const parts = str.split('\n')
if (parts[parts.length - 1] === '') parts.pop()
return Math.max(parts.length, 1)
}
export function getCodeDiffStats(oldCode, newCode, language = 'javascript') {
const oldText = toEditorCode(oldCode, language)
const newText = toEditorCode(newCode, language)
const changes = presentableDiff(oldText, newText)
let additions = 0
let deletions = 0
for (const change of changes) {
const deleted = oldText.slice(change.fromA, change.toA)
const added = newText.slice(change.fromB, change.toB)
if (deleted) deletions += countLines(deleted)
if (added) additions += countLines(added)
}
return { additions, deletions }
}
export default function DiffLabel({
oldCode = '',
newCode = '',
language = 'javascript'
}) {
const { token } = theme.useToken()
const [open, setOpen] = useState(false)
const [viewerReady, setViewerReady] = useState(false)
const { additions, deletions } = useMemo(
() => getCodeDiffStats(oldCode, newCode, language),
[oldCode, newCode, language]
)
const greenCount = Math.round(
(additions / (additions + deletions)) * SQUARE_COUNT
)
return (
<>
<Link
className='diff-label'
onClick={() => {
setOpen(true)
}}
>
<Flex gap='small' align='center' style={{ marginTop: 0.5 }}>
<Text style={{ color: token.colorSuccess }}>+{additions}</Text>
<Flex gap='4px' align='center' style={{ marginBottom: 2 }}>
{Array.from({ length: SQUARE_COUNT }).map((_, i) => (
<div
key={i}
className='diff-label-square'
style={{
backgroundColor:
i < greenCount ? token.colorSuccess : token.colorError
}}
/>
))}
</Flex>
<Text style={{ color: token.colorError }}>-{deletions}</Text>
</Flex>
</Link>
<Modal
closeIcon={false}
open={open}
width='90%'
destroyOnClose
afterOpenChange={setViewerReady}
onCancel={() => {
setOpen(false)
}}
footer={
<Button
onClick={() => {
setOpen(false)
}}
>
Close
</Button>
}
>
{viewerReady ? (
<CodeDiffViewer
oldCode={oldCode}
newCode={newCode}
language={language}
/>
) : null}
</Modal>
</>
)
}
DiffLabel.propTypes = {
oldCode: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
newCode: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
language: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string)
])
}

View File

@ -0,0 +1,108 @@
import { useLayoutEffect, useRef, useState } from 'react'
import PropTypes from 'prop-types'
import { Typography } from 'antd'
const { Text } = Typography
const childrenToString = (children) => {
if (children == null || typeof children === 'boolean') return ''
if (typeof children === 'string' || typeof children === 'number') {
return String(children)
}
if (Array.isArray(children)) {
return children.map(childrenToString).join('')
}
if (typeof children === 'object' && children.props) {
return childrenToString(children.props.children)
}
return ''
}
const splitMiddle = (text) => {
const mid = Math.ceil(text.length / 2)
return {
start: text.slice(0, mid),
end: text.slice(mid)
}
}
const ElipsisText = ({ children, style, className, title, code, ...rest }) => {
const text = childrenToString(children)
const { start, end } = splitMiddle(text)
const containerRef = useRef(null)
const measureRef = useRef(null)
const truncatedRef = useRef(false)
const [truncated, setTruncated] = useState(false)
useLayoutEffect(() => {
const container = containerRef.current
const measure = measureRef.current
if (!container || !measure) return
const update = () => {
const available = container.getBoundingClientRect().width
if (available < 1) return
const textWidth = measure.getBoundingClientRect().width
const next = Boolean(end) && textWidth > available
if (truncatedRef.current === next) return
truncatedRef.current = next
setTruncated(next)
}
update()
const frame = requestAnimationFrame(update)
const resizeObserver = new ResizeObserver(update)
resizeObserver.observe(container)
const intersectionObserver = new IntersectionObserver(update)
intersectionObserver.observe(container)
return () => {
cancelAnimationFrame(frame)
resizeObserver.disconnect()
intersectionObserver.disconnect()
}
}, [text, end])
const showTruncated = truncated && Boolean(end)
const RootTag = code ? 'code' : 'span'
return (
<Text
{...rest}
className={['elipsis-text-wrapper', className].filter(Boolean).join(' ')}
title={title ?? text}
style={style}
>
<span
className={showTruncated ? 'elipsis-text is-truncated' : 'elipsis-text'}
ref={containerRef}
>
<RootTag className='elipsis-text-measure' ref={measureRef}>
{text}
</RootTag>
<RootTag className='elipsis-text-full'>{text}</RootTag>
<RootTag className='elipsis-text-truncated'>
<span className='elipsis-text-start'>{start}</span>
<span className='elipsis-text-dots'>...</span>
<span className='elipsis-text-end'>
<span className='elipsis-text-end-inner'>{end}</span>
</span>
</RootTag>
</span>
</Text>
)
}
ElipsisText.propTypes = {
children: PropTypes.node,
style: PropTypes.object,
className: PropTypes.string,
title: PropTypes.string,
code: PropTypes.bool
}
export default ElipsisText

View File

@ -3,6 +3,7 @@ import { Typography, Flex, Button, Tooltip } from 'antd'
import NewMailIcon from '../../Icons/NewMailIcon'
// import CopyIcon from './CopyIcon'
import CopyButton from './CopyButton'
import ElipsisText from './ElipsisText'
const { Text, Link } = Typography
@ -18,9 +19,9 @@ const EmailDisplay = ({ email, showCopy = true, showLink = false }) => {
</Link>
) : (
<>
<Text style={{ marginRight: 8 }} ellipsis>
<ElipsisText style={{ marginRight: 8 }}>
{email}
</Text>
</ElipsisText>
<Tooltip title='Email' arrow={false}>
<Button
icon={<NewMailIcon />}

View File

@ -1,4 +1,4 @@
import { Card, Flex, Typography, Button, Tag, Divider } from 'antd'
import { Card, Flex, Button, Tag, Divider } from 'antd'
import PropTypes from 'prop-types'
import FileIcon from '../../Icons/FileIcon'
import BinIcon from '../../Icons/BinIcon'
@ -11,8 +11,7 @@ import EyeSlashIcon from '../../Icons/EyeSlashIcon'
import { getModelByName } from '../../../database/ObjectModels'
import InfoCircleIcon from '../../Icons/InfoCircleIcon'
import { useNavigate } from 'react-router-dom'
const { Text } = Typography
import ElipsisText from './ElipsisText'
const FileList = ({
files,
@ -87,15 +86,15 @@ const FileList = ({
<Flex
gap={'small'}
align='center'
style={{ minWidth: 0, flex: '0 1 auto', overflow: 'hidden' }}
style={{ minWidth: 0, flex: '1 1 auto', overflow: 'hidden' }}
>
<FileIcon
style={{ margin: 0, fontSize: card == true ? '24px' : '16px' }}
/>
<Text style={{ marginTop: '1px', minWidth: 0 }} ellipsis>
<ElipsisText style={{ marginTop: '1px', minWidth: 0 }}>
{file.name || file.filename || 'Unknown file'}
</Text>
</ElipsisText>
{file.extension && <Tag style={{ margin: 0 }}>{file.extension}</Tag>}
</Flex>
{!minimal && (

View File

@ -4,6 +4,7 @@ import { Flex, Typography, Popover } from 'antd'
import { useNavigate } from 'react-router-dom'
import { useMediaQuery } from 'react-responsive'
import CopyButton from './CopyButton'
import ElipsisText from './ElipsisText'
import SpotlightTooltip from './SpotlightTooltip'
import { getModelByName } from '../../../database/ObjectModels'
import { buildActionUrl } from '../../../utils/modelActions'
@ -68,13 +69,12 @@ const IdDisplay = ({
if (plainCode == false) {
textElement = (
<Text
<ElipsisText
code
ellipsis
style={showCopy ? { marginRight: 6, minWidth: '0px' } : undefined}
>
{displayId}
</Text>
</ElipsisText>
)
}
@ -83,8 +83,12 @@ const IdDisplay = ({
const linkElement = (
<Link
onClick={() => navigate(hyperlink)}
ellipsis
style={showCopy ? { marginRight: 6 } : undefined}
style={{
minWidth: 0,
maxWidth: '100%',
display: 'block',
...(showCopy ? { marginRight: 6 } : null)
}}
>
{textElement}
</Link>

View File

@ -1,6 +1,7 @@
import PropTypes from 'prop-types'
import { Flex, Typography } from 'antd'
import CopyButton from './CopyButton'
import ElipsisText from './ElipsisText'
const { Text } = Typography
@ -15,13 +16,12 @@ const MiscId = ({ value, showCopy = true }) => {
className='miscid'
style={{ minWidth: '0px', width: '100%' }}
>
<Text
<ElipsisText
code
ellipsis
style={showCopy ? { marginRight: 6, minWidth: '0px' } : undefined}
>
{value}
</Text>
</ElipsisText>
{showCopy && (
<CopyButton

View File

@ -71,7 +71,9 @@ const NoteItem = ({
setChildNotesLoading(true)
try {
const childNotesData = await fetchObjects('note', {
filter: { 'parent._id': note._id }
filter: {
parent: getModelByName('note').prefix + ':' + note._id
}
})
setChildNotes(childNotesData.data)
} catch (error) {
@ -105,7 +107,7 @@ const NoteItem = ({
if (isExpanded == true) {
subscribeToObjectTypeUpdatesRef.current = subscribeToObjectTypeUpdates(
'note',
{ 'parent._id': note._id },
{ parent: getModelByName('note').prefix + ':' + note._id },
() => {
if (isExpanded == true) {
handleNoteExpand()

View File

@ -19,6 +19,7 @@ import InfoCircleIcon from '../../Icons/InfoCircleIcon'
import ReloadIcon from '../../Icons/ReloadIcon'
import NewNote from '../Management/Notes/NewNote'
import NoteItem from './NoteItem'
import { getModelByName } from '../../../database/ObjectModels.js'
const { Text } = Typography
@ -40,14 +41,14 @@ const NotesPanel = ({ _id, type }) => {
const fetchData = useCallback(
async (id) => {
try {
const newData = await fetchNotes(id)
const newData = await fetchNotes(id, type)
return newData
} catch (error) {
setError(error)
return null
}
},
[fetchNotes]
[fetchNotes, type]
)
const generateNotes = useCallback(
@ -98,7 +99,7 @@ const NotesPanel = ({ _id, type }) => {
if (connected == true && subscribeToObjectTypeUpdatesRef.current == null) {
subscribeToObjectTypeUpdatesRef.current = subscribeToObjectTypeUpdates(
'note',
{ 'parent._id': _id },
{ parent: getModelByName(type).prefix + ':' + _id },
() => handleReloadData()
)
}

View File

@ -23,6 +23,7 @@ import ExclamationOctagonIcon from '../../Icons/ExclamationOctagonIcon'
import CheckCircleIcon from '../../Icons/CheckCircleIcon'
import BellIcon from '../../Icons/BellIcon'
import { getModelByName } from '../../../database/ObjectModels'
import ElipsisText from './ElipsisText'
const { Text, Paragraph } = Typography
@ -361,13 +362,12 @@ const Notification = ({
{inlineIcon &&
getNotificationIcon(notification.type, notification.metadata)}
<Text
<ElipsisText
strong={!notification.read}
ellipsis
style={{ minWidth: 0 }}
>
{notification.title}
</Text>
</ElipsisText>
</Flex>
<Flex align='center' gap='5px' style={{ marginLeft: 10 }}>
{showDetails && (

View File

@ -9,6 +9,7 @@ import { ApiServerContext } from '../context/ApiServerContext'
import { AuthContext } from '../context/AuthContext'
import merge from 'lodash/merge'
import IdDisplay from './IdDisplay'
import ElipsisText from './ElipsisText'
import SpotlightTooltip from './SpotlightTooltip'
import StateTag from './StateTag'
@ -183,13 +184,7 @@ const ObjectDisplay = ({
const objectId = getStringId(objectData)
if (defaultModelActions.length >= 1 && objectId) {
hyperlink = buildActionUrl(
model,
defaultModelActions[0],
objectId,
'',
''
)
hyperlink = buildActionUrl(model, defaultModelActions[0], objectId, '', '')
}
// Render name with hyperlink/spotlight support
@ -197,9 +192,9 @@ const ObjectDisplay = ({
if (!objectData?.name) return null
const textElement = (
<Text ellipsis style={{ lineHeight: '1', paddingBottom: '2px' }}>
<ElipsisText style={{ lineHeight: '1', paddingBottom: '2px' }}>
{objectData.name}
</Text>
</ElipsisText>
)
// If hyperlink is enabled
@ -268,7 +263,7 @@ const ObjectDisplay = ({
style={{ minWidth: 0, height: '24px' }}
>
<Icon />
<Flex gap={'small'} align='center' style={{ minWidth: 0 }}>
<Flex gap={'small'} align='center' style={{ minWidth: 0, flex: 1 }}>
{objectData?.color ? (
<Badge
color={objectData?.color}
@ -282,7 +277,7 @@ const ObjectDisplay = ({
style={{ marginBottom: '1.5px' }}
/>
) : null}
<div style={{ minWidth: 0 }}>
<div style={{ minWidth: 0, flex: 1, overflow: 'hidden' }}>
{renderNameDisplay()}
{objectId && !objectData?.name ? (

View File

@ -51,6 +51,7 @@ import MiscId from './MiscId'
import AddressDisplay from './AddressDisplay'
import ArrayDisplay from './ArrayDisplay'
import ArrayInput from './ArrayInput'
import ElipsisText from './ElipsisText'
import { round } from '../utils/Utils'
const { Text } = Typography
@ -378,11 +379,11 @@ const ObjectProperty = ({
case 'text':
if (value != null && value != '') {
return (
<Text ellipsis style={style}>
<ElipsisText style={style}>
{prefix}
{getTextValue(value)}
{suffix}
</Text>
</ElipsisText>
)
} else {
return (

View File

@ -1,7 +1,11 @@
import PropTypes from 'prop-types'
import { Descriptions, Typography, Flex } from 'antd'
import { getModelProperty } from '../../../database/ObjectModels'
import {
getModelProperty,
getPropertyValue
} from '../../../database/ObjectModels'
import ObjectProperty from './ObjectProperty'
import DiffLabel from './DiffLabel'
import ArrowRightIcon from '../../Icons/ArrowRightIcon'
const { Text } = Typography
@ -51,6 +55,17 @@ const PropertyChanges = ({ type, value }) => {
if (!changeProperty) {
return null
}
const oldValue = getPropertyValue(value?.old, key)
const newValue = getPropertyValue(value?.new, key)
const isCodeKey = key === 'code' || changeProperty.type === 'codeBlock'
const isCodeEdit =
isCodeKey &&
oldValue != null &&
oldValue !== '' &&
newValue != null &&
newValue !== ''
return (
<Descriptions.Item key={key} label={changeProperty.label}>
<Flex
@ -58,31 +73,41 @@ const PropertyChanges = ({ type, value }) => {
style={{ minWidth: 0, width: '100%' }}
className='property-changes'
>
{value?.old ? (
<ObjectProperty
{...changeProperty}
longId={false}
minimal={true}
showPreview={false}
objectData={value?.old}
maxWidth='200px'
{isCodeEdit ? (
<DiffLabel
oldCode={oldValue}
newCode={newValue}
language={changeProperty.language}
/>
) : null}
{value?.old && value?.new ? (
<Text type='secondary'>
<ArrowRightIcon />
</Text>
) : null}
{value?.new ? (
<ObjectProperty
{...changeProperty}
longId={false}
minimal={true}
showPreview={false}
objectData={value?.new}
maxWidth='200px'
/>
) : null}
) : (
<>
{value?.old ? (
<ObjectProperty
{...changeProperty}
longId={false}
minimal={true}
showPreview={false}
objectData={value?.old}
maxWidth='200px'
/>
) : null}
{value?.old && value?.new ? (
<Text type='secondary'>
<ArrowRightIcon />
</Text>
) : null}
{value?.new ? (
<ObjectProperty
{...changeProperty}
longId={false}
minimal={true}
showPreview={false}
objectData={value?.new}
maxWidth='200px'
/>
) : null}
</>
)}
</Flex>
</Descriptions.Item>
)

View File

@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
import { Typography, Flex, Button, Tooltip } from 'antd'
import LinkIcon from '../../Icons/LinkIcon'
import CopyButton from './CopyButton'
import ElipsisText from './ElipsisText'
const { Text, Link } = Typography
@ -24,15 +25,15 @@ const UrlDisplay = ({ url, showCopy = true, showLink = false }) => {
width: 0
}}
>
<Text ellipsis style={{ display: 'block' }}>
<ElipsisText style={{ display: 'block' }}>
{url}
</Text>
</ElipsisText>
</Link>
) : (
<>
<Text style={{ marginRight: 8, minWidth: 0 }} ellipsis>
<ElipsisText style={{ marginRight: 8, minWidth: 0 }}>
{url}
</Text>
</ElipsisText>
<Tooltip title='Open URL' arrow={false}>
<Button
icon={<LinkIcon />}

View File

@ -8,6 +8,7 @@ import { User } from '../../../database/models/User'
import { buildActionUrl } from '../../../utils/modelActions'
import { AuthContext } from '../context/AuthContext'
import ObjectActions from './ObjectActions'
import ElipsisText from './ElipsisText'
const { Text } = Typography
@ -89,13 +90,12 @@ const UserProfilePopover = ({ onClose }) => {
)}
<Flex vertical style={{ minWidth: 0 }}>
{fullName && (
<Text
<ElipsisText
strong
ellipsis
style={{ fontSize: 18, lineHeight: 1, marginTop: 1 }}
>
{fullName}
</Text>
</ElipsisText>
)}
{email && (
<Space>
@ -106,13 +106,12 @@ const UserProfilePopover = ({ onClose }) => {
>
@{username}
</Text>
<Text
<ElipsisText
type='secondary'
ellipsis
style={{ fontSize: 12, lineHeight: 1 }}
>
{email}
</Text>
</ElipsisText>
</Space>
)}
{!username && !fullName && !email && (

View File

@ -16,6 +16,7 @@ import {
buildActionUrl,
stripActionParams
} from '../../../utils/modelActions'
import ElipsisText from '../common/ElipsisText'
const ActionsModalContext = createContext()
@ -291,15 +292,14 @@ const ActionsModalProvider = ({ children }) => {
>
{Icon ? <Icon style={{ fontSize: '18px' }} /> : null}
<Flex vertical style={{ flexGrow: 1, minWidth: 0 }}>
<Text
ellipsis
<ElipsisText
style={{
maxWidth: 320,
width: '100%'
}}
>
{action.fullLabel || action.label || action.name}
</Text>
</ElipsisText>
</Flex>
</Flex>
<Flex gap='small' align='center'>

View File

@ -1543,12 +1543,12 @@ const ApiServerProvider = ({ children }) => {
}
// Fetch notes for a specific parent
const fetchNotes = async (parentId) => {
logger.debug('Fetching notes for parent:', parentId)
const fetchNotes = async (parentId, parentType) => {
logger.debug('Fetching notes for parent:', parentId, parentType)
try {
const response = await axios.get(`${config.backendUrl}/notes`, {
params: {
'parent._id': parentId,
parent: getModelByName(parentType).prefix + ':' + parentId,
sort: 'createdAt',
order: 'ascend'
},
@ -1564,7 +1564,7 @@ const ApiServerProvider = ({ children }) => {
} catch (err) {
console.error(err)
showError(err, () => {
fetchNotes(parentId)
fetchNotes(parentId, parentType)
})
}
}

View File

@ -26,6 +26,7 @@ import PropTypes from 'prop-types'
import { useNavigate } from 'react-router-dom'
import StateDisplay from '../common/StateDisplay'
import IdDisplay from '../common/IdDisplay'
import ElipsisText from '../common/ElipsisText'
import config from '../../../config'
import {
@ -501,8 +502,7 @@ const SpotlightContent = ({
{Icon ? <Icon style={{ fontSize: '20px' }} /> : null}
{item.name ? (
<Text
ellipsis
<ElipsisText
style={{
maxWidth: 170,
flexGrow: 1,
@ -510,7 +510,7 @@ const SpotlightContent = ({
}}
>
{item.name}
</Text>
</ElipsisText>
) : null}
{item?.state ? (
<StateDisplay

View File

@ -97,7 +97,6 @@ export const AppPassword = {
'name',
'user',
'active',
'user._id',
'createdAt',
'updatedAt',
'_reference'

View File

@ -17,8 +17,8 @@ export const AuditLog = {
'createdAt'
],
filters: [
'parent._id',
'owner._id',
'parent',
'owner',
'operation',
'createdAt',
'updatedAt',

View File

@ -89,7 +89,6 @@ export const CourierService = {
filters: [
'_id',
'courier',
'courier._id',
'name',
'active',
'tracked',

View File

@ -110,7 +110,6 @@ export const Filament = {
filters: [
'_id',
'material',
'material._id',
'diameter',
'name',
'cost',

View File

@ -90,7 +90,6 @@ export const FilamentSku = {
'_id',
'barcode',
'filament',
'filament._id',
'name',
'color',
'cost',

View File

@ -45,14 +45,11 @@ export const FilamentStock = {
],
filters: [
'filament',
'filament._id',
'filamentSku',
'state',
'startingWeight',
'currentWeight',
'filamentSku._id',
'stockLocation',
'stockLocation._id',
'createdAt',
'updatedAt',
'_reference'

View File

@ -101,9 +101,7 @@ export const GCodeFile = {
'_id',
'name',
'filament',
'filament._id',
'filamentSku',
'filamentSku._id',
'createdAt',
'updatedAt',
'_reference'

View File

@ -166,10 +166,7 @@ export const Invoice = {
'vendor',
'client',
'state',
'vendor._id',
'client._id',
'order',
'order._id',
'orderType',
'createdAt',
'updatedAt',

View File

@ -122,7 +122,6 @@ export const ListingVarient = {
],
filters: [
'listing',
'listing._id',
'product',
'productSku',
'state',

View File

@ -56,12 +56,10 @@ export const Note = {
filters: [
'_id',
'user',
'user._id',
'parentType',
'parent',
'parent._id',
'parent',
'noteType',
'noteType._id',
'createdAt',
'updatedAt',
'_reference'

View File

@ -87,12 +87,9 @@ export const OrderItem = {
'name',
'itemType',
'item',
'item._id',
'order',
'order._id',
'orderType',
'shipment',
'shipment._id',
'state',
'createdAt',
'updatedAt',

View File

@ -92,7 +92,6 @@ export const PartSku = {
'_id',
'barcode',
'part',
'part._id',
'name',
'cost',
'price',

View File

@ -36,9 +36,7 @@ export const PartStock = {
'state',
'startingQuantity',
'currentQuantity',
'partSku._id',
'stockLocation',
'stockLocation._id',
'createdAt',
'updatedAt',
'_reference'

View File

@ -163,10 +163,7 @@ export const Payment = {
'vendor',
'client',
'state',
'vendor._id',
'client._id',
'invoice',
'invoice._id',
'createdAt',
'updatedAt',
'_reference'

View File

@ -102,7 +102,6 @@ export const Product = {
'name',
'globalPrice',
'productCategory',
'productCategory._id',
'createdAt',
'updatedAt',
'_reference'

View File

@ -92,7 +92,6 @@ export const ProductSku = {
'_id',
'barcode',
'product',
'product._id',
'name',
'cost',
'price',

View File

@ -7,6 +7,7 @@ const PostProductStock = lazy(
() => import('../../components/Dashboard/Inventory/ProductStocks/PostProductStock')
)
import ProductStockIcon from '../../components/Icons/ProductStockIcon'
import { getModelByName } from '../ObjectModels.js'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
@ -103,9 +104,7 @@ export const ProductStock = {
'productSku',
'state',
'currentQuantity',
'productSku._id',
'stockLocation',
'stockLocation._id',
'createdAt',
'updatedAt',
'_reference'
@ -227,7 +226,9 @@ export const ProductStock = {
masterFilter: (objectData) => {
const partSkuId = objectData?.partSku?._id
if (partSkuId == null) return {}
return { 'partSku._id': partSkuId }
return {
partSku: getModelByName('partSku').prefix + ':' + partSkuId
}
}
},
{

View File

@ -231,7 +231,6 @@ export const PurchaseOrder = {
'vendor',
'state',
'value',
'vendor._id',
'totalAmount',
'totalAmountWithTax',
'totalTaxAmount',

View File

@ -238,7 +238,6 @@ export const SalesOrder = {
'client',
'state',
'value',
'client._id',
'createdAt',
'updatedAt',
'_reference'

View File

@ -147,7 +147,6 @@ export const Shipment = {
'order',
'state',
'courierService',
'order._id',
'taxRate',
'createdAt',
'updatedAt',

View File

@ -9,14 +9,8 @@ export const StockEvent = {
icon: StockEventIcon,
actions: [],
columns: ['_reference', 'owner', 'parent', 'value', 'createdAt', 'updatedAt'],
filters: [
'owner._id',
'parent._id',
'createdAt',
'updatedAt',
'_reference'
],
sorters: ['createdAt','updatedAt'],
filters: ['owner', 'parent', 'createdAt', 'updatedAt', '_reference'],
sorters: ['createdAt', 'updatedAt'],
properties: [
{
name: '_id',