diff --git a/src/components/Dashboard/common/TemplateEditor.jsx b/src/components/Dashboard/common/TemplateEditor.jsx index ce360d5..0934c46 100644 --- a/src/components/Dashboard/common/TemplateEditor.jsx +++ b/src/components/Dashboard/common/TemplateEditor.jsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useState, useCallback } from 'react' import PropTypes from 'prop-types' import { Flex, @@ -31,10 +31,10 @@ const TemplateEditor = ({ const [previewError, setPreviewError] = useState(false) //const isMobile = useMediaQuery({ maxWidth: 768 }) - const handlePreviewMessage = (message, isError) => { + const handlePreviewMessage = useCallback((message, isError) => { setPreviewMessage(message) setPreviewError(isError) - } + }, []) return ( <> diff --git a/src/components/Dashboard/common/TemplatePreview.jsx b/src/components/Dashboard/common/TemplatePreview.jsx index ee004f8..5a136b6 100644 --- a/src/components/Dashboard/common/TemplatePreview.jsx +++ b/src/components/Dashboard/common/TemplatePreview.jsx @@ -7,17 +7,20 @@ import InfoCircleIcon from '../../Icons/InfoCircleIcon.jsx' import ObjectProperty from '../common/ObjectProperty.jsx' import { ApiServerContext } from '../context/ApiServerContext.jsx' +const noop = () => {} + const TemplatePreview = ({ objectData, documentTemplate, loading, isEditing, - onTestObjectOpen, - onPreviewMessage, + onTestObjectOpen = noop, + onPreviewMessage = noop, showTestObject = false, showPreviewSwitch = true }) => { const iframeRef = useRef(null) + const previewRequestIdRef = useRef(0) const { fetchTemplatePreview, fetchTemplatePDF } = useContext(ApiServerContext) const [previewContentHTML, setPreviewContentHTML] = useState('') @@ -46,11 +49,19 @@ const TemplatePreview = ({ const reloadPreviewPDF = useCallback( (content, testObject = {}) => { + const templateId = documentTemplate?._id + if (!templateId) { + return + } + + const requestId = ++previewRequestIdRef.current setReloadLoading(true) - fetchTemplatePDF(documentTemplate._id, content, testObject, (result) => { + fetchTemplatePDF(templateId, content, testObject, (result) => { + if (requestId !== previewRequestIdRef.current) { + return + } setReloadLoading(false) if (result?.error) { - // Handle error through parent component onPreviewMessage(result.error, true) } else { const pdfBlob = new Blob([result.pdf], { type: 'application/pdf' }) @@ -66,16 +77,24 @@ const TemplatePreview = ({ const reloadPreview = useCallback( (content, testObject = {}, scale = 1) => { + const templateId = documentTemplate?._id + if (!templateId) { + return + } + + const requestId = ++previewRequestIdRef.current setReloadLoading(true) fetchTemplatePreview( - documentTemplate._id, + templateId, content, testObject, scale, (result) => { + if (requestId !== previewRequestIdRef.current) { + return + } setReloadLoading(false) if (result?.error) { - // Handle error through parent component onPreviewMessage(result.error, true) } else { updatePreviewContentHTML(result.html) @@ -87,18 +106,30 @@ const TemplatePreview = ({ [fetchTemplatePreview, onPreviewMessage, documentTemplate?._id] ) + const templateContent = documentTemplate?.content + const templateId = documentTemplate?._id + // Move useEffect to component level and use state to track objectData changes useEffect(() => { - if (documentTemplate?.content) { + if (!templateId || !templateContent) { + return + } + + const timeoutId = window.setTimeout(() => { if (previewType == 'HTML') { - reloadPreview(documentTemplate.content, objectData, previewScale) + reloadPreview(templateContent, objectData, previewScale) } else { - reloadPreviewPDF(documentTemplate.content, objectData) + reloadPreviewPDF(templateContent, objectData) } + }, 300) + + return () => { + window.clearTimeout(timeoutId) } }, [ objectData, - documentTemplate, + templateContent, + templateId, previewScale, previewType, reloadPreview, @@ -197,8 +228,8 @@ TemplatePreview.propTypes = { isEditing: PropTypes.bool, style: PropTypes.object, showTestObject: PropTypes.bool, - onTestObjectOpen: PropTypes.func.isRequired, - onPreviewMessage: PropTypes.func.isRequired, + onTestObjectOpen: PropTypes.func, + onPreviewMessage: PropTypes.func, showPreviewSwitch: PropTypes.bool } diff --git a/src/components/Dashboard/context/ApiServerContext.jsx b/src/components/Dashboard/context/ApiServerContext.jsx index 209f8e7..807b3bb 100644 --- a/src/components/Dashboard/context/ApiServerContext.jsx +++ b/src/components/Dashboard/context/ApiServerContext.jsx @@ -1691,6 +1691,9 @@ const ApiServerProvider = ({ children }) => { callback ) } + if (typeof callback === 'function') { + callback({ error: 'Api Server disconnected' }) + } } const fetchTemplatePDF = async (id, content, testObject, callback) => { @@ -1706,6 +1709,9 @@ const ApiServerProvider = ({ children }) => { callback ) } + if (typeof callback === 'function') { + callback({ error: 'Api Server disconnected' }) + } } const downloadTemplatePDF = async (