feat: expandable accordion in grades module

This commit is contained in:
Thea Schöbl
2022-06-01 15:26:23 +00:00
parent 51bb8e3b9c
commit 3f81afda82
27 changed files with 857 additions and 276 deletions

View File

@@ -34,6 +34,7 @@ import {AssessmentsDetailComponent} from './detail/assessments-detail.component'
import {AssessmentsProvider} from './assessments.provider';
import {AssessmentsSimpleDataListComponent} from './list/assessments-simple-data-list.component';
import {ProtectedRoutes} from '../auth/protected.routes';
import {AssessmentsTreeListComponent} from './list/assessments-tree-list.component';
const routes: ProtectedRoutes = [
{
@@ -56,6 +57,7 @@ const routes: ProtectedRoutes = [
AssessmentBaseInfoComponent,
AssessmentDetailComponent,
AssessmentsListItemComponent,
AssessmentsTreeListComponent,
CourseOfStudyAssessmentComponent,
AssessmentsPageComponent,
AssessmentsDataListComponent,

View File

@@ -13,29 +13,60 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, ViewChild} from '@angular/core';
import {Component, Input, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {AssessmentsProvider} from '../assessments.provider';
import {
DataDetailComponent,
ExternalDataLoadEvent,
} from '../../data/detail/data-detail.component';
import {ViewWillEnter} from '@ionic/angular';
import {NavController, ViewWillEnter} from '@ionic/angular';
import {Subscription} from 'rxjs';
import {DataRoutingService} from '../../data/data-routing.service';
@Component({
selector: 'assessments-detail',
templateUrl: 'assessments-detail.html',
styleUrls: ['assessments-detail.scss'],
})
export class AssessmentsDetailComponent implements ViewWillEnter {
export class AssessmentsDetailComponent
implements ViewWillEnter, OnInit, OnDestroy
{
constructor(
readonly route: ActivatedRoute,
readonly assessmentsProvider: AssessmentsProvider,
readonly dataRoutingService: DataRoutingService,
readonly navController: NavController,
readonly activatedRoute: ActivatedRoute,
) {}
subscriptions: Subscription[] = [];
@Input() dataPathAutoRouting = true;
@ViewChild(DataDetailComponent)
detailComponent: DataDetailComponent;
ngOnInit() {
if (!this.dataPathAutoRouting) return;
this.subscriptions.push(
this.dataRoutingService.pathSelectListener().subscribe(item => {
void this.navController.navigateBack(
['assessments', 'detail', item.uid],
{
queryParams: {
token: this.activatedRoute.snapshot.queryParamMap.get('token'),
},
},
);
}),
);
}
ngOnDestroy() {
for (const sub of this.subscriptions) sub.unsubscribe();
}
getItem(event: ExternalDataLoadEvent) {
this.assessmentsProvider
.getAssessments(

View File

@@ -22,6 +22,7 @@
</ion-toolbar>
</ion-header>
<stapps-data-detail
[autoRouteDataPath]="false"
[externalData]="true"
(loadItem)="getItem($event)"
[defaultHeader]="false"

View File

@@ -0,0 +1,30 @@
/*
* 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 License 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 {Component, Input} from '@angular/core';
import {SCThings} from '@openstapps/core';
@Component({
selector: 'assessments-tree-list',
templateUrl: 'assessments-tree-list.html',
styleUrls: ['assessments-tree-list.scss'],
})
export class AssessmentsTreeListComponent {
@Input() items?: Promise<SCThings[] | undefined>;
@Input() singleType = false;
@Input() groupingKey: string;
}

View File

@@ -0,0 +1,27 @@
<!--
~ 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 License 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/>.
-->
<tree-list
[items]="items"
[singleType]="singleType"
[groupingKey]="groupingKey"
>
<ng-template let-item>
<assessments-list-item
[item]="item"
[hideThumbnail]="singleType"
></assessments-list-item>
</ng-template>
</tree-list>

View File

@@ -0,0 +1,15 @@
/*!
* 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 License 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/>.
*/

View File

@@ -1,3 +1,19 @@
/*!
* 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 License 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/>.
*/
.content {
height: 100%;
padding-inline: 8px;
}

View File

@@ -1,18 +1,29 @@
<ion-note *ngIf="item.courseOfStudy as courseOfStudy">
{{ $any('courseOfStudy' | propertyNameTranslate: item) | titlecase }}:
{{ 'name' | thingTranslate: $any(courseOfStudy) }}
({{ 'academicDegree' | thingTranslate: $any(courseOfStudy) }})
</ion-note>
<!--
~ 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 License 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/>.
-->
<ion-card>
<ion-card-content>
<ion-note *ngIf="item.courseOfStudy as courseOfStudy">
{{ $any('courseOfStudy' | propertyNameTranslate: item) | titlecase }}:
{{ 'name' | thingTranslate: $any(courseOfStudy) }}
({{ 'academicDegree' | thingTranslate: $any(courseOfStudy) }})
</ion-note>
</ion-card-content>
</ion-card>
<ion-list class="container">
<ion-item lines="none">
<assessment-base-info [item]="item"></assessment-base-info>
</ion-item>
<h2 *ngIf="item.superAssessments">
{{ $any('superAssessments' | propertyNameTranslate: item) | titlecase }}
</h2>
<assessments-simple-data-list
*ngIf="item.superAssessments"
[items]="$any(item.superAssessments)"
[singleType]="true"
></assessments-simple-data-list>
</ion-list>

View File

@@ -1,5 +1,22 @@
<h2 class="name">
{{ 'name' | thingTranslate: item }}
{{ item.date ? (item.date | amDateFormat) : '' }}
</h2>
<assessment-base-info [item]="item"></assessment-base-info>
<!--
~ 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 License 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/>.
-->
<div class="container">
<h2 class="name">
{{ 'name' | thingTranslate: item }}
{{ item.date ? (item.date | amDateFormat) : '' }}
</h2>
<assessment-base-info [item]="item"></assessment-base-info>
</div>

View File

@@ -0,0 +1,41 @@
/*!
* 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/>.
*/
.column {
display: flex;
flex-direction: column;
}
.item {
height: 72px;
}
.tree-indicator {
width: 16px;
margin-right: 4px;
padding-left: 1px;
}
.super-assessments-list {
// prevent the list from hijacking hover overlays
z-index: -1;
:last-child {
.tree-indicator-after {
display: none;
}
}
}

View File

@@ -25,21 +25,23 @@ import {sum, sumBy} from '../../../../_helpers/collections/sum';
export class CourseOfStudyAssessmentComponent {
@Input() courseOfStudy: SCCourseOfStudyWithoutReferences | null;
_assessments: SCAssessment[];
_assessments: Promise<SCAssessment[]>;
grade = 0;
ects = 0;
@Input() set assessments(value: SCAssessment[]) {
this._assessments = value;
const assessments = value;
const grades = this._assessments
const grades = assessments
// TODO: find out if this is correct
.filter(assessment => assessment.status === 'bestanden')
.map(assessment => Number(assessment.grade))
.filter(grade => !Number.isNaN(grade));
this.grade = grades.length > 0 ? sum(grades) / grades.length : 0;
this.ects = sumBy(this._assessments, it => it.ects);
this.ects = sumBy(assessments, it => it.ects);
this._assessments = Promise.resolve(assessments);
}
}

View File

@@ -13,25 +13,25 @@
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<assessments-data-list
[singleType]="true"
[items]="_assessments"
[loading]="false"
>
<div header>
<section>
<h3>{{ 'assessments.courseOfStudyAssessments.PROGRESS' | translate }}</h3>
<p>
{{ $any('grade' | propertyNameTranslate: 'assessment') | titlecase }}:
{{
grade
| numberLocalized: 'minimumFractionDigits:1,maximumFractionDigits:1'
}}
</p>
<p>{{ 'ects' | propertyNameTranslate: 'assessment' }}: {{ ects }}</p>
</section>
<h3>
{{ 'assessments.courseOfStudyAssessments.ASSESSMENTS' | translate }}
</h3>
</div>
</assessments-data-list>
<section>
<h3>{{ 'assessments.courseOfStudyAssessments.PROGRESS' | translate }}</h3>
<p>
{{ $any('grade' | propertyNameTranslate: 'assessment') | titlecase }}:
{{
grade | numberLocalized: 'minimumFractionDigits:1,maximumFractionDigits:1'
}}
</p>
<p>{{ 'ects' | propertyNameTranslate: 'assessment' }}: {{ ects }}</p>
</section>
<section>
<h3>
{{ 'assessments.courseOfStudyAssessments.ASSESSMENTS' | translate }}
</h3>
<assessments-tree-list
[items]="_assessments"
[singleType]="true"
[groupingKey]="'superAssessments'"
>
</assessments-tree-list>
</section>