From 873f52013510b2cd35772186d40b6b0967cd62f9 Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Thu, 19 Jun 2025 11:21:47 -0700
Subject: [PATCH] Enhancement: show document count on sidebar saved views
---
.../app-frame/app-frame.component.html | 9 ++++-
.../app-frame/app-frame.component.spec.ts | 1 +
.../app-frame/app-frame.component.ts | 10 ++++-
.../services/rest/saved-view.service.spec.ts | 35 +++++++++++++++--
.../app/services/rest/saved-view.service.ts | 38 +++++++++++++++++--
5 files changed, 83 insertions(+), 10 deletions(-)
diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html
index ff80288aa..aab547dd4 100644
--- a/src-ui/src/app/components/app-frame/app-frame.component.html
+++ b/src-ui/src/app/components/app-frame/app-frame.component.html
@@ -112,7 +112,14 @@
routerLinkActive="active" (click)="closeMenu()" [ngbPopover]="view.name"
[disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave"
popoverClass="popover-slim">
- {{view.name}}
+ {{view.name}}
+ @if (!slimSidebarEnabled) {
+ {{ savedViewService.getDocumentCount(view) }}
+ }
+
+ @if (slimSidebarEnabled) {
+ {{ savedViewService.getDocumentCount(view) }}
+ }
@if (settingsService.organizingSidebarSavedViews) {
diff --git a/src-ui/src/app/components/app-frame/app-frame.component.spec.ts b/src-ui/src/app/components/app-frame/app-frame.component.spec.ts
index f1d54ba70..5547eb429 100644
--- a/src-ui/src/app/components/app-frame/app-frame.component.spec.ts
+++ b/src-ui/src/app/components/app-frame/app-frame.component.spec.ts
@@ -121,6 +121,7 @@ describe('AppFrameComponent', () => {
results: saved_views,
}),
sidebarViews: saved_views.filter((v) => v.show_in_sidebar),
+ getDocumentCount: (view: SavedView) => 5,
},
},
PermissionsService,
diff --git a/src-ui/src/app/components/app-frame/app-frame.component.ts b/src-ui/src/app/components/app-frame/app-frame.component.ts
index 09252fe19..11ed3a564 100644
--- a/src-ui/src/app/components/app-frame/app-frame.component.ts
+++ b/src-ui/src/app/components/app-frame/app-frame.component.ts
@@ -35,6 +35,7 @@ import {
PermissionsService,
PermissionType,
} from 'src/app/services/permissions.service'
+import { DocumentService } from 'src/app/services/rest/document.service'
import {
AppRemoteVersion,
RemoteVersionService,
@@ -91,7 +92,8 @@ export class AppFrameComponent
private readonly toastService: ToastService,
private modalService: NgbModal,
public permissionsService: PermissionsService,
- private djangoMessagesService: DjangoMessagesService
+ private djangoMessagesService: DjangoMessagesService,
+ private documentService: DocumentService
) {
super()
@@ -101,7 +103,11 @@ export class AppFrameComponent
PermissionType.SavedView
)
) {
- this.savedViewService.reload()
+ this.savedViewService.reload(() => {
+ this.savedViewService.getDocumentCounts(
+ this.savedViewService.sidebarViews
+ )
+ })
}
}
diff --git a/src-ui/src/app/services/rest/saved-view.service.spec.ts b/src-ui/src/app/services/rest/saved-view.service.spec.ts
index cc206de08..d3e1a913e 100644
--- a/src-ui/src/app/services/rest/saved-view.service.spec.ts
+++ b/src-ui/src/app/services/rest/saved-view.service.spec.ts
@@ -17,7 +17,7 @@ const saved_views = [
id: 1,
show_on_dashboard: true,
show_in_sidebar: true,
- sort_field: 'name',
+ sort_field: 'title',
sort_reverse: true,
filter_rules: [],
},
@@ -26,7 +26,7 @@ const saved_views = [
id: 2,
show_on_dashboard: true,
show_in_sidebar: true,
- sort_field: 'name',
+ sort_field: 'created',
sort_reverse: true,
filter_rules: [],
},
@@ -35,7 +35,7 @@ const saved_views = [
id: 3,
show_on_dashboard: true,
show_in_sidebar: true,
- sort_field: 'name',
+ sort_field: 'added',
sort_reverse: true,
filter_rules: [],
},
@@ -44,7 +44,7 @@ const saved_views = [
id: 4,
show_on_dashboard: false,
show_in_sidebar: false,
- sort_field: 'name',
+ sort_field: 'owner',
sort_reverse: true,
filter_rules: [],
},
@@ -222,6 +222,33 @@ describe(`Additional service tests for SavedViewService`, () => {
})
})
+ it('should accept a callback for reload', () => {
+ const reloadSpy = jest.fn()
+ service.reload(reloadSpy)
+ const req = httpTestingController.expectOne(
+ `${environment.apiBaseUrl}${endpoint}/?page=1&page_size=100000`
+ )
+ req.flush({
+ results: saved_views,
+ })
+ expect(reloadSpy).toHaveBeenCalled()
+ })
+
+ it('should support getting document counts for views', () => {
+ service.getDocumentCounts(saved_views)
+ saved_views.forEach((saved_view) => {
+ const req = httpTestingController.expectOne(
+ `${environment.apiBaseUrl}documents/?page=1&page_size=1&ordering=-${saved_view.sort_field}&fields=id&truncate_content=true`
+ )
+ req.flush({
+ all: [],
+ count: 1,
+ results: [{ id: 1 }],
+ })
+ })
+ expect(service.getDocumentCount(saved_views[0])).toEqual(1)
+ })
+
beforeEach(() => {
// Dont need to setup again
diff --git a/src-ui/src/app/services/rest/saved-view.service.ts b/src-ui/src/app/services/rest/saved-view.service.ts
index ef794ae06..30fd73c17 100644
--- a/src-ui/src/app/services/rest/saved-view.service.ts
+++ b/src-ui/src/app/services/rest/saved-view.service.ts
@@ -7,6 +7,7 @@ import { SavedView } from 'src/app/data/saved-view'
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
import { SettingsService } from '../settings.service'
import { AbstractPaperlessService } from './abstract-paperless-service'
+import { DocumentService } from './document.service'
@Injectable({
providedIn: 'root',
@@ -14,10 +15,12 @@ import { AbstractPaperlessService } from './abstract-paperless-service'
export class SavedViewService extends AbstractPaperlessService {
public loading: boolean = true
private savedViews: SavedView[] = []
+ private savedViewDocumentCounts: Map = new Map()
constructor(
protected http: HttpClient,
- private settingsService: SettingsService
+ private settingsService: SettingsService,
+ private documentService: DocumentService
) {
super(http, 'saved_views')
}
@@ -45,8 +48,16 @@ export class SavedViewService extends AbstractPaperlessService {
)
}
- public reload() {
- this.listAll().subscribe()
+ public reload(callback: any = null) {
+ this.listAll()
+ .pipe(
+ tap((r) => {
+ if (callback) {
+ callback(r)
+ }
+ })
+ )
+ .subscribe()
}
get allViews() {
@@ -109,4 +120,25 @@ export class SavedViewService extends AbstractPaperlessService {
delete(o: SavedView) {
return super.delete(o).pipe(tap(() => this.reload()))
}
+
+ getDocumentCounts(views: SavedView[]) {
+ views.forEach((view) => {
+ this.documentService
+ .listFiltered(
+ 1,
+ 1,
+ view.sort_field,
+ view.sort_reverse,
+ view.filter_rules,
+ { fields: 'id', truncate_content: true }
+ )
+ .subscribe((results: Results) => {
+ this.savedViewDocumentCounts.set(view.id, results.count)
+ })
+ })
+ }
+
+ public getDocumentCount(view: SavedView): number {
+ return this.savedViewDocumentCounts.get(view.id)
+ }
}