From 1da652ba4d50b562d3e69fd4f48ddd467d204a3f Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Sat, 19 Dec 2020 21:42:19 -0800 Subject: [PATCH] Only apply edits when something has changed --- .../filterable-dropdown.component.ts | 16 ++++--- .../bulk-editor/bulk-editor.component.html | 6 +-- .../bulk-editor/bulk-editor.component.ts | 47 +++++++++++++++---- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts index 7463e7b19..2d224567f 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts @@ -37,7 +37,7 @@ export class FilterableDropdownComponent { @Input() set items(items: ObjectWithId[]) { if (items) { - this.selectableItems = items.map(i => { + this._selectableItems = items.map(i => { return {item: i, state: SelectableItemState.NotSelected} }) } @@ -84,15 +84,16 @@ export class FilterableDropdownComponent { toggle = new EventEmitter() @Output() - close = new EventEmitter() + open = new EventEmitter() + + @Output() + editingComplete = new EventEmitter() constructor(private filterPipe: FilterPipe) { } toggleItem(selectableItem: SelectableItem): void { if (this.singular && selectableItem.state == SelectableItemState.Selected) { - this._selectableItems.forEach(si => { - if (si.state == SelectableItemState.Selected && si.item.id !== selectableItem.item.id) si.state = SelectableItemState.NotSelected - }) + this._selectableItems.filter(si => si.item.id !== selectableItem.item.id).forEach(si => si.state = SelectableItemState.NotSelected) } this.toggle.emit(selectableItem.item) } @@ -101,10 +102,11 @@ export class FilterableDropdownComponent { if (open) { setTimeout(() => { this.listFilterTextInput.nativeElement.focus(); - }, 0); + }, 0) + this.open.next() } else { this.filterText = '' - this.close.emit(this.itemsSelected) + if (this.type == FilterableDropdownType.Editing) this.editingComplete.emit(this.itemsSelected) } } diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html index 859876a67..4f79a6c3e 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -26,9 +26,9 @@
- - - + + +
diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts index d6f0fc1c7..54ecb6d0a 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts @@ -1,4 +1,5 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { ObjectWithId } from 'src/app/data/object-with-id'; import { PaperlessTag } from 'src/app/data/paperless-tag'; import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'; import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'; @@ -47,7 +48,12 @@ export class BulkEditorComponent { correspondents: PaperlessCorrespondent[] documentTypes: PaperlessDocumentType[] + private _initialTagsSelectableItems: SelectableItem[] + private _initialCorrespondentsSelectableItems: SelectableItem[] + private _initialDocumentTypesSelectableItems: SelectableItem[] + dropdownTypes = FilterableDropdownType + get tagsSelectableItems(): SelectableItem[] { let tagsSelectableItems = [] let selectedDocuments: PaperlessDocument[] = this.allDocuments.filter(d => this.selectedDocuments.has(d.id)) @@ -72,7 +78,6 @@ export class BulkEditorComponent { else if (selectedDocumentsWithCorrespondent.length > 0 && selectedDocumentsWithCorrespondent.length < selectedDocuments.length) state = SelectableItemState.PartiallySelected correspondentsSelectableItems.push( { item: c, state: state } ) }) - return correspondentsSelectableItems } @@ -87,7 +92,6 @@ export class BulkEditorComponent { else if (selectedDocumentsWithDocumentType.length > 0 && selectedDocumentsWithDocumentType.length < selectedDocuments.length) state = SelectableItemState.PartiallySelected documentTypesSelectableItems.push( { item: dt, state: state } ) }) - return documentTypesSelectableItems } @@ -104,16 +108,43 @@ export class BulkEditorComponent { this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results) } - applyTags(tags: PaperlessTag[]) { - this.setTags.emit(tags) + tagsDropdownOpen() { + this._initialTagsSelectableItems = this.tagsSelectableItems } - applyCorrespondent(selectedCorrespondent: PaperlessCorrespondent[]) { - this.setCorrespondent.emit(selectedCorrespondent.length > 0 ? selectedCorrespondent.shift() : null) + correspondentsDropdownOpen() { + this._initialCorrespondentsSelectableItems = this.correspondentsSelectableItems } - applyDocumentType(selectedDocumentType: PaperlessDocumentType[]) { - this.setDocumentType.emit(selectedDocumentType.length > 0 ? selectedDocumentType.shift() : null) + documentTypesDropdownOpen() { + this._initialDocumentTypesSelectableItems = this.documentTypesSelectableItems + } + + applyTags(selectedTags: PaperlessTag[]) { + let initiallySelectedSelectableTags = this._initialTagsSelectableItems.filter(tsi => tsi.state == SelectableItemState.Selected) + let unchanged = this.equateItemsToSelectableItems(selectedTags, initiallySelectedSelectableTags) + if (!unchanged) this.setTags.emit(selectedTags) + this._initialTagsSelectableItems = null + } + + applyCorrespondent(selectedCorrespondents: PaperlessCorrespondent[]) { + let initiallySelectedSelectableCorrespondents = this._initialCorrespondentsSelectableItems.filter(csi => csi.state == SelectableItemState.Selected) + let unchanged = this.equateItemsToSelectableItems(selectedCorrespondents, initiallySelectedSelectableCorrespondents) + if (!unchanged) this.setCorrespondent.emit(selectedCorrespondents?.length > 0 ? selectedCorrespondents.shift() : null) + this._initialCorrespondentsSelectableItems = null + } + + applyDocumentType(selectedDocumentTypes: PaperlessDocumentType[]) { + let initiallySelectedSelectableDocumentTypes = this._initialDocumentTypesSelectableItems.filter(dtsi => dtsi.state == SelectableItemState.Selected) + let unchanged = this.equateItemsToSelectableItems(selectedDocumentTypes, initiallySelectedSelectableDocumentTypes) + if (!unchanged) this.setDocumentType.emit(selectedDocumentTypes.length > 0 ? selectedDocumentTypes.shift() : null) + this._initialDocumentTypesSelectableItems = null + } + + equateItemsToSelectableItems(items: ObjectWithId[], selectableItems: SelectableItem[]): boolean { + // either both empty or all items must in selectableItems and vice-versa + return (selectableItems.length == 0 && items.length == 0) || + (items.every(i => selectableItems.find(si => si.item.id == i.id) !== undefined) && selectableItems.every(si => items.find(i => i.id == si.item.id) !== undefined)) } applyDelete() {