@@ -87,5 +104,4 @@
>
-
-
+
diff --git a/src/app/modules/data/list/data-list.component.ts b/src/app/modules/data/list/data-list.component.ts
index 46ed10a1..fadb9000 100644
--- a/src/app/modules/data/list/data-list.component.ts
+++ b/src/app/modules/data/list/data-list.component.ts
@@ -1,20 +1,21 @@
/*
- * Copyright (C) 2021 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.
+ * 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.
+ * 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
.
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see
.
*/
import {CdkVirtualScrollViewport} from '@angular/cdk/scrolling';
import {
Component,
+ ContentChild,
EventEmitter,
HostListener,
Input,
@@ -23,11 +24,16 @@ import {
OnInit,
Output,
SimpleChanges,
+ TemplateRef,
ViewChild,
} from '@angular/core';
import {SCThings} from '@openstapps/core';
import {BehaviorSubject, Observable, Subscription} from 'rxjs';
+export interface DataListContext
{
+ $implicit: T;
+}
+
/**
* Shows the list of items
*/
@@ -47,6 +53,10 @@ export class DataListComponent implements OnChanges, OnInit, OnDestroy {
*/
@Input() items?: SCThings[];
+ @ContentChild(TemplateRef) listItemTemplateRef: TemplateRef<
+ DataListContext
+ >;
+
/**
* Stream of SCThings for virtual scroll to consume
*/
diff --git a/src/app/modules/data/list/data-list.html b/src/app/modules/data/list/data-list.html
index bd871310..225b9d00 100644
--- a/src/app/modules/data/list/data-list.html
+++ b/src/app/modules/data/list/data-list.html
@@ -6,12 +6,16 @@
(scrolledIndexChange)="scrolled($event)"
[style.display]="items && items.length ? 'block' : 'none'"
>
+
-
+
+
+
@@ -28,3 +32,10 @@
*ngFor="let skeleton of [].constructor(skeletonItems)"
>
+
+
+
+
diff --git a/src/app/modules/data/list/simple-data-list.component.ts b/src/app/modules/data/list/simple-data-list.component.ts
index 8bf36e85..bec8a807 100644
--- a/src/app/modules/data/list/simple-data-list.component.ts
+++ b/src/app/modules/data/list/simple-data-list.component.ts
@@ -1,22 +1,30 @@
/*
- * Copyright (C) 2021 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.
+ * 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.
+ * 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 .
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
*/
-import {Component, Input, OnDestroy, OnInit} from '@angular/core';
+import {
+ Component,
+ ContentChild,
+ Input,
+ OnDestroy,
+ OnInit,
+ TemplateRef,
+} from '@angular/core';
import {SCThings} from '@openstapps/core';
import {Subscription} from 'rxjs';
import {Router} from '@angular/router';
import {DataRoutingService} from '../data-routing.service';
+import {DataListContext} from './data-list.component';
/**
* Shows the list of items
@@ -30,18 +38,24 @@ export class SimpleDataListComponent implements OnInit, OnDestroy {
/**
* All SCThings to display
*/
- @Input() items?: SCThings[];
+ @Input() items?: Promise;
/**
* Indicates whether or not the list is to display SCThings of a single type
*/
@Input() singleType = false;
+ @Input() autoRouting = true;
+
/**
* List header
*/
@Input() listHeader?: string;
+ @ContentChild(TemplateRef) listItemTemplateRef: TemplateRef<
+ DataListContext
+ >;
+
/**
* Items that display the skeleton list
*/
@@ -58,6 +72,7 @@ export class SimpleDataListComponent implements OnInit, OnDestroy {
) {}
ngOnInit(): void {
+ if (!this.autoRouting) return;
this.subscriptions.push(
this.dataRoutingService.itemSelectListener().subscribe(item => {
void this.router.navigate(['data-detail', item.uid]);
diff --git a/src/app/modules/data/list/simple-data-list.html b/src/app/modules/data/list/simple-data-list.html
index 20778d73..2934ccc6 100644
--- a/src/app/modules/data/list/simple-data-list.html
+++ b/src/app/modules/data/list/simple-data-list.html
@@ -1,11 +1,14 @@
-
+
+
+
@@ -26,3 +29,9 @@
+
+
+
diff --git a/src/app/modules/hebis/daia-availability/daia-availability.component.spec.ts b/src/app/modules/hebis/daia-availability/daia-availability.component.spec.ts
index 9afda024..c912a596 100644
--- a/src/app/modules/hebis/daia-availability/daia-availability.component.spec.ts
+++ b/src/app/modules/hebis/daia-availability/daia-availability.component.spec.ts
@@ -1,18 +1,19 @@
-/* eslint-disable @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any */
/*
- * Copyright (C) 2018, 2019 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.
+ * 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.
+ * 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 .
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
*/
+
+/* eslint-disable @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any */
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {ActivatedRoute, RouterModule} from '@angular/router';
diff --git a/src/app/modules/hebis/hebis-detail/hebis-detail.component.spec.ts b/src/app/modules/hebis/hebis-detail/hebis-detail.component.spec.ts
index 5a1055d7..51de1074 100644
--- a/src/app/modules/hebis/hebis-detail/hebis-detail.component.spec.ts
+++ b/src/app/modules/hebis/hebis-detail/hebis-detail.component.spec.ts
@@ -1,17 +1,19 @@
/*
- * Copyright (C) 2018, 2019 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.
+ * 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.
+ * 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 .
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
*/
+
+/* eslint-disable @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any */
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
@@ -110,9 +112,10 @@ describe('HebisDetailComponent', () => {
it('should create component', () => expect(comp).toBeDefined());
it('should get a data item', () => {
- comp.getItem(sampleThing.uid);
+ comp.getItem(sampleThing.uid, false);
expect(HebisDetailComponent.prototype.getItem).toHaveBeenCalledWith(
sampleThing.uid,
+ false,
);
});
@@ -120,6 +123,7 @@ describe('HebisDetailComponent', () => {
comp.ionViewWillEnter();
expect(HebisDetailComponent.prototype.getItem).toHaveBeenCalledWith(
sampleThing.uid,
+ false,
);
});
@@ -127,6 +131,7 @@ describe('HebisDetailComponent', () => {
await comp.refresh(refresher);
expect(HebisDetailComponent.prototype.getItem).toHaveBeenCalledWith(
sampleThing.uid,
+ true,
);
expect(refresher.complete).toHaveBeenCalled();
});
diff --git a/src/app/modules/hebis/hebis-detail/hebis-detail.component.ts b/src/app/modules/hebis/hebis-detail/hebis-detail.component.ts
index ce053f12..2f79fff4 100644
--- a/src/app/modules/hebis/hebis-detail/hebis-detail.component.ts
+++ b/src/app/modules/hebis/hebis-detail/hebis-detail.component.ts
@@ -1,16 +1,16 @@
/*
- * Copyright (C) 2018-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.
+ * 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.
+ * 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 .
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
*/
import {Component} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
@@ -56,15 +56,16 @@ export class HebisDetailComponent extends DataDetailComponent {
*/
async ionViewWillEnter() {
const uid = this.route.snapshot.paramMap.get('uid') || '';
- await this.getItem(uid ?? '');
+ await this.getItem(uid ?? '', false);
}
/**
* Provides data item with given UID
*
* @param uid Unique identifier of a thing
+ * @param _forceReload Ignore any cached data
*/
- async getItem(uid: SCUuid) {
+ async getItem(uid: SCUuid, _forceReload: boolean) {
this.hebisDataProvider.hebisSearch({query: uid, page: 0}).then(result => {
// eslint-disable-next-line unicorn/no-null
this.item = (result.data && result.data[0]) || null;
diff --git a/src/app/modules/profile/profile.module.ts b/src/app/modules/profile/profile.module.ts
index fae13a46..6a502943 100644
--- a/src/app/modules/profile/profile.module.ts
+++ b/src/app/modules/profile/profile.module.ts
@@ -1,3 +1,18 @@
+/*
+ * 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 .
+ */
+
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
diff --git a/src/app/translation/common-string-pipes.ts b/src/app/translation/common-string-pipes.ts
index 572b17d5..18ae162f 100644
--- a/src/app/translation/common-string-pipes.ts
+++ b/src/app/translation/common-string-pipes.ts
@@ -356,6 +356,34 @@ export class MetersLocalizedPipe implements PipeTransform, OnDestroy {
}
}
+@Injectable()
+@Pipe({
+ name: 'isNaN',
+ pure: true,
+})
+export class IsNaNPipe implements PipeTransform {
+ transform(value: unknown): boolean {
+ return Number.isNaN(value);
+ }
+}
+
+@Injectable()
+@Pipe({
+ name: 'isNumeric',
+ pure: true,
+})
+export class IsNumericPipe implements PipeTransform {
+ transform(value: unknown): boolean {
+ return !Number.isNaN(
+ typeof value === 'number'
+ ? value
+ : typeof value === 'string'
+ ? Number.parseFloat(value)
+ : Number.NaN,
+ );
+ }
+}
+
@Injectable()
@Pipe({
name: 'numberLocalized',
diff --git a/src/app/translation/thing-translate.module.ts b/src/app/translation/thing-translate.module.ts
index 5f4c5ef2..c2cb56f7 100644
--- a/src/app/translation/thing-translate.module.ts
+++ b/src/app/translation/thing-translate.module.ts
@@ -25,6 +25,8 @@ import {
DurationLocalizedPipe,
ToUnixPipe,
EntriesPipe,
+ IsNaNPipe,
+ IsNumericPipe,
} from './common-string-pipes';
import {
ThingTranslateDefaultParser,
@@ -56,6 +58,8 @@ export interface ThingTranslateModuleConfig {
SentenceCasePipe,
ToUnixPipe,
EntriesPipe,
+ IsNaNPipe,
+ IsNumericPipe,
],
exports: [
ArrayJoinPipe,
@@ -71,6 +75,8 @@ export interface ThingTranslateModuleConfig {
SentenceCasePipe,
ToUnixPipe,
EntriesPipe,
+ IsNaNPipe,
+ IsNumericPipe,
],
})
export class ThingTranslateModule {
diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json
index 0ea9cb6a..cd3c78f7 100644
--- a/src/assets/i18n/de.json
+++ b/src/assets/i18n/de.json
@@ -15,6 +15,13 @@
"UNKNOWN": "Unbekannter Fehler."
}
},
+ "assessments": {
+ "TITLE": "Noten",
+ "courseOfStudyAssessments": {
+ "PROGRESS": "Fortschritt",
+ "ASSESSMENTS": "Bewertungen"
+ }
+ },
"auth": {
"messages": {
"default": {
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index b9c67519..aedac993 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -15,6 +15,13 @@
"UNKNOWN": "Unknown problem."
}
},
+ "assessments": {
+ "TITLE": "Grades",
+ "courseOfStudyAssessments": {
+ "PROGRESS": "Progress",
+ "ASSESSMENTS": "Assessments"
+ }
+ },
"auth": {
"messages": {
"default": {