Unified date filter
This commit is contained in:
@@ -81,14 +81,15 @@ test('text filtering', async ({ page }) => {
|
|||||||
test('date filtering', async ({ page }) => {
|
test('date filtering', async ({ page }) => {
|
||||||
await page.routeFromHAR(REQUESTS_HAR3, { notFound: 'fallback' })
|
await page.routeFromHAR(REQUESTS_HAR3, { notFound: 'fallback' })
|
||||||
await page.goto('/documents')
|
await page.goto('/documents')
|
||||||
await page.getByRole('button', { name: 'Created' }).click()
|
await page.getByRole('button', { name: 'Dates' }).click()
|
||||||
await page.getByRole('menuitem', { name: 'Last 3 months' }).click()
|
await page.getByRole('menuitem', { name: 'Last 3 months' }).first().click()
|
||||||
await expect(page.locator('pngx-document-list')).toHaveText(/one document/i)
|
await expect(page.locator('pngx-document-list')).toHaveText(/one document/i)
|
||||||
await page.getByRole('button', { name: 'Created Clear selected' }).click()
|
await page.getByRole('button', { name: 'Dates Clear selected' }).click()
|
||||||
await page.getByRole('button', { name: 'Created' }).click()
|
await page.getByRole('button', { name: 'Dates' }).click()
|
||||||
await page
|
await page
|
||||||
.getByRole('menuitem', { name: 'After mm/dd/yyyy' })
|
.getByRole('menuitem', { name: 'After mm/dd/yyyy' })
|
||||||
.getByRole('button')
|
.getByRole('button')
|
||||||
|
.first()
|
||||||
.click()
|
.click()
|
||||||
await page.getByRole('combobox', { name: 'Select month' }).selectOption('12')
|
await page.getByRole('combobox', { name: 'Select month' }).selectOption('12')
|
||||||
await page.getByRole('combobox', { name: 'Select year' }).selectOption('2022')
|
await page.getByRole('combobox', { name: 'Select year' }).selectOption('2022')
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import { ToastsComponent } from './components/common/toasts/toasts.component'
|
|||||||
import { FilterEditorComponent } from './components/document-list/filter-editor/filter-editor.component'
|
import { FilterEditorComponent } from './components/document-list/filter-editor/filter-editor.component'
|
||||||
import { FilterableDropdownComponent } from './components/common/filterable-dropdown/filterable-dropdown.component'
|
import { FilterableDropdownComponent } from './components/common/filterable-dropdown/filterable-dropdown.component'
|
||||||
import { ToggleableDropdownButtonComponent } from './components/common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component'
|
import { ToggleableDropdownButtonComponent } from './components/common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component'
|
||||||
import { DateDropdownComponent } from './components/common/date-dropdown/date-dropdown.component'
|
import { DatesDropdownComponent } from './components/common/dates-dropdown/dates-dropdown.component'
|
||||||
import { DocumentCardLargeComponent } from './components/document-list/document-card-large/document-card-large.component'
|
import { DocumentCardLargeComponent } from './components/document-list/document-card-large/document-card-large.component'
|
||||||
import { DocumentCardSmallComponent } from './components/document-list/document-card-small/document-card-small.component'
|
import { DocumentCardSmallComponent } from './components/document-list/document-card-small/document-card-small.component'
|
||||||
import { BulkEditorComponent } from './components/document-list/bulk-editor/bulk-editor.component'
|
import { BulkEditorComponent } from './components/document-list/bulk-editor/bulk-editor.component'
|
||||||
@@ -140,6 +140,7 @@ import {
|
|||||||
boxes,
|
boxes,
|
||||||
calendar,
|
calendar,
|
||||||
calendarEvent,
|
calendarEvent,
|
||||||
|
calendarEventFill,
|
||||||
cardChecklist,
|
cardChecklist,
|
||||||
cardHeading,
|
cardHeading,
|
||||||
caretDown,
|
caretDown,
|
||||||
@@ -235,6 +236,7 @@ const icons = {
|
|||||||
boxes,
|
boxes,
|
||||||
calendar,
|
calendar,
|
||||||
calendarEvent,
|
calendarEvent,
|
||||||
|
calendarEventFill,
|
||||||
cardChecklist,
|
cardChecklist,
|
||||||
cardHeading,
|
cardHeading,
|
||||||
caretDown,
|
caretDown,
|
||||||
@@ -407,7 +409,7 @@ function initializeApp(settings: SettingsService) {
|
|||||||
FilterEditorComponent,
|
FilterEditorComponent,
|
||||||
FilterableDropdownComponent,
|
FilterableDropdownComponent,
|
||||||
ToggleableDropdownButtonComponent,
|
ToggleableDropdownButtonComponent,
|
||||||
DateDropdownComponent,
|
DatesDropdownComponent,
|
||||||
DocumentCardLargeComponent,
|
DocumentCardLargeComponent,
|
||||||
DocumentCardSmallComponent,
|
DocumentCardSmallComponent,
|
||||||
BulkEditorComponent,
|
BulkEditorComponent,
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
<div class="btn-group w-100" ngbDropdown role="group">
|
|
||||||
<button class="btn btn-sm" id="dropdown{{title}}" ngbDropdownToggle [ngClass]="dateBefore || dateAfter ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled">
|
|
||||||
{{title}}
|
|
||||||
<pngx-clearable-badge [selected]="isActive" (cleared)="reset()"></pngx-clearable-badge><span class="visually-hidden">selected</span>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu date-dropdown shadow pt-0" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}">
|
|
||||||
<div class="list-group list-group-flush">
|
|
||||||
@for (rd of relativeDates; track rd) {
|
|
||||||
<button class="list-group-item small list-goup list-group-item-action d-flex p-2" role="menuitem" (click)="setRelativeDate(rd.id)">
|
|
||||||
<div class="selected-icon">
|
|
||||||
@if (relativeDate === rd.id) {
|
|
||||||
<i-bs width="1em" height="1em" name="check"></i-bs>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="d-flex justify-content-between w-100 align-items-center ps-2">
|
|
||||||
<div class="pe-2 pe-lg-4">
|
|
||||||
{{rd.name}}
|
|
||||||
</div>
|
|
||||||
<div class="text-muted small pe-2">
|
|
||||||
<span class="small">
|
|
||||||
{{ rd.date | customDate:'mediumDate' }} – <ng-container i18n>now</ng-container>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
<div class="list-group-item d-flex flex-column align-items-start" role="menuitem">
|
|
||||||
|
|
||||||
<div class="mb-2 d-flex flex-row w-100 justify-content-between small">
|
|
||||||
<div i18n>After</div>
|
|
||||||
@if (dateAfter) {
|
|
||||||
<a class="btn btn-link p-0 m-0" (click)="clearAfter()">
|
|
||||||
<i-bs width="1em" height="1em" name="x"></i-bs>
|
|
||||||
<small i18n>Clear</small>
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<input class="form-control" [placeholder]="datePlaceHolder" (dateSelect)="onChangeDebounce()" (change)="onChangeDebounce()" (keypress)="onKeyPress($event)"
|
|
||||||
maxlength="10" [(ngModel)]="dateAfter" ngbDatepicker #dateAfterPicker="ngbDatepicker">
|
|
||||||
<button class="btn btn-outline-secondary" (click)="dateAfterPicker.toggle()" type="button">
|
|
||||||
<i-bs width="1em" height="1em" name="calendar"></i-bs>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="list-group-item d-flex flex-column align-items-start" role="menuitem">
|
|
||||||
|
|
||||||
<div class="mb-2 d-flex flex-row w-100 justify-content-between small">
|
|
||||||
<div i18n>Before</div>
|
|
||||||
@if (dateBefore) {
|
|
||||||
<a class="btn btn-link p-0 m-0" (click)="clearBefore()">
|
|
||||||
<i-bs width="1em" height="1em" name="x"></i-bs>
|
|
||||||
<small i18n>Clear</small>
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<input class="form-control" [placeholder]="datePlaceHolder" (dateSelect)="onChangeDebounce()" (change)="onChangeDebounce()" (keypress)="onKeyPress($event)"
|
|
||||||
maxlength="10" [(ngModel)]="dateBefore" ngbDatepicker #dateBeforePicker="ngbDatepicker">
|
|
||||||
<button class="btn btn-outline-secondary" (click)="dateBeforePicker.toggle()" type="button">
|
|
||||||
<i-bs width="1em" height="1em" name="calendar"></i-bs>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
import {
|
|
||||||
Component,
|
|
||||||
EventEmitter,
|
|
||||||
Input,
|
|
||||||
Output,
|
|
||||||
OnInit,
|
|
||||||
OnDestroy,
|
|
||||||
} from '@angular/core'
|
|
||||||
import { NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { Subject, Subscription } from 'rxjs'
|
|
||||||
import { debounceTime } from 'rxjs/operators'
|
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
|
||||||
import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter'
|
|
||||||
|
|
||||||
export interface DateSelection {
|
|
||||||
before?: string
|
|
||||||
after?: string
|
|
||||||
relativeDateID?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum RelativeDate {
|
|
||||||
LAST_7_DAYS = 0,
|
|
||||||
LAST_MONTH = 1,
|
|
||||||
LAST_3_MONTHS = 2,
|
|
||||||
LAST_YEAR = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'pngx-date-dropdown',
|
|
||||||
templateUrl: './date-dropdown.component.html',
|
|
||||||
styleUrls: ['./date-dropdown.component.scss'],
|
|
||||||
providers: [{ provide: NgbDateAdapter, useClass: ISODateAdapter }],
|
|
||||||
})
|
|
||||||
export class DateDropdownComponent implements OnInit, OnDestroy {
|
|
||||||
constructor(settings: SettingsService) {
|
|
||||||
this.datePlaceHolder = settings.getLocalizedDateInputFormat()
|
|
||||||
}
|
|
||||||
|
|
||||||
relativeDates = [
|
|
||||||
{
|
|
||||||
id: RelativeDate.LAST_7_DAYS,
|
|
||||||
name: $localize`Last 7 days`,
|
|
||||||
date: new Date().setDate(new Date().getDate() - 7),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: RelativeDate.LAST_MONTH,
|
|
||||||
name: $localize`Last month`,
|
|
||||||
date: new Date().setMonth(new Date().getMonth() - 1),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: RelativeDate.LAST_3_MONTHS,
|
|
||||||
name: $localize`Last 3 months`,
|
|
||||||
date: new Date().setMonth(new Date().getMonth() - 3),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: RelativeDate.LAST_YEAR,
|
|
||||||
name: $localize`Last year`,
|
|
||||||
date: new Date().setFullYear(new Date().getFullYear() - 1),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
datePlaceHolder: string
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
dateBefore: string
|
|
||||||
|
|
||||||
@Output()
|
|
||||||
dateBeforeChange = new EventEmitter<string>()
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
dateAfter: string
|
|
||||||
|
|
||||||
@Output()
|
|
||||||
dateAfterChange = new EventEmitter<string>()
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
relativeDate: RelativeDate
|
|
||||||
|
|
||||||
@Output()
|
|
||||||
relativeDateChange = new EventEmitter<number>()
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
title: string
|
|
||||||
|
|
||||||
@Output()
|
|
||||||
datesSet = new EventEmitter<DateSelection>()
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
disabled: boolean = false
|
|
||||||
|
|
||||||
get isActive(): boolean {
|
|
||||||
return (
|
|
||||||
this.relativeDate !== null ||
|
|
||||||
this.dateAfter?.length > 0 ||
|
|
||||||
this.dateBefore?.length > 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private datesSetDebounce$ = new Subject()
|
|
||||||
|
|
||||||
private sub: Subscription
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.sub = this.datesSetDebounce$.pipe(debounceTime(400)).subscribe(() => {
|
|
||||||
this.onChange()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
if (this.sub) {
|
|
||||||
this.sub.unsubscribe()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.dateBefore = null
|
|
||||||
this.dateAfter = null
|
|
||||||
this.relativeDate = null
|
|
||||||
this.onChange()
|
|
||||||
}
|
|
||||||
|
|
||||||
setRelativeDate(rd: RelativeDate) {
|
|
||||||
this.dateBefore = null
|
|
||||||
this.dateAfter = null
|
|
||||||
this.relativeDate = this.relativeDate == rd ? null : rd
|
|
||||||
this.onChange()
|
|
||||||
}
|
|
||||||
|
|
||||||
onChange() {
|
|
||||||
this.dateBeforeChange.emit(this.dateBefore)
|
|
||||||
this.dateAfterChange.emit(this.dateAfter)
|
|
||||||
this.relativeDateChange.emit(this.relativeDate)
|
|
||||||
this.datesSet.emit({
|
|
||||||
after: this.dateAfter,
|
|
||||||
before: this.dateBefore,
|
|
||||||
relativeDateID: this.relativeDate,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onChangeDebounce() {
|
|
||||||
this.relativeDate = null
|
|
||||||
this.datesSetDebounce$.next({
|
|
||||||
after: this.dateAfter,
|
|
||||||
before: this.dateBefore,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
clearBefore() {
|
|
||||||
this.dateBefore = null
|
|
||||||
this.onChange()
|
|
||||||
}
|
|
||||||
|
|
||||||
clearAfter() {
|
|
||||||
this.dateAfter = null
|
|
||||||
this.onChange()
|
|
||||||
}
|
|
||||||
|
|
||||||
// prevent chars other than numbers and separators
|
|
||||||
onKeyPress(event: KeyboardEvent) {
|
|
||||||
if ('Enter' !== event.key && !/[0-9,\.\/-]+/.test(event.key)) {
|
|
||||||
event.preventDefault()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
<div class="btn-group w-100" ngbDropdown role="group">
|
||||||
|
<button class="btn btn-sm" id="dropdown{{title}}" ngbDropdownToggle [ngClass]="createdDateBefore || createdDateAfter ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled">
|
||||||
|
<i-bs width="1em" height="1em" name="calendar-event-fill"></i-bs>
|
||||||
|
<div class="d-none d-sm-inline"> {{title}}</div>
|
||||||
|
<pngx-clearable-badge [selected]="isActive" (cleared)="reset()"></pngx-clearable-badge><span class="visually-hidden">selected</span>
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu date-dropdown shadow pt-0" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}">
|
||||||
|
<div class="row d-flex">
|
||||||
|
<div class="col border-end">
|
||||||
|
<div class="list-group list-group-flush">
|
||||||
|
<h6 class="dropdown-header border-bottom" i18n>Created</h6>
|
||||||
|
@for (rd of relativeDates; track rd) {
|
||||||
|
<button class="list-group-item small list-goup list-group-item-action d-flex p-2" role="menuitem" (click)="setCreatedRelativeDate(rd.id)">
|
||||||
|
<div class="selected-icon">
|
||||||
|
@if (createdRelativeDate === rd.id) {
|
||||||
|
<i-bs width="1em" height="1em" name="check"></i-bs>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-between w-100 align-items-center ps-2">
|
||||||
|
<div class="pe-2 pe-lg-4">
|
||||||
|
{{rd.name}}
|
||||||
|
</div>
|
||||||
|
<div class="text-muted small pe-2">
|
||||||
|
<span class="small">
|
||||||
|
{{ rd.date | customDate:'mediumDate' }} – <ng-container i18n>now</ng-container>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
<div class="list-group-item d-flex flex-column align-items-start" role="menuitem">
|
||||||
|
|
||||||
|
<div class="mb-2 d-flex flex-row w-100 justify-content-between small">
|
||||||
|
<div i18n>After</div>
|
||||||
|
@if (createdDateAfter) {
|
||||||
|
<a class="btn btn-link p-0 m-0" (click)="clearCreatedAfter()">
|
||||||
|
<i-bs width="1em" height="1em" name="x"></i-bs>
|
||||||
|
<small i18n>Clear</small>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<input class="form-control" [placeholder]="datePlaceHolder" (dateSelect)="onChangeDebounce()" (change)="onChangeDebounce()" (keypress)="onKeyPress($event)"
|
||||||
|
maxlength="10" [(ngModel)]="createdDateAfter" ngbDatepicker #createdDateAfterPicker="ngbDatepicker">
|
||||||
|
<button class="btn btn-outline-secondary" (click)="createdDateAfterPicker.toggle()" type="button">
|
||||||
|
<i-bs width="1em" height="1em" name="calendar"></i-bs>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="list-group-item d-flex flex-column align-items-start" role="menuitem">
|
||||||
|
|
||||||
|
<div class="mb-2 d-flex flex-row w-100 justify-content-between small">
|
||||||
|
<div i18n>Before</div>
|
||||||
|
@if (createdDateBefore) {
|
||||||
|
<a class="btn btn-link p-0 m-0" (click)="clearCreatedBefore()">
|
||||||
|
<i-bs width="1em" height="1em" name="x"></i-bs>
|
||||||
|
<small i18n>Clear</small>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<input class="form-control" [placeholder]="datePlaceHolder" (dateSelect)="onChangeDebounce()" (change)="onChangeDebounce()" (keypress)="onKeyPress($event)"
|
||||||
|
maxlength="10" [(ngModel)]="createdDateBefore" ngbDatepicker #createdDateBeforePicker="ngbDatepicker">
|
||||||
|
<button class="btn btn-outline-secondary" (click)="createdDateBeforePicker.toggle()" type="button">
|
||||||
|
<i-bs width="1em" height="1em" name="calendar"></i-bs>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h6 class="dropdown-header border-bottom" i18n>Added</h6>
|
||||||
|
<div class="list-group list-group-flush">
|
||||||
|
@for (rd of relativeDates; track rd) {
|
||||||
|
<button class="list-group-item small list-goup list-group-item-action d-flex p-2" role="menuitem" (click)="setAddedRelativeDate(rd.id)">
|
||||||
|
<div class="selected-icon">
|
||||||
|
@if (addedRelativeDate === rd.id) {
|
||||||
|
<i-bs width="1em" height="1em" name="check"></i-bs>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-between w-100 align-items-center ps-2">
|
||||||
|
<div class="pe-2 pe-lg-4">
|
||||||
|
{{rd.name}}
|
||||||
|
</div>
|
||||||
|
<div class="text-muted small pe-2">
|
||||||
|
<span class="small">
|
||||||
|
{{ rd.date | customDate:'mediumDate' }} – <ng-container i18n>now</ng-container>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
<div class="list-group-item d-flex flex-column align-items-start" role="menuitem">
|
||||||
|
|
||||||
|
<div class="mb-2 d-flex flex-row w-100 justify-content-between small">
|
||||||
|
<div i18n>After</div>
|
||||||
|
@if (addedDateAfter) {
|
||||||
|
<a class="btn btn-link p-0 m-0" (click)="clearAddedAfter()">
|
||||||
|
<i-bs width="1em" height="1em" name="x"></i-bs>
|
||||||
|
<small i18n>Clear</small>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<input class="form-control" [placeholder]="datePlaceHolder" (dateSelect)="onChangeDebounce()" (change)="onChangeDebounce()" (keypress)="onKeyPress($event)"
|
||||||
|
maxlength="10" [(ngModel)]="addedDateAfter" ngbDatepicker #addedDateAfterPicker="ngbDatepicker">
|
||||||
|
<button class="btn btn-outline-secondary" (click)="addedDateAfterPicker.toggle()" type="button">
|
||||||
|
<i-bs width="1em" height="1em" name="calendar"></i-bs>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="list-group-item d-flex flex-column align-items-start" role="menuitem">
|
||||||
|
|
||||||
|
<div class="mb-2 d-flex flex-row w-100 justify-content-between small">
|
||||||
|
<div i18n>Before</div>
|
||||||
|
@if (addedDateBefore) {
|
||||||
|
<a class="btn btn-link p-0 m-0" (click)="clearAddedBefore()">
|
||||||
|
<i-bs width="1em" height="1em" name="x"></i-bs>
|
||||||
|
<small i18n>Clear</small>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<input class="form-control" [placeholder]="datePlaceHolder" (dateSelect)="onChangeDebounce()" (change)="onChangeDebounce()" (keypress)="onKeyPress($event)"
|
||||||
|
maxlength="10" [(ngModel)]="addedDateBefore" ngbDatepicker #addedDateBeforePicker="ngbDatepicker">
|
||||||
|
<button class="btn btn-outline-secondary" (click)="addedDateBeforePicker.toggle()" type="button">
|
||||||
|
<i-bs width="1em" height="1em" name="calendar"></i-bs>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
.date-dropdown {
|
.date-dropdown {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
@media(min-width: 768px) {
|
||||||
|
--bs-dropdown-min-width: 40rem;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-link {
|
.btn-link {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,12 @@ import {
|
|||||||
fakeAsync,
|
fakeAsync,
|
||||||
tick,
|
tick,
|
||||||
} from '@angular/core/testing'
|
} from '@angular/core/testing'
|
||||||
let fixture: ComponentFixture<DateDropdownComponent>
|
let fixture: ComponentFixture<DatesDropdownComponent>
|
||||||
import {
|
import {
|
||||||
DateDropdownComponent,
|
DatesDropdownComponent,
|
||||||
DateSelection,
|
DateSelection,
|
||||||
RelativeDate,
|
RelativeDate,
|
||||||
} from './date-dropdown.component'
|
} from './dates-dropdown.component'
|
||||||
import { HttpClientTestingModule } from '@angular/common/http/testing'
|
import { HttpClientTestingModule } from '@angular/common/http/testing'
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
import { SettingsService } from 'src/app/services/settings.service'
|
||||||
@@ -19,15 +19,15 @@ import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
|||||||
import { DatePipe } from '@angular/common'
|
import { DatePipe } from '@angular/common'
|
||||||
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
||||||
|
|
||||||
describe('DateDropdownComponent', () => {
|
describe('DatesDropdownComponent', () => {
|
||||||
let component: DateDropdownComponent
|
let component: DatesDropdownComponent
|
||||||
let settingsService: SettingsService
|
let settingsService: SettingsService
|
||||||
let settingsSpy
|
let settingsSpy
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
DateDropdownComponent,
|
DatesDropdownComponent,
|
||||||
ClearableBadgeComponent,
|
ClearableBadgeComponent,
|
||||||
CustomDatePipe,
|
CustomDatePipe,
|
||||||
],
|
],
|
||||||
@@ -44,7 +44,7 @@ describe('DateDropdownComponent', () => {
|
|||||||
settingsService = TestBed.inject(SettingsService)
|
settingsService = TestBed.inject(SettingsService)
|
||||||
settingsSpy = jest.spyOn(settingsService, 'getLocalizedDateInputFormat')
|
settingsSpy = jest.spyOn(settingsService, 'getLocalizedDateInputFormat')
|
||||||
|
|
||||||
fixture = TestBed.createComponent(DateDropdownComponent)
|
fixture = TestBed.createComponent(DatesDropdownComponent)
|
||||||
component = fixture.componentInstance
|
component = fixture.componentInstance
|
||||||
|
|
||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
@@ -57,7 +57,7 @@ describe('DateDropdownComponent', () => {
|
|||||||
|
|
||||||
it('should support date input, emit change', fakeAsync(() => {
|
it('should support date input, emit change', fakeAsync(() => {
|
||||||
let result: string
|
let result: string
|
||||||
component.dateAfterChange.subscribe((date) => (result = date))
|
component.createdDateAfterChange.subscribe((date) => (result = date))
|
||||||
const input: HTMLInputElement = fixture.nativeElement.querySelector('input')
|
const input: HTMLInputElement = fixture.nativeElement.querySelector('input')
|
||||||
input.value = '5/30/2023'
|
input.value = '5/30/2023'
|
||||||
input.dispatchEvent(new Event('change'))
|
input.dispatchEvent(new Event('change'))
|
||||||
@@ -78,45 +78,69 @@ describe('DateDropdownComponent', () => {
|
|||||||
it('should support relative dates', fakeAsync(() => {
|
it('should support relative dates', fakeAsync(() => {
|
||||||
let result: DateSelection
|
let result: DateSelection
|
||||||
component.datesSet.subscribe((date) => (result = date))
|
component.datesSet.subscribe((date) => (result = date))
|
||||||
component.setRelativeDate(null)
|
component.setCreatedRelativeDate(null)
|
||||||
component.setRelativeDate(RelativeDate.LAST_7_DAYS)
|
component.setCreatedRelativeDate(RelativeDate.LAST_7_DAYS)
|
||||||
|
component.setAddedRelativeDate(null)
|
||||||
|
component.setAddedRelativeDate(RelativeDate.LAST_7_DAYS)
|
||||||
tick(500)
|
tick(500)
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
after: null,
|
createdAfter: null,
|
||||||
before: null,
|
createdBefore: null,
|
||||||
relativeDateID: RelativeDate.LAST_7_DAYS,
|
createdRelativeDateID: RelativeDate.LAST_7_DAYS,
|
||||||
|
addedAfter: null,
|
||||||
|
addedBefore: null,
|
||||||
|
addedRelativeDateID: RelativeDate.LAST_7_DAYS,
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
it('should support report if active', () => {
|
it('should support report if active', () => {
|
||||||
component.relativeDate = RelativeDate.LAST_7_DAYS
|
component.createdRelativeDate = RelativeDate.LAST_7_DAYS
|
||||||
expect(component.isActive).toBeTruthy()
|
expect(component.isActive).toBeTruthy()
|
||||||
component.relativeDate = null
|
component.createdRelativeDate = null
|
||||||
component.dateAfter = '2023-05-30'
|
component.createdDateAfter = '2023-05-30'
|
||||||
expect(component.isActive).toBeTruthy()
|
expect(component.isActive).toBeTruthy()
|
||||||
component.dateAfter = null
|
component.createdDateAfter = null
|
||||||
component.dateBefore = '2023-05-30'
|
component.createdDateBefore = '2023-05-30'
|
||||||
expect(component.isActive).toBeTruthy()
|
expect(component.isActive).toBeTruthy()
|
||||||
component.dateBefore = null
|
component.createdDateBefore = null
|
||||||
|
|
||||||
|
component.addedRelativeDate = RelativeDate.LAST_7_DAYS
|
||||||
|
expect(component.isActive).toBeTruthy()
|
||||||
|
component.addedRelativeDate = null
|
||||||
|
component.addedDateAfter = '2023-05-30'
|
||||||
|
expect(component.isActive).toBeTruthy()
|
||||||
|
component.addedDateAfter = null
|
||||||
|
component.addedDateBefore = '2023-05-30'
|
||||||
|
expect(component.isActive).toBeTruthy()
|
||||||
|
component.addedDateBefore = null
|
||||||
|
|
||||||
expect(component.isActive).toBeFalsy()
|
expect(component.isActive).toBeFalsy()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support reset', () => {
|
it('should support reset', () => {
|
||||||
component.dateAfter = '2023-05-30'
|
component.createdDateAfter = '2023-05-30'
|
||||||
component.reset()
|
component.reset()
|
||||||
expect(component.dateAfter).toBeNull()
|
expect(component.createdDateAfter).toBeNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support clearAfter', () => {
|
it('should support clearAfter', () => {
|
||||||
component.dateAfter = '2023-05-30'
|
component.createdDateAfter = '2023-05-30'
|
||||||
component.clearAfter()
|
component.clearCreatedAfter()
|
||||||
expect(component.dateAfter).toBeNull()
|
expect(component.createdDateAfter).toBeNull()
|
||||||
|
|
||||||
|
component.addedDateAfter = '2023-05-30'
|
||||||
|
component.clearAddedAfter()
|
||||||
|
expect(component.addedDateAfter).toBeNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support clearBefore', () => {
|
it('should support clearBefore', () => {
|
||||||
component.dateBefore = '2023-05-30'
|
component.createdDateBefore = '2023-05-30'
|
||||||
component.clearBefore()
|
component.clearCreatedBefore()
|
||||||
expect(component.dateBefore).toBeNull()
|
expect(component.createdDateBefore).toBeNull()
|
||||||
|
|
||||||
|
component.addedDateBefore = '2023-05-30'
|
||||||
|
component.clearAddedBefore()
|
||||||
|
expect(component.addedDateBefore).toBeNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should limit keyboard events', () => {
|
it('should limit keyboard events', () => {
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
import {
|
||||||
|
Component,
|
||||||
|
EventEmitter,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
} from '@angular/core'
|
||||||
|
import { NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import { Subject, Subscription } from 'rxjs'
|
||||||
|
import { debounceTime } from 'rxjs/operators'
|
||||||
|
import { SettingsService } from 'src/app/services/settings.service'
|
||||||
|
import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter'
|
||||||
|
|
||||||
|
export interface DateSelection {
|
||||||
|
createdBefore?: string
|
||||||
|
createdAfter?: string
|
||||||
|
createdRelativeDateID?: number
|
||||||
|
addedBefore?: string
|
||||||
|
addedAfter?: string
|
||||||
|
addedRelativeDateID?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum RelativeDate {
|
||||||
|
LAST_7_DAYS = 0,
|
||||||
|
LAST_MONTH = 1,
|
||||||
|
LAST_3_MONTHS = 2,
|
||||||
|
LAST_YEAR = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'pngx-dates-dropdown',
|
||||||
|
templateUrl: './dates-dropdown.component.html',
|
||||||
|
styleUrls: ['./dates-dropdown.component.scss'],
|
||||||
|
providers: [{ provide: NgbDateAdapter, useClass: ISODateAdapter }],
|
||||||
|
})
|
||||||
|
export class DatesDropdownComponent implements OnInit, OnDestroy {
|
||||||
|
constructor(settings: SettingsService) {
|
||||||
|
this.datePlaceHolder = settings.getLocalizedDateInputFormat()
|
||||||
|
}
|
||||||
|
|
||||||
|
relativeDates = [
|
||||||
|
{
|
||||||
|
id: RelativeDate.LAST_7_DAYS,
|
||||||
|
name: $localize`Last 7 days`,
|
||||||
|
date: new Date().setDate(new Date().getDate() - 7),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: RelativeDate.LAST_MONTH,
|
||||||
|
name: $localize`Last month`,
|
||||||
|
date: new Date().setMonth(new Date().getMonth() - 1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: RelativeDate.LAST_3_MONTHS,
|
||||||
|
name: $localize`Last 3 months`,
|
||||||
|
date: new Date().setMonth(new Date().getMonth() - 3),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: RelativeDate.LAST_YEAR,
|
||||||
|
name: $localize`Last year`,
|
||||||
|
date: new Date().setFullYear(new Date().getFullYear() - 1),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
datePlaceHolder: string
|
||||||
|
|
||||||
|
// created
|
||||||
|
@Input()
|
||||||
|
createdDateBefore: string
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
createdDateBeforeChange = new EventEmitter<string>()
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
createdDateAfter: string
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
createdDateAfterChange = new EventEmitter<string>()
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
createdRelativeDate: RelativeDate
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
createdRelativeDateChange = new EventEmitter<number>()
|
||||||
|
|
||||||
|
// added
|
||||||
|
@Input()
|
||||||
|
addedDateBefore: string
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
addedDateBeforeChange = new EventEmitter<string>()
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
addedDateAfter: string
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
addedDateAfterChange = new EventEmitter<string>()
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
addedRelativeDate: RelativeDate
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
addedRelativeDateChange = new EventEmitter<number>()
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
title: string
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
datesSet = new EventEmitter<DateSelection>()
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
disabled: boolean = false
|
||||||
|
|
||||||
|
get isActive(): boolean {
|
||||||
|
return (
|
||||||
|
this.createdRelativeDate !== null ||
|
||||||
|
this.createdDateAfter?.length > 0 ||
|
||||||
|
this.createdDateBefore?.length > 0 ||
|
||||||
|
this.addedRelativeDate !== null ||
|
||||||
|
this.addedDateAfter?.length > 0 ||
|
||||||
|
this.addedDateBefore?.length > 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private datesSetDebounce$ = new Subject()
|
||||||
|
|
||||||
|
private sub: Subscription
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.sub = this.datesSetDebounce$.pipe(debounceTime(400)).subscribe(() => {
|
||||||
|
this.onChange()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
if (this.sub) {
|
||||||
|
this.sub.unsubscribe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.createdDateBefore = null
|
||||||
|
this.createdDateAfter = null
|
||||||
|
this.createdRelativeDate = null
|
||||||
|
this.addedDateBefore = null
|
||||||
|
this.addedDateAfter = null
|
||||||
|
this.addedRelativeDate = null
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
setCreatedRelativeDate(rd: RelativeDate) {
|
||||||
|
this.createdDateBefore = null
|
||||||
|
this.createdDateAfter = null
|
||||||
|
this.createdRelativeDate = this.createdRelativeDate == rd ? null : rd
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
setAddedRelativeDate(rd: RelativeDate) {
|
||||||
|
this.addedDateBefore = null
|
||||||
|
this.addedDateAfter = null
|
||||||
|
this.addedRelativeDate = this.addedRelativeDate == rd ? null : rd
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange() {
|
||||||
|
this.createdDateBeforeChange.emit(this.createdDateBefore)
|
||||||
|
this.createdDateAfterChange.emit(this.createdDateAfter)
|
||||||
|
this.createdRelativeDateChange.emit(this.createdRelativeDate)
|
||||||
|
this.addedDateBeforeChange.emit(this.addedDateBefore)
|
||||||
|
this.addedDateAfterChange.emit(this.addedDateAfter)
|
||||||
|
this.addedRelativeDateChange.emit(this.addedRelativeDate)
|
||||||
|
this.datesSet.emit({
|
||||||
|
createdAfter: this.createdDateAfter,
|
||||||
|
createdBefore: this.createdDateBefore,
|
||||||
|
createdRelativeDateID: this.createdRelativeDate,
|
||||||
|
addedAfter: this.addedDateAfter,
|
||||||
|
addedBefore: this.addedDateBefore,
|
||||||
|
addedRelativeDateID: this.addedRelativeDate,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeDebounce() {
|
||||||
|
this.createdRelativeDate = null
|
||||||
|
this.addedRelativeDate = null
|
||||||
|
this.datesSetDebounce$.next({
|
||||||
|
createdAfter: this.createdDateAfter,
|
||||||
|
createdBefore: this.createdDateBefore,
|
||||||
|
addedAfter: this.addedDateAfter,
|
||||||
|
addedBefore: this.addedDateBefore,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCreatedBefore() {
|
||||||
|
this.createdDateBefore = null
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCreatedAfter() {
|
||||||
|
this.createdDateAfter = null
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
clearAddedBefore() {
|
||||||
|
this.addedDateBefore = null
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
clearAddedAfter() {
|
||||||
|
this.addedDateAfter = null
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent chars other than numbers and separators
|
||||||
|
onKeyPress(event: KeyboardEvent) {
|
||||||
|
if ('Enter' !== event.key && !/[0-9,\.\/-]+/.test(event.key)) {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import { RouterTestingModule } from '@angular/router/testing'
|
|||||||
import { routes } from 'src/app/app-routing.module'
|
import { routes } from 'src/app/app-routing.module'
|
||||||
import { FilterEditorComponent } from './filter-editor/filter-editor.component'
|
import { FilterEditorComponent } from './filter-editor/filter-editor.component'
|
||||||
import { PermissionsFilterDropdownComponent } from '../common/permissions-filter-dropdown/permissions-filter-dropdown.component'
|
import { PermissionsFilterDropdownComponent } from '../common/permissions-filter-dropdown/permissions-filter-dropdown.component'
|
||||||
import { DateDropdownComponent } from '../common/date-dropdown/date-dropdown.component'
|
import { DatesDropdownComponent } from '../common/dates-dropdown/dates-dropdown.component'
|
||||||
import { FilterableDropdownComponent } from '../common/filterable-dropdown/filterable-dropdown.component'
|
import { FilterableDropdownComponent } from '../common/filterable-dropdown/filterable-dropdown.component'
|
||||||
import { PageHeaderComponent } from '../common/page-header/page-header.component'
|
import { PageHeaderComponent } from '../common/page-header/page-header.component'
|
||||||
import { BulkEditorComponent } from './bulk-editor/bulk-editor.component'
|
import { BulkEditorComponent } from './bulk-editor/bulk-editor.component'
|
||||||
@@ -113,7 +113,7 @@ describe('DocumentListComponent', () => {
|
|||||||
PageHeaderComponent,
|
PageHeaderComponent,
|
||||||
FilterEditorComponent,
|
FilterEditorComponent,
|
||||||
FilterableDropdownComponent,
|
FilterableDropdownComponent,
|
||||||
DateDropdownComponent,
|
DatesDropdownComponent,
|
||||||
PermissionsFilterDropdownComponent,
|
PermissionsFilterDropdownComponent,
|
||||||
ToggleableDropdownButtonComponent,
|
ToggleableDropdownButtonComponent,
|
||||||
BulkEditorComponent,
|
BulkEditorComponent,
|
||||||
|
|||||||
@@ -84,18 +84,16 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-wrap gap-2">
|
<div class="d-flex flex-wrap gap-2">
|
||||||
<pngx-date-dropdown
|
<pngx-dates-dropdown
|
||||||
title="Created" i18n-title
|
title="Dates" i18n-title
|
||||||
(datesSet)="updateRules()"
|
(datesSet)="updateRules()"
|
||||||
[(dateBefore)]="dateCreatedBefore"
|
[(createdDateBefore)]="dateCreatedBefore"
|
||||||
[(dateAfter)]="dateCreatedAfter"
|
[(createdDateAfter)]="dateCreatedAfter"
|
||||||
[(relativeDate)]="dateCreatedRelativeDate"></pngx-date-dropdown>
|
[(createdRelativeDate)]="dateCreatedRelativeDate"
|
||||||
<pngx-date-dropdown
|
[(addedDateBefore)]="dateAddedBefore"
|
||||||
title="Added" i18n-title
|
[(addedDateAfter)]="dateAddedAfter"
|
||||||
(datesSet)="updateRules()"
|
[(addedRelativeDate)]="dateAddedRelativeDate">
|
||||||
[(dateBefore)]="dateAddedBefore"
|
</pngx-dates-dropdown>
|
||||||
[(dateAfter)]="dateAddedAfter"
|
|
||||||
[(relativeDate)]="dateAddedRelativeDate"></pngx-date-dropdown>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-wrap">
|
<div class="d-flex flex-wrap">
|
||||||
<pngx-permissions-filter-dropdown
|
<pngx-permissions-filter-dropdown
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ import { TagService } from 'src/app/services/rest/tag.service'
|
|||||||
import { UserService } from 'src/app/services/rest/user.service'
|
import { UserService } from 'src/app/services/rest/user.service'
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
import { SettingsService } from 'src/app/services/settings.service'
|
||||||
import { ClearableBadgeComponent } from '../../common/clearable-badge/clearable-badge.component'
|
import { ClearableBadgeComponent } from '../../common/clearable-badge/clearable-badge.component'
|
||||||
import { DateDropdownComponent } from '../../common/date-dropdown/date-dropdown.component'
|
import { DatesDropdownComponent } from '../../common/dates-dropdown/dates-dropdown.component'
|
||||||
import {
|
import {
|
||||||
FilterableDropdownComponent,
|
FilterableDropdownComponent,
|
||||||
LogicalOperator,
|
LogicalOperator,
|
||||||
@@ -175,7 +175,7 @@ describe('FilterEditorComponent', () => {
|
|||||||
IfPermissionsDirective,
|
IfPermissionsDirective,
|
||||||
ClearableBadgeComponent,
|
ClearableBadgeComponent,
|
||||||
ToggleableDropdownButtonComponent,
|
ToggleableDropdownButtonComponent,
|
||||||
DateDropdownComponent,
|
DatesDropdownComponent,
|
||||||
CustomDatePipe,
|
CustomDatePipe,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
@@ -1517,7 +1517,7 @@ describe('FilterEditorComponent', () => {
|
|||||||
|
|
||||||
it('should convert user input to correct filter rules on date created after', fakeAsync(() => {
|
it('should convert user input to correct filter rules on date created after', fakeAsync(() => {
|
||||||
const dateCreatedDropdown = fixture.debugElement.queryAll(
|
const dateCreatedDropdown = fixture.debugElement.queryAll(
|
||||||
By.directive(DateDropdownComponent)
|
By.directive(DatesDropdownComponent)
|
||||||
)[0]
|
)[0]
|
||||||
const dateCreatedAfter = dateCreatedDropdown.queryAll(By.css('input'))[0]
|
const dateCreatedAfter = dateCreatedDropdown.queryAll(By.css('input'))[0]
|
||||||
|
|
||||||
@@ -1537,7 +1537,7 @@ describe('FilterEditorComponent', () => {
|
|||||||
|
|
||||||
it('should convert user input to correct filter rules on date created before', fakeAsync(() => {
|
it('should convert user input to correct filter rules on date created before', fakeAsync(() => {
|
||||||
const dateCreatedDropdown = fixture.debugElement.queryAll(
|
const dateCreatedDropdown = fixture.debugElement.queryAll(
|
||||||
By.directive(DateDropdownComponent)
|
By.directive(DatesDropdownComponent)
|
||||||
)[0]
|
)[0]
|
||||||
const dateCreatedBefore = dateCreatedDropdown.queryAll(By.css('input'))[1]
|
const dateCreatedBefore = dateCreatedDropdown.queryAll(By.css('input'))[1]
|
||||||
|
|
||||||
@@ -1557,7 +1557,7 @@ describe('FilterEditorComponent', () => {
|
|||||||
|
|
||||||
it('should convert user input to correct filter rules on date created with relative date', fakeAsync(() => {
|
it('should convert user input to correct filter rules on date created with relative date', fakeAsync(() => {
|
||||||
const dateCreatedDropdown = fixture.debugElement.queryAll(
|
const dateCreatedDropdown = fixture.debugElement.queryAll(
|
||||||
By.directive(DateDropdownComponent)
|
By.directive(DatesDropdownComponent)
|
||||||
)[0]
|
)[0]
|
||||||
const dateCreatedBeforeRelativeButton = dateCreatedDropdown.queryAll(
|
const dateCreatedBeforeRelativeButton = dateCreatedDropdown.queryAll(
|
||||||
By.css('button')
|
By.css('button')
|
||||||
@@ -1576,7 +1576,7 @@ describe('FilterEditorComponent', () => {
|
|||||||
it('should carry over text filtering on date created with relative date', fakeAsync(() => {
|
it('should carry over text filtering on date created with relative date', fakeAsync(() => {
|
||||||
component.textFilter = 'foo'
|
component.textFilter = 'foo'
|
||||||
const dateCreatedDropdown = fixture.debugElement.queryAll(
|
const dateCreatedDropdown = fixture.debugElement.queryAll(
|
||||||
By.directive(DateDropdownComponent)
|
By.directive(DatesDropdownComponent)
|
||||||
)[0]
|
)[0]
|
||||||
const dateCreatedBeforeRelativeButton = dateCreatedDropdown.queryAll(
|
const dateCreatedBeforeRelativeButton = dateCreatedDropdown.queryAll(
|
||||||
By.css('button')
|
By.css('button')
|
||||||
@@ -1621,10 +1621,10 @@ describe('FilterEditorComponent', () => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
it('should convert user input to correct filter rules on date added after', fakeAsync(() => {
|
it('should convert user input to correct filter rules on date added after', fakeAsync(() => {
|
||||||
const dateAddedDropdown = fixture.debugElement.queryAll(
|
const datesDropdown = fixture.debugElement.query(
|
||||||
By.directive(DateDropdownComponent)
|
By.directive(DatesDropdownComponent)
|
||||||
)[1]
|
)
|
||||||
const dateAddedAfter = dateAddedDropdown.queryAll(By.css('input'))[0]
|
const dateAddedAfter = datesDropdown.queryAll(By.css('input'))[2]
|
||||||
|
|
||||||
dateAddedAfter.nativeElement.value = '05/14/2023'
|
dateAddedAfter.nativeElement.value = '05/14/2023'
|
||||||
// dateAddedAfter.triggerEventHandler('change')
|
// dateAddedAfter.triggerEventHandler('change')
|
||||||
@@ -1641,10 +1641,10 @@ describe('FilterEditorComponent', () => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
it('should convert user input to correct filter rules on date added before', fakeAsync(() => {
|
it('should convert user input to correct filter rules on date added before', fakeAsync(() => {
|
||||||
const dateAddedDropdown = fixture.debugElement.queryAll(
|
const datesDropdown = fixture.debugElement.query(
|
||||||
By.directive(DateDropdownComponent)
|
By.directive(DatesDropdownComponent)
|
||||||
)[1]
|
)
|
||||||
const dateAddedBefore = dateAddedDropdown.queryAll(By.css('input'))[1]
|
const dateAddedBefore = datesDropdown.queryAll(By.css('input'))[2]
|
||||||
|
|
||||||
dateAddedBefore.nativeElement.value = '05/14/2023'
|
dateAddedBefore.nativeElement.value = '05/14/2023'
|
||||||
// dateAddedBefore.triggerEventHandler('change')
|
// dateAddedBefore.triggerEventHandler('change')
|
||||||
@@ -1661,38 +1661,38 @@ describe('FilterEditorComponent', () => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
it('should convert user input to correct filter rules on date added with relative date', fakeAsync(() => {
|
it('should convert user input to correct filter rules on date added with relative date', fakeAsync(() => {
|
||||||
const dateAddedDropdown = fixture.debugElement.queryAll(
|
const datesDropdown = fixture.debugElement.query(
|
||||||
By.directive(DateDropdownComponent)
|
By.directive(DatesDropdownComponent)
|
||||||
)[1]
|
)
|
||||||
const dateAddedBeforeRelativeButton = dateAddedDropdown.queryAll(
|
const dateCreatedBeforeRelativeButton = datesDropdown.queryAll(
|
||||||
By.css('button')
|
By.css('button')
|
||||||
)[1]
|
)[1]
|
||||||
dateAddedBeforeRelativeButton.triggerEventHandler('click')
|
dateCreatedBeforeRelativeButton.triggerEventHandler('click')
|
||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
tick(400)
|
tick(400)
|
||||||
expect(component.filterRules).toEqual([
|
expect(component.filterRules).toEqual([
|
||||||
{
|
{
|
||||||
rule_type: FILTER_FULLTEXT_QUERY,
|
rule_type: FILTER_FULLTEXT_QUERY,
|
||||||
value: 'added:[-1 week to now]',
|
value: 'created:[-1 week to now]',
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
}))
|
}))
|
||||||
|
|
||||||
it('should carry over text filtering on date added with relative date', fakeAsync(() => {
|
it('should carry over text filtering on date added with relative date', fakeAsync(() => {
|
||||||
component.textFilter = 'foo'
|
component.textFilter = 'foo'
|
||||||
const dateAddedDropdown = fixture.debugElement.queryAll(
|
const datesDropdown = fixture.debugElement.query(
|
||||||
By.directive(DateDropdownComponent)
|
By.directive(DatesDropdownComponent)
|
||||||
)[1]
|
)
|
||||||
const dateAddedBeforeRelativeButton = dateAddedDropdown.queryAll(
|
const dateCreatedBeforeRelativeButton = datesDropdown.queryAll(
|
||||||
By.css('button')
|
By.css('button')
|
||||||
)[1]
|
)[1]
|
||||||
dateAddedBeforeRelativeButton.triggerEventHandler('click')
|
dateCreatedBeforeRelativeButton.triggerEventHandler('click')
|
||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
tick(400)
|
tick(400)
|
||||||
expect(component.filterRules).toEqual([
|
expect(component.filterRules).toEqual([
|
||||||
{
|
{
|
||||||
rule_type: FILTER_FULLTEXT_QUERY,
|
rule_type: FILTER_FULLTEXT_QUERY,
|
||||||
value: 'foo,added:[-1 week to now]',
|
value: 'foo,created:[-1 week to now]',
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ import {
|
|||||||
import { Document } from 'src/app/data/document'
|
import { Document } from 'src/app/data/document'
|
||||||
import { StoragePath } from 'src/app/data/storage-path'
|
import { StoragePath } from 'src/app/data/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'
|
import { RelativeDate } from '../../common/dates-dropdown/dates-dropdown.component'
|
||||||
import {
|
import {
|
||||||
OwnerFilterType,
|
OwnerFilterType,
|
||||||
PermissionsSelectionModel,
|
PermissionsSelectionModel,
|
||||||
|
|||||||
Reference in New Issue
Block a user