Skip to content

Commit aed144a

Browse files
committed
feat: add multi-PDF support in SignPDF component
- Load multiple PDFs from initial state or store - Add loadEnvelopePdfs() to fetch envelope children via API - Add loadPdfsFromStore() for private access path - Handle both envelope and single file scenarios Signed-off-by: Vitor Mattos <[email protected]>
1 parent acd5853 commit aed144a

1 file changed

Lines changed: 77 additions & 24 deletions

File tree

src/views/SignPDF/SignPDF.vue

Lines changed: 77 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
<TopBar
88
v-if="!isMobile"
99
:sidebar-toggle="true" />
10-
<PdfEditor v-if="mounted && !signStore.errors.length && pdfBlob"
10+
<PdfEditor v-if="mounted && !signStore.errors.length && pdfBlobs.length > 0"
1111
ref="pdfEditor"
1212
width="100%"
1313
height="100%"
14-
:files="[pdfBlob]"
15-
:file-names="[pdfFileName]"
14+
:files="pdfBlobs"
15+
:file-names="pdfBlobs.map((_, i) => `${pdfFileName}_${i + 1}`)"
1616
:read-only="true"
1717
@pdf-editor:end-init="updateSigners" />
1818
<div class="button-wrapper">
@@ -40,6 +40,7 @@ import NcButton from '@nextcloud/vue/components/NcButton'
4040
import PdfEditor from '../../Components/PdfEditor/PdfEditor.vue'
4141
import TopBar from '../../Components/TopBar/TopBar.vue'
4242
43+
import { loadState } from '@nextcloud/initial-state'
4344
import { useFilesStore } from '../../store/files.js'
4445
import { useSidebarStore } from '../../store/sidebar.js'
4546
import { useSignStore } from '../../store/sign.js'
@@ -66,13 +67,14 @@ export default {
6667
data() {
6768
return {
6869
mounted: false,
69-
pdfBlob: null,
70+
pdfBlobs: [],
7071
}
7172
},
7273
computed: {
7374
pdfFileName() {
7475
const doc = this.signStore.document
75-
return `${doc.name}.${doc.metadata.extension}`
76+
const extension = doc.metadata?.extension || 'pdf'
77+
return `${doc.name}.${extension}`
7678
},
7779
},
7880
async created() {
@@ -87,6 +89,14 @@ export default {
8789
if (this.isMobile){
8890
this.toggleSidebar();
8991
}
92+
93+
const pdfs = loadState('libresign', 'pdfs', [])
94+
if (pdfs.length > 0) {
95+
await this.handleInitialStatePdfs(pdfs)
96+
} else {
97+
await this.loadPdfsFromStore()
98+
}
99+
this.mounted = true
90100
},
91101
beforeRouteLeave(to, from, next) {
92102
this.sidebarStore.hideSidebar()
@@ -98,8 +108,6 @@ export default {
98108
if (!this.signStore.document.uuid) {
99109
this.signStore.document.uuid = this.$route.params.uuid
100110
}
101-
await this.fetchPdfAsBlob(this.signStore.document.url)
102-
this.mounted = true
103111
},
104112
async initSignInternal() {
105113
const files = await this.fileStore.getAllFiles({
@@ -108,10 +116,8 @@ export default {
108116
for (const nodeId in files) {
109117
const signer = files[nodeId].signers.find(row => row.me) || {}
110118
if (Object.keys(signer).length > 0) {
111-
this.signStore.setDocumentToSign(files[nodeId])
119+
this.signStore.setFileToSign(files[nodeId])
112120
this.fileStore.selectedNodeId = nodeId
113-
await this.fetchPdfAsBlob(this.signStore.document.url)
114-
this.mounted = true
115121
return
116122
}
117123
}
@@ -120,27 +126,74 @@ export default {
120126
const response = await axios.get(
121127
generateOcsUrl('/apps/libresign/api/v1/file/validate/uuid/{uuid}', { uuid: this.$route.params.uuid })
122128
)
123-
this.signStore.setDocumentToSign(response.data.ocs.data)
129+
this.signStore.setFileToSign(response.data.ocs.data)
124130
this.fileStore.selectedNodeId = response.data.ocs.data.nodeId
125-
await this.fetchPdfAsBlob(this.signStore.document.url)
126-
this.mounted = true
127131
},
128-
async fetchPdfAsBlob(url) {
129-
const response = await fetch(url)
130-
const contentType = response.headers.get('Content-Type') || ''
132+
async handleInitialStatePdfs(urls) {
133+
if (!Array.isArray(urls) || urls.length === 0) {
134+
return
135+
}
136+
137+
const blobs = []
138+
for (const url of urls) {
139+
const response = await fetch(url)
140+
const contentType = response.headers.get('Content-Type') || ''
131141
132-
if (contentType.includes('application/json')) {
133-
const data = await response.json()
134-
this.sidebarStore.hideSidebar()
135-
if (data?.errors?.[0]?.message.length > 0) {
136-
this.signStore.errors = data.errors
142+
if (contentType.includes('application/json')) {
143+
const data = await response.json()
144+
this.sidebarStore.hideSidebar()
145+
if (data?.errors?.[0]?.message.length > 0) {
146+
this.signStore.errors = data.errors
147+
} else {
148+
this.signStore.errors = [{ message: t('libresign', 'File not found') }]
149+
}
137150
return
138151
}
139-
this.signStore.errors = [{ message: t('libresign', 'File not found') }]
152+
153+
const blob = await response.blob()
154+
blobs.push(new File([blob], 'arquivo.pdf', { type: 'application/pdf' }))
155+
}
156+
157+
this.pdfBlobs = blobs
158+
},
159+
async loadPdfsFromStore() {
160+
const doc = this.signStore.document
161+
162+
if (!doc || !doc.nodeId) {
163+
this.signStore.errors = [{ message: t('libresign', 'Document not found') }]
140164
return
141165
}
142-
const blob = await response.blob()
143-
this.pdfBlob = new File([blob], 'arquivo.pdf', { type: 'application/pdf' })
166+
167+
// Check if it's an envelope
168+
if (doc.nodeType === 'envelope') {
169+
await this.loadEnvelopePdfs(doc.nodeId)
170+
} else if (doc.url) {
171+
// Single document
172+
await this.handleInitialStatePdfs([doc.url])
173+
} else {
174+
this.signStore.errors = [{ message: t('libresign', 'Document URL not found') }]
175+
}
176+
},
177+
async loadEnvelopePdfs(parentNodeId) {
178+
try {
179+
const url = generateOcsUrl('/apps/libresign/api/v1/file/list')
180+
const params = new URLSearchParams({
181+
page: '1',
182+
length: '100',
183+
parentNodeId: parentNodeId.toString(),
184+
signer_uuid: this.$route.params.uuid,
185+
})
186+
187+
const { data } = await axios.get(`${url}?${params.toString()}`)
188+
if (data.ocs?.data?.data) {
189+
const urls = data.ocs.data.data.map(file => file.file)
190+
await this.handleInitialStatePdfs(urls)
191+
} else {
192+
this.signStore.errors = [{ message: t('libresign', 'Failed to load envelope files') }]
193+
}
194+
} catch (error) {
195+
this.signStore.errors = [{ message: t('libresign', 'Failed to load envelope files') }]
196+
}
144197
},
145198
updateSigners(data) {
146199
const currentSigner = this.signStore.document.signers.find(signer => signer.me)

0 commit comments

Comments
 (0)