mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
[ADF-5230] - Implement process date range filter (#6086)
* [ADF-5230] - Implement process date range filter * i18n Co-authored-by: Silviu Popa <p3701014@L3700101120.ness.com>
This commit is contained in:
@@ -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>
|
@@ -0,0 +1,3 @@
|
|||||||
|
.adf-cloud-date-range-picker {
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
@@ -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();
|
||||||
|
});
|
||||||
|
});
|
@@ -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)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@@ -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 {}
|
@@ -165,10 +165,24 @@
|
|||||||
"LAST_MODIFIED_DATE_FORM": "LastModifiedFrom",
|
"LAST_MODIFIED_DATE_FORM": "LastModifiedFrom",
|
||||||
"LAST_MODIFIED_TO": "LastModifiedTo",
|
"LAST_MODIFIED_TO": "LastModifiedTo",
|
||||||
"PROCESS_NAME": "ProcessName",
|
"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": {
|
"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": {
|
"TOOL_TIP": {
|
||||||
"SAVE": "Save filter",
|
"SAVE": "Save filter",
|
||||||
|
@@ -99,3 +99,17 @@ export class ProcessFilterProperties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ProcessDateFilterType {
|
||||||
|
today = 'today',
|
||||||
|
week = 'week',
|
||||||
|
month = 'month',
|
||||||
|
quarter = 'quarter',
|
||||||
|
year = 'year',
|
||||||
|
range = 'range'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DateRangeFilter {
|
||||||
|
startDate: Date;
|
||||||
|
endDate: Date;
|
||||||
|
}
|
||||||
|
@@ -27,6 +27,7 @@ import { EditProcessFilterCloudComponent } from './components/edit-process-filte
|
|||||||
import { ProcessFilterDialogCloudComponent } from './components/process-filter-dialog-cloud.component';
|
import { ProcessFilterDialogCloudComponent } from './components/process-filter-dialog-cloud.component';
|
||||||
import { AppListCloudModule } from './../../app/app-list-cloud.module';
|
import { AppListCloudModule } from './../../app/app-list-cloud.module';
|
||||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||||
|
import { ProcessCommonModule } from '../../common/process-common.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -37,8 +38,8 @@ import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
|||||||
FlexLayoutModule,
|
FlexLayoutModule,
|
||||||
MaterialModule,
|
MaterialModule,
|
||||||
AppListCloudModule,
|
AppListCloudModule,
|
||||||
CoreModule
|
CoreModule,
|
||||||
|
ProcessCommonModule
|
||||||
],
|
],
|
||||||
declarations: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent],
|
declarations: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent],
|
||||||
exports: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent],
|
exports: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent],
|
||||||
|
Reference in New Issue
Block a user