Skip to content

Commit 2e323c7

Browse files
authored
Add users tab to ScheduledEvent dashboard (hobbyfarm#234)
* Add users dashboard tab * Move download CSV button to list actions * Retreive scenarios on courses directly * Remove unused imports * Add CSV Export of user data * More efficient to calculate eventScenarioIds once instead of multiple times * fetch dynamic scenarios * Remove switchMap that was not used
1 parent 3572853 commit 2e323c7

File tree

8 files changed

+433
-59
lines changed

8 files changed

+433
-59
lines changed

src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import { IntervalTimer } from './IntervalTimer/interval-timer.component';
5454
import { ProgressDashboardComponent } from './dashboards/progress-dashboard/progress-dashboard.component';
5555
import { DashboardsComponent } from './dashboards/dashboards.component';
5656
import { VmDashboardComponent } from './dashboards/vm-dashboard/vm-dashboard.component';
57+
import { UsersDashboardComponent } from './dashboards/users-dashboard/users-dashboard.component';
5758
import { StepComponent } from './step/step-component/step.component';
5859
import { CtrService } from './data/ctr.service';
5960
import { SessionService } from './data/session.service';
@@ -277,6 +278,7 @@ export function jwtOptionsFactory(): JwtConfig {
277278
ProgressDashboardComponent,
278279
DashboardsComponent,
279280
VmDashboardComponent,
281+
UsersDashboardComponent,
280282
StepComponent,
281283
HfMarkdownComponent,
282284
TerminalComponent,

src/app/dashboards/dashboard-details/dashboard-details.component.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
<h3>Sessions for {{ selectedEvent.event_name }}</h3>
55
} @else if (vmDashboardActive && rbacSuccessVms) {
66
<h3>VMs for {{ selectedEvent.event_name }}</h3>
7+
} @else if (usersDashboardActive && rbacSuccessVms) {
8+
<h3>Users participating in {{ selectedEvent.event_name }}</h3>
79
} @else if (statisticsDashboardActive && rbacSuccessSessions) {
810
<h3>Statistics for {{ selectedEvent.event_name }}</h3>
911
}
@@ -48,6 +50,20 @@ <h3>Statistics for {{ selectedEvent.event_name }}</h3>
4850
</ng-template>
4951
</clr-tab>
5052
}
53+
@if (rbacSuccessSessions) {
54+
<clr-tab>
55+
<button clrTabLink>Users</button>
56+
<ng-template [(clrIfActive)]="usersDashboardActive">
57+
<clr-tab-content *clrIfActive>
58+
<div class="content-area">
59+
<users-dashboard
60+
[selectedEvent]="selectedEvent"
61+
></users-dashboard>
62+
</div>
63+
</clr-tab-content>
64+
</ng-template>
65+
</clr-tab>
66+
}
5167
@if (rbacSuccessSessions) {
5268
<clr-tab>
5369
<button clrTabLink>Statistics</button>

src/app/dashboards/dashboard-details/dashboard-details.component.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export class DashboardDetailsComponent implements OnInit, OnDestroy {
1515
public sessionDashboardActive: boolean = true;
1616
public vmDashboardActive: boolean = false;
1717
public statisticsDashboardActive: boolean = false;
18+
public usersDashboardActive: boolean = false;
1819

1920
public selectedEvent?: DashboardScheduledEvent;
2021
public loggedInAdminEmail: string;
@@ -28,7 +29,7 @@ export class DashboardDetailsComponent implements OnInit, OnDestroy {
2829
constructor(
2930
private route: ActivatedRoute,
3031
private scheduledeventService: ScheduledeventService,
31-
private rbacService: RbacService
32+
private rbacService: RbacService,
3233
) {}
3334
ngOnDestroy(): void {
3435
this.eventSubscription.unsubscribe();
@@ -40,7 +41,7 @@ export class DashboardDetailsComponent implements OnInit, OnDestroy {
4041
tap((params: Params) => {
4142
this.eventId = params['id'] ?? '';
4243
}),
43-
switchMap(() => this.scheduledeventService.getDashboardCache())
44+
switchMap(() => this.scheduledeventService.getDashboardCache()),
4445
)
4546
.subscribe((cache: Map<string, DashboardScheduledEvent>) => {
4647
const currentEvent = cache.get(this.eventId);
@@ -59,14 +60,14 @@ export class DashboardDetailsComponent implements OnInit, OnDestroy {
5960
'courses',
6061
'scenarios',
6162
],
62-
['list', 'get']
63+
['list', 'get'],
6364
).then((rbacCheckSessions: boolean) => {
6465
this.rbacSuccessSessions = rbacCheckSessions;
6566
});
6667

6768
this.setRbacCheck(
6869
['scheduledevents', 'virtualmachines', 'virtualmachinesets', 'users'],
69-
['list', 'get']
70+
['list', 'get'],
7071
).then((rbacCheck: boolean) => {
7172
this.rbacSuccessVms = rbacCheck;
7273
});
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
@if (loading) {
2+
<span class="spinner spinner-inline"> Loading... </span>
3+
<span> Loading... </span>
4+
} @else {
5+
@if (dashboardUsers.length < 1) {
6+
<div>No Users found</div>
7+
}
8+
9+
<clr-datagrid>
10+
<clr-dg-column>ID</clr-dg-column>
11+
<clr-dg-column [clrDgField]="'email'">Username</clr-dg-column>
12+
<clr-dg-column [clrDgField]="'otac'">OTAC</clr-dg-column>
13+
<clr-dg-column [clrDgSortBy]="'started'">Started</clr-dg-column>
14+
<clr-dg-column [clrDgSortBy]="'progresses.size'">Sessions</clr-dg-column>
15+
<clr-dg-column [clrDgSortBy]="'uniqueScenarios'"
16+
>Unique Scenarios</clr-dg-column
17+
>
18+
<clr-dg-column [clrDgField]="'status'">Status</clr-dg-column>
19+
20+
<clr-dg-row *clrDgItems="let user of dashboardUsers">
21+
<clr-dg-cell>{{ user.id }} </clr-dg-cell>
22+
<clr-dg-cell>{{ user.email }}</clr-dg-cell>
23+
<clr-dg-cell>
24+
@if (user.otac) {
25+
{{ user.otac.name }}
26+
} @else {
27+
-
28+
}
29+
</clr-dg-cell>
30+
<clr-dg-cell>
31+
{{ user.started | date: "MMMM d, y, HH:mm:ss z" }}
32+
</clr-dg-cell>
33+
<clr-dg-cell>
34+
{{ user.progresses?.length ?? 0 }}
35+
</clr-dg-cell>
36+
<clr-dg-cell>{{ user.uniqueScenarios }}</clr-dg-cell>
37+
<clr-dg-cell>
38+
@if (user.status == "completed") {
39+
<span class="badge badge-success">COMPLETED</span>
40+
} @else if (user.status == "in-progress") {
41+
<span class="badge badge-info">IN PROGRESS</span>
42+
} @else if (user.status == "out-of-time") {
43+
<span class="badge badge-danger">OUT OF TIME</span>
44+
}
45+
</clr-dg-cell>
46+
</clr-dg-row>
47+
<clr-dg-footer>
48+
<clr-dg-action-bar>
49+
<button
50+
type="button"
51+
class="btn btn-sm btn-secondary btn-outline"
52+
(click)="downloadCSV()"
53+
>
54+
<cds-icon shape="download"></cds-icon> Download CSV
55+
</button>
56+
</clr-dg-action-bar>
57+
<clr-dg-pagination #pagination [clrDgPageSize]="20">
58+
<clr-dg-page-size [clrPageSizeOptions]="[10, 20, 50]"
59+
>Users per page</clr-dg-page-size
60+
>
61+
{{ pagination.firstItem + 1 }} - {{ pagination.lastItem + 1 }} of
62+
{{ pagination.totalItems }} users
63+
</clr-dg-pagination>
64+
</clr-dg-footer>
65+
</clr-datagrid>
66+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.badge {
2+
padding: 10px;
3+
}

0 commit comments

Comments
 (0)