Skip to content

Commit

Permalink
[ACA-3637] - Add due date range filter
Browse files Browse the repository at this point in the history
  • Loading branch information
Silviu Popa authored and Silviu Popa committed Sep 8, 2020
1 parent 4fb26ea commit 327571e
Show file tree
Hide file tree
Showing 14 changed files with 305 additions and 157 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

<mat-form-field [attr.data-automation-id]="processFilterProperty.key">
<mat-select
placeholder="{{processFilterProperty.label | translate}}"
placeholder="{{ processFilterProperty.label | translate }}"
(selectionChange)="onSelectionChange($event)"
[attr.data-automation-id]="'adf-cloud-edit-process-property-' + processFilterProperty.key">
<mat-option *ngFor="let propertyOption of options" [value]="propertyOption.key" [attr.data-automation-id]="'adf-cloud-edit-process-property-options-' + processFilterProperty.key">
<mat-option *ngFor="let propertyOption of filteredProperties" [value]="propertyOption.value" [attr.data-automation-id]="'adf-cloud-edit-process-property-options-' + processFilterProperty.value">
{{ propertyOption.label | translate }}
</mat-option>
</mat-select>
Expand All @@ -14,13 +14,13 @@
<mat-form-field class="adf-cloud-date-range-picker">
<mat-label>{{ 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE_TITLE' | translate }}</mat-label>
<mat-date-range-input [formGroup]="dateRangeForm" [rangePicker]="picker">
<input matStartDate formControlName="start" placeholder="Start date">
<input matEndDate formControlName="end" placeholder="End date">
<input matStartDate formControlName="from" placeholder="Start date">
<input matEndDate formControlName="to" placeholder="End date">
</mat-date-range-input>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker #picker (closed)="onDateRangeClosed()"></mat-date-range-picker>

<mat-error *ngIf="dateRangeForm.controls.start.hasError('matStartDateInvalid')">{{ 'ADF_CLOUD_EDIT_PROCESS_FILTER.ERROR.INDALID_START_DATE' | translate }}</mat-error>
<mat-error *ngIf="dateRangeForm.controls.end.hasError('matEndDateInvalid')">{{ 'ADF_CLOUD_EDIT_PROCESS_FILTER.ERROR.INDALID_END_DATE' | translate }}</mat-error>
<mat-error *ngIf="dateRangeForm.controls.from.hasError('matStartDateInvalid')">{{ 'ADF_CLOUD_EDIT_PROCESS_FILTER.ERROR.INDALID_START_DATE' | translate }}</mat-error>
<mat-error *ngIf="dateRangeForm.controls.to.hasError('matEndDateInvalid')">{{ 'ADF_CLOUD_EDIT_PROCESS_FILTER.ERROR.INDALID_END_DATE' | translate }}</mat-error>
</mat-form-field>
</ng-container>
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@
*/

import { DateRangeFilterComponent } from './date-range-filter.component';
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { setupTestBed } from 'core';
import { TranslateModule } from '@ngx-translate/core';
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
import { By } from '@angular/platform-browser';
import { ProcessDateFilterType } from '../../process/process-filters/models/process-filter-cloud.model';
import { MatSelectChange } from '@angular/material/select';
import moment from 'moment-es6';
import { DateCloudFilterType } from '../../models/date-cloud-filter.model';
import { DateRangeFilterService } from './date-range-filter.service';

describe('DateRangeFilterComponent', () => {
let component: DateRangeFilterComponent;
let fixture: ComponentFixture<DateRangeFilterComponent>;
let service: DateRangeFilterService;

setupTestBed({
imports: [
Expand All @@ -39,6 +41,7 @@ describe('DateRangeFilterComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(DateRangeFilterComponent);
component = fixture.componentInstance;
service = TestBed.inject(DateRangeFilterService);

component.processFilterProperty = {
key: 'createdDate',
Expand All @@ -54,23 +57,22 @@ describe('DateRangeFilterComponent', () => {
fixture.destroy();
});

it('should setDate on option change', async(() => {
spyOn(component, 'setDate');
it('should get on option change', async () => {
spyOn(service, 'getDateRange');
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-createdDate"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();

const options = fixture.debugElement.queryAll(By.css('.mat-option-text'));
options[2].nativeElement.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.setDate).toHaveBeenCalled();
});
}));
await fixture.whenStable();
expect(service.getDateRange).toHaveBeenCalled();
});

it('should emit today range', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: ProcessDateFilterType.today };
const value = <MatSelectChange> { value: DateCloudFilterType.TODAY };
component.onSelectionChange(value);
const expectedDate = {
startDate: moment().startOf('day').toDate(),
Expand All @@ -81,7 +83,7 @@ describe('DateRangeFilterComponent', () => {

it('should emit month range', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: ProcessDateFilterType.month };
const value = <MatSelectChange> { value: DateCloudFilterType.MONTH };
component.onSelectionChange(value);
const expectedDate = {
startDate: moment().startOf('month').toDate(),
Expand All @@ -92,7 +94,7 @@ describe('DateRangeFilterComponent', () => {

it('should emit year range', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: ProcessDateFilterType.year };
const value = <MatSelectChange> { value: DateCloudFilterType.YEAR };
component.onSelectionChange(value);
const expectedDate = {
startDate: moment().startOf('year').toDate(),
Expand All @@ -103,7 +105,7 @@ describe('DateRangeFilterComponent', () => {

it('should emit quarter range', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: ProcessDateFilterType.quarter };
const value = <MatSelectChange> { value: DateCloudFilterType.QUARTER };
component.onSelectionChange(value);
const currentDate = new Date();
const quarter = Math.floor((currentDate.getMonth() / 3));
Expand All @@ -115,9 +117,9 @@ describe('DateRangeFilterComponent', () => {
expect(component.dateChanged.emit).toHaveBeenCalledWith(expectedDate);
});

it('should reset date range when no type is selected', () => {
it('should reset date range when no_date type is selected', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: null };
const value = <MatSelectChange> { value: DateCloudFilterType.NO_DATE };
component.onSelectionChange(value);
const expectedDate = {
startDate: null,
Expand All @@ -126,8 +128,23 @@ describe('DateRangeFilterComponent', () => {
expect(component.dateChanged.emit).toHaveBeenCalledWith(expectedDate);
});

it('should reset date range when range type is selected', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: DateCloudFilterType.RANGE };
component.onSelectionChange(value);
const expectedDate = {
startDate: null,
endDate: null
};
expect(component.dateChanged.emit).toHaveBeenCalledWith(expectedDate);
});

it('should throw error no supported type is selected', () => {
expect(function () { service.getDateRange(null); } ).toThrow(new Error('ADF_CLOUD_EDIT_PROCESS_FILTER.ERROR.INVALID_DATE_FILTER'));
});

it('should show date-range picker when type is range', async () => {
const value = <MatSelectChange> { value: ProcessDateFilterType.range };
const value = <MatSelectChange> { value: DateCloudFilterType.RANGE };
component.onSelectionChange(value);
fixture.detectChanges();
await fixture.whenStable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,19 @@

import { Component, Input, EventEmitter, Output } from '@angular/core';
import { MatSelectChange } from '@angular/material/select';
import moment from 'moment-es6';
import { ProcessFilterProperties, DateRangeFilter, ProcessDateFilterType } from '../../process/process-filters/models/process-filter-cloud.model';
import { ProcessFilterProperties, ProcessFilterOptions } from '../../process/process-filters/models/process-filter-cloud.model';
import { FormGroup, FormControl } from '@angular/forms';
import { DateRangeFilterService } from './date-range-filter.service';
import { DateRangeFilter, DateCloudFilterType } from '../../models/date-cloud-filter.model';

const DEFAULT_DATE_RANGE_OPTIONS = [
DateCloudFilterType.TODAY,
DateCloudFilterType.WEEK,
DateCloudFilterType.MONTH,
DateCloudFilterType.QUARTER,
DateCloudFilterType.YEAR,
DateCloudFilterType.RANGE
];

@Component({
selector: 'adf-cloud-date-range-filter',
Expand All @@ -31,128 +41,86 @@ import { FormGroup, FormControl } from '@angular/forms';
@Input()
processFilterProperty: ProcessFilterProperties;

@Input()
options: DateCloudFilterType[] = DEFAULT_DATE_RANGE_OPTIONS;

@Output()
dateChanged = new EventEmitter<DateRangeFilter>();

type: ProcessDateFilterType;
currentDate = new Date();
dateRange: DateRangeFilter = {
startDate: null,
endDate: null
};

type: DateCloudFilterType;
filteredProperties: ProcessFilterOptions[] = [];
dateRangeForm = new FormGroup({
start: new FormControl(),
end: new FormControl()
from: new FormControl(),
to: new FormControl()
});

options = [
{
key: ProcessDateFilterType.today,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.TODAY'
},
{
key: ProcessDateFilterType.week,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.WEEK'
},
{
key: ProcessDateFilterType.month,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.MONTH'
},
{
key: ProcessDateFilterType.quarter,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.QUARTER'
},
{
key: ProcessDateFilterType.year,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.YEAR'
},
{
key: ProcessDateFilterType.range,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.RANGE'
}
];
constructor(private dateRangeFilterService: DateRangeFilterService) {}

onSelectionChange(option: MatSelectChange) {
this.type = option.value;
this.setDate();
this.dateChanged.emit(this.dateRange);
ngOnInit() {
const defaultProperties = this.createDefaultDateOptions();
this.filteredProperties = defaultProperties.filter((filterProperty: ProcessFilterOptions) => this.isValidProperty(this.options, filterProperty));
}

setDate() {
switch (this.type) {
case ProcessDateFilterType.today:
this.setTodayDateRange();
break;
case ProcessDateFilterType.week:
this.setCurrentWeekRange();
break;
case ProcessDateFilterType.month:
this.setCurrentMonthDateRange();
break;
case ProcessDateFilterType.quarter:
this.setQuarterDateRange();
break;
case ProcessDateFilterType.year:
this.setCurrentYearDateRange();
break;
default: this.resetDateRange();
}
onSelectionChange(option: MatSelectChange) {
this.type = option.value;
const dateRange = this.dateRangeFilterService.getDateRange(this.type);
this.dateChanged.emit(dateRange);
}

isDateRangeType(): boolean {
return this.type === ProcessDateFilterType.range;
return this.type === DateCloudFilterType.RANGE;
}

onDateRangeClosed() {
this.dateRange = {
startDate: this.dateRangeForm.controls.start.value,
endDate: this.dateRangeForm.controls.end.value
const dateRange = {
startDate: this.dateRangeForm.controls.from.value,
endDate: this.dateRangeForm.controls.to.value
};
this.dateChanged.emit(this.dateRange);
this.dateChanged.emit(dateRange);
}

private resetDateRange() {
this.dateRange = {
startDate: null,
endDate: null
};
}

private setCurrentYearDateRange() {
this.dateRange = {
startDate: moment().startOf('year').toDate(),
endDate: moment().endOf('year').toDate()
};
private isValidProperty(filterProperties: string[], filterProperty: any): boolean {
return filterProperties ? filterProperties.indexOf(filterProperty.value) >= 0 : true;
}

private setTodayDateRange() {
this.dateRange = {
startDate: moment().startOf('day').toDate(),
endDate: moment().endOf('day').toDate()
};
}

private setCurrentWeekRange() {
this.dateRange = {
startDate: moment().startOf('week').toDate(),
endDate: moment().endOf('week').toDate()
};
}

private setCurrentMonthDateRange() {
this.dateRange = {
startDate: moment().startOf('month').toDate(),
endDate: moment().endOf('month').toDate()
};
}

private setQuarterDateRange() {
const quarter = Math.floor((this.currentDate.getMonth() / 3));
const firstDate = new Date(this.currentDate.getFullYear(), quarter * 3, 1);
this.dateRange = {
startDate: firstDate,
endDate: new Date(firstDate.getFullYear(), firstDate.getMonth() + 3, 0)
};
private createDefaultDateOptions(): ProcessFilterOptions[] {
return [
{
value: DateCloudFilterType.NO_DATE,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.NO_DATE'
},
{
value: DateCloudFilterType.TODAY,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.TODAY'
},
{
value: DateCloudFilterType.TOMORROW,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.TOMORROW'
},
{
value: DateCloudFilterType.NEXT_7_DAYS,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.NEXT_7_DAYS'
},
{
value: DateCloudFilterType.WEEK,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.WEEK'
},
{
value: DateCloudFilterType.MONTH,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.MONTH'
},
{
value: DateCloudFilterType.QUARTER,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.QUARTER'
},
{
value: DateCloudFilterType.YEAR,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.YEAR'
},
{
value: DateCloudFilterType.RANGE,
label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DATE_RANGE.RANGE'
}
];
}
}

0 comments on commit 327571e

Please sign in to comment.