From e2ffaa4731512ea9ba387e4c68c72cb36597e33c Mon Sep 17 00:00:00 2001 From: Trevor Richards Date: Thu, 19 Dec 2024 11:30:24 -0800 Subject: [PATCH] feat: add support for message attachments --- backend/src/components/files.js | 22 +++++++--- .../messages/RequestConversations.vue | 42 ++++++++++++++++--- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/backend/src/components/files.js b/backend/src/components/files.js index fdba983b..550c66f3 100644 --- a/backend/src/components/files.js +++ b/backend/src/components/files.js @@ -4,14 +4,24 @@ const HttpStatus = require('http-status-codes') async function getFile(req, res) { try { - let operation = `msdyn_richtextfiles(${req.params.fileId})/` - if (req.query.image) { - operation += 'msdyn_imageblob/$value?size=full' + let fileDataOperation = `msdyn_richtextfiles(${req.params.fileId})/` + + if (req.query.image === 'true') { + fileDataOperation += 'msdyn_imageblob/$value?size=full' } else { - operation += 'msdyn_fileblob' + fileDataOperation += 'msdyn_fileblob' } - const response = await getOperation(operation) - return res.status(HttpStatus.OK).json(response?.value) + const fileDataResponse = await getOperation(fileDataOperation) + + const fileDetailsOperation = `fileattachments?$filter=(_objectid_value eq ${req.params.fileId})` + const fileDetailsResponse = await getOperation(fileDetailsOperation) + const fileDetails = fileDetailsResponse?.value[0] || { mimetype: undefined, filename: undefined } + + return res.status(HttpStatus.OK).json({ + fileData: fileDataResponse?.value, + mimetype: fileDetails.mimetype, + filename: fileDetails.filename, + }) } catch (e) { handleError(res, e) } diff --git a/frontend/src/components/messages/RequestConversations.vue b/frontend/src/components/messages/RequestConversations.vue index 8067152b..8a17fd02 100644 --- a/frontend/src/components/messages/RequestConversations.vue +++ b/frontend/src/components/messages/RequestConversations.vue @@ -67,7 +67,7 @@ Sent: {{ format.formatDate(item.sentDate) }} -
+
@@ -209,6 +209,17 @@ export default { deriveFromDisplay(item) { return item.ofmSourceSystem ? `${this.userInfo?.firstName ?? ''} ${this.userInfo?.lastName}` : OFM_PROGRAM }, + handlePdf(event) { + console.log(event.target) + if (event.target.classList.contains('conversation-pdf')) { + fetch(event.target.dataset.link) + .then((res) => res.blob()) + .then((blob) => { + const blobUrl = URL.createObjectURL(blob) + window.open(blobUrl) + }) + } + }, async formatConversation() { const parser = new DOMParser() for (const conversation of this.assistanceRequestConversation) { @@ -218,15 +229,36 @@ export default { const matches = ID_REGEX.exec(img.getAttribute('src')) if (matches) { const fileId = matches[1] - const image = await FileService.getFile(fileId) - const imageType = deriveImageType(image) - img.setAttribute('src', `data:image/${imageType};base64,${image}`) + const imageFile = await FileService.getFile(fileId, true) + const imageType = deriveImageType(imageFile.fileData) + img.setAttribute('src', `data:image/${imageType};base64,${imageFile.fileData}`) } else { img.remove() } } + // Remove CRM links for now until we can support them - document.querySelectorAll('a[href*="/api/data"]').forEach((link) => link.remove()) + const fileLinks = document.querySelectorAll('a[href*="/api/data"]') + + for (const fileLink of fileLinks) { + const matches = ID_REGEX.exec(fileLink.dataset.value) + if (matches) { + const fileId = matches[1] + const file = await FileService.getFile(fileId) + const dataLink = `data:${file.mimetype};base64,${file.fileData}` + + if (file.mimetype === 'application/pdf') { + fileLink.setAttribute('href', '#') + fileLink.classList.add('conversation-pdf') + fileLink.setAttribute('data-link', dataLink) + } else { + fileLink.setAttribute('href', dataLink) + fileLink.setAttribute('download', file.filename) + } + } else { + fileLink.remove() + } + } // Update the message content conversation.message = document.documentElement.innerHTML