diff --git a/src-ui/src/app/components/document-detail/document-detail.component.spec.ts b/src-ui/src/app/components/document-detail/document-detail.component.spec.ts index 83490cb57..554f7ef64 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.spec.ts +++ b/src-ui/src/app/components/document-detail/document-detail.component.spec.ts @@ -1842,6 +1842,43 @@ describe('DocumentDetailComponent', () => { expect(errorSpy).toHaveBeenCalled() }) + it('should clear and isolate version upload state on document change', () => { + initNormally() + httpTestingController.expectOne(component.previewUrl).flush('preview') + + component.versionUploadState = UploadState.Failed + component.versionUploadError = 'boom' + component.docChangeNotifier.next(999) + expect(component.versionUploadState).toBe(UploadState.Idle) + expect(component.versionUploadError).toBeNull() + + const uploadSpy = jest.spyOn(documentService, 'uploadVersion') + const versionsSpy = jest.spyOn(documentService, 'getVersions') + const finished$ = new Subject() + const failed$ = new Subject() + jest + .spyOn(websocketStatusService, 'onDocumentConsumptionFinished') + .mockReturnValueOnce(finished$ as any) + jest + .spyOn(websocketStatusService, 'onDocumentConsumptionFailed') + .mockReturnValueOnce(failed$ as any) + + uploadSpy.mockReturnValueOnce(of('task-stale')) + component.onVersionFileSelected({ + target: createFileInput( + new File(['data'], 'version.pdf', { type: 'application/pdf' }) + ), + } as any) + expect(component.versionUploadState).toBe(UploadState.Processing) + + component.docChangeNotifier.next(1000) + failed$.next({ taskId: 'task-stale', message: 'stale-error' }) + + expect(component.versionUploadState).toBe(UploadState.Idle) + expect(component.versionUploadError).toBeNull() + expect(versionsSpy).not.toHaveBeenCalled() + }) + it('createDisabled should return true if the user does not have permission to add the specified data type', () => { currentUserCan = false expect(component.createDisabled(DataType.Correspondent)).toBeTruthy() 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 522ef5474..4dbffccab 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 @@ -674,6 +674,10 @@ export class DocumentDetailComponent this.loadDocument(documentId) }) + this.docChangeNotifier + .pipe(takeUntil(this.unsubscribeNotifier)) + .subscribe(() => this.clearVersionUploadStatus()) + this.route.paramMap .pipe(takeUntil(this.unsubscribeNotifier)) .subscribe((paramMap) => { @@ -1311,6 +1315,7 @@ export class DocumentDetailComponent onVersionFileSelected(event: Event) { const input = event.target as HTMLInputElement if (!input?.files || input.files.length === 0) return + const uploadDocumentId = this.documentId const file = input.files[0] // Reset input to allow re-selection of the same file later input.value = '' @@ -1318,7 +1323,7 @@ export class DocumentDetailComponent this.versionUploadState = UploadState.Uploading this.versionUploadError = null this.documentsService - .uploadVersion(this.documentId, file, label) + .uploadVersion(uploadDocumentId, file, label) .pipe( first(), tap(() => { @@ -1351,7 +1356,10 @@ export class DocumentDetailComponent message: status.message, })) ) - ).pipe(take(1)) + ).pipe( + takeUntil(merge(this.unsubscribeNotifier, this.docChangeNotifier)), + take(1) + ) }), switchMap((result) => { if (result?.state !== 'success') { @@ -1362,13 +1370,14 @@ export class DocumentDetailComponent } return of(null) } - return this.documentsService.getVersions(this.documentId) + return this.documentsService.getVersions(uploadDocumentId) }), takeUntil(this.unsubscribeNotifier), takeUntil(this.docChangeNotifier) ) .subscribe({ next: (doc) => { + if (uploadDocumentId !== this.documentId) return if (doc?.versions) { this.document.versions = doc.versions const openDoc = this.openDocumentService.getOpenDocument( @@ -1385,6 +1394,7 @@ export class DocumentDetailComponent } }, error: (error) => { + if (uploadDocumentId !== this.documentId) return this.versionUploadState = UploadState.Failed this.versionUploadError = error?.message || $localize`Upload failed.` this.toastService.showError(