From 11c2468d585761a1d7972393d3373235045ea6c0 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 12 Jan 2022 11:53:11 +0100 Subject: [PATCH] MOBILE-3934 grades: Add swipe navigation --- .../grades/classes/grades-courses-source.ts | 41 +++++++++++++++++++ .../grades/grades-course-lazy.module.ts | 1 + .../features/grades/pages/course/course.html | 4 +- .../grades/pages/course/course.page.ts | 24 ++++++++++- .../grades/pages/courses/courses.page.ts | 38 ++++++----------- 5 files changed, 79 insertions(+), 29 deletions(-) create mode 100644 src/core/features/grades/classes/grades-courses-source.ts diff --git a/src/core/features/grades/classes/grades-courses-source.ts b/src/core/features/grades/classes/grades-courses-source.ts new file mode 100644 index 000000000..6d2b74608 --- /dev/null +++ b/src/core/features/grades/classes/grades-courses-source.ts @@ -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 { + + /** + * @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(); + } + +} diff --git a/src/core/features/grades/grades-course-lazy.module.ts b/src/core/features/grades/grades-course-lazy.module.ts index 877a0fec9..974a15c9d 100644 --- a/src/core/features/grades/grades-course-lazy.module.ts +++ b/src/core/features/grades/grades-course-lazy.module.ts @@ -22,6 +22,7 @@ const routes: Routes = [ { path: '', component: CoreGradesCoursePage, + data: { swipeEnabled: false }, }, ]; diff --git a/src/core/features/grades/pages/course/course.html b/src/core/features/grades/pages/course/course.html index c0e19a660..a34967aa7 100644 --- a/src/core/features/grades/pages/course/course.html +++ b/src/core/features/grades/pages/course/course.html @@ -4,11 +4,11 @@ -

{{ 'core.grades.grades' | translate }}

+

{{ title }}

- + diff --git a/src/core/features/grades/pages/course/course.page.ts b/src/core/features/grades/pages/course/course.page.ts index 3073c5aa3..fe22fc527 100644 --- a/src/core/features/grades/pages/course/course.page.ts +++ b/src/core/features/grades/pages/course/course.page.ts @@ -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 { 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); diff --git a/src/core/features/grades/pages/courses/courses.page.ts b/src/core/features/grades/pages/courses/courses.page.ts index bd6a4c51d..dd47d084c 100644 --- a/src/core/features/grades/pages/courses/courses.page.ts +++ b/src/core/features/grades/pages/courses/courses.page.ts @@ -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 { 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 { 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 { - const grades = await CoreGrades.getCoursesGrades(); - const courses = await CoreGradesHelper.getGradesCourseData(grades); - - this.courses.setItems(courses); - } - } /** * Helper class to manage courses. */ -class CoreGradesCoursesManager extends CorePageItemsListManager { - - /** - * @inheritdoc - */ - protected getItemPath(courseGrade: CoreGradesGradeOverviewWithCourseData): string { - return courseGrade.courseid.toString(); - } +class CoreGradesCoursesManager extends CoreListItemsManager { /** * @inheritdoc