mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
partial selection model implementation
This commit is contained in:
parent
80420a99f5
commit
b8e7506de4
@ -30,9 +30,15 @@ export class DateDropdownComponent implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
dateBefore: string
|
||||
|
||||
@Output()
|
||||
dateBeforeChange = new EventEmitter<string>()
|
||||
|
||||
@Input()
|
||||
dateAfter: string
|
||||
|
||||
@Output()
|
||||
dateAfterChange = new EventEmitter<string>()
|
||||
|
||||
@Input()
|
||||
title: string
|
||||
|
||||
@ -83,6 +89,8 @@ export class DateDropdownComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
onChange() {
|
||||
this.dateAfterChange.emit(this.dateAfter)
|
||||
this.dateBeforeChange.emit(this.dateBefore)
|
||||
this.datesSet.emit({after: this.dateAfter, before: this.dateBefore})
|
||||
}
|
||||
|
||||
@ -91,12 +99,12 @@ export class DateDropdownComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
clearBefore() {
|
||||
this.dateBefore = null;
|
||||
this.dateBefore = null
|
||||
this.onChange()
|
||||
}
|
||||
|
||||
clearAfter() {
|
||||
this.dateAfter = null;
|
||||
this.dateAfter = null
|
||||
this.onChange()
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
<div class="btn-group" ngbDropdown role="group" (openChange)="dropdownOpenChange($event)" #dropdown="ngbDropdown">
|
||||
<button class="btn btn-sm" id="dropdown{{title}}" ngbDropdownToggle [ngClass]="type !== types.Editing && itemsSelected?.length > 0 ? 'btn-primary' : 'btn-outline-primary'">
|
||||
<button class="btn btn-sm" id="dropdown{{title}}" ngbDropdownToggle [ngClass]="type !== types.Editing && selectionModel.selectionSize() > 0 ? 'btn-primary' : 'btn-outline-primary'">
|
||||
<div class="d-none d-md-inline">{{title}}</div>
|
||||
<div class="d-inline-block d-md-none">
|
||||
<svg class="toolbaricon" fill="currentColor">
|
||||
<use attr.xlink:href="assets/bootstrap-icons.svg#{{icon}}" />
|
||||
</svg>
|
||||
</div>
|
||||
<ng-container *ngIf="type !== types.Editing && itemsSelected?.length > 0">
|
||||
<ng-container *ngIf="type !== types.Editing && selectionModel.selectionSize() > 0">
|
||||
<div class="badge bg-secondary text-light rounded-pill badge-corner">
|
||||
{{itemsSelected?.length}}
|
||||
{{selectionModel.selectionSize()}}
|
||||
</div>
|
||||
</ng-container>
|
||||
</button>
|
||||
@ -19,9 +19,9 @@
|
||||
<input class="form-control" type="text" [(ngModel)]="filterText" placeholder="Filter {{title}}" (keyup.enter)="listFilterEnter()" #listFilterTextInput>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="toggleableItems" class="items">
|
||||
<ng-container *ngFor="let toggleableItem of toggleableItems | filter: filterText">
|
||||
<app-toggleable-dropdown-button [toggleableItem]="toggleableItem" (toggle)="toggleItem($event)"></app-toggleable-dropdown-button>
|
||||
<div *ngIf="selectionModel.items" class="items">
|
||||
<ng-container *ngFor="let toggleableItem of selectionModel.items | filter: filterText">
|
||||
<app-toggleable-dropdown-button [toggleableItem]="toggleableItem" (toggle)="selectionModel.toggle(toggleableItem.item)"></app-toggleable-dropdown-button>
|
||||
</ng-container>
|
||||
</div>
|
||||
<button *ngIf="type == types.Editing" class="list-group-item list-group-item-action bg-light" (click)="dropdown.close()" [disabled]="!hasBeenToggled || (toggleableItems | filter: filterText).length == 0">
|
||||
|
@ -3,12 +3,55 @@ import { FilterPipe } from 'src/app/pipes/filter.pipe';
|
||||
import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { ToggleableItem, ToggleableItemState } from './toggleable-dropdown-button/toggleable-dropdown-button.component';
|
||||
import { MatchingModel } from 'src/app/data/matching-model';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
export enum FilterableDropdownType {
|
||||
Filtering = 'filtering',
|
||||
Editing = 'editing'
|
||||
}
|
||||
|
||||
export class FilterableDropdownSelectionModel {
|
||||
|
||||
changed = new Subject<FilterableDropdownSelectionModel>()
|
||||
|
||||
multiple = false
|
||||
|
||||
items: ToggleableItem[] = []
|
||||
|
||||
getSelected() {
|
||||
return this.items.filter(i => i.state == ToggleableItemState.Selected).map(i => i.item)
|
||||
}
|
||||
|
||||
|
||||
|
||||
toggle(item: MatchingModel, fireEvent = true) {
|
||||
console.log("TOGGLE TAG")
|
||||
let toggleableItem = this.items.find(i => i.item == item)
|
||||
console.log(toggleableItem)
|
||||
|
||||
if (toggleableItem) {
|
||||
if (toggleableItem.state == ToggleableItemState.Selected) {
|
||||
toggleableItem.state = ToggleableItemState.NotSelected
|
||||
} else {
|
||||
this.items.forEach(i => {
|
||||
if (i.item == item) {
|
||||
i.state = ToggleableItemState.Selected
|
||||
} else if (!this.multiple) {
|
||||
i.state = ToggleableItemState.NotSelected
|
||||
}
|
||||
})
|
||||
}
|
||||
if (fireEvent) {
|
||||
this.changed.next(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectionSize() {
|
||||
return this.getSelected().length
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-filterable-dropdown',
|
||||
templateUrl: './filterable-dropdown.component.html',
|
||||
@ -24,33 +67,45 @@ export class FilterableDropdownComponent {
|
||||
@Input()
|
||||
set items(items: MatchingModel[]) {
|
||||
if (items) {
|
||||
this._toggleableItems = items.map(i => {
|
||||
this._selectionModel.items = items.map(i => {
|
||||
return {item: i, state: ToggleableItemState.NotSelected, count: i.document_count}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
_toggleableItems: ToggleableItem[] = []
|
||||
|
||||
@Input()
|
||||
set toggleableItems (toggleableItems: ToggleableItem[]) {
|
||||
if (this.type == FilterableDropdownType.Editing && this.dropdown?.isOpen()) return
|
||||
else this._toggleableItems = toggleableItems
|
||||
get items(): MatchingModel[] {
|
||||
return this._selectionModel.items.map(i => i.item)
|
||||
}
|
||||
|
||||
get toggleableItems(): ToggleableItem[] {
|
||||
return this._toggleableItems
|
||||
}
|
||||
_selectionModel = new FilterableDropdownSelectionModel()
|
||||
|
||||
@Input()
|
||||
set itemsSelected(itemsSelected: MatchingModel[]) {
|
||||
this.toggleableItems.forEach(i => {
|
||||
i.state = (itemsSelected.find(is => is.id == i.item.id)) ? ToggleableItemState.Selected : ToggleableItemState.NotSelected
|
||||
set selectionModel(model: FilterableDropdownSelectionModel) {
|
||||
if (this.selectionModel) {
|
||||
this.selectionModel.changed.complete()
|
||||
model.items = this.selectionModel.items
|
||||
model.multiple = this.selectionModel.multiple
|
||||
}
|
||||
model.changed.subscribe(updatedModel => {
|
||||
this.selectionModelChange.next(updatedModel)
|
||||
})
|
||||
this._selectionModel = model
|
||||
}
|
||||
|
||||
get itemsSelected(): MatchingModel[] {
|
||||
return this.toggleableItems.filter(ti => ti.state == ToggleableItemState.Selected).map(ti => ti.item)
|
||||
get selectionModel(): FilterableDropdownSelectionModel {
|
||||
return this._selectionModel
|
||||
}
|
||||
|
||||
@Output()
|
||||
selectionModelChange = new EventEmitter<FilterableDropdownSelectionModel>()
|
||||
|
||||
@Input()
|
||||
set multiple(value: boolean) {
|
||||
this.selectionModel.multiple = value
|
||||
}
|
||||
|
||||
get multiple() {
|
||||
return this.selectionModel.multiple
|
||||
}
|
||||
|
||||
@Input()
|
||||
@ -64,50 +119,40 @@ export class FilterableDropdownComponent {
|
||||
|
||||
types = FilterableDropdownType
|
||||
|
||||
@Input()
|
||||
singular: boolean = false
|
||||
|
||||
@Output()
|
||||
toggle = new EventEmitter()
|
||||
|
||||
@Output()
|
||||
open = new EventEmitter()
|
||||
|
||||
@Output()
|
||||
editingComplete = new EventEmitter()
|
||||
|
||||
hasBeenToggled:boolean = false
|
||||
|
||||
constructor(private filterPipe: FilterPipe) { }
|
||||
constructor(private filterPipe: FilterPipe) {
|
||||
this.selectionModel = new FilterableDropdownSelectionModel()
|
||||
}
|
||||
|
||||
toggleItem(toggleableItem: ToggleableItem): void {
|
||||
if (this.singular && toggleableItem.state == ToggleableItemState.Selected) {
|
||||
this._toggleableItems.filter(ti => ti.item.id !== toggleableItem.item.id).forEach(ti => ti.state = ToggleableItemState.NotSelected)
|
||||
}
|
||||
this.hasBeenToggled = true
|
||||
this.toggle.emit(toggleableItem.item)
|
||||
// if (this.singular && toggleableItem.state == ToggleableItemState.Selected) {
|
||||
// this.selectionModel.items.filter(ti => ti.item.id !== toggleableItem.item.id).forEach(ti => ti.state = ToggleableItemState.NotSelected)
|
||||
// }
|
||||
// this.hasBeenToggled = true
|
||||
// this.toggle.emit(toggleableItem.item)
|
||||
}
|
||||
|
||||
dropdownOpenChange(open: boolean): void {
|
||||
if (open) {
|
||||
setTimeout(() => {
|
||||
this.listFilterTextInput.nativeElement.focus();
|
||||
}, 0)
|
||||
this.hasBeenToggled = false
|
||||
this.open.next()
|
||||
} else {
|
||||
this.filterText = ''
|
||||
if (this.type == FilterableDropdownType.Editing) this.editingComplete.emit(this.toggleableItems)
|
||||
}
|
||||
// if (open) {
|
||||
// setTimeout(() => {
|
||||
// this.listFilterTextInput.nativeElement.focus();
|
||||
// }, 0)
|
||||
// this.hasBeenToggled = false
|
||||
// this.open.next()
|
||||
// } else {
|
||||
// this.filterText = ''
|
||||
// if (this.type == FilterableDropdownType.Editing) this.editingComplete.emit(this.toggleableItems)
|
||||
// }
|
||||
}
|
||||
|
||||
listFilterEnter(): void {
|
||||
let filtered = this.filterPipe.transform(this.toggleableItems, this.filterText)
|
||||
if (filtered.length == 1) {
|
||||
let toggleableItem = this.toggleableItems.find(ti => ti.item.id == filtered[0].item.id)
|
||||
if (toggleableItem) toggleableItem.state = ToggleableItemState.Selected
|
||||
this.toggleItem(filtered[0])
|
||||
this.dropdown.close()
|
||||
}
|
||||
// let filtered = this.filterPipe.transform(this.toggleableItems, this.filterText)
|
||||
// if (filtered.length == 1) {
|
||||
// let toggleableItem = this.toggleableItems.find(ti => ti.item.id == filtered[0].item.id)
|
||||
// if (toggleableItem) toggleableItem.state = ToggleableItemState.Selected
|
||||
// this.toggleItem(filtered[0])
|
||||
// this.dropdown.close()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -31,8 +31,7 @@ export class ToggleableDropdownButtonComponent {
|
||||
}
|
||||
|
||||
toggleItem(): void {
|
||||
this.toggleableItem.state = (this.toggleableItem.state == ToggleableItemState.NotSelected || this.toggleableItem.state == ToggleableItemState.PartiallySelected) ? ToggleableItemState.Selected : ToggleableItemState.NotSelected
|
||||
this.toggle.emit(this.toggleableItem)
|
||||
this.toggle.emit()
|
||||
}
|
||||
|
||||
getSelectedIconName() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="row">
|
||||
<!-- <div class="row">
|
||||
<div class="col-auto mb-2 mb-xl-0" role="group" aria-label="Select">
|
||||
<button class="btn btn-sm btn-outline-danger" (click)="documentList.selectNone()">
|
||||
<svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor">
|
||||
@ -58,4 +58,4 @@
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
@ -8,11 +8,11 @@
|
||||
<div class="w-100 d-xl-none"></div>
|
||||
<div class="col col-xl-auto mb-2 mb-xl-0">
|
||||
<div class="d-flex">
|
||||
<app-filterable-dropdown class="mr-2 mr-md-3" [items]="tags" [itemsSelected]="selectedTags" title="Tags" icon="tag-fill" (toggle)="toggleTag($event.id)"></app-filterable-dropdown>
|
||||
<app-filterable-dropdown class="mr-2 mr-md-3" [items]="correspondents" [itemsSelected]="selectedCorrespondents" title="Correspondents" icon="person-fill" (toggle)="toggleCorrespondent($event.id)"></app-filterable-dropdown>
|
||||
<app-filterable-dropdown class="mr-2 mr-md-3" [items]="documentTypes" [itemsSelected]="selectedDocumentTypes" title="Document types" icon="file-earmark-fill" (toggle)="toggleDocumentType($event.id)"></app-filterable-dropdown>
|
||||
<app-date-dropdown class="mr-2 mr-md-3" [dateBefore]="dateCreatedBefore" [dateAfter]="dateCreatedAfter" title="Created" (datesSet)="onDatesCreatedSet($event)"></app-date-dropdown>
|
||||
<app-date-dropdown [dateBefore]="dateAddedBefore" [dateAfter]="dateAddedAfter" title="Added" (datesSet)="onDatesAddedSet($event)"></app-date-dropdown>
|
||||
<app-filterable-dropdown class="mr-2 mr-md-3" [items]="tags" [(selectionModel)]="tagSelectionModel" (selectionModelChange)="updateRules()" [multiple]="true" title="Tags" icon="tag-fill"></app-filterable-dropdown>
|
||||
<app-filterable-dropdown class="mr-2 mr-md-3" [items]="correspondents" [(selectionModel)]="correspondentSelectionModel" (selectionModelChange)="updateRules()" title="Correspondents" icon="person-fill"></app-filterable-dropdown>
|
||||
<app-filterable-dropdown class="mr-2 mr-md-3" [items]="documentTypes" [(selectionModel)]="documentTypeSelectionModel" (selectionModelChange)="updateRules()" title="Document types" icon="file-earmark-fill"></app-filterable-dropdown>
|
||||
<app-date-dropdown class="mr-2 mr-md-3" [(dateBefore)]="dateCreatedBefore" [(dateAfter)]="dateCreatedAfter" title="Created" (datesSet)="updateRules()"></app-date-dropdown>
|
||||
<app-date-dropdown [(dateBefore)]="dateAddedBefore" [(dateAfter)]="dateAddedAfter" title="Added" (datesSet)="updateRules()"></app-date-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-100 d-xl-none"></div>
|
||||
|
@ -3,14 +3,13 @@ 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 { Subject, Subscription } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
||||
import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { debounceTime, distinctUntilChanged, filter, flatMap, mergeMap } from 'rxjs/operators';
|
||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service';
|
||||
import { TagService } from 'src/app/services/rest/tag.service';
|
||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
|
||||
import { FilterRule } from 'src/app/data/filter-rule';
|
||||
import { FILTER_ADDED_AFTER, FILTER_ADDED_BEFORE, FILTER_CORRESPONDENT, FILTER_CREATED_AFTER, FILTER_CREATED_BEFORE, FILTER_DOCUMENT_TYPE, FILTER_HAS_TAG, FILTER_RULE_TYPES, FILTER_TITLE } from 'src/app/data/filter-rule-type';
|
||||
import { DateSelection } from 'src/app/components/common/date-dropdown/date-dropdown.component';
|
||||
import { FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-filter-editor',
|
||||
@ -46,37 +45,91 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
) { }
|
||||
|
||||
tags: PaperlessTag[] = []
|
||||
correspondents: PaperlessCorrespondent[]
|
||||
correspondents: PaperlessCorrespondent[] = []
|
||||
documentTypes: PaperlessDocumentType[] = []
|
||||
|
||||
_titleFilter = ""
|
||||
|
||||
tagSelectionModel = new FilterableDropdownSelectionModel()
|
||||
correspondentSelectionModel = new FilterableDropdownSelectionModel()
|
||||
documentTypeSelectionModel = new FilterableDropdownSelectionModel()
|
||||
|
||||
dateCreatedBefore: string
|
||||
dateCreatedAfter: string
|
||||
dateAddedBefore: string
|
||||
dateAddedAfter: string
|
||||
|
||||
@Input()
|
||||
filterRules: FilterRule[]
|
||||
set filterRules (value: FilterRule[]) {
|
||||
console.log("SET FILTER RULES")
|
||||
value.forEach(rule => {
|
||||
switch (rule.rule_type) {
|
||||
case FILTER_TITLE:
|
||||
this._titleFilter = rule.value
|
||||
break
|
||||
case FILTER_CREATED_AFTER:
|
||||
this.dateCreatedAfter = rule.value
|
||||
break
|
||||
case FILTER_CREATED_BEFORE:
|
||||
this.dateCreatedBefore = rule.value
|
||||
break
|
||||
case FILTER_ADDED_AFTER:
|
||||
this.dateAddedAfter = rule.value
|
||||
break
|
||||
case FILTER_ADDED_BEFORE:
|
||||
this.dateAddedBefore = rule.value
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
this.tagService.getCachedMany(value.filter(v => v.rule_type == FILTER_HAS_TAG).map(rule => +rule.value)).subscribe(tags => {
|
||||
console.log(tags)
|
||||
tags.forEach(tag => this.tagSelectionModel.toggle(tag, false))
|
||||
})
|
||||
}
|
||||
|
||||
@Output()
|
||||
filterRulesChange = new EventEmitter<FilterRule[]>()
|
||||
|
||||
updateRules() {
|
||||
console.log("UPDATE RULES!!!")
|
||||
let filterRules: FilterRule[] = []
|
||||
if (this._titleFilter) {
|
||||
filterRules.push({rule_type: FILTER_TITLE, value: this._titleFilter})
|
||||
}
|
||||
this.tagSelectionModel.getSelected().forEach(tag => {
|
||||
filterRules.push({rule_type: FILTER_HAS_TAG, value: tag.id.toString()})
|
||||
})
|
||||
this.correspondentSelectionModel.getSelected().forEach(correspondent => {
|
||||
filterRules.push({rule_type: FILTER_CORRESPONDENT, value: correspondent.id.toString()})
|
||||
})
|
||||
this.documentTypeSelectionModel.getSelected().forEach(documentType => {
|
||||
filterRules.push({rule_type: FILTER_DOCUMENT_TYPE, value: documentType.id.toString()})
|
||||
})
|
||||
if (this.dateCreatedBefore) {
|
||||
filterRules.push({rule_type: FILTER_CREATED_BEFORE, value: this.dateCreatedBefore})
|
||||
}
|
||||
if (this.dateCreatedAfter) {
|
||||
filterRules.push({rule_type: FILTER_CREATED_AFTER, value: this.dateCreatedAfter})
|
||||
}
|
||||
if (this.dateAddedBefore) {
|
||||
filterRules.push({rule_type: FILTER_ADDED_BEFORE, value: this.dateAddedBefore})
|
||||
}
|
||||
if (this.dateAddedAfter) {
|
||||
filterRules.push({rule_type: FILTER_ADDED_AFTER, value: this.dateAddedAfter})
|
||||
}
|
||||
console.log(filterRules)
|
||||
this.filterRulesChange.next(filterRules)
|
||||
}
|
||||
|
||||
hasFilters() {
|
||||
return this.filterRules.length > 0
|
||||
}
|
||||
|
||||
get selectedTags(): PaperlessTag[] {
|
||||
let tagRules: FilterRule[] = this.filterRules.filter(fr => fr.rule_type == FILTER_HAS_TAG)
|
||||
return this.tags?.filter(t => tagRules.find(tr => +tr.value == t.id))
|
||||
}
|
||||
|
||||
get selectedCorrespondents(): PaperlessCorrespondent[] {
|
||||
let correspondentRules: FilterRule[] = this.filterRules.filter(fr => fr.rule_type == FILTER_CORRESPONDENT)
|
||||
return this.correspondents?.filter(c => correspondentRules.find(cr => +cr.value == c.id))
|
||||
}
|
||||
|
||||
get selectedDocumentTypes(): PaperlessDocumentType[] {
|
||||
let documentTypeRules: FilterRule[] = this.filterRules.filter(fr => fr.rule_type == FILTER_DOCUMENT_TYPE)
|
||||
return this.documentTypes?.filter(dt => documentTypeRules.find(dtr => +dtr.value == dt.id))
|
||||
return this._titleFilter ||
|
||||
this.dateCreatedAfter || this.dateAddedBefore || this.dateCreatedAfter || this.dateCreatedBefore ||
|
||||
this.tagSelectionModel.selectionSize() || this.correspondentSelectionModel.selectionSize() || this.documentTypeSelectionModel.selectionSize()
|
||||
}
|
||||
|
||||
get titleFilter() {
|
||||
let existingRule = this.filterRules.find(rule => rule.rule_type == FILTER_TITLE)
|
||||
return existingRule ? existingRule.value : ''
|
||||
return this._titleFilter
|
||||
}
|
||||
|
||||
set titleFilter(value) {
|
||||
@ -97,142 +150,27 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
debounceTime(400),
|
||||
distinctUntilChanged()
|
||||
).subscribe(title => {
|
||||
this.setTitleRule(title)
|
||||
this._titleFilter = title
|
||||
this.updateRules()
|
||||
})
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.titleFilterDebounce.complete()
|
||||
// TODO: not sure if both is necessary
|
||||
this.subscription.unsubscribe()
|
||||
}
|
||||
|
||||
applyFilters() {
|
||||
this.filterRulesChange.next(this.filterRules)
|
||||
}
|
||||
|
||||
clearSelected() {
|
||||
this.filterRules = []
|
||||
this.applyFilters()
|
||||
}
|
||||
|
||||
private toggleFilterRule(filterRuleTypeID: number, value: number) {
|
||||
|
||||
let filterRuleType = FILTER_RULE_TYPES.find(t => t.id == filterRuleTypeID)
|
||||
|
||||
let existingRule = this.filterRules.find(rule => rule.rule_type == filterRuleTypeID && rule.value == value?.toString())
|
||||
let existingRuleOfSameType = this.filterRules.find(rule => rule.rule_type == filterRuleTypeID)
|
||||
|
||||
if (existingRule) {
|
||||
// if this exact rule already exists, remove it in all cases.
|
||||
this.filterRules.splice(this.filterRules.indexOf(existingRule), 1)
|
||||
} else if (filterRuleType.multi || !existingRuleOfSameType) {
|
||||
// if we allow multiple rules per type, or no rule of this type already exists, push a new rule.
|
||||
this.filterRules.push({rule_type: filterRuleTypeID, value: value?.toString()})
|
||||
} else {
|
||||
// otherwise (i.e., no multi support AND there's already a rule of this type), update the rule.
|
||||
existingRuleOfSameType.value = value?.toString()
|
||||
}
|
||||
this.applyFilters()
|
||||
}
|
||||
|
||||
private setTitleRule(title: string) {
|
||||
let existingRule = this.filterRules.find(rule => rule.rule_type == FILTER_TITLE)
|
||||
|
||||
if (!existingRule && title) {
|
||||
this.filterRules.push({rule_type: FILTER_TITLE, value: title})
|
||||
} else if (existingRule && !title) {
|
||||
this.filterRules.splice(this.filterRules.findIndex(rule => rule.rule_type == FILTER_TITLE), 1)
|
||||
} else if (existingRule && title) {
|
||||
existingRule.value = title
|
||||
}
|
||||
this.applyFilters()
|
||||
this._titleFilter = ""
|
||||
this.updateRules()
|
||||
}
|
||||
|
||||
toggleTag(tagId: number) {
|
||||
this.toggleFilterRule(FILTER_HAS_TAG, tagId)
|
||||
}
|
||||
|
||||
toggleCorrespondent(correspondentId: number) {
|
||||
this.toggleFilterRule(FILTER_CORRESPONDENT, correspondentId)
|
||||
}
|
||||
|
||||
toggleDocumentType(documentTypeId: number) {
|
||||
this.toggleFilterRule(FILTER_DOCUMENT_TYPE, documentTypeId)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Date handling
|
||||
|
||||
|
||||
onDatesCreatedSet(dates: DateSelection) {
|
||||
this.setDateCreatedBefore(dates.before)
|
||||
this.setDateCreatedAfter(dates.after)
|
||||
this.applyFilters()
|
||||
}
|
||||
|
||||
onDatesAddedSet(dates: DateSelection) {
|
||||
this.setDateAddedBefore(dates.before)
|
||||
this.setDateAddedAfter(dates.after)
|
||||
this.applyFilters()
|
||||
}
|
||||
|
||||
get dateCreatedBefore(): string {
|
||||
let createdBeforeRule: FilterRule = this.filterRules.find(fr => fr.rule_type == FILTER_CREATED_BEFORE)
|
||||
return createdBeforeRule ? createdBeforeRule.value : null
|
||||
}
|
||||
|
||||
get dateCreatedAfter(): string {
|
||||
let createdAfterRule: FilterRule = this.filterRules.find(fr => fr.rule_type == FILTER_CREATED_AFTER)
|
||||
return createdAfterRule ? createdAfterRule.value : null
|
||||
}
|
||||
|
||||
get dateAddedBefore(): string {
|
||||
let addedBeforeRule: FilterRule = this.filterRules.find(fr => fr.rule_type == FILTER_ADDED_BEFORE)
|
||||
return addedBeforeRule ? addedBeforeRule.value : null
|
||||
}
|
||||
|
||||
get dateAddedAfter(): string {
|
||||
let addedAfterRule: FilterRule = this.filterRules.find(fr => fr.rule_type == FILTER_ADDED_AFTER)
|
||||
return addedAfterRule ? addedAfterRule.value : null
|
||||
}
|
||||
|
||||
setDateCreatedBefore(date?: string) {
|
||||
if (date) this.setDateFilter(date, FILTER_CREATED_BEFORE)
|
||||
else this.clearDateFilter(FILTER_CREATED_BEFORE)
|
||||
}
|
||||
|
||||
setDateCreatedAfter(date?: string) {
|
||||
if (date) this.setDateFilter(date, FILTER_CREATED_AFTER)
|
||||
else this.clearDateFilter(FILTER_CREATED_AFTER)
|
||||
}
|
||||
|
||||
setDateAddedBefore(date?: string) {
|
||||
if (date) this.setDateFilter(date, FILTER_ADDED_BEFORE)
|
||||
else this.clearDateFilter(FILTER_ADDED_BEFORE)
|
||||
}
|
||||
|
||||
setDateAddedAfter(date?: string) {
|
||||
if (date) this.setDateFilter(date, FILTER_ADDED_AFTER)
|
||||
else this.clearDateFilter(FILTER_ADDED_AFTER)
|
||||
}
|
||||
|
||||
setDateFilter(date: string, dateRuleTypeID: number) {
|
||||
let existingRule = this.filterRules.find(rule => rule.rule_type == dateRuleTypeID)
|
||||
|
||||
if (existingRule) {
|
||||
existingRule.value = date
|
||||
} else {
|
||||
this.filterRules.push({rule_type: dateRuleTypeID, value: date})
|
||||
}
|
||||
}
|
||||
|
||||
clearDateFilter(dateRuleTypeID: number) {
|
||||
let ruleIndex = this.filterRules.findIndex(rule => rule.rule_type == dateRuleTypeID)
|
||||
if (ruleIndex != -1) {
|
||||
this.filterRules.splice(ruleIndex, 1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user