From 99bdfdfe7a8c7cd4ba8552f4c60d0d2919b4fc1c Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sun, 19 Jul 2026 07:44:12 -0700
Subject: [PATCH] Fix: better handle saved view errors in dashboard widgets
(#13164)
---
.../saved-view-widget.component.html | 4 +-
.../saved-view-widget.component.spec.ts | 29 ++++++++++++-
.../saved-view-widget.component.ts | 43 ++++++++++++++++---
3 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html
index d53e39bbf..9712a64bb 100644
--- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html
+++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html
@@ -14,7 +14,9 @@
}
- @if (displayMode() === DisplayMode.TABLE) {
+ @if (error()) {
+
Error while loading documents: {{error()}}
+ } @else if (displayMode() === DisplayMode.TABLE) {
diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts
index 39480d373..b985bcb26 100644
--- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts
+++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts
@@ -1,6 +1,10 @@
import { DragDropModule } from '@angular/cdk/drag-drop'
import { DatePipe } from '@angular/common'
-import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
+import {
+ HttpErrorResponse,
+ provideHttpClient,
+ withInterceptorsFromDi,
+} from '@angular/common/http'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { By } from '@angular/platform-browser'
@@ -8,7 +12,7 @@ import { Router } from '@angular/router'
import { RouterTestingModule } from '@angular/router/testing'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
-import { Subject, of } from 'rxjs'
+import { Subject, of, throwError } from 'rxjs'
import { routes } from 'src/app/app-routing.module'
import { CustomFieldDisplayComponent } from 'src/app/components/common/custom-field-display/custom-field-display.component'
import { PreviewPopupComponent } from 'src/app/components/common/preview-popup/preview-popup.component'
@@ -230,6 +234,27 @@ describe('SavedViewWidgetComponent', () => {
expect(component.documents()).toEqual(documentResults)
})
+ it('should show an error if documents fail to load', () => {
+ jest.spyOn(documentService, 'listFiltered').mockReturnValue(
+ throwError(
+ () =>
+ new HttpErrorResponse({
+ error: { added__date__lte: ['Enter a valid date.'] },
+ status: 400,
+ })
+ )
+ )
+
+ component.reload()
+ fixture.detectChanges()
+
+ expect(component.loading()).toBe(false)
+ expect(component.error()).toEqual('Added: Enter a valid date.')
+ expect(fixture.debugElement.nativeElement.textContent).toContain(
+ 'Error while loading documents: Added: Enter a valid date.'
+ )
+ })
+
it('should reload on document consumption finished', () => {
const fileStatusSubject = new Subject()
jest
diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts
index 271ce16bb..6cbf18698 100644
--- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts
+++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts
@@ -125,6 +125,8 @@ export class SavedViewWidgetComponent
readonly count = signal(null)
+ readonly error = signal(null)
+
placeholderRows: number[] = []
ngOnInit(): void {
@@ -180,6 +182,7 @@ export class SavedViewWidgetComponent
reload() {
this.loading.set(this.documents().length == 0)
+ this.error.set(null)
this.show.set(true)
this.documentService
.listFiltered(
@@ -191,12 +194,40 @@ export class SavedViewWidgetComponent
{ truncate_content: true }
)
.pipe(takeUntil(this.unsubscribeNotifier))
- .subscribe((result) => {
- this.documents.set(result.results)
- this.count.set(result.count)
- this.savedViewService.setDocumentCount(this.savedView, result.count)
- this.loading.set(false)
- this.show.set(true)
+ .subscribe({
+ next: (result) => {
+ this.documents.set(result.results)
+ this.count.set(result.count)
+ this.savedViewService.setDocumentCount(this.savedView, result.count)
+ this.loading.set(false)
+ this.show.set(true)
+ },
+ error: (error) => {
+ this.documents.set([])
+ this.count.set(null)
+ let errorMessage
+ if (
+ typeof error.error === 'object' &&
+ Object.keys(error.error).length > 0
+ ) {
+ errorMessage = Object.keys(error.error)
+ .map((fieldName) => {
+ const fieldNameBase = fieldName.split('__')[0]
+ const fieldError: Array = error.error[fieldName]
+ return `${
+ this.documentService.sortFields.find(
+ (f) => f.field?.split('__')[0] == fieldNameBase
+ )?.name ?? fieldNameBase
+ }: ${fieldError[0]}`
+ })
+ .join(', ')
+ } else {
+ errorMessage = error.error
+ }
+ this.error.set(errorMessage)
+ this.loading.set(false)
+ this.show.set(true)
+ },
})
}