mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Only apply edits when something has changed
This commit is contained in:
		| @@ -37,7 +37,7 @@ export class FilterableDropdownComponent { | |||||||
|   @Input() |   @Input() | ||||||
|   set items(items: ObjectWithId[]) { |   set items(items: ObjectWithId[]) { | ||||||
|     if (items) { |     if (items) { | ||||||
|       this.selectableItems = items.map(i => { |       this._selectableItems = items.map(i => { | ||||||
|         return {item: i, state: SelectableItemState.NotSelected} |         return {item: i, state: SelectableItemState.NotSelected} | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
| @@ -84,15 +84,16 @@ export class FilterableDropdownComponent { | |||||||
|   toggle = new EventEmitter() |   toggle = new EventEmitter() | ||||||
|  |  | ||||||
|   @Output() |   @Output() | ||||||
|   close = new EventEmitter() |   open = new EventEmitter() | ||||||
|  |  | ||||||
|  |   @Output() | ||||||
|  |   editingComplete = new EventEmitter() | ||||||
|  |  | ||||||
|   constructor(private filterPipe: FilterPipe) { } |   constructor(private filterPipe: FilterPipe) { } | ||||||
|  |  | ||||||
|   toggleItem(selectableItem: SelectableItem): void { |   toggleItem(selectableItem: SelectableItem): void { | ||||||
|     if (this.singular && selectableItem.state == SelectableItemState.Selected) { |     if (this.singular && selectableItem.state == SelectableItemState.Selected) { | ||||||
|       this._selectableItems.forEach(si => { |       this._selectableItems.filter(si => si.item.id !== selectableItem.item.id).forEach(si => si.state = SelectableItemState.NotSelected) | ||||||
|         if (si.state == SelectableItemState.Selected && si.item.id !== selectableItem.item.id) si.state = SelectableItemState.NotSelected |  | ||||||
|       }) |  | ||||||
|     } |     } | ||||||
|     this.toggle.emit(selectableItem.item) |     this.toggle.emit(selectableItem.item) | ||||||
|   } |   } | ||||||
| @@ -101,10 +102,11 @@ export class FilterableDropdownComponent { | |||||||
|     if (open) { |     if (open) { | ||||||
|       setTimeout(() => { |       setTimeout(() => { | ||||||
|         this.listFilterTextInput.nativeElement.focus(); |         this.listFilterTextInput.nativeElement.focus(); | ||||||
|       }, 0); |       }, 0) | ||||||
|  |       this.open.next() | ||||||
|     } else { |     } else { | ||||||
|       this.filterText = '' |       this.filterText = '' | ||||||
|       this.close.emit(this.itemsSelected) |       if (this.type == FilterableDropdownType.Editing) this.editingComplete.emit(this.itemsSelected) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,9 +26,9 @@ | |||||||
|   <div class="col mb-2 mb-xl-0"> |   <div class="col mb-2 mb-xl-0"> | ||||||
|     <div class="d-flex"> |     <div class="d-flex"> | ||||||
|       <label class="ml-auto mt-1 mr-2">Apply:</label> |       <label class="ml-auto mt-1 mr-2">Apply:</label> | ||||||
|       <app-filterable-dropdown class="mr-2 mr-md-3" title="Tags" icon="tag-fill" [selectableItems]="tagsSelectableItems" [type]="dropdownTypes.Editing" (close)="applyTags($event)"></app-filterable-dropdown> |       <app-filterable-dropdown class="mr-2 mr-md-3" title="Tags" icon="tag-fill" [selectableItems]="tagsSelectableItems" [type]="dropdownTypes.Editing" (open)="tagsDropdownOpen()" (editingComplete)="applyTags($event)"></app-filterable-dropdown> | ||||||
|       <app-filterable-dropdown class="mr-2 mr-md-3" title="Correspondent" icon="person-fill" [selectableItems]="correspondentsSelectableItems" [type]="dropdownTypes.Editing" singular="true" (close)="applyCorrespondent($event)"></app-filterable-dropdown> |       <app-filterable-dropdown class="mr-2 mr-md-3" title="Correspondent" icon="person-fill" [selectableItems]="correspondentsSelectableItems" [type]="dropdownTypes.Editing" singular="true" (open)="correspondentsDropdownOpen()" (editingComplete)="applyCorrespondent($event)"></app-filterable-dropdown> | ||||||
|       <app-filterable-dropdown class="mr-2 mr-md-3" title="Document Type" icon="file-earmark-fill" [selectableItems]="documentTypesSelectableItems" [type]="dropdownTypes.Editing" singular="true" (close)="applyDocumentType($event)"></app-filterable-dropdown> |       <app-filterable-dropdown class="mr-2 mr-md-3" title="Document Type" icon="file-earmark-fill" [selectableItems]="documentTypesSelectableItems" [type]="dropdownTypes.Editing" singular="true" (open)="documentTypesDropdownOpen()" (editingComplete)="applyDocumentType($event)"></app-filterable-dropdown> | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
|   <div class="w-100 d-xl-none"></div> |   <div class="w-100 d-xl-none"></div> | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { Component, EventEmitter, Input, Output } from '@angular/core'; | 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 { PaperlessTag } from 'src/app/data/paperless-tag'; | ||||||
| import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'; | import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'; | ||||||
| import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'; | import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'; | ||||||
| @@ -47,7 +48,12 @@ export class BulkEditorComponent { | |||||||
|   correspondents: PaperlessCorrespondent[] |   correspondents: PaperlessCorrespondent[] | ||||||
|   documentTypes: PaperlessDocumentType[] |   documentTypes: PaperlessDocumentType[] | ||||||
|  |  | ||||||
|  |   private _initialTagsSelectableItems: SelectableItem[] | ||||||
|  |   private _initialCorrespondentsSelectableItems: SelectableItem[] | ||||||
|  |   private _initialDocumentTypesSelectableItems: SelectableItem[] | ||||||
|  |  | ||||||
|   dropdownTypes = FilterableDropdownType |   dropdownTypes = FilterableDropdownType | ||||||
|  |  | ||||||
|   get tagsSelectableItems(): SelectableItem[] { |   get tagsSelectableItems(): SelectableItem[] { | ||||||
|     let tagsSelectableItems = [] |     let tagsSelectableItems = [] | ||||||
|     let selectedDocuments: PaperlessDocument[] = this.allDocuments.filter(d => this.selectedDocuments.has(d.id)) |     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 |       else if (selectedDocumentsWithCorrespondent.length > 0 && selectedDocumentsWithCorrespondent.length < selectedDocuments.length) state = SelectableItemState.PartiallySelected | ||||||
|       correspondentsSelectableItems.push( { item: c, state: state } ) |       correspondentsSelectableItems.push( { item: c, state: state } ) | ||||||
|     }) |     }) | ||||||
|  |  | ||||||
|     return correspondentsSelectableItems |     return correspondentsSelectableItems | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -87,7 +92,6 @@ export class BulkEditorComponent { | |||||||
|       else if (selectedDocumentsWithDocumentType.length > 0 && selectedDocumentsWithDocumentType.length < selectedDocuments.length) state = SelectableItemState.PartiallySelected |       else if (selectedDocumentsWithDocumentType.length > 0 && selectedDocumentsWithDocumentType.length < selectedDocuments.length) state = SelectableItemState.PartiallySelected | ||||||
|       documentTypesSelectableItems.push( { item: dt, state: state } ) |       documentTypesSelectableItems.push( { item: dt, state: state } ) | ||||||
|     }) |     }) | ||||||
|  |  | ||||||
|     return documentTypesSelectableItems |     return documentTypesSelectableItems | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -104,16 +108,43 @@ export class BulkEditorComponent { | |||||||
|     this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results) |     this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   applyTags(tags: PaperlessTag[]) { |   tagsDropdownOpen() { | ||||||
|     this.setTags.emit(tags) |     this._initialTagsSelectableItems = this.tagsSelectableItems | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   applyCorrespondent(selectedCorrespondent: PaperlessCorrespondent[]) { |   correspondentsDropdownOpen() { | ||||||
|     this.setCorrespondent.emit(selectedCorrespondent.length > 0 ? selectedCorrespondent.shift() : null) |     this._initialCorrespondentsSelectableItems = this.correspondentsSelectableItems | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   applyDocumentType(selectedDocumentType: PaperlessDocumentType[]) { |   documentTypesDropdownOpen() { | ||||||
|     this.setDocumentType.emit(selectedDocumentType.length > 0 ? selectedDocumentType.shift() : null) |     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() { |   applyDelete() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Michael Shamoon
					Michael Shamoon