MOBILE-3934 grades: Add swipe navigation
parent
275991d9ef
commit
11c2468d58
|
@ -0,0 +1,41 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CoreRoutedItemsManagerSource } from '@classes/items-management/routed-items-manager-source';
|
||||
import { CoreGrades } from '../services/grades';
|
||||
import { CoreGradesGradeOverviewWithCourseData, CoreGradesHelper } from '../services/grades-helper';
|
||||
|
||||
/**
|
||||
* Provides a collection of courses.
|
||||
*/
|
||||
export class CoreGradesCoursesSource extends CoreRoutedItemsManagerSource<CoreGradesGradeOverviewWithCourseData> {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected async loadPageItems(): Promise<{ items: CoreGradesGradeOverviewWithCourseData[] }> {
|
||||
const grades = await CoreGrades.getCoursesGrades();
|
||||
const courses = await CoreGradesHelper.getGradesCourseData(grades);
|
||||
|
||||
return { items: courses };
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getItemPath(course: CoreGradesGradeOverviewWithCourseData): string {
|
||||
return course.courseid.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ const routes: Routes = [
|
|||
{
|
||||
path: '',
|
||||
component: CoreGradesCoursePage,
|
||||
data: { swipeEnabled: false },
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
<ion-back-button [text]="'core.back' | translate"></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>
|
||||
<h1>{{ 'core.grades.grades' | translate }}</h1>
|
||||
<h1>{{ title }}</h1>
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-content [core-swipe-navigation]="courses">
|
||||
<ion-refresher slot="fixed" [disabled]="!columns || !rows" (ionRefresh)="refreshGrades($event.target)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AfterViewInit, Component, ElementRef } from '@angular/core';
|
||||
import { AfterViewInit, Component, ElementRef, OnDestroy } from '@angular/core';
|
||||
import { IonRefresher } from '@ionic/angular';
|
||||
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
|
@ -28,6 +28,9 @@ import { CoreUtils } from '@services/utils/utils';
|
|||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreScreen } from '@services/screen';
|
||||
import { Translate } from '@singletons';
|
||||
import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager';
|
||||
import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker';
|
||||
import { CoreGradesCoursesSource } from '@features/grades/classes/grades-courses-source';
|
||||
|
||||
/**
|
||||
* Page that displays a course grades.
|
||||
|
@ -37,12 +40,14 @@ import { Translate } from '@singletons';
|
|||
templateUrl: 'course.html',
|
||||
styleUrls: ['course.scss'],
|
||||
})
|
||||
export class CoreGradesCoursePage implements AfterViewInit {
|
||||
export class CoreGradesCoursePage implements AfterViewInit, OnDestroy {
|
||||
|
||||
courseId!: number;
|
||||
userId!: number;
|
||||
expandLabel!: string;
|
||||
collapseLabel!: string;
|
||||
title?: string;
|
||||
courses?: CoreSwipeNavigationItemsManager;
|
||||
columns?: CoreGradesFormattedTableColumn[];
|
||||
rows?: CoreGradesFormattedTableRow[];
|
||||
totalColumnsSpan?: number;
|
||||
|
@ -54,6 +59,12 @@ export class CoreGradesCoursePage implements AfterViewInit {
|
|||
this.userId = CoreNavigator.getRouteNumberParam('userId', { route }) ?? CoreSites.getCurrentSiteUserId();
|
||||
this.expandLabel = Translate.instant('core.expand');
|
||||
this.collapseLabel = Translate.instant('core.collapse');
|
||||
|
||||
if (route.snapshot.data.swipeEnabled ?? true) {
|
||||
const source = CoreRoutedItemsManagerSourcesTracker.getOrCreateSource(CoreGradesCoursesSource, []);
|
||||
|
||||
this.courses = new CoreSwipeNavigationItemsManager(source);
|
||||
}
|
||||
} catch (error) {
|
||||
CoreDomUtils.showErrorModal(error);
|
||||
|
||||
|
@ -73,10 +84,18 @@ export class CoreGradesCoursePage implements AfterViewInit {
|
|||
async ngAfterViewInit(): Promise<void> {
|
||||
this.withinSplitView = !!this.element.nativeElement.parentElement?.closest('core-split-view');
|
||||
|
||||
await this.courses?.start();
|
||||
await this.fetchInitialGrades();
|
||||
await CoreGrades.logCourseGradesView(this.courseId, this.userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.courses?.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get aria label for row.
|
||||
*
|
||||
|
@ -151,6 +170,7 @@ export class CoreGradesCoursePage implements AfterViewInit {
|
|||
const table = await CoreGrades.getCourseGradesTable(this.courseId, this.userId);
|
||||
const formattedTable = await CoreGradesHelper.formatGradesTable(table);
|
||||
|
||||
this.title = formattedTable.rows[0]?.gradeitem ?? Translate.instant('core.grades.grades');
|
||||
this.columns = formattedTable.columns;
|
||||
this.rows = formattedTable.rows;
|
||||
this.totalColumnsSpan = formattedTable.columns.reduce((total, column) => total + column.colspan, 0);
|
||||
|
|
|
@ -13,11 +13,12 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { AfterViewInit, Component, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { CorePageItemsListManager } from '@classes/page-items-list-manager';
|
||||
import { CoreListItemsManager } from '@classes/items-management/list-items-manager';
|
||||
import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker';
|
||||
|
||||
import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
||||
import { CoreGradesCoursesSource } from '@features/grades/classes/grades-courses-source';
|
||||
import { CoreGrades } from '@features/grades/services/grades';
|
||||
import { CoreGradesGradeOverviewWithCourseData, CoreGradesHelper } from '@features/grades/services/grades-helper';
|
||||
import { IonRefresher } from '@ionic/angular';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
|
@ -31,10 +32,16 @@ import { CoreUtils } from '@services/utils/utils';
|
|||
})
|
||||
export class CoreGradesCoursesPage implements OnDestroy, AfterViewInit {
|
||||
|
||||
courses: CoreGradesCoursesManager = new CoreGradesCoursesManager(CoreGradesCoursesPage);
|
||||
courses: CoreGradesCoursesManager;
|
||||
|
||||
@ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent;
|
||||
|
||||
constructor() {
|
||||
const source = CoreRoutedItemsManagerSourcesTracker.getOrCreateSource(CoreGradesCoursesSource, []);
|
||||
|
||||
this.courses = new CoreGradesCoursesManager(source, CoreGradesCoursesPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
|
@ -58,7 +65,7 @@ export class CoreGradesCoursesPage implements OnDestroy, AfterViewInit {
|
|||
*/
|
||||
async refreshCourses(refresher: IonRefresher): Promise<void> {
|
||||
await CoreUtils.ignoreErrors(CoreGrades.invalidateCoursesGradesData());
|
||||
await CoreUtils.ignoreErrors(this.fetchCourses());
|
||||
await CoreUtils.ignoreErrors(this.courses.reload());
|
||||
|
||||
refresher?.complete();
|
||||
}
|
||||
|
@ -68,37 +75,18 @@ export class CoreGradesCoursesPage implements OnDestroy, AfterViewInit {
|
|||
*/
|
||||
private async fetchInitialCourses(): Promise<void> {
|
||||
try {
|
||||
await this.fetchCourses();
|
||||
await this.courses.load();
|
||||
} catch (error) {
|
||||
CoreDomUtils.showErrorModalDefault(error, 'Error loading courses');
|
||||
|
||||
this.courses.setItems([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the list of courses.
|
||||
*/
|
||||
private async fetchCourses(): Promise<void> {
|
||||
const grades = await CoreGrades.getCoursesGrades();
|
||||
const courses = await CoreGradesHelper.getGradesCourseData(grades);
|
||||
|
||||
this.courses.setItems(courses);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to manage courses.
|
||||
*/
|
||||
class CoreGradesCoursesManager extends CorePageItemsListManager<CoreGradesGradeOverviewWithCourseData> {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected getItemPath(courseGrade: CoreGradesGradeOverviewWithCourseData): string {
|
||||
return courseGrade.courseid.toString();
|
||||
}
|
||||
class CoreGradesCoursesManager extends CoreListItemsManager {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
|
|
Loading…
Reference in New Issue