Refactor TemplateEditor and TemplatePreview components for improved performance and error handling
Some checks failed
farmcontrol/farmcontrol-ui/pipeline/head There was a failure building this commit
Some checks failed
farmcontrol/farmcontrol-ui/pipeline/head There was a failure building this commit
- Updated TemplateEditor to use useCallback for handlePreviewMessage, optimizing performance. - Enhanced TemplatePreview by adding default no-op functions for onTestObjectOpen and onPreviewMessage props. - Improved error handling in fetchTemplatePDF and fetchTemplatePreview methods to ensure callbacks are only invoked if they are functions. - Refactored preview loading logic to prevent unnecessary calls when template ID is not available.
This commit is contained in:
parent
59d16f80aa
commit
f743f9b892
@ -1,4 +1,4 @@
|
|||||||
import { useState } from 'react'
|
import { useState, useCallback } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {
|
import {
|
||||||
Flex,
|
Flex,
|
||||||
@ -31,10 +31,10 @@ const TemplateEditor = ({
|
|||||||
const [previewError, setPreviewError] = useState(false)
|
const [previewError, setPreviewError] = useState(false)
|
||||||
//const isMobile = useMediaQuery({ maxWidth: 768 })
|
//const isMobile = useMediaQuery({ maxWidth: 768 })
|
||||||
|
|
||||||
const handlePreviewMessage = (message, isError) => {
|
const handlePreviewMessage = useCallback((message, isError) => {
|
||||||
setPreviewMessage(message)
|
setPreviewMessage(message)
|
||||||
setPreviewError(isError)
|
setPreviewError(isError)
|
||||||
}
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -7,17 +7,20 @@ import InfoCircleIcon from '../../Icons/InfoCircleIcon.jsx'
|
|||||||
import ObjectProperty from '../common/ObjectProperty.jsx'
|
import ObjectProperty from '../common/ObjectProperty.jsx'
|
||||||
import { ApiServerContext } from '../context/ApiServerContext.jsx'
|
import { ApiServerContext } from '../context/ApiServerContext.jsx'
|
||||||
|
|
||||||
|
const noop = () => {}
|
||||||
|
|
||||||
const TemplatePreview = ({
|
const TemplatePreview = ({
|
||||||
objectData,
|
objectData,
|
||||||
documentTemplate,
|
documentTemplate,
|
||||||
loading,
|
loading,
|
||||||
isEditing,
|
isEditing,
|
||||||
onTestObjectOpen,
|
onTestObjectOpen = noop,
|
||||||
onPreviewMessage,
|
onPreviewMessage = noop,
|
||||||
showTestObject = false,
|
showTestObject = false,
|
||||||
showPreviewSwitch = true
|
showPreviewSwitch = true
|
||||||
}) => {
|
}) => {
|
||||||
const iframeRef = useRef(null)
|
const iframeRef = useRef(null)
|
||||||
|
const previewRequestIdRef = useRef(0)
|
||||||
const { fetchTemplatePreview, fetchTemplatePDF } =
|
const { fetchTemplatePreview, fetchTemplatePDF } =
|
||||||
useContext(ApiServerContext)
|
useContext(ApiServerContext)
|
||||||
const [previewContentHTML, setPreviewContentHTML] = useState('')
|
const [previewContentHTML, setPreviewContentHTML] = useState('')
|
||||||
@ -46,11 +49,19 @@ const TemplatePreview = ({
|
|||||||
|
|
||||||
const reloadPreviewPDF = useCallback(
|
const reloadPreviewPDF = useCallback(
|
||||||
(content, testObject = {}) => {
|
(content, testObject = {}) => {
|
||||||
|
const templateId = documentTemplate?._id
|
||||||
|
if (!templateId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestId = ++previewRequestIdRef.current
|
||||||
setReloadLoading(true)
|
setReloadLoading(true)
|
||||||
fetchTemplatePDF(documentTemplate._id, content, testObject, (result) => {
|
fetchTemplatePDF(templateId, content, testObject, (result) => {
|
||||||
|
if (requestId !== previewRequestIdRef.current) {
|
||||||
|
return
|
||||||
|
}
|
||||||
setReloadLoading(false)
|
setReloadLoading(false)
|
||||||
if (result?.error) {
|
if (result?.error) {
|
||||||
// Handle error through parent component
|
|
||||||
onPreviewMessage(result.error, true)
|
onPreviewMessage(result.error, true)
|
||||||
} else {
|
} else {
|
||||||
const pdfBlob = new Blob([result.pdf], { type: 'application/pdf' })
|
const pdfBlob = new Blob([result.pdf], { type: 'application/pdf' })
|
||||||
@ -66,16 +77,24 @@ const TemplatePreview = ({
|
|||||||
|
|
||||||
const reloadPreview = useCallback(
|
const reloadPreview = useCallback(
|
||||||
(content, testObject = {}, scale = 1) => {
|
(content, testObject = {}, scale = 1) => {
|
||||||
|
const templateId = documentTemplate?._id
|
||||||
|
if (!templateId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestId = ++previewRequestIdRef.current
|
||||||
setReloadLoading(true)
|
setReloadLoading(true)
|
||||||
fetchTemplatePreview(
|
fetchTemplatePreview(
|
||||||
documentTemplate._id,
|
templateId,
|
||||||
content,
|
content,
|
||||||
testObject,
|
testObject,
|
||||||
scale,
|
scale,
|
||||||
(result) => {
|
(result) => {
|
||||||
|
if (requestId !== previewRequestIdRef.current) {
|
||||||
|
return
|
||||||
|
}
|
||||||
setReloadLoading(false)
|
setReloadLoading(false)
|
||||||
if (result?.error) {
|
if (result?.error) {
|
||||||
// Handle error through parent component
|
|
||||||
onPreviewMessage(result.error, true)
|
onPreviewMessage(result.error, true)
|
||||||
} else {
|
} else {
|
||||||
updatePreviewContentHTML(result.html)
|
updatePreviewContentHTML(result.html)
|
||||||
@ -87,18 +106,30 @@ const TemplatePreview = ({
|
|||||||
[fetchTemplatePreview, onPreviewMessage, documentTemplate?._id]
|
[fetchTemplatePreview, onPreviewMessage, documentTemplate?._id]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const templateContent = documentTemplate?.content
|
||||||
|
const templateId = documentTemplate?._id
|
||||||
|
|
||||||
// Move useEffect to component level and use state to track objectData changes
|
// Move useEffect to component level and use state to track objectData changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (documentTemplate?.content) {
|
if (!templateId || !templateContent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeoutId = window.setTimeout(() => {
|
||||||
if (previewType == 'HTML') {
|
if (previewType == 'HTML') {
|
||||||
reloadPreview(documentTemplate.content, objectData, previewScale)
|
reloadPreview(templateContent, objectData, previewScale)
|
||||||
} else {
|
} else {
|
||||||
reloadPreviewPDF(documentTemplate.content, objectData)
|
reloadPreviewPDF(templateContent, objectData)
|
||||||
}
|
}
|
||||||
|
}, 300)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.clearTimeout(timeoutId)
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
objectData,
|
objectData,
|
||||||
documentTemplate,
|
templateContent,
|
||||||
|
templateId,
|
||||||
previewScale,
|
previewScale,
|
||||||
previewType,
|
previewType,
|
||||||
reloadPreview,
|
reloadPreview,
|
||||||
@ -197,8 +228,8 @@ TemplatePreview.propTypes = {
|
|||||||
isEditing: PropTypes.bool,
|
isEditing: PropTypes.bool,
|
||||||
style: PropTypes.object,
|
style: PropTypes.object,
|
||||||
showTestObject: PropTypes.bool,
|
showTestObject: PropTypes.bool,
|
||||||
onTestObjectOpen: PropTypes.func.isRequired,
|
onTestObjectOpen: PropTypes.func,
|
||||||
onPreviewMessage: PropTypes.func.isRequired,
|
onPreviewMessage: PropTypes.func,
|
||||||
showPreviewSwitch: PropTypes.bool
|
showPreviewSwitch: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1691,6 +1691,9 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (typeof callback === 'function') {
|
||||||
|
callback({ error: 'Api Server disconnected' })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchTemplatePDF = async (id, content, testObject, callback) => {
|
const fetchTemplatePDF = async (id, content, testObject, callback) => {
|
||||||
@ -1706,6 +1709,9 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (typeof callback === 'function') {
|
||||||
|
callback({ error: 'Api Server disconnected' })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadTemplatePDF = async (
|
const downloadTemplatePDF = async (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user