diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown-button/filterable-dropdown-button.component.ts b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown-button/filterable-dropdown-button.component.ts index a928d715e..b0ced21cc 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown-button/filterable-dropdown-button.component.ts +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown-button/filterable-dropdown-button.component.ts @@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, Output, OnInit } from '@angular/core'; 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'; -import { SelectableItem, SelectableItemState } from '../filterable-dropdown.component'; +import { ToggleableItem, ToggleableItemState } from '../filterable-dropdown.component'; @Component({ selector: 'app-filterable-dropdown-button', @@ -12,10 +12,10 @@ import { SelectableItem, SelectableItemState } from '../filterable-dropdown.comp export class FilterableDropdownButtonComponent implements OnInit { @Input() - selectableItem: SelectableItem + toggleableItem: ToggleableItem get item(): PaperlessTag | PaperlessDocumentType | PaperlessCorrespondent { - return this.selectableItem?.item + return this.toggleableItem?.item } @Output() @@ -28,14 +28,14 @@ export class FilterableDropdownButtonComponent implements OnInit { } toggleItem(): void { - this.selectableItem.state = (this.selectableItem.state == SelectableItemState.NotSelected || this.selectableItem.state == SelectableItemState.PartiallySelected) ? SelectableItemState.Selected : SelectableItemState.NotSelected - this.toggle.emit(this.selectableItem) + this.toggleableItem.state = (this.toggleableItem.state == ToggleableItemState.NotSelected || this.toggleableItem.state == ToggleableItemState.PartiallySelected) ? ToggleableItemState.Selected : ToggleableItemState.NotSelected + this.toggle.emit(this.toggleableItem) } getSelectedIconName() { let iconName = '' - if (this.selectableItem?.state == SelectableItemState.Selected) iconName = 'check' - else if (this.selectableItem?.state == SelectableItemState.PartiallySelected) iconName = 'dash' + if (this.toggleableItem?.state == ToggleableItemState.Selected) iconName = 'check' + else if (this.toggleableItem?.state == ToggleableItemState.PartiallySelected) iconName = 'dash' return iconName } } diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html index 425a290a5..052bca03d 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -19,9 +19,9 @@ -
- - +
+ +
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 2d224567f..76b588be5 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 @@ -6,12 +6,12 @@ import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'; import { FilterPipe } from 'src/app/pipes/filter.pipe'; import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' -export interface SelectableItem { +export interface ToggleableItem { item: PaperlessTag | PaperlessDocumentType | PaperlessCorrespondent, - state: SelectableItemState + state: ToggleableItemState } -export enum SelectableItemState { +export enum ToggleableItemState { NotSelected = 0, Selected = 1, PartiallySelected = 2 @@ -37,33 +37,33 @@ export class FilterableDropdownComponent { @Input() set items(items: ObjectWithId[]) { if (items) { - this._selectableItems = items.map(i => { - return {item: i, state: SelectableItemState.NotSelected} + this._toggleableItems = items.map(i => { + return {item: i, state: ToggleableItemState.NotSelected} }) } } - _selectableItems: SelectableItem[] = [] + _toggleableItems: ToggleableItem[] = [] @Input() - set selectableItems (selectableItems: SelectableItem[]) { + set toggleableItems (toggleableItems: ToggleableItem[]) { if (this.type == FilterableDropdownType.Editing && this.dropdown?.isOpen()) return - else this._selectableItems = selectableItems + else this._toggleableItems = toggleableItems } - get selectableItems(): SelectableItem[] { - return this._selectableItems + get toggleableItems(): ToggleableItem[] { + return this._toggleableItems } @Input() set itemsSelected(itemsSelected: ObjectWithId[]) { - this.selectableItems.forEach(i => { - i.state = (itemsSelected.find(is => is.id == i.item.id)) ? SelectableItemState.Selected : SelectableItemState.NotSelected + this.toggleableItems.forEach(i => { + i.state = (itemsSelected.find(is => is.id == i.item.id)) ? ToggleableItemState.Selected : ToggleableItemState.NotSelected }) } get itemsSelected() :ObjectWithId[] { - return this.selectableItems.filter(si => si.state == SelectableItemState.Selected).map(si => si.item) + return this.toggleableItems.filter(si => si.state == ToggleableItemState.Selected).map(si => si.item) } @Input() @@ -91,11 +91,11 @@ export class FilterableDropdownComponent { constructor(private filterPipe: FilterPipe) { } - toggleItem(selectableItem: SelectableItem): void { - if (this.singular && selectableItem.state == SelectableItemState.Selected) { - this._selectableItems.filter(si => si.item.id !== selectableItem.item.id).forEach(si => si.state = SelectableItemState.NotSelected) + toggleItem(toggleableItem: ToggleableItem): void { + if (this.singular && toggleableItem.state == ToggleableItemState.Selected) { + this._toggleableItems.filter(si => si.item.id !== toggleableItem.item.id).forEach(si => si.state = ToggleableItemState.NotSelected) } - this.toggle.emit(selectableItem.item) + this.toggle.emit(toggleableItem.item) } dropdownOpenChange(open: boolean): void { @@ -111,7 +111,7 @@ export class FilterableDropdownComponent { } listFilterEnter(): void { - let filtered = this.filterPipe.transform(this.selectableItems, this.filterText) + let filtered = this.filterPipe.transform(this.toggleableItems, this.filterText) if (filtered.length == 1) this.toggleItem(filtered.shift()) this.dropdown.close() } 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 4f79a6c3e..58ca5e5a7 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 7ba134e15..2e6edbb71 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 @@ -8,7 +8,7 @@ import { TagService } from 'src/app/services/rest/tag.service'; import { CorrespondentService } from 'src/app/services/rest/correspondent.service'; import { DocumentTypeService } from 'src/app/services/rest/document-type.service'; import { DocumentService } from 'src/app/services/rest/document.service'; -import { SelectableItem, SelectableItemState, FilterableDropdownType } from 'src/app/components/common/filterable-dropdown/filterable-dropdown.component'; +import { ToggleableItem, ToggleableItemState, FilterableDropdownType } from 'src/app/components/common/filterable-dropdown/filterable-dropdown.component'; @Component({ selector: 'app-bulk-editor', @@ -48,51 +48,51 @@ export class BulkEditorComponent { correspondents: PaperlessCorrespondent[] documentTypes: PaperlessDocumentType[] - private initiallySelectedTagsSelectableItems: SelectableItem[] - private initiallySelectedCorrespondentsSelectableItems: SelectableItem[] - private initiallySelectedDocumentTypesSelectableItems: SelectableItem[] + private initiallySelectedTagsToggleableItems: ToggleableItem[] + private initiallySelectedCorrespondentsToggleableItems: ToggleableItem[] + private initiallySelectedDocumentTypesToggleableItems: ToggleableItem[] dropdownTypes = FilterableDropdownType - get tagsSelectableItems(): SelectableItem[] { - let tagsSelectableItems = [] + get tagsToggleableItems(): ToggleableItem[] { + let tagsToggleableItems = [] let selectedDocuments: PaperlessDocument[] = this.allDocuments.filter(d => this.selectedDocuments.has(d.id)) this.tags.forEach(t => { let selectedDocumentsWithTag: PaperlessDocument[] = selectedDocuments.filter(d => d.tags.includes(t.id)) - let state = SelectableItemState.NotSelected - if (selectedDocumentsWithTag.length == selectedDocuments.length) state = SelectableItemState.Selected - else if (selectedDocumentsWithTag.length > 0 && selectedDocumentsWithTag.length < selectedDocuments.length) state = SelectableItemState.PartiallySelected - tagsSelectableItems.push( { item: t, state: state } ) + let state = ToggleableItemState.NotSelected + if (selectedDocumentsWithTag.length == selectedDocuments.length) state = ToggleableItemState.Selected + else if (selectedDocumentsWithTag.length > 0 && selectedDocumentsWithTag.length < selectedDocuments.length) state = ToggleableItemState.PartiallySelected + tagsToggleableItems.push( { item: t, state: state } ) }) - return tagsSelectableItems + return tagsToggleableItems } - get correspondentsSelectableItems(): SelectableItem[] { - let correspondentsSelectableItems = [] + get correspondentsToggleableItems(): ToggleableItem[] { + let correspondentsToggleableItems = [] let selectedDocuments: PaperlessDocument[] = this.allDocuments.filter(d => this.selectedDocuments.has(d.id)) this.correspondents.forEach(c => { let selectedDocumentsWithCorrespondent: PaperlessDocument[] = selectedDocuments.filter(d => d.correspondent == c.id) - let state = SelectableItemState.NotSelected - if (selectedDocumentsWithCorrespondent.length == selectedDocuments.length) state = SelectableItemState.Selected - else if (selectedDocumentsWithCorrespondent.length > 0 && selectedDocumentsWithCorrespondent.length < selectedDocuments.length) state = SelectableItemState.PartiallySelected - correspondentsSelectableItems.push( { item: c, state: state } ) + let state = ToggleableItemState.NotSelected + if (selectedDocumentsWithCorrespondent.length == selectedDocuments.length) state = ToggleableItemState.Selected + else if (selectedDocumentsWithCorrespondent.length > 0 && selectedDocumentsWithCorrespondent.length < selectedDocuments.length) state = ToggleableItemState.PartiallySelected + correspondentsToggleableItems.push( { item: c, state: state } ) }) - return correspondentsSelectableItems + return correspondentsToggleableItems } - get documentTypesSelectableItems(): SelectableItem[] { - let documentTypesSelectableItems = [] + get documentTypesToggleableItems(): ToggleableItem[] { + let documentTypesToggleableItems = [] let selectedDocuments: PaperlessDocument[] = this.allDocuments.filter(d => this.selectedDocuments.has(d.id)) this.documentTypes.forEach(dt => { let selectedDocumentsWithDocumentType: PaperlessDocument[] = selectedDocuments.filter(d => d.document_type == dt.id) - let state = SelectableItemState.NotSelected - if (selectedDocumentsWithDocumentType.length == selectedDocuments.length) state = SelectableItemState.Selected - else if (selectedDocumentsWithDocumentType.length > 0 && selectedDocumentsWithDocumentType.length < selectedDocuments.length) state = SelectableItemState.PartiallySelected - documentTypesSelectableItems.push( { item: dt, state: state } ) + let state = ToggleableItemState.NotSelected + if (selectedDocumentsWithDocumentType.length == selectedDocuments.length) state = ToggleableItemState.Selected + else if (selectedDocumentsWithDocumentType.length > 0 && selectedDocumentsWithDocumentType.length < selectedDocuments.length) state = ToggleableItemState.PartiallySelected + documentTypesToggleableItems.push( { item: dt, state: state } ) }) - return documentTypesSelectableItems + return documentTypesToggleableItems } constructor( @@ -109,39 +109,39 @@ export class BulkEditorComponent { } tagsDropdownOpen() { - this.initiallySelectedTagsSelectableItems = this.tagsSelectableItems.filter(tsi => tsi.state == SelectableItemState.Selected) + this.initiallySelectedTagsToggleableItems = this.tagsToggleableItems.filter(tsi => tsi.state == ToggleableItemState.Selected) } correspondentsDropdownOpen() { - this.initiallySelectedCorrespondentsSelectableItems = this.correspondentsSelectableItems.filter(csi => csi.state == SelectableItemState.Selected) + this.initiallySelectedCorrespondentsToggleableItems = this.correspondentsToggleableItems.filter(csi => csi.state == ToggleableItemState.Selected) } documentTypesDropdownOpen() { - this.initiallySelectedDocumentTypesSelectableItems = this.documentTypesSelectableItems.filter(dtsi => dtsi.state == SelectableItemState.Selected) + this.initiallySelectedDocumentTypesToggleableItems = this.documentTypesToggleableItems.filter(dtsi => dtsi.state == ToggleableItemState.Selected) } applyTags(selectedTags: PaperlessTag[]) { - let unchanged = this.equateItemsToSelectableItems(selectedTags, this.initiallySelectedTagsSelectableItems) + let unchanged = this.equateItemsToToggleableItems(selectedTags, this.initiallySelectedTagsToggleableItems) if (!unchanged) this.setTags.emit(selectedTags) - this.initiallySelectedTagsSelectableItems = null + this.initiallySelectedTagsToggleableItems = null } applyCorrespondent(selectedCorrespondents: PaperlessCorrespondent[]) { - let unchanged = this.equateItemsToSelectableItems(selectedCorrespondents, this.initiallySelectedCorrespondentsSelectableItems) + let unchanged = this.equateItemsToToggleableItems(selectedCorrespondents, this.initiallySelectedCorrespondentsToggleableItems) if (!unchanged) this.setCorrespondent.emit(selectedCorrespondents?.length > 0 ? selectedCorrespondents.shift() : null) - this.initiallySelectedCorrespondentsSelectableItems = null + this.initiallySelectedCorrespondentsToggleableItems = null } applyDocumentType(selectedDocumentTypes: PaperlessDocumentType[]) { - let unchanged = this.equateItemsToSelectableItems(selectedDocumentTypes, this.initiallySelectedDocumentTypesSelectableItems) + let unchanged = this.equateItemsToToggleableItems(selectedDocumentTypes, this.initiallySelectedDocumentTypesToggleableItems) if (!unchanged) this.setDocumentType.emit(selectedDocumentTypes.length > 0 ? selectedDocumentTypes.shift() : null) - this.initiallySelectedDocumentTypesSelectableItems = null + this.initiallySelectedDocumentTypesToggleableItems = 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)) + equateItemsToToggleableItems(items: ObjectWithId[], toggleableItems: ToggleableItem[]): boolean { + // either both empty or all items must in toggleableItems and vice-versa + return (toggleableItems.length == 0 && items.length == 0) || + (items.every(i => toggleableItems.find(si => si.item.id == i.id) !== undefined) && toggleableItems.every(si => items.find(i => i.id == si.item.id) !== undefined)) } applyDelete() { diff --git a/src-ui/src/app/pipes/filter.pipe.ts b/src-ui/src/app/pipes/filter.pipe.ts index 51d1924b8..1ea10c56e 100644 --- a/src-ui/src/app/pipes/filter.pipe.ts +++ b/src-ui/src/app/pipes/filter.pipe.ts @@ -1,17 +1,17 @@ import { Pipe, PipeTransform } from '@angular/core'; -import { SelectableItem } from 'src/app/components/common/filterable-dropdown/filterable-dropdown.component'; +import { ToggleableItem } from 'src/app/components/common/filterable-dropdown/filterable-dropdown.component'; @Pipe({ name: 'filter' }) export class FilterPipe implements PipeTransform { - transform(selectableItems: SelectableItem[], searchText: string): any[] { - if (!selectableItems) return []; - if (!searchText) return selectableItems; + transform(toggleableItems: ToggleableItem[], searchText: string): any[] { + if (!toggleableItems) return []; + if (!searchText) return toggleableItems; - return selectableItems.filter(selectableItem => { - return Object.keys(selectableItem.item).some(key => { - return String(selectableItem.item[key]).toLowerCase().includes(searchText.toLowerCase()); + return toggleableItems.filter(toggleableItem => { + return Object.keys(toggleableItem.item).some(key => { + return String(toggleableItem.item[key]).toLowerCase().includes(searchText.toLowerCase()); }); }); }