Commit d0ce822c authored by Konstantin Schulz's avatar Konstantin Schulz

display of exercises in the exercise list is now more mobile friendly

parent 75584031
{ {
"name": "mc_frontend", "name": "mc_frontend",
"version": "1.4.3", "version": "1.4.5",
"author": "Ionic Framework", "author": "Ionic Framework",
"homepage": "https://ionicframework.com/", "homepage": "https://ionicframework.com/",
"scripts": { "scripts": {
......
...@@ -64,4 +64,4 @@ ...@@ -64,4 +64,4 @@
</ion-col> </ion-col>
</ion-row> </ion-row>
</ion-grid> </ion-grid>
</ion-content> </ion-content>
\ No newline at end of file
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
<ion-row> <ion-row>
<ion-col> <ion-col>
<label> <label>
<input type="search" (ngModelChange)="filterExercises($event.toString())" class="searchbar" <input type="search" (ngModelChange)="filterExercises($event.toString())"
placeholder="{{ 'SEARCH' | translate }}" [(ngModel)]="currentSearchValue" /> class="searchbar" placeholder="{{ 'SEARCH' | translate }}" [(ngModel)]="currentSearchValue"/>
</label> </label>
</ion-col> </ion-col>
</ion-row> </ion-row>
...@@ -40,140 +40,101 @@ ...@@ -40,140 +40,101 @@
</ion-row> </ion-row>
<ion-row> <ion-row>
<ion-col class="toggle-menu"> <ion-col class="toggle-menu">
<button *ngIf="showVocabularyCorpus; else dropright" <button *ngIf="showVocabularyCorpus; else dropright" (click)="toggleVocCorpus()">
(click)="showVocabularyCorpus = !showVocabularyCorpus">
<ion-icon name="arrow-dropdown"></ion-icon> <ion-icon name="arrow-dropdown"></ion-icon>
</button> </button>
<ng-template #dropright> <ng-template #dropright>
<button (click)="showVocabularyCorpus = !showVocabularyCorpus"> <button (click)="toggleVocCorpus()">
<ion-icon name="arrow-dropright"></ion-icon> <ion-icon name="arrow-dropright"></ion-icon>
</button> </button>
</ng-template> </ng-template>
<div> <div>
<h4 (click)="showVocabularyCorpus = !showVocabularyCorpus">{{ 'VOCABULARY_CHECK' | translate }}</h4> <h4 (click)="toggleVocCorpus()">{{ 'VOCABULARY_CHECK' | translate }}</h4>
</div> </div>
</ion-col> </ion-col>
</ion-row> </ion-row>
<ion-row *ngIf="showVocabularyCorpus"> <ion-row id="vocCorpus" style="display: none">
<ion-col> <ion-col style="display: inline-grid">
<label> <ion-grid style="padding: 0; text-align: left">
<h6>{{ 'VOCABULARY_REFERENCE_CORPUS' | translate }}</h6> <ion-row>
<select [(ngModel)]="vocService.currentReferenceVocabulary" name="currentReferenceVocabulary" <ion-col>
(change)="vocService.updateReferenceRange(); hasChanges = true"> <label>
<option *ngFor="let key of ObjectKeys(vocService.refVocMap)" [value]=VocabularyCorpus[key]> <h6>{{ 'VOCABULARY_REFERENCE_CORPUS' | translate }}</h6>
{{ VocabularyCorpusTranslation[key] | translate}} ({{vocService.refVocMap[key].totalCount}} <select [(ngModel)]="vocService.currentReferenceVocabulary"
{{'VOCABULARY_ITEMS' | translate}}) name="currentReferenceVocabulary"
</option> (change)="vocService.updateReferenceRange(); hasVocChanged = true">
</select> <option *ngFor="let key of ObjectKeys(vocService.refVocMap)"
</label> [value]=VocabularyCorpus[key]>
<br> {{ VocabularyCorpusTranslation[key] | translate}}
<br> ({{vocService.refVocMap[key].totalCount}}
<label> {{'VOCABULARY_ITEMS' | translate}})
<h6>{{ 'VOCABULARY_REFERENCE_RANGE_START' | translate }} </option>
<select </select>
*ngIf="!vocService.getCurrentReferenceVocabulary()?.hasFrequencyOrder; else hasFrequencyOrder" </label>
[(ngModel)]="vocService.frequencyUpperBound" name="frequencyUpperBound" </ion-col>
(change)="hasChanges = true"> </ion-row>
<option <ion-row>
*ngFor="let subcount of vocService.getCurrentReferenceVocabulary()?.possibleSubcounts" <ion-col>
[value]=subcount> <label>
{{subcount}} <h6>{{ 'VOCABULARY_REFERENCE_RANGE_START' | translate }}
</option> <select
</select> *ngIf="!vocService.getCurrentReferenceVocabulary()?.hasFrequencyOrder; else hasFrequencyOrder"
<br>{{'VOCABULARY_REFERENCE_RANGE_END' | translate}}</h6> [(ngModel)]="vocService.frequencyUpperBound" name="frequencyUpperBound"
<ng-template #hasFrequencyOrder> (change)="hasVocChanged = true">
<input type="number" [(ngModel)]="vocService.frequencyUpperBound" <option
(change)="hasChanges = true" /> *ngFor="let subcount of vocService.getCurrentReferenceVocabulary()?.possibleSubcounts"
</ng-template> [value]=subcount>
</label> {{subcount}}
</ion-col> </option>
</ion-row> </select>
<ion-row> <br>{{'VOCABULARY_REFERENCE_RANGE_END' | translate}}</h6>
<ion-col> <ng-template #hasFrequencyOrder>
<ion-button (click)="getExerciseList()" disabled="{{!hasChanges}}">{{ 'APPLY' | translate }} <input type="number" [(ngModel)]="vocService.frequencyUpperBound"
</ion-button> (change)="hasVocChanged = true"/>
</ng-template>
</label>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-button (click)="getExerciseList()"
disabled="{{!hasVocChanged}}">{{ 'APPLY' | translate }}
</ion-button>
</ion-col>
</ion-row>
</ion-grid>
</ion-col> </ion-col>
</ion-row> </ion-row>
<ion-row> <ion-row>
<ion-col></ion-col>
</ion-row> </ion-row>
<ion-row> <ion-row *ngIf="exercises; else loading" style="padding: 1em 0 0 0">
<ion-col> <ion-grid style="padding: 0">
{{'EXERCISE_TYPE' | translate}} <ion-row *ngFor="let exercise of exercises" (click)="showExercise(exercise)" class="exercises">
</ion-col> <ion-grid style="padding: 0">
<ion-col> <ion-row style="text-align: left">
{{'DATE' | translate}} <ion-col>
</ion-col> {{exercise.exercise_type_translation}}
<ion-col> </ion-col>
{{'AUTHOR' | translate}} <ion-col>
</ion-col> {{ getDateString(exercise.last_access_time) }}
<ion-col> </ion-col>
{{'TEXT_SELECTION' | translate}} <ion-col>
</ion-col> {{Math.round(exercise.text_complexity)}}
<ion-col> </ion-col>
{{'TEXT_COMPLEXITY' | translate}} <ion-col>
</ion-col> {{getMatchingDegree(exercise)}}
<ion-col> </ion-col>
{{'VOCABULARY_MATCHING_DEGREE' | translate}} </ion-row>
</ion-col> <ion-row>
</ion-row>
<ion-row *ngIf="exercises; else loading">
<div *ngFor="let exercise of exercises" (click)="showExercise(exercise)" class="exercises">
<ion-col>
{{exercise.exercise_type_translation}}
</ion-col>
<ion-col>
{{ getDateString(exercise.last_access_time) }}
</ion-col>
<ion-col>
{{exercise.work_author}} {{exercise.work_author}}
</ion-col> </ion-row>
<ion-col> <ion-row>
{{exercise.work_title}} {{exercise.work_title}}
</ion-col> </ion-row>
<ion-col> </ion-grid>
{{Math.round(exercise.text_complexity)}} </ion-row>
</ion-col> </ion-grid>
<ion-col>
{{getMatchingDegree(exercise)}}
</ion-col>
</div>
</ion-row> </ion-row>
<!-- <ion-row>
<ion-col>{{ 'EXERCISE_LIST_LEGEND' | translate}}:</ion-col>
<ion-col><span class="span-tc">{{ 'TEXT_COMPLEXITY' | translate}}</span></ion-col>
<ion-col><span class="span-md">{{ 'VOCABULARY_MATCHING_DEGREE' | translate}}</span></ion-col>
</ion-row>
<ion-row *ngIf="exercises; else loading">
<ion-col>
<ion-list>
<ion-item *ngFor="let exercise of exercises">
<ion-grid (click)="showExercise(exercise)" class="exercises">
<ion-row class="item-nested-top">
<ion-col>
{{exercise.work_author}}: {{exercise.work_title}}
</ion-col>
</ion-row>
<ion-row class="item-nested-bottom">
<ion-col size="8">
<span>{{exercise.exercise_type_translation}}
({{ getDateString(exercise.last_access_time) }})</span>
</ion-col>
<ion-col size="2">
<span class="span-tc">{{Math.round(exercise.text_complexity)}}</span>
</ion-col>
<ion-col size="2">
<span class="span-md">{{getMatchingDegree(exercise)}}</span>
</ion-col>
</ion-row>
</ion-grid>
</ion-item>
</ion-list>
</ion-col>
</ion-row> -->
<br>
<ng-template #loading> <ng-template #loading>
<h2 *ngIf="!HelperService.isLoading">{{ 'NO_EXERCISES_FOUND' | translate }}</h2> <h2 *ngIf="!HelperService.isLoading">{{ 'NO_EXERCISES_FOUND' | translate }}</h2>
</ng-template> </ng-template>
......
ion-list { .exercises {
cursor: pointer; cursor: pointer;
padding: 0;
border: 2px solid black;
} }
.exercises { .exercises ion-col {
padding: 0; padding: 0 2em 0 0;
} }
.item-nested-top { .item-nested-top {
......
...@@ -29,7 +29,7 @@ export class ExerciseListPage implements OnInit { ...@@ -29,7 +29,7 @@ export class ExerciseListPage implements OnInit {
public currentSortingCategory: SortingCategory = SortingCategory.dateDesc; public currentSortingCategory: SortingCategory = SortingCategory.dateDesc;
public exercises: ExerciseMC[]; public exercises: ExerciseMC[];
public ExerciseTypeTranslation = ExerciseTypeTranslation; public ExerciseTypeTranslation = ExerciseTypeTranslation;
public hasChanges = false; public hasVocChanged = false;
public HelperService = HelperService; public HelperService = HelperService;
public Math = Math; public Math = Math;
public metadata: { [eid: string]: string } = {}; public metadata: { [eid: string]: string } = {};
...@@ -37,7 +37,8 @@ export class ExerciseListPage implements OnInit { ...@@ -37,7 +37,8 @@ export class ExerciseListPage implements OnInit {
public showVocabularyCorpus = false; public showVocabularyCorpus = false;
public SortingCategory = SortingCategory; public SortingCategory = SortingCategory;
public sortingCategoriesAsc: Set<SortingCategory> = new Set<SortingCategory>([ public sortingCategoriesAsc: Set<SortingCategory> = new Set<SortingCategory>([
SortingCategory.vocAsc, SortingCategory.authorAsc, SortingCategory.dateAsc, SortingCategory.typeAsc]); SortingCategory.vocAsc, SortingCategory.authorAsc, SortingCategory.dateAsc, SortingCategory.typeAsc,
SortingCategory.complexityAsc]);
public sortingCategoriesMap: { [sc: string]: string } = { public sortingCategoriesMap: { [sc: string]: string } = {
[SortingCategory.authorAsc]: 'work_author', [SortingCategory.authorAsc]: 'work_author',
[SortingCategory.authorDesc]: 'work_author', [SortingCategory.authorDesc]: 'work_author',
...@@ -70,7 +71,7 @@ export class ExerciseListPage implements OnInit { ...@@ -70,7 +71,7 @@ export class ExerciseListPage implements OnInit {
const searchValueLower: string = searchValue.toLowerCase(); const searchValueLower: string = searchValue.toLowerCase();
const metadata = this.metadata; const metadata = this.metadata;
this.exercises = this.availableExercises.filter((exercise: ExerciseMC) => { this.exercises = this.availableExercises.filter((exercise: ExerciseMC) => {
return metadata[exercise.eid].includes(searchValueLower); return metadata[exercise.eid].toLowerCase().includes(searchValueLower);
}); });
} }
this.sortExercises(); this.sortExercises();
...@@ -82,7 +83,7 @@ export class ExerciseListPage implements OnInit { ...@@ -82,7 +83,7 @@ export class ExerciseListPage implements OnInit {
getExerciseList(): void { getExerciseList(): void {
const url: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiExerciseListPath']; const url: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiExerciseListPath'];
this.hasChanges = false; this.hasVocChanged = false;
let params: HttpParams = new HttpParams().set('lang', this.translateService.currentLang); let params: HttpParams = new HttpParams().set('lang', this.translateService.currentLang);
if (this.vocService.currentReferenceVocabulary) { if (this.vocService.currentReferenceVocabulary) {
params = params.set('vocabulary', VocabularyCorpus[this.vocService.currentReferenceVocabulary]); params = params.set('vocabulary', VocabularyCorpus[this.vocService.currentReferenceVocabulary]);
...@@ -97,7 +98,7 @@ export class ExerciseListPage implements OnInit { ...@@ -97,7 +98,7 @@ export class ExerciseListPage implements OnInit {
this.metadata[exercise.eid] = [exercise.work_author, exercise.exercise_type_translation, exercise.work_title] this.metadata[exercise.eid] = [exercise.work_author, exercise.exercise_type_translation, exercise.work_title]
.join(' ').toLowerCase(); .join(' ').toLowerCase();
}); });
this.sortExercises(); this.filterExercises(this.currentSearchValue);
}, () => { }, () => {
}); });
} }
...@@ -141,4 +142,14 @@ export class ExerciseListPage implements OnInit { ...@@ -141,4 +142,14 @@ export class ExerciseListPage implements OnInit {
}); });
} }
} }
toggleVocCorpus() {
this.showVocabularyCorpus = !this.showVocabularyCorpus;
if (this.showVocabularyCorpus && !this.vocService.currentReferenceVocabulary) {
this.vocService.currentReferenceVocabulary = VocabularyCorpus.bws;
this.hasVocChanged = true;
}
const iRowElement: HTMLElement = document.querySelector('#vocCorpus');
iRowElement.style.display = this.showVocabularyCorpus ? 'block' : 'none';
}
} }
...@@ -223,10 +223,16 @@ export class HelperService { ...@@ -223,10 +223,16 @@ export class HelperService {
static makeGetRequest(http: HttpClient, toastCtrl: ToastController, url: string, params: HttpParams): Promise<any> { static makeGetRequest(http: HttpClient, toastCtrl: ToastController, url: string, params: HttpParams): Promise<any> {
HelperService.currentError = null; HelperService.currentError = null;
HelperService.isLoading = true; // dirty hack to avoid ExpressionChangedAfterItHasBeenCheckedError
setTimeout(() => {
HelperService.isLoading = true;
}, 0);
return new Promise(((resolve, reject) => { return new Promise(((resolve, reject) => {
http.get(url, {params}).subscribe((result: any) => { http.get(url, {params}).subscribe((result: any) => {
HelperService.isLoading = false; // dirty hack to avoid ExpressionChangedAfterItHasBeenCheckedError
setTimeout(() => {
HelperService.isLoading = false;
}, 0);
return resolve(result); return resolve(result);
}, async (error: HttpErrorResponse) => { }, async (error: HttpErrorResponse) => {
HelperService.isLoading = false; HelperService.isLoading = false;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment