Feature: option for auto-remove inbox tags on save (#5562)

This commit is contained in:
shamoon 2024-02-01 18:41:10 -08:00 committed by GitHub
parent 9e6aa55230
commit c62d892969
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 196 additions and 35 deletions

View File

@ -1967,7 +1967,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">733</context> <context context-type="linenumber">735</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
@ -2006,7 +2006,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">735</context> <context context-type="linenumber">737</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
@ -4856,78 +4856,78 @@
<source>An error occurred loading content: <x id="PH" equiv-text="err.message ?? err.toString()"/></source> <source>An error occurred loading content: <x id="PH" equiv-text="err.message ?? err.toString()"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">298,300</context> <context context-type="linenumber">300,302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3200733026060976258" datatype="html"> <trans-unit id="3200733026060976258" datatype="html">
<source>Document changes detected</source> <source>Document changes detected</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">321</context> <context context-type="linenumber">323</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2887155916749964" datatype="html"> <trans-unit id="2887155916749964" datatype="html">
<source>The version of this document in your browser session appears older than the existing version.</source> <source>The version of this document in your browser session appears older than the existing version.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">322</context> <context context-type="linenumber">324</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="237142428785956348" datatype="html"> <trans-unit id="237142428785956348" datatype="html">
<source>Saving the document here may overwrite other changes that were made. To restore the existing version, discard your changes or close the document.</source> <source>Saving the document here may overwrite other changes that were made. To restore the existing version, discard your changes or close the document.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">323</context> <context context-type="linenumber">325</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8720977247725652816" datatype="html"> <trans-unit id="8720977247725652816" datatype="html">
<source>Ok</source> <source>Ok</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">325</context> <context context-type="linenumber">327</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5758784066858623886" datatype="html"> <trans-unit id="5758784066858623886" datatype="html">
<source>Error retrieving metadata</source> <source>Error retrieving metadata</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">465</context> <context context-type="linenumber">467</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3456881259945295697" datatype="html"> <trans-unit id="3456881259945295697" datatype="html">
<source>Error retrieving suggestions.</source> <source>Error retrieving suggestions.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">490</context> <context context-type="linenumber">492</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8348337312757497317" datatype="html"> <trans-unit id="8348337312757497317" datatype="html">
<source>Document saved successfully.</source> <source>Document saved successfully.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">608</context> <context context-type="linenumber">610</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">617</context> <context context-type="linenumber">619</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="448882439049417053" datatype="html"> <trans-unit id="448882439049417053" datatype="html">
<source>Error saving document</source> <source>Error saving document</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">621</context> <context context-type="linenumber">623</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">662</context> <context context-type="linenumber">664</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="9021887951960049161" datatype="html"> <trans-unit id="9021887951960049161" datatype="html">
<source>Confirm delete</source> <source>Confirm delete</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">688</context> <context context-type="linenumber">690</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
@ -4938,35 +4938,35 @@
<source>Do you really want to delete document &quot;<x id="PH" equiv-text="this.document.title"/>&quot;?</source> <source>Do you really want to delete document &quot;<x id="PH" equiv-text="this.document.title"/>&quot;?</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">689</context> <context context-type="linenumber">691</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6691075929777935948" datatype="html"> <trans-unit id="6691075929777935948" datatype="html">
<source>The files for this document will be deleted permanently. This operation cannot be undone.</source> <source>The files for this document will be deleted permanently. This operation cannot be undone.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">690</context> <context context-type="linenumber">692</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="719892092227206532" datatype="html"> <trans-unit id="719892092227206532" datatype="html">
<source>Delete document</source> <source>Delete document</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">692</context> <context context-type="linenumber">694</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7295637485862454066" datatype="html"> <trans-unit id="7295637485862454066" datatype="html">
<source>Error deleting document</source> <source>Error deleting document</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">711</context> <context context-type="linenumber">713</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7362691899087997122" datatype="html"> <trans-unit id="7362691899087997122" datatype="html">
<source>Redo OCR confirm</source> <source>Redo OCR confirm</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">731</context> <context context-type="linenumber">733</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
@ -4977,28 +4977,28 @@
<source>This operation will permanently redo OCR for this document.</source> <source>This operation will permanently redo OCR for this document.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">732</context> <context context-type="linenumber">734</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5729001209753056399" datatype="html"> <trans-unit id="5729001209753056399" datatype="html">
<source>Redo OCR operation will begin in the background. Close and re-open or reload this document after the operation has completed to see new content.</source> <source>Redo OCR operation will begin in the background. Close and re-open or reload this document after the operation has completed to see new content.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">743</context> <context context-type="linenumber">745</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4409560272830824468" datatype="html"> <trans-unit id="4409560272830824468" datatype="html">
<source>Error executing operation</source> <source>Error executing operation</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">754</context> <context context-type="linenumber">756</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4458954481601077369" datatype="html"> <trans-unit id="4458954481601077369" datatype="html">
<source>Page Fit</source> <source>Page Fit</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">823</context> <context context-type="linenumber">825</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6857598786757174736" datatype="html"> <trans-unit id="6857598786757174736" datatype="html">

View File

@ -158,6 +158,14 @@
</div> </div>
</div> </div>
<h4 class="mt-4" i18n>Document editing</h4>
<div class="row mb-3">
<div class="offset-md-3 col">
<pngx-input-check i18n-title title="Automatically remove inbox tag(s) on save" formControlName="documentEditingRemoveInboxTags"></pngx-input-check>
</div>
</div>
<h4 class="mt-4" i18n>Bulk editing</h4> <h4 class="mt-4" i18n>Bulk editing</h4>
<div class="row mb-3"> <div class="row mb-3">

View File

@ -289,7 +289,7 @@ describe('SettingsComponent', () => {
expect(toastErrorSpy).toHaveBeenCalled() expect(toastErrorSpy).toHaveBeenCalled()
expect(storeSpy).toHaveBeenCalled() expect(storeSpy).toHaveBeenCalled()
expect(appearanceSettingsSpy).not.toHaveBeenCalled() expect(appearanceSettingsSpy).not.toHaveBeenCalled()
expect(setSpy).toHaveBeenCalledTimes(24) expect(setSpy).toHaveBeenCalledTimes(25)
// succeed // succeed
storeSpy.mockReturnValueOnce(of(true)) storeSpy.mockReturnValueOnce(of(true))

View File

@ -88,6 +88,7 @@ export class SettingsComponent
defaultPermsViewGroups: new FormControl(null), defaultPermsViewGroups: new FormControl(null),
defaultPermsEditUsers: new FormControl(null), defaultPermsEditUsers: new FormControl(null),
defaultPermsEditGroups: new FormControl(null), defaultPermsEditGroups: new FormControl(null),
documentEditingRemoveInboxTags: new FormControl(null),
notificationsConsumerNewDocument: new FormControl(null), notificationsConsumerNewDocument: new FormControl(null),
notificationsConsumerSuccess: new FormControl(null), notificationsConsumerSuccess: new FormControl(null),
@ -271,6 +272,9 @@ export class SettingsComponent
defaultPermsEditGroups: this.settings.get( defaultPermsEditGroups: this.settings.get(
SETTINGS_KEYS.DEFAULT_PERMS_EDIT_GROUPS SETTINGS_KEYS.DEFAULT_PERMS_EDIT_GROUPS
), ),
documentEditingRemoveInboxTags: this.settings.get(
SETTINGS_KEYS.DOCUMENT_EDITING_REMOVE_INBOX_TAGS
),
savedViews: {}, savedViews: {},
} }
} }
@ -484,6 +488,10 @@ export class SettingsComponent
SETTINGS_KEYS.DEFAULT_PERMS_EDIT_GROUPS, SETTINGS_KEYS.DEFAULT_PERMS_EDIT_GROUPS,
this.settingsForm.value.defaultPermsEditGroups this.settingsForm.value.defaultPermsEditGroups
) )
this.settings.set(
SETTINGS_KEYS.DOCUMENT_EDITING_REMOVE_INBOX_TAGS,
this.settingsForm.value.documentEditingRemoveInboxTags
)
this.settings.setLanguage(this.settingsForm.value.displayLanguage) this.settings.setLanguage(this.settingsForm.value.displayLanguage)
this.settings this.settings
.storeSettings() .storeSettings()

View File

@ -630,7 +630,9 @@ export class DocumentDetailComponent
.update(this.document) .update(this.document)
.pipe(first()) .pipe(first())
.subscribe({ .subscribe({
next: () => { next: (docValues) => {
// in case data changed while saving eg removing inbox_tags
this.documentForm.patchValue(docValues)
this.store.next(this.documentForm.value) this.store.next(this.documentForm.value)
this.toastService.showInfo($localize`Document saved successfully.`) this.toastService.showInfo($localize`Document saved successfully.`)
close && this.close() close && this.close()

View File

@ -63,4 +63,7 @@ export interface Document extends ObjectWithPermissions {
__search_hit__?: SearchHit __search_hit__?: SearchHit
custom_fields?: CustomFieldInstance[] custom_fields?: CustomFieldInstance[]
// write-only field
remove_inbox_tags?: boolean
} }

View File

@ -53,6 +53,8 @@ export const SETTINGS_KEYS = {
DEFAULT_PERMS_VIEW_GROUPS: 'general-settings:permissions:default-view-groups', DEFAULT_PERMS_VIEW_GROUPS: 'general-settings:permissions:default-view-groups',
DEFAULT_PERMS_EDIT_USERS: 'general-settings:permissions:default-edit-users', DEFAULT_PERMS_EDIT_USERS: 'general-settings:permissions:default-edit-users',
DEFAULT_PERMS_EDIT_GROUPS: 'general-settings:permissions:default-edit-groups', DEFAULT_PERMS_EDIT_GROUPS: 'general-settings:permissions:default-edit-groups',
DOCUMENT_EDITING_REMOVE_INBOX_TAGS:
'general-settings:document-editing:remove-inbox-tags',
} }
export const SETTINGS: UiSetting[] = [ export const SETTINGS: UiSetting[] = [
@ -206,4 +208,9 @@ export const SETTINGS: UiSetting[] = [
type: 'string', type: 'string',
default: '', default: '',
}, },
{
key: SETTINGS_KEYS.DOCUMENT_EDITING_REMOVE_INBOX_TAGS,
type: 'boolean',
default: false,
},
] ]

View File

@ -7,10 +7,13 @@ import { TestBed } from '@angular/core/testing'
import { environment } from 'src/environments/environment' import { environment } from 'src/environments/environment'
import { DocumentService } from './document.service' import { DocumentService } from './document.service'
import { FILTER_TITLE } from 'src/app/data/filter-rule-type' import { FILTER_TITLE } from 'src/app/data/filter-rule-type'
import { SettingsService } from '../settings.service'
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
let httpTestingController: HttpTestingController let httpTestingController: HttpTestingController
let service: DocumentService let service: DocumentService
let subscription: Subscription let subscription: Subscription
let settingsService: SettingsService
const endpoint = 'documents' const endpoint = 'documents'
const documents = [ const documents = [
{ {
@ -34,6 +37,17 @@ const documents = [
}, },
] ]
beforeEach(() => {
TestBed.configureTestingModule({
providers: [DocumentService],
imports: [HttpClientTestingModule],
})
httpTestingController = TestBed.inject(HttpTestingController)
service = TestBed.inject(DocumentService)
settingsService = TestBed.inject(SettingsService)
})
describe(`DocumentService`, () => { describe(`DocumentService`, () => {
// common tests e.g. commonAbstractPaperlessServiceTests differ slightly // common tests e.g. commonAbstractPaperlessServiceTests differ slightly
it('should call appropriate api endpoint for list all', () => { it('should call appropriate api endpoint for list all', () => {
@ -237,16 +251,21 @@ describe(`DocumentService`, () => {
) )
expect(req.request.method).toEqual('GET') expect(req.request.method).toEqual('GET')
}) })
})
beforeEach(() => { it('should pass remove_inbox_tags setting to update', () => {
TestBed.configureTestingModule({ subscription = service.update(documents[0]).subscribe()
providers: [DocumentService], let req = httpTestingController.expectOne(
imports: [HttpClientTestingModule], `${environment.apiBaseUrl}${endpoint}/${documents[0].id}/`
)
expect(req.request.body.remove_inbox_tags).toEqual(false)
settingsService.set(SETTINGS_KEYS.DOCUMENT_EDITING_REMOVE_INBOX_TAGS, true)
subscription = service.update(documents[0]).subscribe()
req = httpTestingController.expectOne(
`${environment.apiBaseUrl}${endpoint}/${documents[0].id}/`
)
expect(req.request.body.remove_inbox_tags).toEqual(true)
}) })
httpTestingController = TestBed.inject(HttpTestingController)
service = TestBed.inject(DocumentService)
}) })
afterEach(() => { afterEach(() => {

View File

@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'
import { Document } from 'src/app/data/document' import { Document } from 'src/app/data/document'
import { DocumentMetadata } from 'src/app/data/document-metadata' import { DocumentMetadata } from 'src/app/data/document-metadata'
import { AbstractPaperlessService } from './abstract-paperless-service' import { AbstractPaperlessService } from './abstract-paperless-service'
import { HttpClient, HttpParams } from '@angular/common/http' import { HttpClient } from '@angular/common/http'
import { Observable } from 'rxjs' import { Observable } from 'rxjs'
import { Results } from 'src/app/data/results' import { Results } from 'src/app/data/results'
import { FilterRule } from 'src/app/data/filter-rule' import { FilterRule } from 'src/app/data/filter-rule'
@ -18,6 +18,8 @@ import {
PermissionType, PermissionType,
PermissionsService, PermissionsService,
} from '../permissions.service' } from '../permissions.service'
import { SettingsService } from '../settings.service'
import { SETTINGS, SETTINGS_KEYS } from 'src/app/data/ui-settings'
export const DOCUMENT_SORT_FIELDS = [ export const DOCUMENT_SORT_FIELDS = [
{ field: 'archive_serial_number', name: $localize`ASN` }, { field: 'archive_serial_number', name: $localize`ASN` },
@ -63,7 +65,8 @@ export class DocumentService extends AbstractPaperlessService<Document> {
private documentTypeService: DocumentTypeService, private documentTypeService: DocumentTypeService,
private tagService: TagService, private tagService: TagService,
private storagePathService: StoragePathService, private storagePathService: StoragePathService,
private permissionsService: PermissionsService private permissionsService: PermissionsService,
private settingsService: SettingsService
) { ) {
super(http, 'documents') super(http, 'documents')
} }
@ -180,6 +183,9 @@ export class DocumentService extends AbstractPaperlessService<Document> {
update(o: Document): Observable<Document> { update(o: Document): Observable<Document> {
// we want to only set created_date // we want to only set created_date
o.created = undefined o.created = undefined
o.remove_inbox_tags = this.settingsService.get(
SETTINGS_KEYS.DOCUMENT_EDITING_REMOVE_INBOX_TAGS
)
return super.update(o) return super.update(o)
} }

View File

@ -638,6 +638,11 @@ class DocumentSerializer(
allow_null=True, allow_null=True,
) )
remove_inbox_tags = serializers.BooleanField(
default=False,
write_only=True,
)
def get_original_file_name(self, obj): def get_original_file_name(self, obj):
return obj.original_filename return obj.original_filename
@ -681,12 +686,48 @@ class DocumentSerializer(
custom_field_instance.field, custom_field_instance.field,
doc_id, doc_id,
) )
if (
"remove_inbox_tags" in validated_data
and validated_data["remove_inbox_tags"]
):
tag_ids_being_added = (
[
tag.id
for tag in validated_data["tags"]
if tag not in instance.tags.all()
]
if "tags" in validated_data
else []
)
inbox_tags_not_being_added = Tag.objects.filter(is_inbox_tag=True).exclude(
id__in=tag_ids_being_added,
)
if "tags" in validated_data:
validated_data["tags"] = [
tag
for tag in validated_data["tags"]
if tag not in inbox_tags_not_being_added
]
else:
validated_data["tags"] = [
tag
for tag in instance.tags.all()
if tag not in inbox_tags_not_being_added
]
super().update(instance, validated_data) super().update(instance, validated_data)
return instance return instance
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.truncate_content = kwargs.pop("truncate_content", False) self.truncate_content = kwargs.pop("truncate_content", False)
# return full permissions if we're doing a PATCH or PUT
context = kwargs.get("context")
if (
context.get("request").method == "PATCH"
or context.get("request").method == "PUT"
):
kwargs["full_perms"] = True
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
class Meta: class Meta:
@ -714,6 +755,7 @@ class DocumentSerializer(
"set_permissions", "set_permissions",
"notes", "notes",
"custom_fields", "custom_fields",
"remove_inbox_tags",
) )

View File

@ -2080,6 +2080,72 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
self.assertEqual(resp.status_code, status.HTTP_200_OK) self.assertEqual(resp.status_code, status.HTTP_200_OK)
self.assertEqual(resp.content, b"1") self.assertEqual(resp.content, b"1")
def test_remove_inbox_tags(self):
"""
GIVEN:
- Existing document with or without inbox tags
WHEN:
- API request to update document, with or without `remove_inbox_tags` flag
THEN:
- Inbox tags are removed as long as they are not being added
"""
tag1 = Tag.objects.create(name="tag1", color="#abcdef")
inbox_tag1 = Tag.objects.create(
name="inbox1",
color="#abcdef",
is_inbox_tag=True,
)
inbox_tag2 = Tag.objects.create(
name="inbox2",
color="#abcdef",
is_inbox_tag=True,
)
doc1 = Document.objects.create(
title="test",
mime_type="application/pdf",
content="this is a document 1",
checksum="1",
)
doc1.tags.add(tag1)
doc1.tags.add(inbox_tag1)
doc1.tags.add(inbox_tag2)
doc1.save()
# Remove inbox tags defaults to false
resp = self.client.patch(
f"/api/documents/{doc1.pk}/",
{
"title": "New title",
},
)
doc1.refresh_from_db()
self.assertEqual(resp.status_code, status.HTTP_200_OK)
self.assertEqual(doc1.tags.count(), 3)
# Remove inbox tags set to true
resp = self.client.patch(
f"/api/documents/{doc1.pk}/",
{
"remove_inbox_tags": True,
},
)
doc1.refresh_from_db()
self.assertEqual(resp.status_code, status.HTTP_200_OK)
self.assertEqual(doc1.tags.count(), 1)
# Remove inbox tags set to true but adding a new inbox tag
resp = self.client.patch(
f"/api/documents/{doc1.pk}/",
{
"remove_inbox_tags": True,
"tags": [inbox_tag1.pk, tag1.pk],
},
)
doc1.refresh_from_db()
self.assertEqual(resp.status_code, status.HTTP_200_OK)
self.assertEqual(doc1.tags.count(), 2)
class TestDocumentApiV2(DirectoriesMixin, APITestCase): class TestDocumentApiV2(DirectoriesMixin, APITestCase):
def setUp(self): def setUp(self):