Skip to content

Commit a3a5b05

Browse files
committed
feat(admin): tasks wave filtering
1 parent b5e95bb commit a3a5b05

File tree

4 files changed

+67
-7
lines changed

4 files changed

+67
-7
lines changed

src/app/components/admin/page-admin-tasks/page-admin-tasks.component.html

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
<div class="content-container">
33
<div class="content">
44
<h2 class="title">{{'admin.root.tasks.title'|translate}}</h2>
5+
6+
<div class="wave-selection">
7+
<span class="form-label">{{'admin.tasks.wave-selection.caption'|translate}}</span>
8+
<select class="form-control" (change)="filterWave($event)">
9+
<option *ngFor="let wave of waveTasks$ | async" [value]="wave.wave.id" [selected]="wave.shown">{{wave.wave.caption}}</option>
10+
<option value="-1" [selected]="!(waveFilter$ | async)">{{'admin.tasks.wave-selection.all'|translate}}</option>
11+
</select>
12+
</div>
13+
514
<table class="table table-striped table-responsive-md tasks-table" ksiTheme>
615
<thead>
716
<tr class="table-head-row">
@@ -15,7 +24,7 @@ <h2 class="title">{{'admin.root.tasks.title'|translate}}</h2>
1524
</tr>
1625
</thead>
1726
<tbody>
18-
<ng-container *ngFor="let waveTasks of (waveTasks$ | async)">
27+
<ng-container *ngFor="let waveTasks of (waveTasksShown$ | async)">
1928
<tr class="wave">
2029
<td colspan="7">
2130
<div class="info">

src/app/components/admin/page-admin-tasks/page-admin-tasks.component.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
text-align: center;
1313
}
1414

15+
.wave-selection {
16+
margin-bottom: $ksi-margin;
17+
}
18+
1519
.tasks-table {
1620
position: relative;
1721

src/app/components/admin/page-admin-tasks/page-admin-tasks.component.ts

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ import {
99
YearsService
1010
} from '../../../services';
1111
import { AdminTask, AdminTaskDeployResponse, Wave } from '../../../../api/backend';
12-
import { BehaviorSubject, combineLatest, Observable, of, timer } from 'rxjs';
13-
import { filter, map, mergeMap, take, tap } from 'rxjs/operators';
12+
import {BehaviorSubject, combineLatest, Observable, of, Subject, timer} from 'rxjs';
13+
import {distinctUntilChanged, filter, map, mergeMap, shareReplay, take, tap} from 'rxjs/operators';
1414
import { IAdminTask } from '../../../models';
15-
import { Utils } from '../../../util';
15+
import {SubscribedComponent, Utils} from '../../../util';
16+
import {ActivatedRoute, Router} from '@angular/router';
1617

1718
interface WaveTasks {
19+
shown: boolean,
1820
wave: Wave,
1921
tasks: Observable<IAdminTask>[]
2022
}
@@ -25,7 +27,7 @@ interface WaveTasks {
2527
styleUrls: ['./page-admin-tasks.component.scss'],
2628
changeDetection: ChangeDetectionStrategy.OnPush
2729
})
28-
export class PageAdminTasksComponent implements OnInit {
30+
export class PageAdminTasksComponent extends SubscribedComponent implements OnInit {
2931
@ViewChild('modalDeployLog', {static: true})
3032
modalDeployLog: TemplateRef<unknown>;
3133

@@ -35,6 +37,9 @@ export class PageAdminTasksComponent implements OnInit {
3537
private readonly taskDeployQueue: {task: AdminTask, button: HTMLButtonElement}[] = [];
3638

3739
waveTasks$: Observable<WaveTasks[]>;
40+
waveTasksShown$: Observable<WaveTasks[]>;
41+
waveFilter: Subject<number | null> = new BehaviorSubject<number | null>(null);
42+
readonly waveFilter$: Observable<number | null> = this.waveFilter.asObservable();
3843

3944
constructor(
4045
private years: YearsService,
@@ -45,11 +50,21 @@ export class PageAdminTasksComponent implements OnInit {
4550
private backend: BackendService,
4651
private modal: ModalService,
4752
private adminTasks: AdminTaskService,
53+
private router: Router,
54+
private route: ActivatedRoute
4855
) {
56+
super();
4957
}
5058

5159
ngOnInit(): void {
52-
this.waveTasks$ = this.years.adminTasks$.pipe(
60+
this.subscribe(this.route.queryParams.pipe(
61+
map(params => params['wave']),
62+
map((waveId) => isNaN(+waveId) ? null : +waveId),
63+
distinctUntilChanged(),
64+
tap((waveId) => this.waveFilter.next(waveId))
65+
));
66+
67+
const allWaveTasks$ = this.years.adminTasks$.pipe(
5368
mergeMap((tasks) => {
5469
const waveIdTasks: { [waveId: number]: Observable<IAdminTask>[] } = {};
5570
tasks.forEach((task) => {
@@ -74,7 +89,25 @@ export class PageAdminTasksComponent implements OnInit {
7489
}),
7590
map((waveTasks) => {
7691
return waveTasks.sort((a, b) => b.wave.id - a.wave.id);
77-
})
92+
}),
93+
shareReplay(1)
94+
);
95+
96+
this.waveTasks$ = combineLatest([allWaveTasks$, this.waveFilter$]).pipe(
97+
map(([waveTasks, waveFilter]) => {
98+
return waveTasks.map((waveTask) => {
99+
return {
100+
shown: waveFilter === null || waveTask.wave.id === waveFilter,
101+
wave: waveTask.wave,
102+
tasks: waveTask.tasks
103+
};
104+
});
105+
}),
106+
shareReplay(1)
107+
);
108+
109+
this.waveTasksShown$ = this.waveTasks$.pipe(
110+
map((waveTasks) => waveTasks.filter((waveTask) => waveTask.shown))
78111
);
79112
this.title.subtitle = 'admin.root.tasks.title';
80113
}
@@ -144,4 +177,14 @@ export class PageAdminTasksComponent implements OnInit {
144177
)
145178
.subscribe();
146179
}
180+
181+
filterWave(event: Event): Promise<boolean> {
182+
const waveId = +(event.target as HTMLSelectElement).value;
183+
184+
return this.router.navigate([], {
185+
relativeTo: this.route,
186+
queryParams: { wave: waveId === -1 ? null : waveId },
187+
queryParamsHandling: 'merge' // Merge with existing query params
188+
});
189+
}
147190
}

src/assets/i18n/cs.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,10 @@
538538
}
539539
},
540540
"tasks": {
541+
"wave-selection": {
542+
"caption": "Výběr zobrazených vln",
543+
"all": "Všechny vlny"
544+
},
541545
"wave": {
542546
"tasks": "úloh"
543547
},

0 commit comments

Comments
 (0)