Skip to content

Commit a015570

Browse files
fix: load request signature modal pdf blobs
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 8f7b809 commit a015570

1 file changed

Lines changed: 86 additions & 6 deletions

File tree

src/components/Request/VisibleElements.vue

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@
6868
</NcButton>
6969
</div>
7070
</div>
71-
<PdfEditor v-if="!filesStore.loading && pdfFiles.length > 0"
71+
<PdfEditor v-if="!filesStore.loading && pdfEditorFiles.length > 0"
7272
ref="pdfEditor"
7373
width="100%"
7474
height="100%"
75-
:files="pdfFiles"
75+
:files="pdfEditorFiles"
7676
:file-names="pdfFileNames"
7777
:signers="pdfEditorSigners"
7878
@pdf-editor:end-init="updateSigners"
@@ -90,7 +90,7 @@ import { showSuccess, showError } from '@nextcloud/dialogs'
9090
import { subscribe, unsubscribe, type Event as NextcloudEvent, type EventHandler } from '@nextcloud/event-bus'
9191
import { loadState } from '@nextcloud/initial-state'
9292
import { t } from '@nextcloud/l10n'
93-
import { generateOcsUrl } from '@nextcloud/router'
93+
import { generateOcsUrl, generateUrl } from '@nextcloud/router'
9494
import NcButton from '@nextcloud/vue/components/NcButton'
9595
import NcChip from '@nextcloud/vue/components/NcChip'
9696
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
@@ -247,6 +247,11 @@ function toRecord(value: unknown): Record<string, unknown> | null {
247247
return typeof value === 'object' && value !== null ? value as Record<string, unknown> : null
248248
}
249249
250+
function getUrlValue(value: unknown): string | undefined {
251+
const candidate = toRecord(value)
252+
return candidate && typeof candidate.url === 'string' ? candidate.url : undefined
253+
}
254+
250255
function normalizeMetadata(metadata: unknown): Partial<ValidationMetadataRecord> | undefined {
251256
const candidate = toRecord(metadata)
252257
return candidate ? candidate as Partial<ValidationMetadataRecord> : undefined
@@ -324,19 +329,26 @@ function normalizeEditableRequestFile(file: unknown): EditableRequestChildFile |
324329
const signers = Array.isArray(candidate.signers)
325330
? candidate.signers.map(normalizeEditableRequestSigner).filter((row): row is EditableRequestSigner => row !== null)
326331
: undefined
332+
const nestedFileReference = typeof candidate.file === 'object' && candidate.file !== null
333+
? normalizeEditableRequestFile(candidate.file)
334+
: undefined
327335
const fileReference = typeof candidate.file === 'string' || candidate.file === null
328336
? candidate.file
329-
: undefined
337+
: nestedFileReference && Object.keys(nestedFileReference).length > 0
338+
? nestedFileReference
339+
: undefined
340+
const url = getUrlValue(candidate)
330341
331342
return {
332343
...(Number.isFinite(id) ? { id } : {}),
333344
...(name !== undefined ? { name } : {}),
345+
...(url !== undefined ? { url } : {}),
334346
...(fileReference !== undefined ? { file: fileReference } : {}),
335347
...(nestedFiles !== undefined ? { files: nestedFiles } : {}),
336348
...(normalizeMetadata(candidate.metadata) !== undefined ? { metadata: normalizeMetadata(candidate.metadata) } : {}),
337349
...(normalizeVisibleElementList(candidate.visibleElements) !== undefined ? { visibleElements: normalizeVisibleElementList(candidate.visibleElements) } : {}),
338350
...(signers !== undefined ? { signers } : {}),
339-
}
351+
} as EditableRequestChildFile
340352
}
341353
342354
function toVisibleElementsFile(file: EditableRequestChildFile): FileLike {
@@ -351,10 +363,14 @@ function toVisibleElementsFile(file: EditableRequestChildFile): FileLike {
351363
: file.file
352364
? toVisibleElementsFile(file.file as EditableRequestChildFile)
353365
: undefined
366+
const fileUrl = typeof (file as { url?: unknown }).url === 'string'
367+
? (file as { url?: string }).url
368+
: undefined
354369
355370
return {
356371
id: file.id,
357372
name: file.name,
373+
...(fileUrl !== undefined ? { url: fileUrl } : {}),
358374
...(fileReference !== undefined ? { file: fileReference } : {}),
359375
...(normalizeMetadata(file.metadata) !== undefined ? { metadata: normalizeMetadata(file.metadata) } : {}),
360376
...(normalizeVisibleElementList(file.visibleElements) !== undefined ? { visibleElements: normalizeVisibleElementList(file.visibleElements) } : {}),
@@ -452,9 +468,46 @@ const height = ref(signElementsConfig['full-signature-height'])
452468
const filePagesMap = ref<Record<number, FilePageInfo>>({})
453469
const elementsLoaded = ref(false)
454470
const fetchedFiles = ref<EditableRequestChildFile[]>([])
471+
const pdfEditorFiles = ref<PdfInput[]>([])
455472
456473
const document = computed<EditableRequestFile>(() => filesStore.getEditableFile())
457-
const documentFiles = computed<EditableRequestChildFile[]>(() => fetchedFiles.value.length > 0 ? fetchedFiles.value : (Array.isArray(document.value.files) ? document.value.files : []))
474+
const fallbackDocumentFile = computed<EditableRequestChildFile | null>(() => {
475+
const documentUrl = typeof (document.value as { url?: unknown }).url === 'string'
476+
? (document.value as { url?: string }).url
477+
: null
478+
const pdfUrl = documentUrl
479+
|| (typeof document.value.uuid === 'string' && document.value.uuid.length > 0
480+
? generateUrl('/apps/libresign/p/pdf/{uuid}', { uuid: document.value.uuid })
481+
: null)
482+
const normalizedFile = normalizeEditableRequestFile({
483+
id: document.value.id,
484+
name: document.value.name,
485+
file: document.value.file ?? pdfUrl ?? null,
486+
metadata: document.value.metadata,
487+
signers: document.value.signers,
488+
visibleElements: document.value.visibleElements,
489+
})
490+
491+
if (!normalizedFile) {
492+
return null
493+
}
494+
495+
return getFileUrl(toVisibleElementsFile(normalizedFile)) ? normalizedFile : null
496+
})
497+
function hasRenderablePdfFiles(files: EditableRequestChildFile[]): boolean {
498+
return files.some((file) => getFileUrl(toVisibleElementsFile(file)) !== null)
499+
}
500+
const documentFiles = computed<EditableRequestChildFile[]>(() => {
501+
if (fetchedFiles.value.length > 0) {
502+
return fetchedFiles.value
503+
}
504+
505+
if (Array.isArray(document.value.files) && document.value.files.length > 0 && hasRenderablePdfFiles(document.value.files)) {
506+
return document.value.files
507+
}
508+
509+
return fallbackDocumentFile.value ? [fallbackDocumentFile.value] : []
510+
})
458511
const visibleElementsDocument = computed<DocumentLike>(() => toVisibleElementsDocument(document.value))
459512
const visibleElementsFiles = computed<FileLike[]>(() => documentFiles.value.map(toVisibleElementsFile))
460513
const sidebarSigners = computed<Array<{ signer: EditableRequestSigner; index: number }>>(() => {
@@ -554,15 +607,41 @@ async function showModal() {
554607
}
555608
modal.value = true
556609
filesStore.loading = true
610+
pdfEditorFiles.value = []
557611
558612
if (documentFiles.value.length === 0) {
559613
await fetchFiles()
560614
}
561615
616+
await loadPdfEditorFiles()
562617
buildFilePagesMap()
563618
filesStore.loading = false
564619
}
565620
621+
async function loadPdfEditorFiles() {
622+
const urls = pdfFiles.value.filter((file): file is string => typeof file === 'string' && file.length > 0)
623+
if (urls.length === 0) {
624+
pdfEditorFiles.value = []
625+
return
626+
}
627+
628+
const blobs: File[] = []
629+
for (const [index, url] of urls.entries()) {
630+
const response = await fetch(url)
631+
const contentType = response.headers.get('Content-Type') ?? ''
632+
if (!response.ok || contentType.includes('application/json')) {
633+
showError(t('libresign', 'Document not found'))
634+
pdfEditorFiles.value = []
635+
return
636+
}
637+
638+
const blob = await response.blob()
639+
blobs.push(new File([blob], pdfFileNames.value[index] || `document-${index + 1}.pdf`, { type: 'application/pdf' }))
640+
}
641+
642+
pdfEditorFiles.value = blobs
643+
}
644+
566645
async function fetchFiles() {
567646
const response = await axios.get(generateOcsUrl('/apps/libresign/api/v1/file/list'), {
568647
params: {
@@ -622,6 +701,7 @@ function closeModal() {
622701
filesStore.loading = false
623702
elementsLoaded.value = false
624703
fetchedFiles.value = []
704+
pdfEditorFiles.value = []
625705
stopAddSigner()
626706
}
627707

0 commit comments

Comments
 (0)