]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Fix: prevent infinite loading crash in mail component (#11978)
authorshamoon <4887959+shamoon@users.noreply.github.com>
Mon, 2 Feb 2026 19:08:01 +0000 (11:08 -0800)
committerGitHub <noreply@github.com>
Mon, 2 Feb 2026 19:08:01 +0000 (11:08 -0800)
src-ui/src/app/components/manage/mail/mail.component.html
src-ui/src/app/components/manage/mail/mail.component.ts
src-ui/src/app/services/rest/abstract-paperless-service.ts

index 8b9678353ec124fea4ee00ec7d8c03e5669f1d8a..45249e876f460057f897840a04755b73700509e4 100644 (file)
         <div class="row fade" [class.show]="showRules">
           <div class="col d-flex align-items-center"><button class="btn btn-link p-0 text-start" type="button" (click)="editMailRule(rule)" [disabled]="!permissionsService.currentUserCan(PermissionAction.Change, PermissionType.MailRule) || !userCanEdit(rule)">{{rule.name}}</button></div>
           <div class="col-1 d-flex align-items-center d-none d-sm-flex">{{rule.order}}</div>
-          <div class="col-2 d-flex align-items-center">{{(mailAccountService.getCached(rule.account) | async)?.name}}</div>
+          <div class="col-2 d-flex align-items-center">{{ mailAccountsById.get(rule.account)?.name }}</div>
           <div class="col-2 d-flex align-items-center d-none d-sm-flex">
             <div class="form-check form-switch mb-0">
               <input #inputField type="checkbox" class="form-check-input cursor-pointer" [id]="rule.id+'_enable'" [(ngModel)]="rule.enabled" (change)="onMailRuleEnableToggled(rule)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.MailRule }">
index 825ca1ffdc3a985e0640a70acbc5d8af5d052158..bc119f525857fcf63267b98c3f79d0451c2ff4f0 100644 (file)
@@ -1,4 +1,3 @@
-import { AsyncPipe } from '@angular/common'
 import { Component, OnDestroy, OnInit, inject } from '@angular/core'
 import { FormsModule, ReactiveFormsModule } from '@angular/forms'
 import { ActivatedRoute } from '@angular/router'
@@ -37,7 +36,6 @@ import { ProcessedMailDialogComponent } from './processed-mail-dialog/processed-
     PageHeaderComponent,
     IfPermissionsDirective,
     IfOwnerDirective,
-    AsyncPipe,
     FormsModule,
     ReactiveFormsModule,
     NgbDropdownModule,
@@ -48,8 +46,8 @@ export class MailComponent
   extends ComponentWithPermissions
   implements OnInit, OnDestroy
 {
-  mailAccountService = inject(MailAccountService)
-  mailRuleService = inject(MailRuleService)
+  private readonly mailAccountService = inject(MailAccountService)
+  private readonly mailRuleService = inject(MailRuleService)
   private toastService = inject(ToastService)
   private modalService = inject(NgbModal)
   permissionsService = inject(PermissionsService)
@@ -58,8 +56,19 @@ export class MailComponent
 
   public MailAccountType = MailAccountType
 
-  mailAccounts: MailAccount[] = []
-  mailRules: MailRule[] = []
+  private _mailAccounts: MailAccount[] = []
+
+  public get mailAccounts() {
+    return this._mailAccounts
+  }
+  private set mailAccounts(accounts: MailAccount[]) {
+    this._mailAccounts = accounts
+    this.mailAccountsById = new Map(
+      accounts.map((account) => [account.id, account])
+    )
+  }
+  public mailAccountsById: Map<number, MailAccount> = new Map()
+  public mailRules: MailRule[] = []
 
   unsubscribeNotifier: Subject<any> = new Subject()
   oAuthAccountId: number
index 60f91eb5faf6be6c051ddec070dff4f1a71bf127..d293d6453165ac0ab90c9fcd4d45b2fc9e2b803e 100644 (file)
@@ -1,7 +1,7 @@
 import { HttpClient, HttpParams } from '@angular/common/http'
 import { inject, Injectable } from '@angular/core'
 import { Observable } from 'rxjs'
-import { map, publishReplay, refCount, tap } from 'rxjs/operators'
+import { map, shareReplay, tap } from 'rxjs/operators'
 import { ObjectWithId } from 'src/app/data/object-with-id'
 import { Results } from 'src/app/data/results'
 import { environment } from 'src/environments/environment'
@@ -90,7 +90,7 @@ export abstract class AbstractPaperlessService<T extends ObjectWithId> {
         sortField,
         sortReverse,
         extraParams
-      ).pipe(publishReplay(1), refCount())
+      ).pipe(shareReplay({ bufferSize: 1, refCount: true }))
     }
     return this._listAll
   }