Compare commits

..

No commits in common. "c69c4cf3ddf611f9133c43ab07d43949cce592ae" and "f2ccec483f861950f29bf2d7b529ee4d7ef3a9f2" have entirely different histories.

4 changed files with 59 additions and 197 deletions

View File

@ -1254,13 +1254,13 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
mask-image: linear-gradient( mask-image: linear-gradient(
to right, to right,
#000 0%, #000 0%,
#000 calc(100% - 0.5em), #000 calc(100% - 0.8em),
transparent 100% transparent 100%
); );
-webkit-mask-image: linear-gradient( -webkit-mask-image: linear-gradient(
to right, to right,
#000 0%, #000 0%,
#000 calc(100% - 0.5em), #000 calc(100% - 0.8em),
transparent 100% transparent 100%
); );
} }
@ -1271,13 +1271,13 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
mask-image: linear-gradient( mask-image: linear-gradient(
to left, to left,
#000 0%, #000 0%,
#000 calc(100% - 0.5em), #000 calc(100% - 0.8em),
transparent 100% transparent 100%
); );
-webkit-mask-image: linear-gradient( -webkit-mask-image: linear-gradient(
to left, to left,
#000 0%, #000 0%,
#000 calc(100% - 0.5em), #000 calc(100% - 0.8em),
transparent 100% transparent 100%
); );
} }

View File

@ -8,7 +8,7 @@ import { useContext, useRef, useState } from 'react'
import dayjs from 'dayjs' import dayjs from 'dayjs'
const NewDocumentJob = ({ onOk, defaultValues = {} }) => { const NewDocumentJob = ({ onOk, defaultValues = {} }) => {
const { sendObjectAction, downloadTemplate, formatFileName } = const { sendObjectAction, downloadTemplatePDF, formatFileName } =
useContext(ApiServerContext) useContext(ApiServerContext)
const [downloading, setDownloading] = useState(false) const [downloading, setDownloading] = useState(false)
@ -92,12 +92,11 @@ const NewDocumentJob = ({ onOk, defaultValues = {} }) => {
key: 'pdf', key: 'pdf',
onClick: () => { onClick: () => {
setDownloading(true) setDownloading(true)
downloadTemplate( downloadTemplatePDF(
objectData.documentTemplate._id, objectData.documentTemplate._id,
objectData.documentTemplate.content, objectData.documentTemplate.content,
objectData.object, objectData.object,
fileName, fileName,
'pdf',
() => { () => {
setDownloading(false) setDownloading(false)
} }
@ -106,54 +105,11 @@ const NewDocumentJob = ({ onOk, defaultValues = {} }) => {
}, },
{ {
label: 'PNG', label: 'PNG',
key: 'png', key: 'png'
onClick: () => {
setDownloading(true)
downloadTemplate(
objectData.documentTemplate._id,
objectData.documentTemplate.content,
objectData.object,
fileName,
'png',
() => {
setDownloading(false)
}
)
}
}, },
{ {
label: 'JPEG', 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)
}
)
}
} }
] ]
} }

View File

@ -192,7 +192,9 @@ const ObjectDisplay = ({
if (!objectData?.name) return null if (!objectData?.name) return null
const textElement = ( const textElement = (
<ElipsisText style={{ lineHeight: '1' }}>{objectData.name}</ElipsisText> <ElipsisText style={{ lineHeight: '1', paddingBottom: '2px' }}>
{objectData.name}
</ElipsisText>
) )
// If hyperlink is enabled // If hyperlink is enabled

View File

@ -1750,30 +1750,6 @@ 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 ( const fetchTemplatePreview = async (
id, id,
content, content,
@ -1782,131 +1758,38 @@ const ApiServerProvider = ({ children }) => {
callback callback
) => { ) => {
logger.debug('Fetching preview...') logger.debug('Fetching preview...')
try { if (socketRef.current && socketRef.current.connected) {
const response = await axios.post( return socketRef.current.emit(
`${config.backendUrl}/documenttemplates/${id}/preview`, 'previewTemplate',
{ {
content, _id: id,
testObject, content: content,
scale testObject: testObject,
scale: scale
}, },
{ callback
headers: {
Accept: 'application/json',
Authorization: `Bearer ${token}`
}
}
) )
}
if (typeof callback === 'function') { if (typeof callback === 'function') {
callback(response.data) callback({ error: 'Api Server disconnected' })
}
return response.data
} catch (err) {
const error = getTemplateErrorFromResponse(err)
logger.error('Error fetching template preview:', error)
if (typeof callback === 'function') {
callback({ error })
}
return { error }
}
}
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) => { const fetchTemplatePDF = async (id, content, testObject, callback) => {
logger.debug('Fetching pdf template...') logger.debug('Fetching pdf template...')
try { if (socketRef.current && socketRef.current.connected) {
const result = await fetchTemplateDownload(id, content, testObject, 'pdf') return socketRef.current.emit(
const payload = result.error ? result : { pdf: result.buffer || result } 'renderTemplatePDF',
if (typeof callback === 'function') { {
callback(payload) _id: id,
} content: content,
return payload object: testObject
} catch (err) { },
const error = getTemplateErrorFromResponse(err)
logger.error('Error fetching template PDF:', error)
if (typeof callback === 'function') {
callback({ error })
}
return { error }
}
}
const downloadTemplate = async (
id,
content,
object,
filename,
type = 'pdf',
callback 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 (typeof callback === 'function') {
if (callback) { callback({ error: 'Api Server disconnected' })
callback()
}
} catch (err) {
const error = getTemplateErrorFromResponse(err)
logger.error('Error downloading template:', error)
if (callback) {
callback(error)
}
return { error }
} }
} }
@ -1917,7 +1800,29 @@ const ApiServerProvider = ({ children }) => {
filename, filename,
callback callback
) => { ) => {
return downloadTemplate(id, content, object, filename, 'pdf', 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()
}
}
})
} }
const fetchHostOTP = async (id, callback) => { const fetchHostOTP = async (id, callback) => {
@ -2010,8 +1915,8 @@ const ApiServerProvider = ({ children }) => {
if (!userProfile?._id) return { data: [] } if (!userProfile?._id) return { data: [] }
const result = await fetchObjects('userNotifier', { const result = await fetchObjects('userNotifier', {
filter: { filter: {
'user._id': userProfile._id, user: userProfile._id,
'object._id': objectId, object: objectId,
objectType objectType
}, },
limit: 1 limit: 1
@ -2022,7 +1927,7 @@ const ApiServerProvider = ({ children }) => {
const fetchAllUserNotifiersForObject = async (objectId, objectType) => { const fetchAllUserNotifiersForObject = async (objectId, objectType) => {
const result = await fetchObjects('userNotifier', { const result = await fetchObjects('userNotifier', {
filter: { filter: {
'object._id': objectId, object: objectId,
objectType objectType
}, },
limit: 100 limit: 100
@ -2348,7 +2253,6 @@ const ApiServerProvider = ({ children }) => {
fetchTemplatePreview, fetchTemplatePreview,
fetchTemplatePDF, fetchTemplatePDF,
fetchNotes, fetchNotes,
downloadTemplate,
downloadTemplatePDF, downloadTemplatePDF,
fetchHostOTP, fetchHostOTP,
sendObjectAction, sendObjectAction,