]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Fix: track and restore changed document fields from session storage (#10468)
authorshamoon <4887959+shamoon@users.noreply.github.com>
Tue, 29 Jul 2025 04:38:43 +0000 (00:38 -0400)
committerGitHub <noreply@github.com>
Tue, 29 Jul 2025 04:38:43 +0000 (00:38 -0400)
src-ui/src/app/components/document-detail/document-detail.component.spec.ts
src-ui/src/app/components/document-detail/document-detail.component.ts
src-ui/src/app/data/document.ts
src-ui/src/app/services/open-documents.service.spec.ts
src-ui/src/app/services/open-documents.service.ts

index 9be722c3a38bc8a31dfcd98898da2c4580633052..80b160171cedc268a53a0177c33e6b4c82d5f4fe 100644 (file)
@@ -1030,6 +1030,22 @@ describe('DocumentDetailComponent', () => {
     })
   })
 
+  it('should restore changed fields and mark as dirty', () => {
+    jest
+      .spyOn(activatedRoute, 'paramMap', 'get')
+      .mockReturnValue(of(convertToParamMap({ id: 3, section: 'details' })))
+    jest.spyOn(documentService, 'get').mockReturnValueOnce(of(doc))
+    const docWithChanges = Object.assign({}, doc)
+    docWithChanges.__changedFields = ['title', 'tags', 'owner']
+    jest
+      .spyOn(openDocumentsService, 'getOpenDocument')
+      .mockReturnValue(docWithChanges)
+    fixture.detectChanges() // calls ngOnInit
+    expect(component.documentForm.get('title').dirty).toBeTruthy()
+    expect(component.documentForm.get('tags').dirty).toBeTruthy()
+    expect(component.documentForm.get('permissions_form').dirty).toBeTruthy()
+  })
+
   it('should show custom field errors', () => {
     initNormally()
     component.error = {
index 3f51712ed53fefe472682fda43f2b50caf585b2c..55b8ade3974687b03c98f03af8024ba3f89fd40d 100644 (file)
@@ -451,6 +451,15 @@ export class DocumentDetailComponent
                 ]
               delete openDocument['permissions_form']
             }
+            if (openDocument.__changedFields) {
+              openDocument.__changedFields.forEach((field) => {
+                if (field === 'owner' || field === 'set_permissions') {
+                  this.documentForm.get('permissions_form').markAsDirty()
+                } else {
+                  this.documentForm.get(field)?.markAsDirty()
+                }
+              })
+            }
             this.updateComponent(openDocument)
           } else {
             this.openDocumentService.openDocument(doc)
@@ -514,7 +523,7 @@ export class DocumentDetailComponent
       )
       .subscribe({
         next: ({ doc, dirty }) => {
-          this.openDocumentService.setDirty(doc, dirty)
+          this.openDocumentService.setDirty(doc, dirty, this.getChangedFields())
         },
         error: (error) => {
           this.router.navigate(['404'], {
index 5c23a86002062752c2f55e82893898daa4c70f23..8aae31945e28e14c6b3924eb198024b916d5b766 100644 (file)
@@ -158,4 +158,7 @@ export interface Document extends ObjectWithPermissions {
   remove_inbox_tags?: boolean
 
   page_count?: number
+
+  // Frontend only
+  __changedFields?: string[]
 }
index 70c416bf852bc3653de1d5ef52b353dd3b099f64..2678097df53800b7ebecb8c83a55b02d07b5e0c8 100644 (file)
@@ -241,4 +241,15 @@ describe('OpenDocumentsService', () => {
     openDocumentsService.openDocument(doc)
     expect(consoleSpy).toHaveBeenCalled()
   })
+
+  it('should set dirty status with changed fields', () => {
+    subscriptions.push(
+      openDocumentsService.openDocument(documents[0]).subscribe()
+    )
+    const changedFields = { title: 'foo', content: 'bar' }
+    openDocumentsService.setDirty(documents[0], true, changedFields)
+    expect(
+      openDocumentsService.getOpenDocument(documents[0].id).__changedFields
+    ).toEqual(['title', 'content'])
+  })
 })
index 92c137fec9561f68c4d8cdc168fea9d29a136695..ebe90d8e8ebfc0d1bc0b2cc9cfd015cc1b94d28f 100644 (file)
@@ -84,10 +84,20 @@ export class OpenDocumentsService {
     this.save()
   }
 
-  setDirty(doc: Document, dirty: boolean) {
-    if (!this.openDocuments.find((d) => d.id == doc.id)) return
-    if (dirty) this.dirtyDocuments.add(doc.id)
-    else this.dirtyDocuments.delete(doc.id)
+  setDirty(doc: Document, dirty: boolean, changedFields: object = {}) {
+    const existingDoc = this.getOpenDocument(doc.id)
+    if (!existingDoc) return
+    if (dirty) {
+      this.dirtyDocuments.add(doc.id)
+      existingDoc.__changedFields = Object.keys(changedFields).filter(
+        (key) => key !== 'id'
+      )
+    } else {
+      this.dirtyDocuments.delete(doc.id)
+      existingDoc.__changedFields = []
+    }
+
+    this.save()
   }
 
   hasDirty(): boolean {