Remove relative date query strings from dropdown

This commit is contained in:
Michael Shamoon 2022-10-25 13:34:36 -07:00
parent 6a00d5e08a
commit b52cb193e1
4 changed files with 98 additions and 71 deletions

View File

@ -7,13 +7,13 @@
</button> </button>
<div class="dropdown-menu date-dropdown shadow pt-0" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}"> <div class="dropdown-menu date-dropdown shadow pt-0" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}">
<div class="list-group list-group-flush"> <div class="list-group list-group-flush">
<button *ngFor="let qf of quickFilters" class="list-group-item small list-goup list-group-item-action d-flex p-2" role="menuitem" (click)="setDateQuickFilter(qf.id)"> <button *ngFor="let rd of relativeDates" class="list-group-item small list-goup list-group-item-action d-flex p-2" role="menuitem" (click)="setRelativeDate(rd.date)">
<div _ngcontent-hga-c166="" class="selected-icon me-1"> <div _ngcontent-hga-c166="" class="selected-icon me-1">
<svg *ngIf="quickFilter === qf.id" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16"> <svg *ngIf="relativeDate === rd.date" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16">
<path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z"/> <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z"/>
</svg> </svg>
</div> </div>
{{qf.name}} {{rd.name}}
</button> </button>
<div class="list-group-item d-flex flex-column align-items-start" role="menuitem"> <div class="list-group-item d-flex flex-column align-items-start" role="menuitem">

View File

@ -16,20 +16,16 @@ import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter'
export interface DateSelection { export interface DateSelection {
before?: string before?: string
after?: string after?: string
dateQuery?: string relativeDateID?: number
} }
interface QuickFilter { export enum RelativeDate {
id: number LAST_7_DAYS = 0,
name: string LAST_MONTH = 1,
dateQuery: string LAST_3_MONTHS = 2,
LAST_YEAR = 3,
} }
const LAST_7_DAYS = 0
const LAST_MONTH = 1
const LAST_3_MONTHS = 2
const LAST_YEAR = 3
@Component({ @Component({
selector: 'app-date-dropdown', selector: 'app-date-dropdown',
templateUrl: './date-dropdown.component.html', templateUrl: './date-dropdown.component.html',
@ -41,23 +37,23 @@ export class DateDropdownComponent implements OnInit, OnDestroy {
this.datePlaceHolder = settings.getLocalizedDateInputFormat() this.datePlaceHolder = settings.getLocalizedDateInputFormat()
} }
quickFilters: Array<QuickFilter> = [ relativeDates = [
{ {
id: LAST_7_DAYS, date: RelativeDate.LAST_7_DAYS,
name: $localize`Last 7 days`, name: $localize`Last 7 days`,
dateQuery: '-1 week to now',
}, },
{ {
id: LAST_MONTH, date: RelativeDate.LAST_MONTH,
name: $localize`Last month`, name: $localize`Last month`,
dateQuery: '-1 month to now',
}, },
{ {
id: LAST_3_MONTHS, date: RelativeDate.LAST_3_MONTHS,
name: $localize`Last 3 months`, name: $localize`Last 3 months`,
dateQuery: '-3 month to now',
}, },
{ id: LAST_YEAR, name: $localize`Last year`, dateQuery: '-1 year to now' }, {
date: RelativeDate.LAST_YEAR,
name: $localize`Last year`,
},
] ]
datePlaceHolder: string datePlaceHolder: string
@ -74,21 +70,11 @@ export class DateDropdownComponent implements OnInit, OnDestroy {
@Output() @Output()
dateAfterChange = new EventEmitter<string>() dateAfterChange = new EventEmitter<string>()
quickFilter: number
@Input() @Input()
set dateQuery(query: string) { relativeDate: RelativeDate
this.quickFilter = this.quickFilters.find((qf) => qf.dateQuery == query)?.id
}
get dateQuery(): string {
return (
this.quickFilters.find((qf) => qf.id == this.quickFilter)?.dateQuery ?? ''
)
}
@Output() @Output()
dateQueryChange = new EventEmitter<string>() relativeDateChange = new EventEmitter<number>()
@Input() @Input()
title: string title: string
@ -98,7 +84,7 @@ export class DateDropdownComponent implements OnInit, OnDestroy {
get isActive(): boolean { get isActive(): boolean {
return ( return (
this.quickFilter > -1 || this.relativeDate !== null ||
this.dateAfter?.length > 0 || this.dateAfter?.length > 0 ||
this.dateBefore?.length > 0 this.dateBefore?.length > 0
) )
@ -120,30 +106,26 @@ export class DateDropdownComponent implements OnInit, OnDestroy {
} }
} }
setDateQuickFilter(qf: number) { setRelativeDate(rd: RelativeDate) {
this.dateBefore = null this.dateBefore = null
this.dateAfter = null this.dateAfter = null
this.quickFilter = this.quickFilter == qf ? null : qf this.relativeDate = this.relativeDate == rd ? null : rd
this.onChange() this.onChange()
} }
qfIsSelected(qf: number) {
return this.quickFilter == qf
}
onChange() { onChange() {
this.dateBeforeChange.emit(this.dateBefore) this.dateBeforeChange.emit(this.dateBefore)
this.dateAfterChange.emit(this.dateAfter) this.dateAfterChange.emit(this.dateAfter)
this.dateQueryChange.emit(this.dateQuery) this.relativeDateChange.emit(this.relativeDate)
this.datesSet.emit({ this.datesSet.emit({
after: this.dateAfter, after: this.dateAfter,
before: this.dateBefore, before: this.dateBefore,
dateQuery: this.dateQuery, relativeDateID: this.relativeDate,
}) })
} }
onChangeDebounce() { onChangeDebounce() {
this.dateQuery = null this.relativeDate = null
this.datesSetDebounce$.next({ this.datesSetDebounce$.next({
after: this.dateAfter, after: this.dateAfter,
before: this.dateBefore, before: this.dateBefore,

View File

@ -55,13 +55,13 @@
(datesSet)="updateRules()" (datesSet)="updateRules()"
[(dateBefore)]="dateCreatedBefore" [(dateBefore)]="dateCreatedBefore"
[(dateAfter)]="dateCreatedAfter" [(dateAfter)]="dateCreatedAfter"
[(dateQuery)]="dateCreatedQuery"></app-date-dropdown> [(relativeDate)]="dateCreatedRelativeDate"></app-date-dropdown>
<app-date-dropdown class="mb-2 mb-xl-0" <app-date-dropdown class="mb-2 mb-xl-0"
title="Added" i18n-title title="Added" i18n-title
(datesSet)="updateRules()" (datesSet)="updateRules()"
[(dateBefore)]="dateAddedBefore" [(dateBefore)]="dateAddedBefore"
[(dateAfter)]="dateAddedAfter" [(dateAfter)]="dateAddedAfter"
[(dateQuery)]="dateAddedQuery"></app-date-dropdown> [(relativeDate)]="dateAddedRelativeDate"></app-date-dropdown>
</div> </div>
</div> </div>
</div> </div>

View File

@ -44,6 +44,7 @@ import { DocumentService } from 'src/app/services/rest/document.service'
import { PaperlessDocument } from 'src/app/data/paperless-document' import { PaperlessDocument } from 'src/app/data/paperless-document'
import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path' import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path'
import { StoragePathService } from 'src/app/services/rest/storage-path.service' import { StoragePathService } from 'src/app/services/rest/storage-path.service'
import { RelativeDate } from '../../common/date-dropdown/date-dropdown.component'
const TEXT_FILTER_TARGET_TITLE = 'title' const TEXT_FILTER_TARGET_TITLE = 'title'
const TEXT_FILTER_TARGET_TITLE_CONTENT = 'title-content' const TEXT_FILTER_TARGET_TITLE_CONTENT = 'title-content'
@ -59,6 +60,24 @@ const TEXT_FILTER_MODIFIER_LT = 'less'
const RELATIVE_DATE_QUERY_REGEXP_CREATED = /created:\[([^\]]+)\]/g const RELATIVE_DATE_QUERY_REGEXP_CREATED = /created:\[([^\]]+)\]/g
const RELATIVE_DATE_QUERY_REGEXP_ADDED = /added:\[([^\]]+)\]/g const RELATIVE_DATE_QUERY_REGEXP_ADDED = /added:\[([^\]]+)\]/g
const RELATIVE_DATE_QUERYSTRINGS = [
{
relativeDate: RelativeDate.LAST_7_DAYS,
dateQuery: '-1 week to now',
},
{
relativeDate: RelativeDate.LAST_MONTH,
dateQuery: '-1 month to now',
},
{
relativeDate: RelativeDate.LAST_3_MONTHS,
dateQuery: '-3 month to now',
},
{
relativeDate: RelativeDate.LAST_YEAR,
dateQuery: '-1 year to now',
},
]
@Component({ @Component({
selector: 'app-filter-editor', selector: 'app-filter-editor',
@ -200,8 +219,8 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
dateCreatedAfter: string dateCreatedAfter: string
dateAddedBefore: string dateAddedBefore: string
dateAddedAfter: string dateAddedAfter: string
dateCreatedQuery: string dateCreatedRelativeDate: RelativeDate
dateAddedQuery: string dateAddedRelativeDate: RelativeDate
_unmodifiedFilterRules: FilterRule[] = [] _unmodifiedFilterRules: FilterRule[] = []
_filterRules: FilterRule[] = [] _filterRules: FilterRule[] = []
@ -233,8 +252,8 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
this.dateAddedAfter = null this.dateAddedAfter = null
this.dateCreatedBefore = null this.dateCreatedBefore = null
this.dateCreatedAfter = null this.dateCreatedAfter = null
this.dateCreatedQuery = null this.dateCreatedRelativeDate = null
this.dateAddedQuery = null this.dateAddedRelativeDate = null
this.textFilterModifier = TEXT_FILTER_MODIFIER_EQUALS this.textFilterModifier = TEXT_FILTER_MODIFIER_EQUALS
value.forEach((rule) => { value.forEach((rule) => {
@ -258,7 +277,10 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
;[...arg.matchAll(RELATIVE_DATE_QUERY_REGEXP_CREATED)].forEach( ;[...arg.matchAll(RELATIVE_DATE_QUERY_REGEXP_CREATED)].forEach(
(match) => { (match) => {
if (match[1]?.length) { if (match[1]?.length) {
this.dateCreatedQuery = match[1] this.dateCreatedRelativeDate =
RELATIVE_DATE_QUERYSTRINGS.find(
(qS) => qS.dateQuery == match[1]
)?.relativeDate
} }
} }
) )
@ -268,7 +290,10 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
;[...arg.matchAll(RELATIVE_DATE_QUERY_REGEXP_ADDED)].forEach( ;[...arg.matchAll(RELATIVE_DATE_QUERY_REGEXP_ADDED)].forEach(
(match) => { (match) => {
if (match[1]?.length) { if (match[1]?.length) {
this.dateAddedQuery = match[1] this.dateAddedRelativeDate =
RELATIVE_DATE_QUERYSTRINGS.find(
(qS) => qS.dateQuery == match[1]
)?.relativeDate
} }
} }
) )
@ -501,26 +526,45 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
value: this.dateAddedAfter, value: this.dateAddedAfter,
}) })
} }
if (this.dateAddedQuery || this.dateCreatedQuery) { if (
this.dateAddedRelativeDate !== null ||
this.dateCreatedRelativeDate !== null
) {
let queryArgs: Array<string> = [] let queryArgs: Array<string> = []
if (this.dateCreatedQuery)
queryArgs.push(`created:[${this.dateCreatedQuery}]`)
if (this.dateAddedQuery) queryArgs.push(`added:[${this.dateAddedQuery}]`)
const existingRule = filterRules.find( const existingRule = filterRules.find(
(fr) => fr.rule_type == FILTER_FULLTEXT_QUERY (fr) => fr.rule_type == FILTER_FULLTEXT_QUERY
) )
let existingRuleArgs = existingRule?.value.split(',')
if (this.dateCreatedRelativeDate !== null) {
queryArgs.push(
`created:[${
RELATIVE_DATE_QUERYSTRINGS.find(
(qS) => qS.relativeDate == this.dateCreatedRelativeDate
).dateQuery
}]`
)
if (existingRule) {
queryArgs = existingRuleArgs
.filter((arg) => !arg.match(RELATIVE_DATE_QUERY_REGEXP_CREATED))
.concat(queryArgs)
}
}
if (this.dateAddedRelativeDate !== null) {
queryArgs.push(
`added:[${
RELATIVE_DATE_QUERYSTRINGS.find(
(qS) => qS.relativeDate == this.dateAddedRelativeDate
).dateQuery
}]`
)
if (existingRule) {
queryArgs = existingRuleArgs
.filter((arg) => !arg.match(RELATIVE_DATE_QUERY_REGEXP_ADDED))
.concat(queryArgs)
}
}
if (existingRule) { if (existingRule) {
let existingRuleArgs = existingRule.value.split(',')
if (this.dateCreatedQuery) {
queryArgs = existingRuleArgs
.filter((arg) => !arg.includes('created:'))
.concat(queryArgs)
}
if (this.dateAddedQuery) {
queryArgs = existingRuleArgs
.filter((arg) => !arg.includes('added:'))
.concat(queryArgs)
}
existingRule.value = queryArgs.join(',') existingRule.value = queryArgs.join(',')
} else { } else {
filterRules.push({ filterRules.push({
@ -529,13 +573,16 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
}) })
} }
} }
if (!this.dateAddedQuery && !this.dateCreatedQuery) { if (
this.dateCreatedRelativeDate == null &&
this.dateAddedRelativeDate == null
) {
const existingRule = filterRules.find( const existingRule = filterRules.find(
(fr) => fr.rule_type == FILTER_FULLTEXT_QUERY (fr) => fr.rule_type == FILTER_FULLTEXT_QUERY
) )
if ( if (
existingRule?.value.includes('created:') || existingRule?.value.match(RELATIVE_DATE_QUERY_REGEXP_CREATED) ||
existingRule?.value.includes('added:') existingRule?.value.match(RELATIVE_DATE_QUERY_REGEXP_ADDED)
) { ) {
// remove any existing date query // remove any existing date query
existingRule.value = existingRule.value existingRule.value = existingRule.value
@ -660,8 +707,6 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
target != TEXT_FILTER_TARGET_FULLTEXT_MORELIKE target != TEXT_FILTER_TARGET_FULLTEXT_MORELIKE
) { ) {
this._textFilter = '' this._textFilter = ''
this.dateAddedQuery = ''
this.dateCreatedQuery = ''
} }
this.textFilterTarget = target this.textFilterTarget = target
this.textFilterInput.nativeElement.focus() this.textFilterInput.nativeElement.focus()