TSK-1473: Always display classification and workbasket filter (#1357)
* TSK-1473: Always display classification and workbasket filter * TSK-1473: fix jest test Co-authored-by: Chi Nguyen <c.nguyen.prog@gmail.com>
This commit is contained in:
parent
fc6f420b96
commit
f76b0c4522
|
@ -3,28 +3,28 @@
|
|||
<!-- ACTION TOOLBAR -->
|
||||
<section class="classification-list__action-toolbar">
|
||||
<div class="classification-list__action-buttons">
|
||||
|
||||
<!-- ADD BUTTON -->
|
||||
<button mat-flat-button class="action-toolbar__add-button mr-1" matTooltip="Create new classification"
|
||||
(click)="addClassification()">
|
||||
Add
|
||||
<mat-icon class="md-20">add</mat-icon>
|
||||
</button>
|
||||
|
||||
<!-- IMPORT EXPORT BUTTONS -->
|
||||
<taskana-administration-import-export
|
||||
class="classification-list__import-export" [currentSelection]="taskanaType.CLASSIFICATIONS" [parentComponent]="'classifications'">
|
||||
</taskana-administration-import-export>
|
||||
<span class="workbasket-details__spacer" style="flex: 1 1 auto"> </span>
|
||||
|
||||
<button mat-stroked-button matTooltip="Display filter options" (click)="displayFilter()" style="color: #555">
|
||||
<mat-icon *ngIf="!showFilter">filter_list</mat-icon>
|
||||
<mat-icon *ngIf="showFilter">keyboard_arrow_up</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- FILTER -->
|
||||
<div class="classification-list__filter" *ngIf="showFilter">
|
||||
<div class="classification-list__filter">
|
||||
|
||||
<!-- CATEGORY FILTER -->
|
||||
<div class="classification-list__category-filter">
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu"
|
||||
matTooltip="Filter Category" class="category-filter__filter-button">
|
||||
<button mat-stroked-button class="category-filter__filter-button" [matMenuTriggerFor]="menu"
|
||||
matTooltip="Filter Category">
|
||||
|
||||
<mat-icon *ngIf="selectedCategory == ''">filter_list</mat-icon>
|
||||
<svg-icon class="category-filter__icons" [src]="(getCategoryIcon(selectedCategory) | async)?.name"
|
||||
[title]="(getCategoryIcon(selectedCategory) | async)?.text"
|
||||
|
@ -46,6 +46,7 @@
|
|||
</mat-menu>
|
||||
</div>
|
||||
|
||||
<!-- FILTER INPUT FIELD -->
|
||||
<div class="filter__input">
|
||||
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
||||
<mat-label>Filter classification</mat-label>
|
||||
|
@ -53,9 +54,11 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- TYPE FILTER -->
|
||||
<taskana-administration-classification-types-selector
|
||||
class="pull-right">
|
||||
</taskana-administration-classification-types-selector>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
height: calc(100vh - 55px);
|
||||
}
|
||||
.classification-list__action-toolbar {
|
||||
padding: 0 16px;
|
||||
min-height: 68px;
|
||||
padding: 16px 16px 0;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
.classification-list__action-buttons {
|
||||
display: flex;
|
||||
border: none;
|
||||
margin-bottom: 0;
|
||||
padding: 16px 4px 8px 4px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.action-toolbar__add-button {
|
||||
background-color: $aquamarine;
|
||||
color: white;
|
||||
|
@ -24,11 +24,12 @@
|
|||
}
|
||||
.classification-list__filter {
|
||||
display: flex;
|
||||
padding: 7px 4px 0;
|
||||
}
|
||||
|
||||
.classification-list__category-filter {
|
||||
padding-top: 7px;
|
||||
}
|
||||
|
||||
.category-filter__icons {
|
||||
height: 33px;
|
||||
width: 16px;
|
||||
|
@ -39,6 +40,11 @@
|
|||
margin: 0;
|
||||
top: -2px;
|
||||
}
|
||||
.category-filter__filter-button {
|
||||
color: #555;
|
||||
top: 3px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.filter__input {
|
||||
width: 100%;
|
||||
|
|
|
@ -144,9 +144,7 @@ describe('ClassificationListComponent', () => {
|
|||
expect(debugElement.nativeElement.querySelector('taskana-administration-import-export')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display classification-types-selector component when showFilter is true', () => {
|
||||
component.showFilter = true;
|
||||
fixture.detectChanges();
|
||||
it('should display classification-types-selector component', () => {
|
||||
const typesSelectorComponent = debugElement.nativeElement.querySelector(
|
||||
'taskana-administration-classification-types-selector'
|
||||
);
|
||||
|
@ -154,25 +152,19 @@ describe('ClassificationListComponent', () => {
|
|||
});
|
||||
|
||||
/* HTML: FILTER */
|
||||
it('should display filter input field when showFilter is true', () => {
|
||||
component.showFilter = true;
|
||||
fixture.detectChanges();
|
||||
it('should display filter input field', () => {
|
||||
const button = debugElement.nativeElement.querySelector('.filter__input-field');
|
||||
expect(button).toBeTruthy();
|
||||
expect(button.textContent).toBe('Filter classification');
|
||||
});
|
||||
|
||||
it('should display filter button when showFilter is true', () => {
|
||||
component.showFilter = true;
|
||||
fixture.detectChanges();
|
||||
it('should display filter button', () => {
|
||||
const button = debugElement.nativeElement.querySelector('.category-filter__filter-button');
|
||||
expect(button).toBeTruthy();
|
||||
expect(button.textContent).toBe('filter_list');
|
||||
});
|
||||
|
||||
it('should change selectedCategory property when button is clicked', () => {
|
||||
component.showFilter = true;
|
||||
fixture.detectChanges();
|
||||
const filterButton = debugElement.nativeElement.querySelector('.category-filter__filter-button');
|
||||
filterButton.click();
|
||||
fixture.detectChanges();
|
||||
|
@ -184,8 +176,6 @@ describe('ClassificationListComponent', () => {
|
|||
});
|
||||
|
||||
it('should display list of categories which can be selected', () => {
|
||||
component.showFilter = true;
|
||||
fixture.detectChanges();
|
||||
const filterButton = debugElement.nativeElement.querySelector('.category-filter__filter-button');
|
||||
filterButton.click();
|
||||
fixture.detectChanges();
|
||||
|
|
|
@ -30,7 +30,6 @@ export class ClassificationListComponent implements OnInit, OnDestroy {
|
|||
requestInProgress = true;
|
||||
inputValue: string;
|
||||
selectedCategory = '';
|
||||
showFilter = false;
|
||||
|
||||
@Select(ClassificationSelectors.classificationTypes) classificationTypes$: Observable<string[]>;
|
||||
@Select(ClassificationSelectors.selectedClassificationType) classificationTypeSelected$: Observable<string>;
|
||||
|
@ -112,10 +111,6 @@ export class ClassificationListComponent implements OnInit, OnDestroy {
|
|||
this.selectedCategory = category;
|
||||
}
|
||||
|
||||
displayFilter() {
|
||||
this.showFilter = !this.showFilter;
|
||||
}
|
||||
|
||||
setRequestInProgress(value: boolean) {
|
||||
this.requestInProgressService.setRequestInProgress(value);
|
||||
}
|
||||
|
|
|
@ -19,14 +19,19 @@
|
|||
style="margin-right: 4px;" [sortingFields]="sortingFields" (performSorting)="sorting($event)" [defaultSortBy]="workbasketDefaultSortBy">
|
||||
</taskana-shared-sort>
|
||||
|
||||
<!-- FILTER -->
|
||||
<button mat-stroked-button class="workbasket-list-toolbar__filter-button" matTooltip="Display filter options" (click)="onClickFilter()">
|
||||
<mat-icon *ngIf="!showFilter">filter_list</mat-icon>
|
||||
<mat-icon *ngIf="showFilter">keyboard_arrow_up</mat-icon>
|
||||
</div>
|
||||
|
||||
<!-- FILTER -->
|
||||
<div class="workbasket-list-toolbar__filter">
|
||||
<button mat-stroked-button class="filter__filter-button" matTooltip="Display more filter options" (click)="onClickFilter()">
|
||||
<mat-icon *ngIf="!isExpanded">keyboard_arrow_down</mat-icon>
|
||||
<mat-icon *ngIf="isExpanded">keyboard_arrow_up</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="filter__filter-component-wrapper">
|
||||
<taskana-shared-filter [isExpanded]="isExpanded" (performFilter)="filtering($event)"></taskana-shared-filter>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<taskana-shared-filter *ngIf="showFilter" (performFilter)="filtering($event)" component="workbasket-list" (inputComponent)="setComponent($event)"></taskana-shared-filter>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
@import 'src/theme/_colors.scss';
|
||||
|
||||
.workbasket-list-toolbar {
|
||||
padding: 16px 16px 8px 16px;
|
||||
padding: 16px 16px 20px;
|
||||
flex-wrap: wrap;
|
||||
min-height: 68px;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
|
@ -27,8 +26,18 @@
|
|||
height: 36px;
|
||||
}
|
||||
|
||||
.workbasket-list-toolbar__filter-button {
|
||||
.workbasket-list-toolbar__filter {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 16px 8px 0 4px;
|
||||
}
|
||||
|
||||
.filter__filter-button {
|
||||
padding: 0 5px;
|
||||
color: #555;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.filter__filter-component-wrapper {
|
||||
width: 380px;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class SortStub {
|
|||
|
||||
@Component({ selector: 'taskana-shared-filter', template: '' })
|
||||
class FilterStub {
|
||||
@Input() isExpanded = false;
|
||||
@Output() performFilter = new EventEmitter<Filter>();
|
||||
}
|
||||
|
||||
|
@ -149,15 +150,20 @@ describe('WorkbasketListToolbarComponent', () => {
|
|||
expect(debugElement.nativeElement.querySelector('taskana-shared-sort')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show filter component only when filter button is clicked', () => {
|
||||
const button = debugElement.nativeElement.querySelector('.workbasket-list-toolbar__filter-button');
|
||||
expect(button).toBeTruthy();
|
||||
expect(button.textContent).toBe('filter_list');
|
||||
expect(debugElement.nativeElement.querySelector('filter')).toBeFalsy();
|
||||
button.click();
|
||||
fixture.detectChanges();
|
||||
expect(component.showFilter).toBe(true);
|
||||
expect(button.textContent).toBe('keyboard_arrow_up');
|
||||
it('should display filter component', () => {
|
||||
expect(debugElement.nativeElement.querySelector('taskana-shared-filter')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show expanded filter component only when filter button is clicked', () => {
|
||||
const button = debugElement.nativeElement.querySelector('.filter__filter-button');
|
||||
expect(button).toBeTruthy();
|
||||
button.click();
|
||||
fixture.detectChanges();
|
||||
expect(component.isExpanded).toBe(true);
|
||||
expect(button.textContent).toBe('keyboard_arrow_up');
|
||||
button.click();
|
||||
fixture.detectChanges();
|
||||
expect(component.isExpanded).toBe(false);
|
||||
expect(button.textContent).toBe('keyboard_arrow_down');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,6 +42,7 @@ export class WorkbasketListToolbarComponent implements OnInit {
|
|||
|
||||
filterParams = { name: '', key: '', type: '', description: '', owner: '' };
|
||||
filterType = TaskanaType.WORKBASKETS;
|
||||
isExpanded = false;
|
||||
showFilter = false;
|
||||
component = '';
|
||||
|
||||
|
@ -80,8 +81,8 @@ export class WorkbasketListToolbarComponent implements OnInit {
|
|||
}
|
||||
|
||||
onClickFilter() {
|
||||
this.showFilter = !this.showFilter;
|
||||
this.workbasketService.expandWorkbasketActionToolbar(this.showFilter);
|
||||
this.isExpanded = !this.isExpanded;
|
||||
this.workbasketService.expandWorkbasketActionToolbar(this.isExpanded);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
align-items: stretch;
|
||||
}
|
||||
taskana-administration-workbasket-list {
|
||||
width: 500px;
|
||||
min-width: 500px;
|
||||
}
|
||||
taskana-administration-workbasket-details {
|
||||
flex-grow: 1;
|
||||
|
|
|
@ -1,7 +1,28 @@
|
|||
<div>
|
||||
<!-- WORKBASKET FILTER -->
|
||||
<div *ngIf="filterTypeIsWorkbasket(); else taskType">
|
||||
|
||||
<!-- WORKBASKET FILTER -->
|
||||
<div class="filter" *ngIf="filterTypeIsWorkbasket(); else tasktype">
|
||||
<!-- COLLAPSED WORKBASKET FILTER -->
|
||||
<div class="filter__collapsed-filter" *ngIf="!isExpanded">
|
||||
<!-- TEXT INPUT -->
|
||||
<mat-form-field appearance="legacy" floatLabel="auto" class="collapsed-filter_input-field">
|
||||
<mat-label>Filter by name</mat-label>
|
||||
<input matInput [(ngModel)]="filter.filterParams.name" matTooltip="Type to filter by name" (keyup.enter)="search()">
|
||||
</mat-form-field>
|
||||
|
||||
<!-- CLEAR BUTTON -->
|
||||
<button mat-stroked-button (click)="clear(); search()" matTooltip="Clear workbasket filter" class="filter__undo-button">
|
||||
<mat-icon style="color: #555">undo</mat-icon>
|
||||
</button>
|
||||
|
||||
<!-- SEARCH BUTTON -->
|
||||
<button mat-stroked-button (click)="search()" matTooltip="Search by given filter" class="filter__search-button">
|
||||
<mat-icon>search</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- EXPANDED WORKBASKET FILTER -->
|
||||
<div class="filter" *ngIf="isExpanded">
|
||||
|
||||
<!-- TEXT INPUT -->
|
||||
<div class="filter__text-input">
|
||||
|
@ -17,15 +38,17 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
||||
<mat-label>Filter by description</mat-label>
|
||||
<input matInput [(ngModel)]="filter.filterParams.description" matTooltip="Type to filter by description" (keyup.enter)="search()">
|
||||
</mat-form-field>
|
||||
<div class="filter__name-and-key-input">
|
||||
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
||||
<mat-label>Filter by description</mat-label>
|
||||
<input matInput [(ngModel)]="filter.filterParams.description" matTooltip="Type to filter by description" (keyup.enter)="search()">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
||||
<mat-label>Filter by owner</mat-label>
|
||||
<input matInput [(ngModel)]="filter.filterParams.owner" matTooltip="Type to filter by owner" (keyup.enter)="search()">
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
||||
<mat-label>Filter by owner</mat-label>
|
||||
<input matInput [(ngModel)]="filter.filterParams.owner" matTooltip="Type to filter by owner" (keyup.enter)="search()">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -47,59 +70,58 @@
|
|||
|
||||
<!-- CLEAR BUTTON -->
|
||||
<button mat-stroked-button (click)="clear(); search()" matTooltip="Clear workbasket filter">
|
||||
Reset filter
|
||||
Reset
|
||||
<mat-icon style="color: #555">undo</mat-icon>
|
||||
</button>
|
||||
|
||||
<!-- SEARCH BUTTON -->
|
||||
<button mat-stroked-button (click)="search()" matTooltip="Search by given filter" class="filter__search-button">
|
||||
Apply filter
|
||||
Apply
|
||||
<mat-icon>search</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- TASK FILTER -->
|
||||
<ng-template #tasktype>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<taskana-shared-number-picker [(ngModel)]="filter.filterParams.priority" (keyup.enter)="search()" title="priority" id="display-priority-filter"></taskana-shared-number-picker>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<input type="text" [(ngModel)]="filter.filterParams.name" (keyup.enter)="search()" class="form-control" id="display-name-filter"
|
||||
placeholder="Filter name">
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<input type="text" [(ngModel)]="filter.filterParams.owner" (keyup.enter)="search()" class="form-control" id="display-owner-filter"
|
||||
placeholder="Filter owner">
|
||||
</div>
|
||||
<button (click)="clear(); search()" class="btn btn-default pull-right margin-right" type="button" data-toggle="tooltip"
|
||||
title="Clear">
|
||||
<span class="material-icons md-20 blue">clear</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="dropdown col-xs-2 col-xs-offset-2">
|
||||
<button class="btn btn-default" data-toggle="dropdown" type="button" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="true" title="State: {{filter.filterParams.state ? filter.filterParams?.state : 'All'}}">
|
||||
<span>{{filter.filterParams.state ? filter.filterParams?.state : 'All'}}</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-users" role="menu">
|
||||
<li>
|
||||
<a *ngFor="let state of allStates | mapValues" type="button" (click)="selectState(state.key); search()"
|
||||
data-toggle="tooltip" [title]="state.value">
|
||||
<label class="blue">{{state.value}}</label>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button (click)="search()" type="button" class="btn btn-default pull-right margin-right" data-toggle="tooltip"
|
||||
title="Search">
|
||||
<span class="material-icons md-20 blue">search</span>
|
||||
</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- TASK FILTER -->
|
||||
<ng-template #taskType>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<taskana-shared-number-picker [(ngModel)]="filter.filterParams.priority" (keyup.enter)="search()" title="priority" id="display-priority-filter"></taskana-shared-number-picker>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<input type="text" [(ngModel)]="filter.filterParams.name" (keyup.enter)="search()" class="form-control" id="display-name-filter"
|
||||
placeholder="Filter name">
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<input type="text" [(ngModel)]="filter.filterParams.owner" (keyup.enter)="search()" class="form-control" id="display-owner-filter"
|
||||
placeholder="Filter owner">
|
||||
</div>
|
||||
<button (click)="clear(); search()" class="btn btn-default pull-right margin-right" type="button" data-toggle="tooltip"
|
||||
title="Clear">
|
||||
<span class="material-icons md-20 blue">clear</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="dropdown col-xs-2 col-xs-offset-2">
|
||||
<button class="btn btn-default" data-toggle="dropdown" type="button" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="true" title="State: {{filter.filterParams.state ? filter.filterParams?.state : 'All'}}">
|
||||
<span>{{filter.filterParams.state ? filter.filterParams?.state : 'All'}}</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-users" role="menu">
|
||||
<li>
|
||||
<a *ngFor="let state of allStates | mapValues" type="button" (click)="selectState(state.key); search()"
|
||||
data-toggle="tooltip" [title]="state.value">
|
||||
<label class="blue">{{state.value}}</label>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button (click)="search()" type="button" class="btn btn-default pull-right margin-right" data-toggle="tooltip"
|
||||
title="Search">
|
||||
<span class="material-icons md-20 blue">search</span>
|
||||
</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
@import 'src/theme/_colors.scss';
|
||||
|
||||
.filter {
|
||||
margin: -10px 0 0 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.filter__text-input {
|
||||
.filter__collapsed-filter {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.collapsed-filter_input-field {
|
||||
top: -10px;
|
||||
flex-grow: 1;
|
||||
margin: 0 8px 0 8px;
|
||||
}
|
||||
|
||||
.filter__action-buttons {
|
||||
|
@ -18,7 +24,9 @@
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.filter__undo-buttons {
|
||||
margin-left: 4px;
|
||||
}
|
||||
.filter__search-button {
|
||||
background: $aquamarine;
|
||||
color: white;
|
||||
|
@ -38,14 +46,15 @@
|
|||
}
|
||||
|
||||
.list-group-search {
|
||||
padding: 0px 15px;
|
||||
padding: 0 15px;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
.list-group-search {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
row.padding {
|
||||
padding: 1px 0px;
|
||||
padding: 1px 0;
|
||||
}
|
||||
|
||||
.filter-list {
|
||||
|
|
|
@ -26,9 +26,8 @@ export class FilterComponent implements OnInit {
|
|||
]);
|
||||
|
||||
@Input() filterParams = { name: '', key: '', type: '', description: '', owner: '' };
|
||||
|
||||
@Input() filterType = TaskanaType.WORKBASKETS;
|
||||
|
||||
@Input() isExpanded = true;
|
||||
@Output() performFilter = new EventEmitter<Filter>();
|
||||
@Output() inputComponent = new EventEmitter<string>();
|
||||
|
||||
|
|
Loading…
Reference in New Issue