Frontend service doc updated ws

This commit is contained in:
shamoon
2026-02-17 00:02:49 -08:00
parent 397f102195
commit 18f3821598
3 changed files with 60 additions and 2 deletions

View File

@@ -0,0 +1,7 @@
export interface WebsocketDocumentUpdatedMessage {
document_id: number
modified?: string
owner_id?: number
users_can_view?: number[]
groups_can_view?: number[]
}

View File

@@ -416,4 +416,25 @@ describe('ConsumerStatusService', () => {
websocketStatusService.disconnect() websocketStatusService.disconnect()
expect(deleted).toBeTruthy() expect(deleted).toBeTruthy()
}) })
it('should trigger updated subject on document updated', () => {
let updated = false
websocketStatusService.onDocumentUpdated().subscribe((data) => {
updated = true
expect(data.document_id).toEqual(12)
})
websocketStatusService.connect()
server.send({
type: WebsocketStatusType.DOCUMENT_UPDATED,
data: {
document_id: 12,
modified: '2026-02-17T00:00:00Z',
owner_id: 1,
},
})
websocketStatusService.disconnect()
expect(updated).toBeTruthy()
})
}) })

View File

@@ -2,6 +2,7 @@ import { Injectable, inject } from '@angular/core'
import { Subject } from 'rxjs' import { Subject } from 'rxjs'
import { environment } from 'src/environments/environment' import { environment } from 'src/environments/environment'
import { User } from '../data/user' import { User } from '../data/user'
import { WebsocketDocumentUpdatedMessage } from '../data/websocket-document-updated-message'
import { WebsocketDocumentsDeletedMessage } from '../data/websocket-documents-deleted-message' import { WebsocketDocumentsDeletedMessage } from '../data/websocket-documents-deleted-message'
import { WebsocketProgressMessage } from '../data/websocket-progress-message' import { WebsocketProgressMessage } from '../data/websocket-progress-message'
import { SettingsService } from './settings.service' import { SettingsService } from './settings.service'
@@ -9,6 +10,7 @@ import { SettingsService } from './settings.service'
export enum WebsocketStatusType { export enum WebsocketStatusType {
STATUS_UPDATE = 'status_update', STATUS_UPDATE = 'status_update',
DOCUMENTS_DELETED = 'documents_deleted', DOCUMENTS_DELETED = 'documents_deleted',
DOCUMENT_UPDATED = 'document_updated',
} }
// see ProgressStatusOptions in src/documents/plugins/helpers.py // see ProgressStatusOptions in src/documents/plugins/helpers.py
@@ -103,6 +105,8 @@ export class WebsocketStatusService {
private documentConsumptionFinishedSubject = new Subject<FileStatus>() private documentConsumptionFinishedSubject = new Subject<FileStatus>()
private documentConsumptionFailedSubject = new Subject<FileStatus>() private documentConsumptionFailedSubject = new Subject<FileStatus>()
private documentDeletedSubject = new Subject<boolean>() private documentDeletedSubject = new Subject<boolean>()
private documentUpdatedSubject =
new Subject<WebsocketDocumentUpdatedMessage>()
private connectionStatusSubject = new Subject<boolean>() private connectionStatusSubject = new Subject<boolean>()
private get(taskId: string, filename?: string) { private get(taskId: string, filename?: string) {
@@ -169,7 +173,10 @@ export class WebsocketStatusService {
data: messageData, data: messageData,
}: { }: {
type: WebsocketStatusType type: WebsocketStatusType
data: WebsocketProgressMessage | WebsocketDocumentsDeletedMessage data:
| WebsocketProgressMessage
| WebsocketDocumentsDeletedMessage
| WebsocketDocumentUpdatedMessage
} = JSON.parse(ev.data) } = JSON.parse(ev.data)
switch (type) { switch (type) {
@@ -177,6 +184,12 @@ export class WebsocketStatusService {
this.documentDeletedSubject.next(true) this.documentDeletedSubject.next(true)
break break
case WebsocketStatusType.DOCUMENT_UPDATED:
this.handleDocumentUpdated(
messageData as WebsocketDocumentUpdatedMessage
)
break
case WebsocketStatusType.STATUS_UPDATE: case WebsocketStatusType.STATUS_UPDATE:
this.handleProgressUpdate(messageData as WebsocketProgressMessage) this.handleProgressUpdate(messageData as WebsocketProgressMessage)
break break
@@ -184,7 +197,11 @@ export class WebsocketStatusService {
} }
} }
private canViewMessage(messageData: WebsocketProgressMessage): boolean { private canViewMessage(messageData: {
owner_id?: number
users_can_view?: number[]
groups_can_view?: number[]
}): boolean {
// see paperless.consumers.StatusConsumer._can_view // see paperless.consumers.StatusConsumer._can_view
const user: User = this.settingsService.currentUser const user: User = this.settingsService.currentUser
return ( return (
@@ -244,6 +261,15 @@ export class WebsocketStatusService {
} }
} }
handleDocumentUpdated(messageData: WebsocketDocumentUpdatedMessage) {
// fallback if backend didn't restrict message
if (!this.canViewMessage(messageData)) {
return
}
this.documentUpdatedSubject.next(messageData)
}
fail(status: FileStatus, message: string) { fail(status: FileStatus, message: string) {
status.message = message status.message = message
status.phase = FileStatusPhase.FAILED status.phase = FileStatusPhase.FAILED
@@ -297,6 +323,10 @@ export class WebsocketStatusService {
return this.documentDeletedSubject return this.documentDeletedSubject
} }
onDocumentUpdated() {
return this.documentUpdatedSubject
}
onConnectionStatus() { onConnectionStatus() {
return this.connectionStatusSubject.asObservable() return this.connectionStatusSubject.asObservable()
} }