Skip to content

Commit

Permalink
[ADF-5230] - Implement process date range filter (#6086)
Browse files Browse the repository at this point in the history
* [ADF-5230] - Implement process date range filter

* i18n

Co-authored-by: Silviu Popa <p3701014@L3700101120.ness.com>
  • Loading branch information
SilviuCPopa and Silviu Popa committed Sep 7, 2020
1 parent c9c96e8 commit 8d6baf2
Show file tree
Hide file tree
Showing 8 changed files with 392 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

<mat-form-field [attr.data-automation-id]="processFilterProperty.key">
<mat-select
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">
{{ propertyOption.label | translate }}
</mat-option>
</mat-select>
</mat-form-field>

<ng-container *ngIf="isDateRangeType()">
<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">
</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-form-field>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.adf-cloud-date-range-picker {
margin: 0 10px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { DateRangeFilterComponent } from './date-range-filter.component';
import { ComponentFixture, TestBed, async } 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';

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

setupTestBed({
imports: [
TranslateModule.forRoot(),
ProcessServiceCloudTestingModule
]
});

beforeEach(() => {
fixture = TestBed.createComponent(DateRangeFilterComponent);
component = fixture.componentInstance;

component.processFilterProperty = {
key: 'createdDate',
label: 'mock-filter',
value: null,
type: 'dateRange',
options: null
};
fixture.detectChanges();
});

afterEach(() => {
fixture.destroy();
});

it('should setDate on option change', async(() => {
spyOn(component, 'setDate');
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();
});
}));

it('should emit today range', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: ProcessDateFilterType.today };
component.onSelectionChange(value);
const expectedDate = {
startDate: moment().startOf('day').toDate(),
endDate: moment().endOf('day').toDate()
};
expect(component.dateChanged.emit).toHaveBeenCalledWith(expectedDate);
});

it('should emit month range', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: ProcessDateFilterType.month };
component.onSelectionChange(value);
const expectedDate = {
startDate: moment().startOf('month').toDate(),
endDate: moment().endOf('month').toDate()
};
expect(component.dateChanged.emit).toHaveBeenCalledWith(expectedDate);
});

it('should emit year range', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: ProcessDateFilterType.year };
component.onSelectionChange(value);
const expectedDate = {
startDate: moment().startOf('year').toDate(),
endDate: moment().endOf('year').toDate()
};
expect(component.dateChanged.emit).toHaveBeenCalledWith(expectedDate);
});

it('should emit quarter range', () => {
spyOn(component.dateChanged, 'emit');
const value = <MatSelectChange> { value: ProcessDateFilterType.quarter };
component.onSelectionChange(value);
const currentDate = new Date();
const quarter = Math.floor((currentDate.getMonth() / 3));
const firstDate = new Date(currentDate.getFullYear(), quarter * 3, 1);
const expectedDate = {
startDate: firstDate,
endDate: new Date(firstDate.getFullYear(), firstDate.getMonth() + 3, 0)
};
expect(component.dateChanged.emit).toHaveBeenCalledWith(expectedDate);
});

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

it('should show date-range picker when type is range', async () => {
const value = <MatSelectChange> { value: ProcessDateFilterType.range };
component.onSelectionChange(value);
fixture.detectChanges();
await fixture.whenStable();
const rangePickerElement = fixture.debugElement.nativeElement.querySelector('.adf-cloud-date-range-picker');
expect(rangePickerElement).not.toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

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 { FormGroup, FormControl } from '@angular/forms';

@Component({
selector: 'adf-cloud-date-range-filter',
styleUrls: ['./date-range-filter.component.scss'],
templateUrl: './date-range-filter.component.html'
})
export class DateRangeFilterComponent {

@Input()
processFilterProperty: ProcessFilterProperties;

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

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

dateRangeForm = new FormGroup({
start: new FormControl(),
end: 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'
}
];

onSelectionChange(option: MatSelectChange) {
this.type = option.value;
this.setDate();
this.dateChanged.emit(this.dateRange);
}

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();
}
}

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

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

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

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

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)
};
}
}
35 changes: 35 additions & 0 deletions lib/process-services-cloud/src/lib/common/process-common.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { NgModule } from '@angular/core';
import { CoreModule } from '@alfresco/adf-core';
import { DateRangeFilterComponent } from './date-range-filter/date-range-filter.component';
import { MaterialModule } from '../material.module';
import { CommonModule } from '@angular/common';

@NgModule({
declarations: [ DateRangeFilterComponent ],
imports: [
CommonModule,
CoreModule,
MaterialModule
],
exports: [
DateRangeFilterComponent
]
})
export class ProcessCommonModule {}
18 changes: 16 additions & 2 deletions lib/process-services-cloud/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,24 @@
"LAST_MODIFIED_DATE_FORM": "LastModifiedFrom",
"LAST_MODIFIED_TO": "LastModifiedTo",
"PROCESS_NAME": "ProcessName",
"APP_VERSION": "AppReleaseVersion"
"APP_VERSION": "AppReleaseVersion",
"CREATED_DATE": "Created Date",
"DATE_RANGE": {
"TODAY": "today",
"WEEK": "this week",
"MONTH": "this month",
"QUARTER": "this quarter",
"YEAR": "this year",
"RANGE": "Date within"
},
"DATE_RANGE_TITLE": "Start date - End date",
"START_DATE": "Start date",
"END_DATE": "End date"
},
"ERROR": {
"DATE": "Date format DD/MM/YYYY"
"DATE": "Date format DD/MM/YYYY",
"INDALID_START_DATE": "Invalid start date",
"INDALID_END_DATE": "Invalid end date"
},
"TOOL_TIP": {
"SAVE": "Save filter",
Expand Down

0 comments on commit 8d6baf2

Please sign in to comment.