]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Handle settings live refresh, unsubscribe subscriptions
authorMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Fri, 30 Sep 2022 22:39:02 +0000 (15:39 -0700)
committerMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Fri, 30 Sep 2022 22:39:02 +0000 (15:39 -0700)
src-ui/src/app/components/manage/settings/settings.component.ts
src-ui/src/app/services/settings.service.ts

index 8e26e8b22ab1def546198400e17f93c5000b9625..0cf336a01e7b45559ed8cf6c7bed28a2d1c582a5 100644 (file)
@@ -16,7 +16,15 @@ import {
 } from 'src/app/services/settings.service'
 import { Toast, ToastService } from 'src/app/services/toast.service'
 import { dirtyCheck, DirtyComponent } from '@ngneat/dirty-check-forms'
-import { Observable, Subscription, BehaviorSubject, first } from 'rxjs'
+import {
+  Observable,
+  Subscription,
+  BehaviorSubject,
+  first,
+  tap,
+  takeUntil,
+  Subject,
+} from 'rxjs'
 import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
 import { ActivatedRoute } from '@angular/router'
 import { ViewportScroller } from '@angular/common'
@@ -57,7 +65,9 @@ export class SettingsComponent
   store: BehaviorSubject<any>
   storeSub: Subscription
   isDirty$: Observable<boolean>
-  isDirty: Boolean = false
+  isDirty: boolean = false
+  unsubscribeNotifier: Subject<any> = new Subject()
+  savePending: boolean = false
 
   get computedDateLocale(): string {
     return (
@@ -75,7 +85,11 @@ export class SettingsComponent
     @Inject(LOCALE_ID) public currentLocale: string,
     private viewportScroller: ViewportScroller,
     private activatedRoute: ActivatedRoute
-  ) {}
+  ) {
+    this.settings.settingsSaved.subscribe(() => {
+      if (!this.savePending) this.initialize()
+    })
+  }
 
   ngAfterViewInit(): void {
     if (this.activatedRoute.snapshot.fragment) {
@@ -88,90 +102,98 @@ export class SettingsComponent
   ngOnInit() {
     this.savedViewService.listAll().subscribe((r) => {
       this.savedViews = r.results
-      let storeData = {
-        bulkEditConfirmationDialogs: this.settings.get(
-          SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS
-        ),
-        bulkEditApplyOnClose: this.settings.get(
-          SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE
-        ),
-        documentListItemPerPage: this.settings.get(
-          SETTINGS_KEYS.DOCUMENT_LIST_SIZE
-        ),
-        darkModeUseSystem: this.settings.get(
-          SETTINGS_KEYS.DARK_MODE_USE_SYSTEM
-        ),
-        darkModeEnabled: this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED),
-        darkModeInvertThumbs: this.settings.get(
-          SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED
-        ),
-        themeColor: this.settings.get(SETTINGS_KEYS.THEME_COLOR),
-        useNativePdfViewer: this.settings.get(
-          SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER
-        ),
-        savedViews: {},
-        displayLanguage: this.settings.getLanguage(),
-        dateLocale: this.settings.get(SETTINGS_KEYS.DATE_LOCALE),
-        dateFormat: this.settings.get(SETTINGS_KEYS.DATE_FORMAT),
-        notificationsConsumerNewDocument: this.settings.get(
-          SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT
-        ),
-        notificationsConsumerSuccess: this.settings.get(
-          SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS
-        ),
-        notificationsConsumerFailed: this.settings.get(
-          SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_FAILED
-        ),
-        notificationsConsumerSuppressOnDashboard: this.settings.get(
-          SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD
-        ),
-        commentsEnabled: this.settings.get(SETTINGS_KEYS.COMMENTS_ENABLED),
-        updateCheckingEnabled: this.settings.get(
-          SETTINGS_KEYS.UPDATE_CHECKING_ENABLED
-        ),
-      }
+      this.initialize()
+    })
+  }
 
-      for (let view of this.savedViews) {
-        storeData.savedViews[view.id.toString()] = {
-          id: view.id,
-          name: view.name,
-          show_on_dashboard: view.show_on_dashboard,
-          show_in_sidebar: view.show_in_sidebar,
-        }
-        this.savedViewGroup.addControl(
-          view.id.toString(),
-          new FormGroup({
-            id: new FormControl(null),
-            name: new FormControl(null),
-            show_on_dashboard: new FormControl(null),
-            show_in_sidebar: new FormControl(null),
-          })
-        )
+  initialize() {
+    this.unsubscribeNotifier.next(true)
+
+    let storeData = {
+      bulkEditConfirmationDialogs: this.settings.get(
+        SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS
+      ),
+      bulkEditApplyOnClose: this.settings.get(
+        SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE
+      ),
+      documentListItemPerPage: this.settings.get(
+        SETTINGS_KEYS.DOCUMENT_LIST_SIZE
+      ),
+      darkModeUseSystem: this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM),
+      darkModeEnabled: this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED),
+      darkModeInvertThumbs: this.settings.get(
+        SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED
+      ),
+      themeColor: this.settings.get(SETTINGS_KEYS.THEME_COLOR),
+      useNativePdfViewer: this.settings.get(
+        SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER
+      ),
+      savedViews: {},
+      displayLanguage: this.settings.getLanguage(),
+      dateLocale: this.settings.get(SETTINGS_KEYS.DATE_LOCALE),
+      dateFormat: this.settings.get(SETTINGS_KEYS.DATE_FORMAT),
+      notificationsConsumerNewDocument: this.settings.get(
+        SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT
+      ),
+      notificationsConsumerSuccess: this.settings.get(
+        SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS
+      ),
+      notificationsConsumerFailed: this.settings.get(
+        SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_FAILED
+      ),
+      notificationsConsumerSuppressOnDashboard: this.settings.get(
+        SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD
+      ),
+      commentsEnabled: this.settings.get(SETTINGS_KEYS.COMMENTS_ENABLED),
+      updateCheckingEnabled: this.settings.get(
+        SETTINGS_KEYS.UPDATE_CHECKING_ENABLED
+      ),
+    }
+
+    for (let view of this.savedViews) {
+      storeData.savedViews[view.id.toString()] = {
+        id: view.id,
+        name: view.name,
+        show_on_dashboard: view.show_on_dashboard,
+        show_in_sidebar: view.show_in_sidebar,
       }
+      this.savedViewGroup.addControl(
+        view.id.toString(),
+        new FormGroup({
+          id: new FormControl(null),
+          name: new FormControl(null),
+          show_on_dashboard: new FormControl(null),
+          show_in_sidebar: new FormControl(null),
+        })
+      )
+    }
 
-      this.store = new BehaviorSubject(storeData)
+    this.store = new BehaviorSubject(storeData)
 
-      this.storeSub = this.store.asObservable().subscribe((state) => {
-        this.settingsForm.patchValue(state, { emitEvent: false })
-      })
+    this.storeSub = this.store.asObservable().subscribe((state) => {
+      this.settingsForm.patchValue(state, { emitEvent: false })
+    })
 
-      // Initialize dirtyCheck
-      this.isDirty$ = dirtyCheck(this.settingsForm, this.store.asObservable())
+    // Initialize dirtyCheck
+    this.isDirty$ = dirtyCheck(this.settingsForm, this.store.asObservable())
 
-      // Record dirty in case we need to 'undo' appearance settings if not saved on close
-      this.isDirty$.subscribe((dirty) => {
+    // Record dirty in case we need to 'undo' appearance settings if not saved on close
+    this.isDirty$
+      .pipe(takeUntil(this.unsubscribeNotifier))
+      .subscribe((dirty) => {
         this.isDirty = dirty
       })
 
-      // "Live" visual changes prior to save
-      this.settingsForm.valueChanges.subscribe(() => {
+    // "Live" visual changes prior to save
+    this.settingsForm.valueChanges
+      .pipe(takeUntil(this.unsubscribeNotifier))
+      .subscribe(() => {
         this.settings.updateAppearanceSettings(
           this.settingsForm.get('darkModeUseSystem').value,
           this.settingsForm.get('darkModeEnabled').value,
           this.settingsForm.get('themeColor').value
         )
       })
-    })
   }
 
   ngOnDestroy() {
@@ -190,6 +212,7 @@ export class SettingsComponent
   }
 
   private saveLocalSettings() {
+    this.savePending = true
     const reloadRequired =
       this.settingsForm.value.displayLanguage !=
         this.store?.getValue()['displayLanguage'] || // displayLanguage is dirty
@@ -265,6 +288,7 @@ export class SettingsComponent
     this.settings
       .storeSettings()
       .pipe(first())
+      .pipe(tap(() => (this.savePending = false)))
       .subscribe({
         next: () => {
           this.store.next(this.settingsForm.value)
index b58a1f84502c8bb0cfc30dcda687e89d279bc7b4..10cc93ce0d76e243fa327137941027080b432ecf 100644 (file)
@@ -1,6 +1,7 @@
 import { DOCUMENT } from '@angular/common'
 import { HttpClient } from '@angular/common/http'
 import {
+  EventEmitter,
   Inject,
   Injectable,
   LOCALE_ID,
@@ -46,6 +47,8 @@ export class SettingsService {
 
   public displayName: string
 
+  public settingsSaved: EventEmitter<any> = new EventEmitter()
+
   constructor(
     rendererFactory: RendererFactory2,
     @Inject(DOCUMENT) private document,
@@ -370,7 +373,13 @@ export class SettingsService {
   }
 
   storeSettings(): Observable<any> {
-    return this.http.post(this.baseUrl, { settings: this.settings })
+    return this.http.post(this.baseUrl, { settings: this.settings }).pipe(
+      tap((results) => {
+        if (results.success) {
+          this.settingsSaved.emit()
+        }
+      })
+    )
   }
 
   maybeMigrateSettings() {