mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	cleanup subscriptions
This commit is contained in:
		| @@ -1,8 +1,8 @@ | ||||
| import { Component, OnDestroy } from '@angular/core'; | ||||
| import { Component } from '@angular/core'; | ||||
| import { FormControl } from '@angular/forms'; | ||||
| import { ActivatedRoute, Router, Params } from '@angular/router'; | ||||
| import { from, Observable, Subscription, BehaviorSubject } from 'rxjs'; | ||||
| import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators'; | ||||
| import { debounceTime, distinctUntilChanged, map, switchMap, first } from 'rxjs/operators'; | ||||
| import { PaperlessDocument } from 'src/app/data/paperless-document'; | ||||
| import { OpenDocumentsService } from 'src/app/services/open-documents.service'; | ||||
| import { SavedViewService } from 'src/app/services/rest/saved-view.service'; | ||||
| @@ -18,7 +18,7 @@ import { FILTER_FULLTEXT_QUERY } from 'src/app/data/filter-rule-type'; | ||||
|   templateUrl: './app-frame.component.html', | ||||
|   styleUrls: ['./app-frame.component.scss'] | ||||
| }) | ||||
| export class AppFrameComponent implements OnDestroy { | ||||
| export class AppFrameComponent { | ||||
|  | ||||
|   constructor ( | ||||
|     public router: Router, | ||||
| @@ -40,8 +40,6 @@ export class AppFrameComponent implements OnDestroy { | ||||
|  | ||||
|   searchField = new FormControl('') | ||||
|  | ||||
|   closeAllSub: Subscription | ||||
|  | ||||
|   get openDocuments(): PaperlessDocument[] { | ||||
|     return this.openDocumentsService.getOpenDocuments() | ||||
|   } | ||||
| @@ -81,21 +79,23 @@ export class AppFrameComponent implements OnDestroy { | ||||
|   } | ||||
|  | ||||
|   closeDocument(d: PaperlessDocument) { | ||||
|     this.closeMenu() | ||||
|     this.openDocumentsService.closeDocument(d) | ||||
|  | ||||
|     let route = this.activatedRoute.snapshot | ||||
|     while (route.firstChild) { | ||||
|       route = route.firstChild | ||||
|     } | ||||
|     if (route.component == DocumentDetailComponent && route.params['id'] == d.id) { | ||||
|       this.router.navigate([""]) | ||||
|     } | ||||
|     this.openDocumentsService.closeDocument(d).pipe(first()).subscribe(confirmed => { | ||||
|       if (confirmed) { | ||||
|         this.closeMenu() | ||||
|         let route = this.activatedRoute.snapshot | ||||
|         while (route.firstChild) { | ||||
|           route = route.firstChild | ||||
|         } | ||||
|         if (route.component == DocumentDetailComponent && route.params['id'] == d.id) { | ||||
|           this.router.navigate([""]) | ||||
|         } | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   closeAll() { | ||||
|     // user may need to confirm losing unsaved changes | ||||
|     this.closeAllSub = this.openDocumentsService.closeAll().subscribe(confirmed => { | ||||
|     this.openDocumentsService.closeAll().pipe(first()).subscribe(confirmed => { | ||||
|       if (confirmed) { | ||||
|         this.closeMenu() | ||||
|  | ||||
| @@ -111,10 +111,6 @@ export class AppFrameComponent implements OnDestroy { | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   ngOnDestroy() { | ||||
|     this.closeAllSub && this.closeAllSub.unsubscribe(); | ||||
|   } | ||||
|  | ||||
|   get displayName() { | ||||
|     // TODO: taken from dashboard component, is this the best way to pass around username? | ||||
|     let tagFullName = this.meta.getTag('name=full_name') | ||||
|   | ||||
| @@ -38,7 +38,7 @@ | ||||
|         </svg> <span class="d-none d-lg-inline" i18n>More like this</span> | ||||
|     </button> | ||||
|  | ||||
|     <button type="button" class="btn btn-sm btn-outline-primary" (click)="maybeClose()"> | ||||
|     <button type="button" class="btn btn-sm btn-outline-primary" (click)="close()"> | ||||
|         <svg class="buttonicon" fill="currentColor"> | ||||
|             <use xlink:href="assets/bootstrap-icons.svg#x" /> | ||||
|         </svg> <span class="d-none d-lg-inline" i18n>Close</span> | ||||
|   | ||||
| @@ -110,7 +110,7 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen | ||||
|     this.correspondentService.listAll().pipe(first()).subscribe(result => this.correspondents = result.results) | ||||
|     this.documentTypeService.listAll().pipe(first()).subscribe(result => this.documentTypes = result.results) | ||||
|  | ||||
|     this.route.paramMap.pipe(first()).subscribe(paramMap => { | ||||
|     this.route.paramMap.pipe(takeUntil(this.unsubscribeNotifier)).subscribe(paramMap => { | ||||
|       this.documentId = +paramMap.get('id') | ||||
|       this.previewUrl = this.documentsService.getPreviewUrl(this.documentId) | ||||
|       this.downloadUrl = this.documentsService.getDownloadUrl(this.documentId) | ||||
| @@ -133,7 +133,7 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen | ||||
|  | ||||
|         this.isDirty$ = dirtyCheck(this.documentForm, this.store.asObservable()) | ||||
|         this.isDirty$.pipe(takeUntil(this.unsubscribeNotifier)).subscribe(dirty => { | ||||
|           this.openDocumentService.setDirty(this.document.id, dirty) | ||||
|           this.openDocumentService.setDirty(this.documentId, dirty) | ||||
|         }) | ||||
|  | ||||
|         if (!this.openDocumentService.getOpenDocument(this.documentId)) { | ||||
| @@ -216,12 +216,15 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen | ||||
|     this.store.next(this.documentForm.value) | ||||
|     this.documentsService.update(this.document).pipe(first()).subscribe(result => { | ||||
|       this.error = null | ||||
|       this.documentListViewService.getNext(this.document.id).pipe(first()).subscribe(nextDocId => { | ||||
|       this.documentListViewService.getNext(this.documentId).pipe(first()).subscribe(nextDocId => { | ||||
|         this.networkActive = false | ||||
|         if (nextDocId) { | ||||
|           this.openDocumentService.closeDocument(this.document) | ||||
|           this.router.navigate(['documents', nextDocId]) | ||||
|           this.titleInput.focus() | ||||
|           this.openDocumentService.closeDocument(this.document, true).pipe(first()).subscribe(closed => { | ||||
|             if (closed) { | ||||
|               this.router.navigate(['documents', nextDocId]) | ||||
|               this.titleInput.focus() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }, error => { | ||||
|         this.networkActive = false | ||||
| @@ -232,35 +235,17 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   maybeClose() { | ||||
|     this.isDirty$.pipe(takeUntil(this.unsubscribeNotifier)).subscribe(dirty => { | ||||
|       if (dirty) { | ||||
|         let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) | ||||
|         modal.componentInstance.title = $localize`Unsaved Changes` | ||||
|         modal.componentInstance.messageBold = $localize`You have unsaved changes.` | ||||
|         modal.componentInstance.message = $localize`Are you sure you want to leave?` | ||||
|         modal.componentInstance.btnClass = "btn-warning" | ||||
|         modal.componentInstance.btnCaption = $localize`Leave page` | ||||
|         modal.componentInstance.confirmClicked.pipe(first()).subscribe(() => { | ||||
|           modal.componentInstance.buttonsEnabled = false | ||||
|           modal.close() | ||||
|           this.close() | ||||
|         }) | ||||
|   close() { | ||||
|     this.openDocumentService.closeDocument(this.document).pipe(first()).subscribe(closed => { | ||||
|       if (!closed) return; | ||||
|       if (this.documentListViewService.activeSavedViewId) { | ||||
|         this.router.navigate(['view', this.documentListViewService.activeSavedViewId]) | ||||
|       } else { | ||||
|         this.close() | ||||
|         this.router.navigate(['documents']) | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   close() { | ||||
|     this.openDocumentService.closeDocument(this.document) | ||||
|     if (this.documentListViewService.activeSavedViewId) { | ||||
|       this.router.navigate(['view', this.documentListViewService.activeSavedViewId]) | ||||
|     } else { | ||||
|       this.router.navigate(['documents']) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   delete() { | ||||
|     let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) | ||||
|     modal.componentInstance.title = $localize`Confirm delete` | ||||
|   | ||||
| @@ -23,7 +23,7 @@ export class DirtyFormGuard extends DirtyCheckGuard { | ||||
|       modal.close() | ||||
|     }) | ||||
|     const subject = new Subject<boolean>() | ||||
|     modal.componentInstance.subject = subject | ||||
|     modal.componentInstance.confirmSubject = subject | ||||
|     return subject.asObservable() | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import { DocumentService } from './rest/document.service'; | ||||
| import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; | ||||
| import { ConfirmDialogComponent } from 'src/app/components/common/confirm-dialog/confirm-dialog.component'; | ||||
| import { Observable, Subject, of } from 'rxjs'; | ||||
| import { take } from 'rxjs/operators'; | ||||
| import { first } from 'rxjs/operators'; | ||||
|  | ||||
| @Injectable({ | ||||
|   providedIn: 'root' | ||||
| @@ -63,11 +63,30 @@ export class OpenDocumentsService { | ||||
|     else this.dirtyDocuments.delete(documentId) | ||||
|   } | ||||
|  | ||||
|   closeDocument(doc: PaperlessDocument) { | ||||
|   closeDocument(doc: PaperlessDocument, force: boolean = false): Observable<boolean> { | ||||
|     let index = this.openDocuments.findIndex(d => d.id == doc.id) | ||||
|     if (index > -1) { | ||||
|     if (index == -1) return of(true); | ||||
|     if (force || !this.dirtyDocuments.has(doc.id)) { | ||||
|       this.openDocuments.splice(index, 1) | ||||
|       this.save() | ||||
|       return of(true) | ||||
|     } else { | ||||
|       let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) | ||||
|       modal.componentInstance.title = $localize`Unsaved Changes` | ||||
|       modal.componentInstance.messageBold = $localize`You have unsaved changes.` | ||||
|       modal.componentInstance.message = $localize`Are you sure you want to close this document?` | ||||
|       modal.componentInstance.btnClass = "btn-warning" | ||||
|       modal.componentInstance.btnCaption = $localize`Close document` | ||||
|       modal.componentInstance.confirmClicked.pipe(first()).subscribe(() => { | ||||
|         modal.componentInstance.buttonsEnabled = false | ||||
|         modal.close() | ||||
|         this.openDocuments.splice(index, 1) | ||||
|         this.dirtyDocuments.delete(doc.id) | ||||
|         this.save() | ||||
|       }) | ||||
|       const subject = new Subject<boolean>() | ||||
|       modal.componentInstance.confirmSubject = subject | ||||
|       return subject.asObservable() | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -79,14 +98,14 @@ export class OpenDocumentsService { | ||||
|       modal.componentInstance.message = $localize`Are you sure you want to close all documents?` | ||||
|       modal.componentInstance.btnClass = "btn-warning" | ||||
|       modal.componentInstance.btnCaption = $localize`Close documents` | ||||
|       modal.componentInstance.confirmClicked.pipe(take(1)).subscribe(() => { | ||||
|       modal.componentInstance.confirmClicked.pipe(first()).subscribe(() => { | ||||
|         modal.componentInstance.buttonsEnabled = false | ||||
|         modal.close() | ||||
|         this.openDocuments.splice(0, this.openDocuments.length) | ||||
|         this.save() | ||||
|       }) | ||||
|       const subject = new Subject<boolean>() | ||||
|       modal.componentInstance.subject = subject | ||||
|       modal.componentInstance.confirmSubject = subject | ||||
|       return subject.asObservable() | ||||
|     } else { | ||||
|       this.openDocuments.splice(0, this.openDocuments.length) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Michael Shamoon
					Michael Shamoon