diff --git a/src/components/Dashboard/Management/DocumentJobs/NewDocumentJob.jsx b/src/components/Dashboard/Management/DocumentJobs/NewDocumentJob.jsx
index 20fe4316..bf783c80 100644
--- a/src/components/Dashboard/Management/DocumentJobs/NewDocumentJob.jsx
+++ b/src/components/Dashboard/Management/DocumentJobs/NewDocumentJob.jsx
@@ -8,7 +8,7 @@ import { useContext, useRef, useState } from 'react'
import dayjs from 'dayjs'
const NewDocumentJob = ({ onOk, defaultValues = {} }) => {
- const { sendObjectAction, downloadTemplatePDF, formatFileName } =
+ const { sendObjectAction, downloadTemplate, formatFileName } =
useContext(ApiServerContext)
const [downloading, setDownloading] = useState(false)
@@ -92,11 +92,12 @@ const NewDocumentJob = ({ onOk, defaultValues = {} }) => {
key: 'pdf',
onClick: () => {
setDownloading(true)
- downloadTemplatePDF(
+ downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
+ 'pdf',
() => {
setDownloading(false)
}
@@ -105,11 +106,54 @@ const NewDocumentJob = ({ onOk, defaultValues = {} }) => {
},
{
label: 'PNG',
- key: 'png'
+ key: 'png',
+ onClick: () => {
+ setDownloading(true)
+ downloadTemplate(
+ objectData.documentTemplate._id,
+ objectData.documentTemplate.content,
+ objectData.object,
+ fileName,
+ 'png',
+ () => {
+ setDownloading(false)
+ }
+ )
+ }
},
{
label: 'JPEG',
- key: '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)
+ }
+ )
+ }
}
]
}
diff --git a/src/components/Dashboard/common/ObjectDisplay.jsx b/src/components/Dashboard/common/ObjectDisplay.jsx
index 81f00a12..88a8e1a9 100644
--- a/src/components/Dashboard/common/ObjectDisplay.jsx
+++ b/src/components/Dashboard/common/ObjectDisplay.jsx
@@ -192,9 +192,7 @@ const ObjectDisplay = ({
if (!objectData?.name) return null
const textElement = (
-
- {objectData.name}
-
+ {objectData.name}
)
// If hyperlink is enabled
diff --git a/src/components/Dashboard/context/ApiServerContext.jsx b/src/components/Dashboard/context/ApiServerContext.jsx
index 9c152c2a..8ddb068d 100644
--- a/src/components/Dashboard/context/ApiServerContext.jsx
+++ b/src/components/Dashboard/context/ApiServerContext.jsx
@@ -1750,6 +1750,30 @@ const ApiServerProvider = ({ children }) => {
}
}
+ const getTemplateErrorFromResponse = (err) => {
+ const data = err?.response?.data
+ if (data instanceof ArrayBuffer) {
+ try {
+ const parsed = JSON.parse(new TextDecoder().decode(data))
+ return parsed?.error || err.message
+ } catch {
+ return err.message
+ }
+ }
+ return data?.error || err.message
+ }
+
+ const triggerFileDownload = (blob, filename) => {
+ const fileUrl = URL.createObjectURL(blob)
+ const fileLink = document.createElement('a')
+ fileLink.href = fileUrl
+ fileLink.setAttribute('download', filename)
+ document.body.appendChild(fileLink)
+ fileLink.click()
+ fileLink.parentNode.removeChild(fileLink)
+ URL.revokeObjectURL(fileUrl)
+ }
+
const fetchTemplatePreview = async (
id,
content,
@@ -1758,38 +1782,138 @@ const ApiServerProvider = ({ children }) => {
callback
) => {
logger.debug('Fetching preview...')
- if (socketRef.current && socketRef.current.connected) {
- return socketRef.current.emit(
- 'previewTemplate',
+ try {
+ const response = await axios.post(
+ `${config.backendUrl}/documenttemplates/${id}/preview`,
{
- _id: id,
- content: content,
- testObject: testObject,
- scale: scale
+ content,
+ testObject,
+ scale
},
- callback
+ {
+ headers: {
+ Accept: 'application/json',
+ Authorization: `Bearer ${token}`
+ }
+ }
)
+ if (typeof callback === 'function') {
+ callback(response.data)
+ }
+ return response.data
+ } catch (err) {
+ const error = getTemplateErrorFromResponse(err)
+ logger.error('Error fetching template preview:', error)
+ if (typeof callback === 'function') {
+ callback({ error })
+ }
+ return { error }
}
- if (typeof callback === 'function') {
- callback({ error: 'Api Server disconnected' })
+ }
+
+ const fetchTemplateDownload = async (id, content, object, type = 'pdf') => {
+ logger.debug(`Fetching template download as ${type}...`)
+ const response = await axios.post(
+ `${config.backendUrl}/documenttemplates/${id}/download`,
+ {
+ content,
+ object
+ },
+ {
+ params: { type },
+ responseType: 'arraybuffer',
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ }
+ )
+ const contentType = response.headers['content-type'] || ''
+ if (contentType.includes('application/json')) {
+ return JSON.parse(new TextDecoder().decode(response.data))
+ }
+ return {
+ type,
+ mime: contentType,
+ buffer: response.data
}
}
const fetchTemplatePDF = async (id, content, testObject, callback) => {
logger.debug('Fetching pdf template...')
- if (socketRef.current && socketRef.current.connected) {
- return socketRef.current.emit(
- 'renderTemplatePDF',
- {
- _id: id,
- content: content,
- object: testObject
- },
- callback
+ try {
+ const result = await fetchTemplateDownload(
+ id,
+ content,
+ testObject,
+ 'pdf'
)
+ const payload = result.error
+ ? result
+ : { pdf: result.buffer || result }
+ if (typeof callback === 'function') {
+ callback(payload)
+ }
+ return payload
+ } catch (err) {
+ const error = getTemplateErrorFromResponse(err)
+ logger.error('Error fetching template PDF:', error)
+ if (typeof callback === 'function') {
+ callback({ error })
+ }
+ return { error }
}
- if (typeof callback === 'function') {
- callback({ error: 'Api Server disconnected' })
+ }
+
+ const downloadTemplate = async (
+ id,
+ content,
+ object,
+ filename,
+ type = 'pdf',
+ callback
+ ) => {
+ logger.debug(`Downloading template as ${type}...`)
+ try {
+ const result = await fetchTemplateDownload(id, content, object, type)
+ if (result?.error) {
+ if (callback) {
+ callback(result.error)
+ }
+ return result
+ }
+
+ if (Array.isArray(result.images)) {
+ result.images.forEach((image, index) => {
+ const binary = atob(image)
+ const bytes = new Uint8Array(binary.length)
+ for (let i = 0; i < binary.length; i += 1) {
+ bytes[i] = binary.charCodeAt(i)
+ }
+ const blob = new Blob([bytes], { type: result.mime })
+ const suffix = result.images.length > 1 ? `-${index + 1}` : ''
+ triggerFileDownload(
+ blob,
+ `${filename}${suffix}.${result.extension || type}`
+ )
+ })
+ } else {
+ const blob = new Blob([result.buffer], {
+ type: result.mime || 'application/octet-stream'
+ })
+ const extension = type === 'jpeg' ? 'jpeg' : type
+ triggerFileDownload(blob, `${filename}.${extension}`)
+ }
+
+ if (callback) {
+ callback()
+ }
+ } catch (err) {
+ const error = getTemplateErrorFromResponse(err)
+ logger.error('Error downloading template:', error)
+ if (callback) {
+ callback(error)
+ }
+ return { error }
}
}
@@ -1800,29 +1924,7 @@ const ApiServerProvider = ({ children }) => {
filename,
callback
) => {
- logger.debug('Downloading template PDF...')
-
- fetchTemplatePDF(id, content, object, (result) => {
- logger.debug('Downloading template PDF result:', result)
- if (result?.error) {
- console.error(result.error)
- if (callback) {
- callback(result.error)
- }
- } else {
- const pdfBlob = new Blob([result.pdf], { type: 'application/pdf' })
- const pdfUrl = URL.createObjectURL(pdfBlob)
- const fileLink = document.createElement('a')
- fileLink.href = pdfUrl
- fileLink.setAttribute('download', `${filename}.pdf`)
- document.body.appendChild(fileLink)
- fileLink.click()
- fileLink.parentNode.removeChild(fileLink)
- if (callback) {
- callback()
- }
- }
- })
+ return downloadTemplate(id, content, object, filename, 'pdf', callback)
}
const fetchHostOTP = async (id, callback) => {
@@ -2253,6 +2355,7 @@ const ApiServerProvider = ({ children }) => {
fetchTemplatePreview,
fetchTemplatePDF,
fetchNotes,
+ downloadTemplate,
downloadTemplatePDF,
fetchHostOTP,
sendObjectAction,