]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Fix: saved views do not return to default display fields after setting and then remov...
authorshamoon <4887959+shamoon@users.noreply.github.com>
Wed, 19 Feb 2025 23:44:48 +0000 (15:44 -0800)
committerGitHub <noreply@github.com>
Wed, 19 Feb 2025 23:44:48 +0000 (15:44 -0800)
src-ui/messages.xlf
src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts
src-ui/src/app/services/rest/saved-view.service.spec.ts
src-ui/src/app/services/rest/saved-view.service.ts
src/documents/serialisers.py
src/documents/tests/test_api_documents.py

index b9af58af361663e90152f3c7ba57e08189a38d6b..7d42085c3f8cf96ee958156268e2e359aa09bd74 100644 (file)
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">103</context>
+          <context context-type="linenumber">106</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">105</context>
+          <context context-type="linenumber">108</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">85</context>
+          <context context-type="linenumber">87</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1841172489943868696" datatype="html">
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">93</context>
+          <context context-type="linenumber">96</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6048892649018070225" datatype="html">
         <source>Confirm delete field</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">101</context>
+          <context context-type="linenumber">104</context>
         </context-group>
       </trans-unit>
       <trans-unit id="2939457975223185057" datatype="html">
         <source>This operation will permanently delete this field.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">102</context>
+          <context context-type="linenumber">105</context>
         </context-group>
       </trans-unit>
       <trans-unit id="4679555638382452936" datatype="html">
         <source>Deleted field &quot;<x id="PH" equiv-text="field.name"/>&quot;</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">111</context>
+          <context context-type="linenumber">114</context>
         </context-group>
       </trans-unit>
       <trans-unit id="4704551499967874824" datatype="html">
         <source>Error deleting field &quot;<x id="PH" equiv-text="field.name"/>&quot;.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">118</context>
+          <context context-type="linenumber">122</context>
         </context-group>
       </trans-unit>
       <trans-unit id="8084492669582894778" datatype="html">
index 32bf7a004a14a0e8c7d18682cb6180955dd73a7c..8399b06e1e3e21a1fc389f2be177a34884354096 100644 (file)
@@ -145,7 +145,10 @@ export class SavedViewWidgetComponent
         })
     }
 
-    if (this.savedView.display_fields) {
+    if (
+      this.savedView.display_fields &&
+      this.savedView.display_fields.length > 0
+    ) {
       this.displayFields = this.savedView.display_fields
     }
 
index 9a84fbd2c3059744575d8ba908cc63742de3030e..7b12e8533aa79639ef20e2844c11d642e721ca13 100644 (file)
@@ -114,6 +114,48 @@ describe(`Additional service tests for SavedViewService`, () => {
     ])
   })
 
+  it('should treat empty display_fields as null', () => {
+    subscription = service
+      .patch({
+        id: 1,
+        name: 'Saved View',
+        show_on_dashboard: true,
+        show_in_sidebar: true,
+        sort_field: 'name',
+        sort_reverse: true,
+        filter_rules: [],
+        display_fields: [],
+      })
+      .subscribe()
+    const req = httpTestingController.expectOne(
+      `${environment.apiBaseUrl}${endpoint}/1/`
+    )
+    expect(req.request.body.display_fields).toBeNull()
+  })
+
+  it('should support patch without reload', () => {
+    subscription = service
+      .patch(
+        {
+          id: 1,
+          name: 'Saved View',
+          show_on_dashboard: true,
+          show_in_sidebar: true,
+          sort_field: 'name',
+          sort_reverse: true,
+          filter_rules: [],
+        },
+        false
+      )
+      .subscribe()
+    const req = httpTestingController.expectOne(
+      `${environment.apiBaseUrl}${endpoint}/1/`
+    )
+    expect(req.request.method).toEqual('PATCH')
+    req.flush({})
+    httpTestingController.verify() // no reload
+  })
+
   beforeEach(() => {
     // Dont need to setup again
 
index a23de7cd19c3b64dfac8c795439225163dd0809b..ef794ae0685f2223c188bdf3b12aa77d59869c00 100644 (file)
@@ -87,12 +87,21 @@ export class SavedViewService extends AbstractPaperlessService<SavedView> {
     return super.create(o).pipe(tap(() => this.reload()))
   }
 
-  update(o: SavedView) {
-    return super.update(o).pipe(tap(() => this.reload()))
+  patch(o: SavedView, reload: boolean = false): Observable<SavedView> {
+    if (o.display_fields?.length === 0) {
+      o.display_fields = null
+    }
+    return super.patch(o).pipe(
+      tap(() => {
+        if (reload) {
+          this.reload()
+        }
+      })
+    )
   }
 
   patchMany(objects: SavedView[]): Observable<SavedView[]> {
-    return combineLatest(objects.map((o) => super.patch(o))).pipe(
+    return combineLatest(objects.map((o) => this.patch(o, false))).pipe(
       tap(() => this.reload())
     )
   }
index 84894bff1b615eb7fd6fcf3613039c038d1c8d06..75896ecdd22e7387116ed1c71d150f1796ff35bf 100644 (file)
@@ -1147,6 +1147,15 @@ class SavedViewSerializer(OwnedObjectSerializer):
         if "user" in validated_data:
             # backwards compatibility
             validated_data["owner"] = validated_data.pop("user")
+        if (
+            "display_fields" in validated_data
+            and isinstance(
+                validated_data["display_fields"],
+                list,
+            )
+            and len(validated_data["display_fields"]) == 0
+        ):
+            validated_data["display_fields"] = None
         super().update(instance, validated_data)
         if rules_data is not None:
             SavedViewFilterRule.objects.filter(saved_view=instance).delete()
index 7010c5095d84eb9ae6c76220f00344ffc66f26df..a1bea944a04d9528bc6201f2898bb333a28b3a88 100644 (file)
@@ -1815,6 +1815,19 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
         )
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
 
+        # empty display fields treated as none
+        response = self.client.patch(
+            f"/api/saved_views/{v1.id}/",
+            {
+                "display_fields": [],
+            },
+            format="json",
+        )
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+
+        v1.refresh_from_db()
+        self.assertEqual(v1.display_fields, None)
+
     def test_saved_view_display_customfields(self):
         """
         GIVEN: