Refactor modal behavior across multiple components to use 'destroyOnHidden' instead of 'destroyOnClose' for improved resource management. This change applies to AppPasswordInfo, FilamentInfo, PartInfo, ProductInfo, UserInfo, MarketplaceInfo, and ExportListButton components.
This commit is contained in:
parent
899444e815
commit
634be89698
@ -191,7 +191,7 @@ const AppPasswordInfo = () => {
|
||||
|
||||
<Modal
|
||||
open={regenerateSecretOpen}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
width={650}
|
||||
onCancel={() => {
|
||||
actionHandlerRef.current?.clearAction?.()
|
||||
|
||||
@ -229,7 +229,7 @@ const FilamentInfo = () => {
|
||||
footer={null}
|
||||
width={700}
|
||||
onCancel={() => setNewFilamentSkuOpen(false)}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
>
|
||||
<NewFilamentSku
|
||||
onOk={() => {
|
||||
|
||||
@ -184,7 +184,7 @@ const PartInfo = () => {
|
||||
footer={null}
|
||||
width={700}
|
||||
onCancel={() => setNewPartSkuOpen(false)}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
>
|
||||
<NewPartSku
|
||||
onOk={() => {
|
||||
|
||||
@ -188,7 +188,7 @@ const ProductInfo = () => {
|
||||
footer={null}
|
||||
width={700}
|
||||
onCancel={() => setNewProductSkuOpen(false)}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
>
|
||||
<NewProductSku
|
||||
onOk={() => {
|
||||
|
||||
@ -239,7 +239,7 @@ const UserInfo = () => {
|
||||
|
||||
<Modal
|
||||
open={newAppPasswordOpen}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
width={700}
|
||||
onCancel={() => {
|
||||
actionHandlerRef.current?.clearAction?.()
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Space, Flex, Card } from 'antd'
|
||||
import { Space, Flex, Card, Button, Modal } from 'antd'
|
||||
import NewPrinterProfile, {
|
||||
EditPrinterProfile
|
||||
} from '../PrinterProfiles/NewPrinterProfile'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
import loglevel from 'loglevel'
|
||||
import config from '../../../../config.js'
|
||||
@ -22,17 +25,20 @@ 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 PlusIcon from '../../../Icons/PlusIcon.jsx'
|
||||
import PrinterProfileIcon from '../../../Icons/PrinterProfileIcon.jsx'
|
||||
const log = loglevel.getLogger('PrinterInfo')
|
||||
log.setLevel(config.logLevel)
|
||||
|
||||
const PrinterInfo = () => {
|
||||
const location = useLocation()
|
||||
const objectFormRef = useRef(null)
|
||||
const profilesTableRef = useRef(null)
|
||||
const actionHandlerRef = useRef(null)
|
||||
const printerId = new URLSearchParams(location.search).get('printerId')
|
||||
const [collapseState, updateCollapseState] = useCollapseState('PrinterInfo', {
|
||||
info: true,
|
||||
profiles: true,
|
||||
stocks: true,
|
||||
notes: true,
|
||||
auditLogs: false
|
||||
@ -46,6 +52,15 @@ const PrinterInfo = () => {
|
||||
loading: false,
|
||||
objectData: {}
|
||||
})
|
||||
const [profileModal, setProfileModal] = useState({
|
||||
open: false,
|
||||
profileId: null
|
||||
})
|
||||
|
||||
const handleProfileSaved = () => {
|
||||
setProfileModal({ open: false, profileId: null })
|
||||
profilesTableRef.current?.reload()
|
||||
}
|
||||
|
||||
const actions = {
|
||||
edit: () => {
|
||||
@ -85,6 +100,7 @@ const PrinterInfo = () => {
|
||||
disabled={objectFormState.loading}
|
||||
items={[
|
||||
{ key: 'info', label: 'Printer Information' },
|
||||
{ key: 'profiles', label: 'Printer Profiles' },
|
||||
{ key: 'notes', label: 'Notes' },
|
||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||
]}
|
||||
@ -147,31 +163,73 @@ const PrinterInfo = () => {
|
||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||
}}
|
||||
>
|
||||
{({ loading, isEditing, objectData }) => {
|
||||
return (
|
||||
<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
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
{({ 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
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</ObjectForm>
|
||||
</InfoCollapse>
|
||||
</ActionHandler>
|
||||
|
||||
<InfoCollapse
|
||||
title='Printer Profiles'
|
||||
icon={<PrinterProfileIcon />}
|
||||
active={collapseState.profiles}
|
||||
onToggle={(expanded) => updateCollapseState('profiles', expanded)}
|
||||
collapseKey='profiles'
|
||||
>
|
||||
{objectFormState.loading ? (
|
||||
<InfoCollapsePlaceholder />
|
||||
) : (
|
||||
<Flex vertical gap='middle'>
|
||||
<Flex>
|
||||
<Button
|
||||
icon={<PlusIcon />}
|
||||
onClick={() =>
|
||||
setProfileModal({ open: true, profileId: null })
|
||||
}
|
||||
>
|
||||
New Printer Profile
|
||||
</Button>
|
||||
</Flex>
|
||||
<ObjectTable
|
||||
ref={profilesTableRef}
|
||||
type='printerProfile'
|
||||
masterFilter={{ printer: printerId }}
|
||||
visibleColumns={{
|
||||
printer: false,
|
||||
'printer._id': false
|
||||
}}
|
||||
onRowAction={(action, profile) => {
|
||||
if (action.name === 'edit') {
|
||||
setProfileModal({
|
||||
open: true,
|
||||
profileId: profile._id
|
||||
})
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
</InfoCollapse>
|
||||
|
||||
<InfoCollapse
|
||||
title='Notes'
|
||||
icon={<NoteIcon />}
|
||||
@ -206,6 +264,27 @@ const PrinterInfo = () => {
|
||||
</Flex>
|
||||
</ScrollBox>
|
||||
</Flex>
|
||||
<Modal
|
||||
open={profileModal.open}
|
||||
footer={null}
|
||||
width={1000}
|
||||
onCancel={() => setProfileModal({ open: false, profileId: null })}
|
||||
destroyOnHidden
|
||||
>
|
||||
{profileModal.open &&
|
||||
(profileModal.profileId ? (
|
||||
<EditPrinterProfile
|
||||
profileId={profileModal.profileId}
|
||||
printerId={printerId}
|
||||
onOk={handleProfileSaved}
|
||||
/>
|
||||
) : (
|
||||
<NewPrinterProfile
|
||||
printerId={printerId}
|
||||
onOk={handleProfileSaved}
|
||||
/>
|
||||
))}
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -285,7 +285,7 @@ const MarketplaceInfo = () => {
|
||||
onCancel={() => setSyncListingsOpen(false)}
|
||||
width={500}
|
||||
footer={null}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
centered
|
||||
>
|
||||
<SyncListings
|
||||
@ -301,7 +301,7 @@ const MarketplaceInfo = () => {
|
||||
onCancel={() => setSyncOrdersOpen(false)}
|
||||
width={500}
|
||||
footer={null}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
centered
|
||||
>
|
||||
<SyncOrders
|
||||
@ -317,7 +317,7 @@ const MarketplaceInfo = () => {
|
||||
onCancel={() => setConfigureModalOpen(false)}
|
||||
width={650}
|
||||
footer={null}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
centered
|
||||
>
|
||||
<ConfigureMarketplace
|
||||
|
||||
@ -105,7 +105,7 @@ const ExportListButton = ({
|
||||
</Dropdown>
|
||||
<Modal
|
||||
open={odataModalOpen}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
width={650}
|
||||
onCancel={() => setOdataModalOpen(false)}
|
||||
footer={null}
|
||||
@ -114,7 +114,7 @@ const ExportListButton = ({
|
||||
</Modal>
|
||||
<Modal
|
||||
open={rssModalOpen}
|
||||
destroyOnClose
|
||||
destroyOnHidden={true}
|
||||
width={750}
|
||||
onCancel={() => setRssModalOpen(false)}
|
||||
footer={null}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Typography, Button, Tag, Badge, Flex, Card, Divider } from 'antd'
|
||||
import {
|
||||
@ -31,6 +31,10 @@ const Notification = ({
|
||||
}) => {
|
||||
const [deleting, setDeleting] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
console.log('notificationData', JSON.stringify(notification))
|
||||
}, [notification])
|
||||
|
||||
const getNotificationIcon = (type) => {
|
||||
switch (type) {
|
||||
case 'info':
|
||||
@ -220,7 +224,7 @@ const Notification = ({
|
||||
{showExtraInfo && (
|
||||
<>
|
||||
<Divider style={{ margin: largeSpacing ? '10px 0' : 0 }} />
|
||||
<Flex justify='space-between' align='center'>
|
||||
<Flex ju stify='space-between' align='center'>
|
||||
{getNotificationTag(notification.type)}
|
||||
<TimeDisplay
|
||||
dateTime={notification.createdAt}
|
||||
|
||||
@ -47,17 +47,20 @@ const ObjectDisplay = ({
|
||||
}, [])
|
||||
|
||||
// Detect minimal objects that only contain an _id (must be string, not populated object)
|
||||
const isMinimalObject = useCallback((obj) => {
|
||||
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return false
|
||||
const keys = Object.keys(obj)
|
||||
const id = obj._id
|
||||
return (
|
||||
keys.length === 1 &&
|
||||
keys[0] === '_id' &&
|
||||
typeof id === 'string' &&
|
||||
isValidId(id)
|
||||
)
|
||||
}, [isValidId])
|
||||
const isMinimalObject = useCallback(
|
||||
(obj) => {
|
||||
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return false
|
||||
const keys = Object.keys(obj)
|
||||
const id = obj._id
|
||||
return (
|
||||
keys.length === 1 &&
|
||||
keys[0] === '_id' &&
|
||||
typeof id === 'string' &&
|
||||
isValidId(id)
|
||||
)
|
||||
},
|
||||
[isValidId]
|
||||
)
|
||||
|
||||
// If only an _id is provided, fetch the full object via spotlight
|
||||
const fetchFullObjectIfNeeded = useCallback(
|
||||
@ -131,7 +134,14 @@ const ObjectDisplay = ({
|
||||
cancelled = true
|
||||
setIsHydrating(false)
|
||||
}
|
||||
}, [object, fetchFullObjectIfNeeded, isMinimalObject, isValidId, getStringId, token])
|
||||
}, [
|
||||
object,
|
||||
fetchFullObjectIfNeeded,
|
||||
isMinimalObject,
|
||||
isValidId,
|
||||
getStringId,
|
||||
token
|
||||
])
|
||||
if (!objectData) {
|
||||
return <Text type='secondary'>n/a</Text>
|
||||
}
|
||||
|
||||
@ -43,8 +43,6 @@ const PropertyChanges = ({ type, value }) => {
|
||||
...flatNew
|
||||
}
|
||||
|
||||
console.log(combinedChanges)
|
||||
|
||||
return (
|
||||
<Descriptions size='small' column={1}>
|
||||
{Object.keys(combinedChanges).map((key) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user