diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts index a85be20f3..eb3652676 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.ts +++ b/src-ui/src/app/components/document-detail/document-detail.component.ts @@ -437,6 +437,7 @@ export class DocumentDetailComponent } private loadDocument(documentId: number): void { + let redirectedToHead = false this.selectedVersionId = documentId this.previewUrl = this.documentsService.getPreviewUrl( this.selectedVersionId @@ -459,7 +460,24 @@ export class DocumentDetailComponent this.documentsService .get(documentId) .pipe( - catchError(() => { + catchError((error) => { + if (error?.status === 404) { + return this.documentsService.getHeadId(documentId).pipe( + map((result) => { + const headId = result?.head_id + if (headId && headId !== documentId) { + const section = + this.route.snapshot.paramMap.get('section') || 'details' + redirectedToHead = true + this.router.navigate(['documents', headId, section], { + replaceUrl: true, + }) + } + return null + }), + catchError(() => of(null)) + ) + } // 404 is handled in the subscribe below return of(null) }), @@ -470,6 +488,9 @@ export class DocumentDetailComponent .subscribe({ next: (doc) => { if (!doc) { + if (redirectedToHead) { + return + } this.router.navigate(['404'], { replaceUrl: true }) return } diff --git a/src-ui/src/app/services/rest/document.service.ts b/src-ui/src/app/services/rest/document.service.ts index 7ff001d6e..b3e897e0a 100644 --- a/src-ui/src/app/services/rest/document.service.ts +++ b/src-ui/src/app/services/rest/document.service.ts @@ -211,6 +211,12 @@ export class DocumentService extends AbstractPaperlessService { }) } + getHeadId(documentId: number) { + return this.http.get<{ head_id: number }>( + this.getResourceUrl(documentId, 'head') + ) + } + deleteVersion(headDocumentId: number, versionId: number) { return this.http.delete<{ result: string; current_version_id: number }>( this.getResourceUrl(headDocumentId, `versions/${versionId}`) diff --git a/src/documents/views.py b/src/documents/views.py index 3c1830214..46c396fac 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -805,6 +805,26 @@ class DocumentViewSet( ) return super().get_serializer(*args, **kwargs) + @action(methods=["get"], detail=True, url_path="head") + def head(self, request, pk=None): + try: + doc = Document.global_objects.select_related( + "owner", + "head_version", + ).get(pk=pk) + except Document.DoesNotExist: + raise Http404 + + head_doc = doc if doc.head_version_id is None else doc.head_version + if request.user is not None and not has_perms_owner_aware( + request.user, + "view_document", + head_doc, + ): + return HttpResponseForbidden("Insufficient permissions") + + return Response({"head_id": head_doc.id}) + def update(self, request, *args, **kwargs): response = super().update(request, *args, **kwargs) from documents import index