mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	Cleanup subscriptions
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
			
		||||
import { Component } from '@angular/core';
 | 
			
		||||
import { Component, OnDestroy } from '@angular/core';
 | 
			
		||||
import { FormControl } from '@angular/forms';
 | 
			
		||||
import { ActivatedRoute, Router, Params } from '@angular/router';
 | 
			
		||||
import { from, Observable, Subscription, BehaviorSubject } from 'rxjs';
 | 
			
		||||
@@ -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 {
 | 
			
		||||
export class AppFrameComponent implements OnDestroy {
 | 
			
		||||
 | 
			
		||||
  constructor (
 | 
			
		||||
    public router: Router,
 | 
			
		||||
@@ -40,6 +40,8 @@ export class AppFrameComponent {
 | 
			
		||||
 | 
			
		||||
  searchField = new FormControl('')
 | 
			
		||||
 | 
			
		||||
  closeAllSub: Subscription
 | 
			
		||||
 | 
			
		||||
  get openDocuments(): PaperlessDocument[] {
 | 
			
		||||
    return this.openDocumentsService.getOpenDocuments()
 | 
			
		||||
  }
 | 
			
		||||
@@ -93,7 +95,7 @@ export class AppFrameComponent {
 | 
			
		||||
 | 
			
		||||
  closeAll() {
 | 
			
		||||
    // user may need to confirm losing unsaved changes
 | 
			
		||||
    this.openDocumentsService.closeAll().subscribe(confirmed => {
 | 
			
		||||
    this.closeAllSub = this.openDocumentsService.closeAll().subscribe(confirmed => {
 | 
			
		||||
      if (confirmed) {
 | 
			
		||||
        this.closeMenu()
 | 
			
		||||
 | 
			
		||||
@@ -109,6 +111,8 @@ export class AppFrameComponent {
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnDestroy() {
 | 
			
		||||
    this.closeAllSub && this.closeAllSub.unsubscribe();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get displayName() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
 | 
			
		||||
import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core';
 | 
			
		||||
import { FormControl, FormGroup } from '@angular/forms';
 | 
			
		||||
import { ActivatedRoute, Router } from '@angular/router';
 | 
			
		||||
import { NgbModal, NgbNav } from '@ng-bootstrap/ng-bootstrap';
 | 
			
		||||
@@ -20,7 +20,8 @@ import { ToastService } from 'src/app/services/toast.service';
 | 
			
		||||
import { TextComponent } from '../common/input/text/text.component';
 | 
			
		||||
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
 | 
			
		||||
import { dirtyCheck, DirtyComponent } from '@ngneat/dirty-check-forms';
 | 
			
		||||
import { Observable, Subscription, BehaviorSubject } from 'rxjs';
 | 
			
		||||
import { Observable, Subject, BehaviorSubject } from 'rxjs';
 | 
			
		||||
import { first, takeUntil } from 'rxjs/operators';
 | 
			
		||||
import { PaperlessDocumentSuggestions } from 'src/app/data/paperless-document-suggestions';
 | 
			
		||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type';
 | 
			
		||||
 | 
			
		||||
@@ -29,7 +30,7 @@ import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type';
 | 
			
		||||
  templateUrl: './document-detail.component.html',
 | 
			
		||||
  styleUrls: ['./document-detail.component.scss']
 | 
			
		||||
})
 | 
			
		||||
export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponent {
 | 
			
		||||
 | 
			
		||||
  @ViewChild("inputTitle")
 | 
			
		||||
  titleInput: TextComponent
 | 
			
		||||
@@ -68,8 +69,8 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
  previewNumPages: number = 1
 | 
			
		||||
 | 
			
		||||
  store: BehaviorSubject<any>
 | 
			
		||||
  storeSub: Subscription
 | 
			
		||||
  isDirty$: Observable<boolean>
 | 
			
		||||
  unsubscribeNotifier: Subject<any> = new Subject()
 | 
			
		||||
 | 
			
		||||
  @ViewChild('nav') nav: NgbNav
 | 
			
		||||
  @ViewChild('pdfPreview') set pdfPreview(element) {
 | 
			
		||||
@@ -102,14 +103,14 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
    this.documentForm.valueChanges.subscribe(wow => {
 | 
			
		||||
    this.documentForm.valueChanges.pipe(takeUntil(this.unsubscribeNotifier)).subscribe(wow => {
 | 
			
		||||
      Object.assign(this.document, this.documentForm.value)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    this.correspondentService.listAll().subscribe(result => this.correspondents = result.results)
 | 
			
		||||
    this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results)
 | 
			
		||||
    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.subscribe(paramMap => {
 | 
			
		||||
    this.route.paramMap.pipe(first()).subscribe(paramMap => {
 | 
			
		||||
      this.documentId = +paramMap.get('id')
 | 
			
		||||
      this.previewUrl = this.documentsService.getPreviewUrl(this.documentId)
 | 
			
		||||
      this.downloadUrl = this.documentsService.getDownloadUrl(this.documentId)
 | 
			
		||||
@@ -118,7 +119,7 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
      if (this.openDocumentService.getOpenDocument(this.documentId)) {
 | 
			
		||||
        this.updateComponent(this.openDocumentService.getOpenDocument(this.documentId))
 | 
			
		||||
      }
 | 
			
		||||
      this.documentsService.get(this.documentId).subscribe(doc => {
 | 
			
		||||
      this.documentsService.get(this.documentId).pipe(first()).subscribe(doc => {
 | 
			
		||||
        // Initialize dirtyCheck
 | 
			
		||||
        this.store = new BehaviorSubject({
 | 
			
		||||
          title: doc.title,
 | 
			
		||||
@@ -131,7 +132,7 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        this.isDirty$ = dirtyCheck(this.documentForm, this.store.asObservable())
 | 
			
		||||
        this.isDirty$.subscribe(dirty => {
 | 
			
		||||
        this.isDirty$.pipe(takeUntil(this.unsubscribeNotifier)).subscribe(dirty => {
 | 
			
		||||
          this.openDocumentService.setDirty(this.document.id, dirty)
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
@@ -144,14 +145,19 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnDestroy() : void {
 | 
			
		||||
    this.unsubscribeNotifier.next();
 | 
			
		||||
    this.unsubscribeNotifier.complete();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  updateComponent(doc: PaperlessDocument) {
 | 
			
		||||
    this.document = doc
 | 
			
		||||
    this.documentsService.getMetadata(doc.id).subscribe(result => {
 | 
			
		||||
    this.documentsService.getMetadata(doc.id).pipe(first()).subscribe(result => {
 | 
			
		||||
      this.metadata = result
 | 
			
		||||
    }, error => {
 | 
			
		||||
      this.metadata = null
 | 
			
		||||
    })
 | 
			
		||||
    this.documentsService.getSuggestions(doc.id).subscribe(result => {
 | 
			
		||||
    this.documentsService.getSuggestions(doc.id).pipe(first()).subscribe(result => {
 | 
			
		||||
      this.suggestions = result
 | 
			
		||||
    }, error => {
 | 
			
		||||
      this.suggestions = null
 | 
			
		||||
@@ -164,8 +170,8 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
    var modal = this.modalService.open(DocumentTypeEditDialogComponent, {backdrop: 'static'})
 | 
			
		||||
    modal.componentInstance.dialogMode = 'create'
 | 
			
		||||
    if (newName) modal.componentInstance.object = { name: newName }
 | 
			
		||||
    modal.componentInstance.success.subscribe(newDocumentType => {
 | 
			
		||||
      this.documentTypeService.listAll().subscribe(documentTypes => {
 | 
			
		||||
    modal.componentInstance.success.pipe(first()).subscribe(newDocumentType => {
 | 
			
		||||
      this.documentTypeService.listAll().pipe(first()).subscribe(documentTypes => {
 | 
			
		||||
        this.documentTypes = documentTypes.results
 | 
			
		||||
        this.documentForm.get('document_type').setValue(newDocumentType.id)
 | 
			
		||||
      })
 | 
			
		||||
@@ -176,8 +182,8 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
    var modal = this.modalService.open(CorrespondentEditDialogComponent, {backdrop: 'static'})
 | 
			
		||||
    modal.componentInstance.dialogMode = 'create'
 | 
			
		||||
    if (newName) modal.componentInstance.object = { name: newName }
 | 
			
		||||
    modal.componentInstance.success.subscribe(newCorrespondent => {
 | 
			
		||||
      this.correspondentService.listAll().subscribe(correspondents => {
 | 
			
		||||
    modal.componentInstance.success.pipe(first()).subscribe(newCorrespondent => {
 | 
			
		||||
      this.correspondentService.listAll().pipe(first()).subscribe(correspondents => {
 | 
			
		||||
        this.correspondents = correspondents.results
 | 
			
		||||
        this.documentForm.get('correspondent').setValue(newCorrespondent.id)
 | 
			
		||||
      })
 | 
			
		||||
@@ -185,7 +191,7 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  discard() {
 | 
			
		||||
    this.documentsService.get(this.documentId).subscribe(doc => {
 | 
			
		||||
    this.documentsService.get(this.documentId).pipe(first()).subscribe(doc => {
 | 
			
		||||
      Object.assign(this.document, doc)
 | 
			
		||||
      this.title = doc.title
 | 
			
		||||
      this.documentForm.patchValue(doc)
 | 
			
		||||
@@ -195,7 +201,7 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
  save() {
 | 
			
		||||
    this.networkActive = true
 | 
			
		||||
    this.store.next(this.documentForm.value)
 | 
			
		||||
    this.documentsService.update(this.document).subscribe(result => {
 | 
			
		||||
    this.documentsService.update(this.document).pipe(first()).subscribe(result => {
 | 
			
		||||
      this.close()
 | 
			
		||||
      this.networkActive = false
 | 
			
		||||
      this.error = null
 | 
			
		||||
@@ -208,9 +214,9 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
  saveEditNext() {
 | 
			
		||||
    this.networkActive = true
 | 
			
		||||
    this.store.next(this.documentForm.value)
 | 
			
		||||
    this.documentsService.update(this.document).subscribe(result => {
 | 
			
		||||
    this.documentsService.update(this.document).pipe(first()).subscribe(result => {
 | 
			
		||||
      this.error = null
 | 
			
		||||
      this.documentListViewService.getNext(this.document.id).subscribe(nextDocId => {
 | 
			
		||||
      this.documentListViewService.getNext(this.document.id).pipe(first()).subscribe(nextDocId => {
 | 
			
		||||
        this.networkActive = false
 | 
			
		||||
        if (nextDocId) {
 | 
			
		||||
          this.openDocumentService.closeDocument(this.document)
 | 
			
		||||
@@ -227,7 +233,7 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  maybeClose() {
 | 
			
		||||
    this.isDirty$.subscribe(dirty => {
 | 
			
		||||
    this.isDirty$.pipe(takeUntil(this.unsubscribeNotifier)).subscribe(dirty => {
 | 
			
		||||
      if (dirty) {
 | 
			
		||||
        let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
			
		||||
        modal.componentInstance.title = $localize`Unsaved Changes`
 | 
			
		||||
@@ -235,7 +241,7 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
        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.subscribe(() => {
 | 
			
		||||
        modal.componentInstance.confirmClicked.pipe(first()).subscribe(() => {
 | 
			
		||||
          modal.componentInstance.buttonsEnabled = false
 | 
			
		||||
          modal.close()
 | 
			
		||||
          this.close()
 | 
			
		||||
@@ -262,9 +268,9 @@ export class DocumentDetailComponent implements OnInit, DirtyComponent {
 | 
			
		||||
    modal.componentInstance.message = $localize`The files for this document will be deleted permanently. This operation cannot be undone.`
 | 
			
		||||
    modal.componentInstance.btnClass = "btn-danger"
 | 
			
		||||
    modal.componentInstance.btnCaption = $localize`Delete document`
 | 
			
		||||
    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
			
		||||
    modal.componentInstance.confirmClicked.pipe(first()).subscribe(() => {
 | 
			
		||||
      modal.componentInstance.buttonsEnabled = false
 | 
			
		||||
      this.documentsService.delete(this.document).subscribe(() => {
 | 
			
		||||
      this.documentsService.delete(this.document).pipe(first()).subscribe(() => {
 | 
			
		||||
        modal.close()
 | 
			
		||||
        this.close()
 | 
			
		||||
      }, error => {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +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';
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
  providedIn: 'root'
 | 
			
		||||
@@ -78,7 +79,7 @@ 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.subscribe(() => {
 | 
			
		||||
      modal.componentInstance.confirmClicked.pipe(take(1)).subscribe(() => {
 | 
			
		||||
        modal.componentInstance.buttonsEnabled = false
 | 
			
		||||
        modal.close()
 | 
			
		||||
        this.openDocuments.splice(0, this.openDocuments.length)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user