feat: assessments module

This commit is contained in:
Thea Schöbl
2022-03-17 09:59:52 +00:00
parent eea8d6d339
commit e68d1b73f9
51 changed files with 3372 additions and 222 deletions

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licens for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {
AfterViewInit,
Component,
OnDestroy,
OnInit,
ViewChild,
} from '@angular/core';
import {AssessmentsProvider} from '../assessments.provider';
import {SCAssessment, SCCourseOfStudy} from '@openstapps/core';
import {groupBy, mapValues} from 'lodash-es';
import {ActivatedRoute, Router} from '@angular/router';
import {Subscription} from 'rxjs';
import {NGXLogger} from 'ngx-logger';
import {materialSharedAxisX} from '../../../animation/material-motion';
import {SharedAxisChoreographer} from '../../../animation/animation-choreographer';
import {DataProvider, DataScope} from '../../data/data.provider';
import {DataRoutingService} from '../../data/data-routing.service';
@Component({
selector: 'app-assessments-page',
templateUrl: 'assessments-page.html',
styleUrls: ['assessments-page.scss'],
animations: [materialSharedAxisX],
})
export class AssessmentsPageComponent
implements OnInit, AfterViewInit, OnDestroy
{
assessments: Promise<
Record<
string,
{
assessments: SCAssessment[];
courseOfStudy: Promise<SCCourseOfStudy | undefined>;
}
>
>;
assessmentKeys: string[] = [];
routingSubscription: Subscription;
@ViewChild('segment') segmentView!: HTMLIonSegmentElement;
sharedAxisChoreographer: SharedAxisChoreographer<string> =
new SharedAxisChoreographer<string>('', []);
constructor(
readonly logger: NGXLogger,
readonly assessmentsProvider: AssessmentsProvider,
readonly dataProvider: DataProvider,
readonly activatedRoute: ActivatedRoute,
readonly dataRoutingService: DataRoutingService,
readonly router: Router,
) {}
ngAfterViewInit() {
this.segmentView.value = this.sharedAxisChoreographer.currentValue;
}
ngOnDestroy() {
this.routingSubscription.unsubscribe();
}
ngOnInit() {
this.routingSubscription = this.dataRoutingService
.itemSelectListener()
.subscribe(thing => {
void this.router.navigate(['assessments', 'detail', thing.uid], {
queryParams: {
token: this.activatedRoute.snapshot.queryParamMap.get('token'),
},
});
});
this.activatedRoute.queryParams.subscribe(parameters => {
try {
this.assessments = this.assessmentsProvider
.getAssessments(parameters.token)
.then(assessments =>
groupBy(assessments, it => it.courseOfStudy?.uid ?? 'unknown'),
)
.then(it => {
this.assessmentKeys = Object.keys(it);
this.sharedAxisChoreographer = new SharedAxisChoreographer(
this.assessmentKeys[0],
this.assessmentKeys,
);
if (this.segmentView) {
this.segmentView.value =
this.sharedAxisChoreographer.currentValue;
}
return it;
})
.then(groups =>
mapValues(groups, (group, uid) => ({
assessments: group,
courseOfStudy: this.dataProvider
.get(uid, DataScope.Remote)
.catch(
() => group[0].courseOfStudy,
) as Promise<SCCourseOfStudy>,
})),
);
} catch (error) {
this.logger.error(error);
this.assessments = Promise.resolve({});
}
});
}
}

View File

@@ -0,0 +1,49 @@
<ion-header>
<ion-toolbar color="primary">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title>{{ 'assessments.TITLE' | translate }}</ion-title>
</ion-toolbar>
</ion-header>
<ion-segment
#segment
(ionChange)="sharedAxisChoreographer.changeViewForState(segment.value)"
value=""
>
<ion-segment-button *ngFor="let key of assessmentKeys" [value]="key">
<div *ngIf="assessments | async as assessments">
<ion-label
*ngIf="
assessments[key].courseOfStudy | async as course;
else defaultLabel
"
>
{{ 'name' | thingTranslate: course }} ({{
'academicDegree' | thingTranslate: course
}})
</ion-label>
</div>
<ng-template #defaultLabel>
<ion-label>{{ key }}</ion-label>
</ng-template>
</ion-segment-button>
</ion-segment>
<ion-content>
<div
[ngSwitch]="sharedAxisChoreographer.currentValue"
[@materialSharedAxisX]="sharedAxisChoreographer.animationState"
(@materialSharedAxisX.done)="sharedAxisChoreographer.animationDone()"
*ngIf="assessments | async as items"
class="content"
>
<course-of-study-assessment
[assessments]="items[sharedAxisChoreographer.currentValue].assessments"
[courseOfStudy]="
items[sharedAxisChoreographer.currentValue].courseOfStudy | async
"
></course-of-study-assessment>
</div>
</ion-content>

View File

@@ -0,0 +1,3 @@
.content {
height: 100%;
}