Compare commits

..

No commits in common. "7833b1dbcec83c4ffc0868f2f9459e69b776431c" and "f9ac30026762e96163bb04c6a933b19822bb9b66" have entirely different histories.

4 changed files with 181 additions and 312 deletions

View File

@ -5,7 +5,8 @@ import { Button, Flex, Modal, Typography, theme, Divider } from 'antd'
import CloudIcon from '../../../Icons/CloudIcon' import CloudIcon from '../../../Icons/CloudIcon'
import HostIcon from '../../../Icons/HostIcon' import HostIcon from '../../../Icons/HostIcon'
import ReloadIcon from '../../../Icons/ReloadIcon' import ReloadIcon from '../../../Icons/ReloadIcon'
import ProgressDisplay from '../../common/ProgressDisplay' import HProgress from '../../common/HProgress'
import ElipsisText from '../../common/ElipsisText'
import CheckCircleIcon from '../../../Icons/CheckCircleIcon' import CheckCircleIcon from '../../../Icons/CheckCircleIcon'
import XMarkCircleIcon from '../../../Icons/XMarkCircleIcon' import XMarkCircleIcon from '../../../Icons/XMarkCircleIcon'
@ -135,16 +136,19 @@ const UpdateStage = ({ stage, status, percent, detail }) => {
<Flex align='start' gap='24px' style={{ flex: 1, minWidth: 0 }}> <Flex align='start' gap='24px' style={{ flex: 1, minWidth: 0 }}>
<Text style={{ flexShrink: 0 }}>{config.labels[status]}</Text> <Text style={{ flexShrink: 0 }}>{config.labels[status]}</Text>
{showProgress && ( {showProgress && (
<ProgressDisplay <Flex vertical gap={2} style={{ flex: 1, minWidth: 0 }}>
labelPosition='bottom' <HProgress
labelType='secondary' percent={resolvedPercent}
percent={resolvedPercent} status={getProgressStatus(status)}
status={getProgressStatus(status)} showInfo={typeof resolvedPercent === 'number'}
showInfo={typeof resolvedPercent === 'number'} style={{ flex: 1, margin: 0 }}
style={{ flex: 1 }} />
> {detail && (
{detail} <ElipsisText type='secondary' style={{ minWidth: 0 }}>
</ProgressDisplay> {detail}
</ElipsisText>
)}
</Flex>
)} )}
</Flex> </Flex>
</Flex> </Flex>

View File

@ -3,72 +3,14 @@ import ObjectInfo from '../../common/ObjectInfo'
import NewObjectForm from '../../common/NewObjectForm' import NewObjectForm from '../../common/NewObjectForm'
import WizardView from '../../common/WizardView' import WizardView from '../../common/WizardView'
import TemplatePreview from '../../common/TemplatePreview' import TemplatePreview from '../../common/TemplatePreview'
import ProgressDisplay from '../../common/ProgressDisplay'
import { ApiServerContext } from '../../context/ApiServerContext' import { ApiServerContext } from '../../context/ApiServerContext'
import { useCallback, useContext, useEffect, useRef, useState } from 'react' import { useContext, useRef, useState } from 'react'
import { Modal } from 'antd'
import dayjs from 'dayjs' import dayjs from 'dayjs'
const NewDocumentJob = ({ onOk, defaultValues = {} }) => { const NewDocumentJob = ({ onOk, defaultValues = {} }) => {
const { const { sendObjectAction, downloadTemplate, formatFileName } =
sendObjectAction, useContext(ApiServerContext)
downloadTemplate,
formatFileName,
subscribeToObjectUpdates,
connected
} = useContext(ApiServerContext)
const [downloading, setDownloading] = useState(false) const [downloading, setDownloading] = useState(false)
const [deployingJob, setDeployingJob] = useState(null)
const onOkRef = useRef(onOk)
const pendingJobRef = useRef(null)
const deploySentRef = useRef(false)
const sendObjectActionRef = useRef(sendObjectAction)
onOkRef.current = onOk
sendObjectActionRef.current = sendObjectAction
const deployingJobId = deployingJob?._id
? String(deployingJob._id).toLowerCase()
: null
const handleJobUpdate = useCallback((updatedJob) => {
setDeployingJob((prev) => (prev ? { ...prev, ...updatedJob } : updatedJob))
}, [])
useEffect(() => {
if (!deployingJobId || connected != true) {
return
}
const unsubscribe = subscribeToObjectUpdates(
deployingJobId,
'documentJob',
handleJobUpdate
)
if (!deploySentRef.current && pendingJobRef.current) {
deploySentRef.current = true
sendObjectActionRef.current(
pendingJobRef.current.documentPrinter._id,
'documentPrinter',
{
type: 'deploy',
data: pendingJobRef.current
}
)
}
return () => {
if (unsubscribe) unsubscribe()
}
}, [deployingJobId, connected, subscribeToObjectUpdates, handleJobUpdate])
useEffect(() => {
const stateType = deployingJob?.state?.type
if (stateType === 'queued' || stateType === 'error') {
onOkRef.current?.()
}
}, [deployingJob?.state?.type])
// Capture initial default values so later prop changes don't re-initialize the form // Capture initial default values so later prop changes don't re-initialize the form
const defaultValuesRef = useRef({ const defaultValuesRef = useRef({
@ -78,175 +20,154 @@ const NewDocumentJob = ({ onOk, defaultValues = {} }) => {
}) })
return ( return (
<> <NewObjectForm
<NewObjectForm type={'documentJob'}
type={'documentJob'} defaultValues={defaultValuesRef.current}
defaultValues={defaultValuesRef.current} >
> {({ handleSubmit, submitLoading, objectData, formValid }) => {
{({ handleSubmit, submitLoading, objectData, formValid }) => { const steps = [
const steps = [ {
{ title: 'Required',
title: 'Required', key: 'required',
key: 'required', content: (
content: ( <ObjectInfo
<ObjectInfo type='documentJob'
type='documentJob' column={1}
column={1} visibleProperties={{ name: false }}
visibleProperties={{ name: false }} bordered={false}
bordered={false} labelWidth={115}
labelWidth={115} isEditing={true}
isEditing={true} required={true}
required={true} objectData={objectData}
objectData={objectData} />
/> )
)
}
]
const fileName =
formatFileName(
objectData?.name + ' ' + dayjs().format('YYYY-MM-DD HH:mm:ss')
) || 'document'
return (
<WizardView
steps={steps}
submitText='Print'
title={'Print Document'}
formValid={formValid}
loading={submitLoading}
disabled={downloading}
sideBarGrow={true}
sideBar={
<div
style={{
height: 'calc(100vh - 240px)',
flexGrow: 1,
minWidth: 0
}}
>
<TemplatePreview
objectData={objectData?.object}
documentTemplate={objectData?.documentTemplate}
/>
</div>
}
onSubmit={async () => {
const newDocumentJob = await handleSubmit()
if (!newDocumentJob?._id) {
return
}
pendingJobRef.current = newDocumentJob
deploySentRef.current = false
setDeployingJob({
...newDocumentJob,
state: { type: 'deploying', progress: 0 }
})
}}
actions={[
{
label: 'Download',
steps: ['required'],
loading: downloading == true,
disabled: downloading == true || submitLoading == true,
children: [
{
label: 'PDF',
key: 'pdf',
onClick: () => {
setDownloading(true)
downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
'pdf',
() => {
setDownloading(false)
}
)
}
},
{
label: 'PNG',
key: 'png',
onClick: () => {
setDownloading(true)
downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
'png',
() => {
setDownloading(false)
}
)
}
},
{
label: 'JPEG',
key: 'jpeg',
onClick: () => {
setDownloading(true)
downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
'jpeg',
() => {
setDownloading(false)
}
)
}
},
{
label: 'SVG',
key: 'svg',
onClick: () => {
setDownloading(true)
downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
'svg',
() => {
setDownloading(false)
}
)
}
}
]
}
]}
/>
)
}}
</NewObjectForm>
<Modal
open={Boolean(deployingJob)}
footer={null}
closable={false}
maskClosable={false}
centered
destroyOnHidden={true}
zIndex={2000}
width={320}
getContainer={() => document.body}
>
<ProgressDisplay
percent={Math.round(
(Number(deployingJob?.state?.progress) || 0) * 100
)}
status={
deployingJob?.state?.type === 'error' ? 'exception' : 'active'
} }
> ]
Please wait... const fileName =
</ProgressDisplay> formatFileName(
</Modal> objectData?.name + ' ' + dayjs().format('YYYY-MM-DD HH:mm:ss')
</> ) || 'document'
return (
<WizardView
steps={steps}
submitText='Print'
title={'Print Document'}
formValid={formValid}
loading={submitLoading}
disabled={downloading}
sideBarGrow={true}
sideBar={
<div
style={{
height: 'calc(100vh - 240px)',
flexGrow: 1,
minWidth: 0
}}
>
<TemplatePreview
objectData={objectData?.object}
documentTemplate={objectData?.documentTemplate}
/>
</div>
}
onSubmit={async () => {
const newDocumentJob = await handleSubmit()
if (newDocumentJob) {
await sendObjectAction(
newDocumentJob.documentPrinter._id,
'documentPrinter',
{
type: 'deploy',
data: newDocumentJob
}
)
if (onOk) {
onOk()
}
}
}}
actions={[
{
label: 'Download',
steps: ['required'],
loading: downloading == true,
disabled: downloading == true || submitLoading == true,
children: [
{
label: 'PDF',
key: 'pdf',
onClick: () => {
setDownloading(true)
downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
'pdf',
() => {
setDownloading(false)
}
)
}
},
{
label: 'PNG',
key: 'png',
onClick: () => {
setDownloading(true)
downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
'png',
() => {
setDownloading(false)
}
)
}
},
{
label: 'JPEG',
key: 'jpeg',
onClick: () => {
setDownloading(true)
downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
'jpeg',
() => {
setDownloading(false)
}
)
}
},
{
label: 'SVG',
key: 'svg',
onClick: () => {
setDownloading(true)
downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
'svg',
() => {
setDownloading(false)
}
)
}
}
]
}
]}
/>
)
}}
</NewObjectForm>
) )
} }

View File

@ -1,61 +0,0 @@
import PropTypes from 'prop-types'
import { Flex } from 'antd'
import HProgress from './HProgress'
import ElipsisText from './ElipsisText'
const ProgressDisplay = ({
children,
labelPosition = 'top',
labelType,
percent,
status,
showInfo,
style
}) => {
const label = children ? (
<ElipsisText type={labelType} style={{ width: '100%', minWidth: 0 }}>
{children}
</ElipsisText>
) : null
const progress = (
<HProgress
percent={percent}
status={status}
showInfo={showInfo}
style={{ flex: 1, margin: 0 }}
/>
)
return (
<Flex
vertical
gap={labelPosition === 'bottom' ? 2 : 10}
style={{ width: '100%', minWidth: 0, ...style }}
>
{labelPosition === 'bottom' ? (
<>
{progress}
{label}
</>
) : (
<>
{label}
{progress}
</>
)}
</Flex>
)
}
ProgressDisplay.propTypes = {
children: PropTypes.node,
labelPosition: PropTypes.oneOf(['top', 'bottom']),
labelType: PropTypes.oneOf(['secondary']),
percent: PropTypes.number,
status: PropTypes.oneOf(['normal', 'exception', 'active', 'success']),
showInfo: PropTypes.bool,
style: PropTypes.object
}
export default ProgressDisplay

View File

@ -7,7 +7,7 @@ import {
useCallback useCallback
} from 'react' } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Flex, Button, Input, Select, Card } from 'antd' import { Flex, Button, Input, Select, Typography, Card } from 'antd'
import PlusIcon from '../../Icons/PlusIcon.jsx' import PlusIcon from '../../Icons/PlusIcon.jsx'
import MinusIcon from '../../Icons/MinusIcon.jsx' import MinusIcon from '../../Icons/MinusIcon.jsx'
import InfoCircleIcon from '../../Icons/InfoCircleIcon.jsx' import InfoCircleIcon from '../../Icons/InfoCircleIcon.jsx'
@ -17,7 +17,9 @@ import ObjectProperty from '../common/ObjectProperty.jsx'
import PDFViewer from './PDFViewer.jsx' import PDFViewer from './PDFViewer.jsx'
import ScrollBox from './ScrollBox.jsx' import ScrollBox from './ScrollBox.jsx'
import { ApiServerContext } from '../context/ApiServerContext.jsx' import { ApiServerContext } from '../context/ApiServerContext.jsx'
import ProgressDisplay from './ProgressDisplay.jsx' import HProgress from './HProgress.jsx'
const { Text } = Typography
const noop = () => {} const noop = () => {}
@ -222,7 +224,7 @@ const TemplatePreview = ({
stopRenderProgressListener() stopRenderProgressListener()
setPDFBlob(null) setPDFBlob(null)
setReloadLoading(true) setReloadLoading(true)
setDownloadProgress({ progress: 0, message: 'Starting render...' }) setDownloadProgress({ progress: 0, message: 'Starting render' })
const startDownload = async () => { const startDownload = async () => {
try { try {
@ -588,14 +590,17 @@ const TemplatePreview = ({
}} }}
styles={{ body: { padding: 18 } }} styles={{ body: { padding: 18 } }}
> >
<ProgressDisplay <Flex vertical gap={10} style={{ width: '100%' }}>
percent={Math.round( <Text ellipsis style={{ width: '100%', minWidth: 0 }}>
(Number(downloadProgress.progress) || 0) * 100 {downloadProgress.message || 'Rendering...'}
)} </Text>
status='active' <HProgress
> percent={Math.round(
{downloadProgress.message || 'Rendering...'} (Number(downloadProgress.progress) || 0) * 100
</ProgressDisplay> )}
status='active'
/>
</Flex>
</Card> </Card>
</Flex> </Flex>
) : null} ) : null}