Skip to content

Commit

Permalink
[ACS-5308] Highlight the selected filter in ADW (#8649)
Browse files Browse the repository at this point in the history
* changes for highlight the selected filter

* implemented the changes as per review comments

* added test cases and implemented review comments

* fix code and linting errors

* e2e fixes

* linting fix

* lint fix

* minor fixes

* fix for unit test case

* e2e fix for process

---------

Co-authored-by: Denys Vuika <denys.vuika@gmail.com>
  • Loading branch information
Yasa-Nataliya and DenysVuika committed Jun 16, 2023
1 parent ac694cd commit 13f4f62
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div *ngFor="let filter of filters" class="adf-filters__entry" [class.adf-active]="currentFilter === filter">
<div *ngFor="let filter of filters" class="adf-filters__entry" [class.adf-active]="isActiveRoute(filter)">
<button
(click)="selectFilter(filter)"
[attr.aria-label]="filter.name | translate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,22 @@ import { By } from '@angular/platform-browser';
import { fakeProcessFilters } from '../../mock/process/process-filters.mock';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { NavigationStart, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';

describe('ProcessFiltersComponent', () => {

let filterList: ProcessFiltersComponent;
let fixture: ComponentFixture<ProcessFiltersComponent>;
let processFilterService: ProcessFilterService;
let appsProcessService: AppsProcessService;
let router: Router;

setupTestBed({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
ProcessTestingModule,
RouterTestingModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
Expand All @@ -48,6 +52,7 @@ describe('ProcessFiltersComponent', () => {
filterList = fixture.componentInstance;
processFilterService = TestBed.inject(ProcessFilterService);
appsProcessService = TestBed.inject(AppsProcessService);
router = TestBed.inject(Router);
});

afterEach(() => {
Expand Down Expand Up @@ -305,4 +310,18 @@ describe('ProcessFiltersComponent', () => {
const filters: any = fixture.debugElement.queryAll(By.css('.adf-icon'));
expect(filters.length).toBe(0);
});

it('should set isProcessActive to true when activeRoute includes "processes"', () => {
const navigationStartEvent = new NavigationStart(1, 'processes/123');
spyOn(router.events, 'pipe').and.returnValue(of(navigationStartEvent));
fixture.detectChanges();
expect(filterList.isProcessActive).toBe(true);
});

it('should set isProcessActive to false when activeRoute does not include "processes"', () => {
const navigationStartEvent = new NavigationStart(1, 'other-route');
spyOn(router.events, 'pipe').and.returnValue(of(navigationStartEvent));
fixture.detectChanges();
expect(filterList.isProcessActive).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,24 @@
* limitations under the License.
*/

import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { ProcessInstanceFilterRepresentation, UserProcessInstanceFilterRepresentation } from '@alfresco/js-api';
import { Observable } from 'rxjs';
import { Observable, Subject } from 'rxjs';
import { FilterProcessRepresentationModel } from '../models/filter-process.model';
import { ProcessFilterService } from './../services/process-filter.service';
import { AppsProcessService } from '../../app-list/services/apps-process.service';
import { IconModel } from '../../app-list/icon.model';
import { NavigationStart, Router } from '@angular/router';
import { filter, takeUntil } from 'rxjs/operators';
import { Location } from '@angular/common';

@Component({
selector: 'adf-process-instance-filters',
templateUrl: './process-filters.component.html',
styleUrls: ['./process-filters.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ProcessFiltersComponent implements OnInit, OnChanges {
export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {

/** The parameters to filter the task filter. If there is no match then the default one
* (ie, the first filter in the list) is selected.
Expand Down Expand Up @@ -71,31 +74,51 @@ export class ProcessFiltersComponent implements OnInit, OnChanges {

filters: UserProcessInstanceFilterRepresentation [] = [];
active = false;
isProcessRoute: boolean;
isProcessActive: boolean;
private onDestroy$ = new Subject<boolean>();

private iconsMDL: IconModel;

constructor(private processFilterService: ProcessFilterService,
private appsProcessService: AppsProcessService) {
private appsProcessService: AppsProcessService,
private router: Router,
private location: Location) {
}

ngOnInit() {
this.iconsMDL = new IconModel();
this.router.events
.pipe(
filter((event) => event instanceof NavigationStart),
takeUntil(this.onDestroy$)
)
.subscribe((navigationStart: NavigationStart) => {
const activeRoute = navigationStart.url;
this.isProcessActive = activeRoute.includes('processes');
});
const currentRoute = this.location.path();
this.isProcessRoute = currentRoute.includes('processes');
}

ngOnChanges(changes: SimpleChanges) {
const appId = changes['appId'];
const appName = changes['appName'];
const filter = changes['filterParam'];
const filterParam = changes['filterParam'];

if (appId && (appId.currentValue || appId.currentValue === null)) {
this.getFiltersByAppId(appId.currentValue);
} else if (appName && appName.currentValue) {
this.getFiltersByAppName(appName.currentValue);
} else if (filter && filter.currentValue !== filter.previousValue) {
this.selectProcessFilter(filter.currentValue);
} else if (filterParam && filterParam.currentValue !== filterParam.previousValue) {
this.selectProcessFilter(filterParam.currentValue);
}
}

isActiveRoute(filterActive: ProcessInstanceFilterRepresentation): boolean {
return (this.isProcessActive || this.isProcessRoute) && this.currentFilter === filterActive;
}

/**
* Return the filter list filtered by appId
*
Expand Down Expand Up @@ -148,12 +171,12 @@ export class ProcessFiltersComponent implements OnInit, OnChanges {
/**
* Pass the selected filter as next
*
* @param filter
* @param filterModel
*/
selectFilter(filter: ProcessInstanceFilterRepresentation) {
this.currentFilter = filter;
selectFilter(filterModel: ProcessInstanceFilterRepresentation) {
this.currentFilter = filterModel;
this.active = true;
this.filterClicked.emit(filter);
this.filterClicked.emit(filterModel);
}

/**
Expand Down Expand Up @@ -222,4 +245,9 @@ export class ProcessFiltersComponent implements OnInit, OnChanges {
this.filters = [];
this.currentFilter = undefined;
}

ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div *ngFor="let filter of filters" class="adf-filters__entry" [class.adf-active]="currentFilter === filter">
<div *ngFor="let filter of filters" class="adf-filters__entry" [class.adf-active]="isActiveRoute(filter)">
<button
(click)="onFilterClick(filter)"
[attr.aria-label]="filter.name | translate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { ProcessTestingModule } from '../../testing/process.testing.module';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { fakeTaskFilters } from '../../mock/task/task-filters.mock';
import { NavigationStart, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';

describe('TaskFiltersComponent', () => {

Expand All @@ -36,11 +38,13 @@ describe('TaskFiltersComponent', () => {
let appsProcessService: AppsProcessService;
let component: TaskFiltersComponent;
let fixture: ComponentFixture<TaskFiltersComponent>;
let router: Router;

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

Expand All @@ -54,6 +58,7 @@ describe('TaskFiltersComponent', () => {
taskListService = TestBed.inject(TaskListService);
taskFilterService = TestBed.inject(TaskFilterService);
appsProcessService = TestBed.inject(AppsProcessService);
router = TestBed.inject(Router);
});

it('should emit an error with a bad response', async () => {
Expand Down Expand Up @@ -338,5 +343,19 @@ describe('TaskFiltersComponent', () => {
expect(taskFilterTwo.innerText).toBe('default-involved-filter');
expect(taskFilterThree.innerText).toBe('default-completed-filter');
});

it('should set isTaskActive to true when activeRoute includes "tasks"', () => {
const navigationStartEvent = new NavigationStart(1, 'tasks/123');
spyOn(router.events, 'pipe').and.returnValue(of(navigationStartEvent));
fixture.detectChanges();
expect(component.isTaskActive).toBe(true);
});

it('should set isTaskActive to false when activeRoute does not include "tasks"', () => {
const navigationStartEvent = new NavigationStart(1, 'other-route');
spyOn(router.events, 'pipe').and.returnValue(of(navigationStartEvent));
fixture.detectChanges();
expect(component.isTaskActive).toBe(false);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,22 @@
*/

import { AppsProcessService } from '../../app-list/services/apps-process.service';
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Observable } from 'rxjs';
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { FilterParamsModel, FilterRepresentationModel } from '../models/filter.model';
import { TaskFilterService } from './../services/task-filter.service';
import { TaskListService } from './../services/tasklist.service';
import { IconModel } from '../../app-list/icon.model';
import { ActivatedRoute, NavigationStart, Router } from '@angular/router';
import { filter, takeUntil } from 'rxjs/operators';

@Component({
selector: 'adf-task-filters',
templateUrl: './task-filters.component.html',
styleUrls: ['./task-filters.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class TaskFiltersComponent implements OnInit, OnChanges {
export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {

/** Parameters to use for the task filter. If there is no match then
* the default filter (the first one the list) is selected.
Expand Down Expand Up @@ -71,30 +73,53 @@ export class TaskFiltersComponent implements OnInit, OnChanges {

filters: FilterRepresentationModel [] = [];

private onDestroy$ = new Subject<boolean>();
isTaskRoute: boolean;
isTaskActive: boolean;

private iconsMDL: IconModel;

constructor(private taskFilterService: TaskFilterService,
private taskListService: TaskListService,
private appsProcessService: AppsProcessService) {
private appsProcessService: AppsProcessService,
private router: Router,
private activatedRoute: ActivatedRoute) {
}

ngOnInit() {
this.iconsMDL = new IconModel();
this.router.events
.pipe(
filter((event) => event instanceof NavigationStart),
takeUntil(this.onDestroy$)
)
.subscribe((navigationStart: NavigationStart) => {
const activeRoute = navigationStart.url;
this.isTaskActive = activeRoute.includes('tasks');
});
this.activatedRoute.url.subscribe((segments) => {
const currentRoute = segments.join('/');
this.isTaskRoute = currentRoute.includes('tasks');
});
}

ngOnChanges(changes: SimpleChanges) {
const appName = changes['appName'];
const appId = changes['appId'];
const filter = changes['filterParam'];
const filterParam = changes['filterParam'];
if (appName && appName.currentValue) {
this.getFiltersByAppName(appName.currentValue);
} else if (appId && appId.currentValue !== appId.previousValue) {
this.getFiltersByAppId(appId.currentValue);
} else if (filter && filter.currentValue !== filter.previousValue) {
this.selectFilterAndEmit(filter.currentValue);
} else if (filterParam && filterParam.currentValue !== filterParam.previousValue) {
this.selectFilterAndEmit(filterParam.currentValue);
}
}

isActiveRoute(filterActive: FilterRepresentationModel): boolean {
return (this.isTaskActive || this.isTaskRoute) && this.currentFilter === filterActive;
}

/**
* Return the task list filtered by appId or by appName
*
Expand Down Expand Up @@ -173,11 +198,11 @@ export class TaskFiltersComponent implements OnInit, OnChanges {
*/
public selectFilter(newFilter: FilterParamsModel) {
if (newFilter) {
this.currentFilter = this.filters.find( (filter, index) =>
this.currentFilter = this.filters.find( (entry, index) =>
newFilter.index === index ||
newFilter.id === filter.id ||
newFilter.id === entry.id ||
(newFilter.name &&
(newFilter.name.toLocaleLowerCase() === filter.name.toLocaleLowerCase())
(newFilter.name.toLocaleLowerCase() === entry.name.toLocaleLowerCase())
));
}
}
Expand All @@ -190,8 +215,8 @@ export class TaskFiltersComponent implements OnInit, OnChanges {
/**
* Selects and emits the clicked filter.
*/
onFilterClick(filter: FilterParamsModel) {
this.selectFilter(filter);
onFilterClick(filterParams: FilterParamsModel) {
this.selectFilter(filterParams);
this.filterClicked.emit(this.currentFilter);
}

Expand All @@ -203,8 +228,8 @@ export class TaskFiltersComponent implements OnInit, OnChanges {
public selectFilterWithTask(taskId: string) {
const filteredFilterList: FilterRepresentationModel[] = [];
this.taskListService.getFilterForTaskById(taskId, this.filters).subscribe(
(filter: FilterRepresentationModel) => {
filteredFilterList.push(filter);
(filterModel: FilterRepresentationModel) => {
filteredFilterList.push(filterModel);
},
(err) => {
this.error.emit(err);
Expand Down Expand Up @@ -254,4 +279,9 @@ export class TaskFiltersComponent implements OnInit, OnChanges {
this.filters = [];
this.currentFilter = undefined;
}

ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
}

0 comments on commit 13f4f62

Please sign in to comment.