Add filters by priority + highlighting

This commit is contained in:
Jakob Fahr 2020-06-22 11:21:25 +02:00
parent 03e8c96a1e
commit a81a26d989
No known key found for this signature in database
GPG Key ID: 8873416D8E4CEF6B
7 changed files with 110 additions and 87 deletions

View File

@ -1,33 +1,38 @@
import {sortByNumberAscending, sortByStringAscending} from './sorting.service';
import {Priority} from './backend.service';
export abstract class TableComponentBase<T> {
public sortBy: string;
public sortDescending = false;
public items: T[] = [];
public sortBy: string;
public sortDescending = false;
public items: T[] = [];
protected doNumericSort(by: string, key: (ScrumTask) => number) {
if (this.sortBy === by) {
this.sortDescending = !this.sortDescending;
} else {
this.sortBy = by;
}
this.items = sortByNumberAscending(this.items, key);
if (this.sortDescending) {
this.items = this.items.reverse();
}
protected doNumericSort(by: string, key: (item: T) => number) {
if (this.sortBy === by) {
this.sortDescending = !this.sortDescending;
} else {
this.sortBy = by;
}
protected doStringSort(by: string, key: (ScrumTask) => string) {
if (this.sortBy === by) {
this.sortDescending = !this.sortDescending;
} else {
this.sortBy = by;
}
this.items = sortByStringAscending(this.items, key);
if (this.sortDescending) {
this.items = this.items.reverse();
}
this.items = sortByNumberAscending(this.items, key);
if (this.sortDescending) {
this.items = this.items.reverse();
}
}
protected doStringSort(by: string, key: (item: T) => string) {
if (this.sortBy === by) {
this.sortDescending = !this.sortDescending;
} else {
this.sortBy = by;
}
this.items = sortByStringAscending(this.items, key);
if (this.sortDescending) {
this.items = this.items.reverse();
}
}
public getAllPriorities(): string[] {
return Object.values(Priority);
}
}

View File

@ -2,3 +2,6 @@ table {
table-layout: fixed;
}
th.sortable:hover {
text-decoration: underline;
}

View File

@ -9,6 +9,9 @@
</a>
Tasks
</h3>
<div *ngIf="filterUserstoryId">
<a [routerLink]="'/tasks'">Alle Tasks anzeigen</a>
</div>
<button class="btn btn-secondary my-3" (click)="openTaskForm()">Neuer Task</button>
@ -16,37 +19,43 @@
<thead>
<tr>
<th (click)="sortById()">
<th (click)="sortById()" class="sortable">
<span>ID</span>
<span *ngIf="sortBy === 'id'" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
</span>
</th>
<th (click)="sortByTitle()">
<th (click)="sortByTitle()" class="sortable">
<span>Titel</span>
<span *ngIf="sortBy === 'title'" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
</span>
</th>
<th (click)="sortByContent()">
<th (click)="sortByContent()" class="sortable">
<span>Inhalt</span>
<span *ngIf="sortBy === 'content'" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
</span>
</th>
<th (click)="sortByTasks()">
<span>Tasks</span>
<span *ngIf="sortBy === 'tasks'" class="pl-3">
<th (click)="sortByTasks()" class="sortable">
<span>Userstory</span>
<span *ngIf="sortBy === 'userstory'" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
</span>
</th>
<th (click)="sortByPrio()">
<th (click)="sortByPrio()" class="sortable">
<span>Priorität</span>
<span *ngIf="sortBy === 'priority'" class="pl-3">
<label class="pl-3" (click)="$event.stopPropagation()">
<select [(ngModel)]="filterPriority">
<option [ngValue]="null" selected></option>
<option *ngFor="let p of getAllPriorities()" [ngValue]="p">{{p}}</option>
</select>
</label>
<span *ngIf="sortBy === 'priority'" (click)="sortByPrio()" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
</span>
@ -56,7 +65,7 @@
</thead>
<tbody>
<tr *ngFor="let task of filteredItems">
<tr *ngFor="let task of filteredItems" [class.table-info]="task.id === highlightId">
<td>{{task.id}}</td>
<td>{{task.title}}</td>
<td>{{task.content}}</td>

View File

@ -1,9 +1,10 @@
import {Component} from '@angular/core';
import {BackendService, Priority, ScrumTask, ScrumUserstory} from '../services/backend.service';
import {BackendService, ScrumTask} from '../services/backend.service';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {TaskFormComponent} from '../task-form/task-form.component';
import {TableComponentBase} from '../services/table-component.base';
import {ActivatedRoute, Router} from '@angular/router';
import {ActivatedRoute, ParamMap, Router} from '@angular/router';
import {getNumberForPriority} from '../services/sorting.service';
@Component({
selector: 'app-userstory-table',
@ -12,11 +13,14 @@ import {ActivatedRoute, Router} from '@angular/router';
})
export class TaskTableComponent extends TableComponentBase<ScrumTask> {
public filterUserstoryId: number | null = null;
public filterPriority: string | null = null;
public highlightId: number;
public get filteredItems() {
if (this.filterUserstoryId === null || isNaN(this.filterUserstoryId)) {
return this.items;
}
return this.items.filter(task => task.userstoryid === this.filterUserstoryId);
return this.items.filter(task =>
(this.filterUserstoryId === null || task.userstoryid === this.filterUserstoryId)
&& (this.filterPriority === null || task.priority === this.filterPriority)
);
}
constructor(
@ -25,14 +29,8 @@ export class TaskTableComponent extends TableComponentBase<ScrumTask> {
) {
super();
const params = route.snapshot.paramMap;
if (params.has('userstoryId')) {
this.filterUserstoryId = parseInt(params.get('userstoryId'));
}
if (params.has('id')) {
const id = parseInt(params.get('id'));
this.openTaskForm(this.items.find(t => t.id === id));
}
this.applyFilterParameters(route.snapshot.paramMap);
route.paramMap.subscribe(map => this.applyFilterParameters(map));
backendService.getTasks().subscribe(response => {
if (response.status > 399) {
@ -43,6 +41,17 @@ export class TaskTableComponent extends TableComponentBase<ScrumTask> {
});
}
private applyFilterParameters(params: ParamMap) {
if (params.has('userstoryId')) {
this.filterUserstoryId = parseInt(params.get('userstoryId'));
} else {
this.filterUserstoryId = null;
}
if (params.has('id')) {
this.highlightId = parseInt(params.get('id'));
}
}
public deleteTask(task: ScrumTask) {
this.backendService.deleteTask(task).subscribe(response => {
if (response.status > 399) {
@ -69,37 +78,26 @@ export class TaskTableComponent extends TableComponentBase<ScrumTask> {
}
sortById() {
this.doNumericSort('id', us => us.id);
this.doNumericSort('id', task => task.id);
}
sortByTitle() {
this.doStringSort('title', us => us.title);
this.doStringSort('title', task => task.title);
}
sortByContent() {
this.doStringSort('content', us => us.content);
}
private getNumberForPriority(priority: Priority): number {
switch (priority) {
case Priority.High:
return 2;
case Priority.Medium:
return 1;
case Priority.Low:
return 0;
}
this.doStringSort('content', task => task.content);
}
sortByPrio() {
this.doNumericSort('priority', us => this.getNumberForPriority(us.priority));
}
getNumberOfTasks(userstory: ScrumUserstory) {
return this.items.filter(t => t.userstoryid === userstory.id).length;
this.doNumericSort('priority', task => getNumberForPriority(task.priority));
}
sortByTasks() {
this.doNumericSort('tasks', us => this.getNumberOfTasks(us));
this.doNumericSort('userstory', task => task.userstoryid);
}
private findTaskById(id: number): ScrumTask {
return this.items.find(t => t.id === id);
}
}

View File

@ -2,3 +2,6 @@ table {
table-layout: fixed;
}
th.sortable:hover {
text-decoration: underline;
}

View File

@ -8,36 +8,42 @@
<thead>
<tr>
<th (click)="sortById()">
<th (click)="sortById()" class="sortable">
<span>ID</span>
<span *ngIf="sortBy === 'id'" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
</span>
</th>
<th (click)="sortByTitle()">
<th (click)="sortByTitle()" class="sortable">
<span>Titel</span>
<span *ngIf="sortBy === 'title'" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
</span>
</th>
<th (click)="sortByContent()">
<th (click)="sortByContent()" class="sortable">
<span>Inhalt</span>
<span *ngIf="sortBy === 'content'" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
</span>
</th>
<th (click)="sortByTasks()">
<th (click)="sortByTasks()" class="sortable">
<span>Tasks</span>
<span *ngIf="sortBy === 'tasks'" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
</span>
</th>
<th (click)="sortByPrio()">
<th (click)="sortByPrio()" class="sortable">
<span>Priorität</span>
<label class="pl-3" (click)="$event.stopPropagation()">
<select [(ngModel)]="filterPriority">
<option [ngValue]="null" selected></option>
<option *ngFor="let p of getAllPriorities()" [ngValue]="p">{{p}}</option>
</select>
</label>
<span *ngIf="sortBy === 'priority'" class="pl-3">
<span *ngIf="sortDescending"></span>
<span *ngIf="sortDescending === false"></span>
@ -48,7 +54,7 @@
</thead>
<tbody>
<tr *ngFor="let userstory of items">
<tr *ngFor="let userstory of filteredItems" [class.table-info]="userstory.id === highlightId">
<td>{{userstory.id}}</td>
<td>{{userstory.title}}</td>
<td>{{userstory.content}}</td>

View File

@ -4,7 +4,7 @@ import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {TableComponentBase} from '../services/table-component.base';
import {getNumberForPriority} from '../services/sorting.service';
import {UserstoryFormComponent} from '../userstory-form/userstory-form.component';
import {ActivatedRoute, Router} from '@angular/router';
import {ActivatedRoute, ParamMap, Router} from '@angular/router';
@Component({
selector: 'app-userstory-table',
@ -13,6 +13,12 @@ import {ActivatedRoute, Router} from '@angular/router';
})
export class UserstoryTableComponent extends TableComponentBase<ScrumUserstory> {
public tasks: ScrumTask[] = [];
public filterPriority: string | null = null;
public highlightId: number;
public get filteredItems() {
return this.items.filter(task => this.filterPriority === null || task.priority === this.filterPriority);
}
constructor(
private backendService: BackendService, private modalService: NgbModal,
@ -20,19 +26,14 @@ export class UserstoryTableComponent extends TableComponentBase<ScrumUserstory>
) {
super();
const params = route.snapshot.paramMap;
this.applyFilterParameters(this.route.snapshot.paramMap);
this.route.paramMap.subscribe(map => this.applyFilterParameters(map));
backendService.getUserstories().subscribe(response => {
if (response.status > 399) {
alert('Fehler');
} else {
this.items.push(...response.body);
// Wenn /userstories;id=3 aufgerufen wird, öffne die Userstory mit ID 3
const userstory = this.findUserstoryById(parseInt(params.get('id')));
if (userstory !== null) {
this.openUserstoryForm(userstory);
}
}
});
backendService.getTasks().subscribe(response => {
@ -44,12 +45,10 @@ export class UserstoryTableComponent extends TableComponentBase<ScrumUserstory>
});
}
private findUserstoryById(id: number): ScrumUserstory {
const userstoriesWithId = this.items.filter(us => us.id === id);
if (userstoriesWithId.length === 0) {
return null;
private applyFilterParameters(params: ParamMap) {
if (params.has('id')) {
this.highlightId = parseInt(params.get('id'));
}
return userstoriesWithId[0];
}
public deleteUserstory(userstory: ScrumUserstory) {