forked from EVOgeek/Vmeda.Online
		
	MOBILE-3675 course: Migrate grades tab
This commit is contained in:
		
							parent
							
								
									9ba630c02a
								
							
						
					
					
						commit
						2ef54f4cac
					
				| @ -1,5 +1,3 @@ | ||||
| <ion-app> | ||||
|     <!-- @todo move /login/init UI here --> | ||||
| 
 | ||||
|     <ion-router-outlet></ion-router-outlet> | ||||
| </ion-app> | ||||
|  | ||||
| @ -520,12 +520,12 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     async selectByIndex(index: number, e?: Event): Promise<void> { | ||||
|         if (index < 0 || index >= this.tabs.length) { | ||||
|             if (this.selected) { | ||||
|                 // Invalid index do not change tab.
 | ||||
|         e?.preventDefault(); | ||||
|         e?.stopPropagation(); | ||||
| 
 | ||||
|         if (index < 0 || index >= this.tabs.length) { | ||||
|             if (this.selected) { | ||||
|                 // Invalid index do not change tab.
 | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
| @ -536,9 +536,6 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft | ||||
|         const tabToSelect = this.tabs[index]; | ||||
|         if (!tabToSelect || !tabToSelect.enabled || tabToSelect.id == this.selected) { | ||||
|             // Already selected or not enabled.
 | ||||
|             e?.preventDefault(); | ||||
|             e?.stopPropagation(); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -18,7 +18,7 @@ import { IonRouterOutlet } from '@ionic/angular'; | ||||
| import { CoreScreen } from '@services/screen'; | ||||
| import { BehaviorSubject, Observable, Subscription } from 'rxjs'; | ||||
| 
 | ||||
| enum CoreSplitViewMode { | ||||
| export enum CoreSplitViewMode { | ||||
|     MenuOnly = 'menu-only', // Hides content.
 | ||||
|     ContentOnly = 'content-only', // Hides menu.
 | ||||
|     MenuAndContent = 'menu-and-content', // Shows both menu and content.
 | ||||
| @ -34,6 +34,7 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy { | ||||
|     @ViewChild(IonRouterOutlet) outlet!: IonRouterOutlet; | ||||
|     @HostBinding('class') classes = ''; | ||||
|     @Input() placeholderText = 'core.emptysplit'; | ||||
|     @Input() mode?: CoreSplitViewMode; | ||||
|     isNested = false; | ||||
| 
 | ||||
|     private outletRouteSubject: BehaviorSubject<ActivatedRouteSnapshot | null> = new BehaviorSubject(null); | ||||
| @ -100,6 +101,10 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy { | ||||
|      * @return Split view mode. | ||||
|      */ | ||||
|     private getCurrentMode(): CoreSplitViewMode { | ||||
|         if (this.mode) { | ||||
|             return this.mode; | ||||
|         } | ||||
| 
 | ||||
|         if (this.isNested) { | ||||
|             return CoreSplitViewMode.MenuOnly; | ||||
|         } | ||||
|  | ||||
| @ -43,8 +43,8 @@ import { CoreTabBase, CoreTabsBaseComponent } from '@classes/tabs'; | ||||
|  * | ||||
|  * Tab contents will only be shown if that tab is selected. | ||||
|  * | ||||
|  * @todo: Test behaviour when tabs are added late. | ||||
|  * @todo: Test RTL and tab history. | ||||
|  * @todo: This should behave like the split-view in relation to routing (maybe we could reuse some code from CoreItemsListManager). | ||||
|  */ | ||||
| @Component({ | ||||
|     selector: 'core-tabs-outlet', | ||||
|  | ||||
| @ -115,7 +115,7 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy { | ||||
|         // Load the course handlers.
 | ||||
|         const handlers = await CoreCourseOptionsDelegate.instance.getHandlersToDisplay(this.course!, false, false); | ||||
| 
 | ||||
|         this.tabs.concat(handlers.map(handler => handler.data)); | ||||
|         this.tabs = [...this.tabs, ...handlers.map(handler => handler.data)]; | ||||
| 
 | ||||
|         let tabToLoad: number | undefined; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										38
									
								
								src/core/features/grades/grades-course-lazy.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/core/features/grades/grades-course-lazy.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| // (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 { NgModule } from '@angular/core'; | ||||
| import { RouterModule, Routes } from '@angular/router'; | ||||
| 
 | ||||
| import { CoreGradesCoursePage } from './pages/course/course.page'; | ||||
| import { CoreGradesCoursePageModule } from './pages/course/course.module'; | ||||
| 
 | ||||
| const routes: Routes = [ | ||||
|     { | ||||
|         path: '', | ||||
|         component: CoreGradesCoursePage, | ||||
|         data: { | ||||
|             useSplitView: false, | ||||
|             outsideGradesTab: true, | ||||
|         }, | ||||
|     }, | ||||
| ]; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     imports: [ | ||||
|         RouterModule.forChild(routes), | ||||
|         CoreGradesCoursePageModule, | ||||
|     ], | ||||
| }) | ||||
| export class CoreGradesCourseLazyModule {} | ||||
| @ -18,13 +18,14 @@ import { NgModule } from '@angular/core'; | ||||
| import { RouterModule, Routes } from '@angular/router'; | ||||
| import { TranslateModule } from '@ngx-translate/core'; | ||||
| 
 | ||||
| import { CoreSharedModule } from '@/core/shared.module'; | ||||
| import { conditionalRoutes } from '@/app/app-routing.module'; | ||||
| import { CoreScreen } from '@services/screen'; | ||||
| import { CoreSharedModule } from '@/core/shared.module'; | ||||
| 
 | ||||
| import { CoreGradesCoursePage } from './pages/course/course'; | ||||
| import { CoreGradesCoursePage } from './pages/course/course.page'; | ||||
| import { CoreGradesCoursePageModule } from './pages/course/course.module'; | ||||
| import { CoreGradesCoursesPage } from './pages/courses/courses'; | ||||
| import { CoreGradesGradePage } from './pages/grade/grade'; | ||||
| import { conditionalRoutes } from '@/app/app-routing.module'; | ||||
| 
 | ||||
| const mobileRoutes: Routes = [ | ||||
|     { | ||||
| @ -76,10 +77,10 @@ const routes: Routes = [ | ||||
|         IonicModule, | ||||
|         TranslateModule.forChild(), | ||||
|         CoreSharedModule, | ||||
|         CoreGradesCoursePageModule, | ||||
|     ], | ||||
|     declarations: [ | ||||
|         CoreGradesCoursesPage, | ||||
|         CoreGradesCoursePage, | ||||
|         CoreGradesGradePage, | ||||
|     ], | ||||
| }) | ||||
|  | ||||
| @ -15,6 +15,7 @@ | ||||
| import { APP_INITIALIZER, NgModule } from '@angular/core'; | ||||
| import { Routes } from '@angular/router'; | ||||
| import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate'; | ||||
| import { CoreCourseIndexRoutingModule } from '@features/course/pages/index/index-routing.module'; | ||||
| import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate'; | ||||
| import { CoreMainMenuRoutingModule } from '@features/mainmenu/mainmenu-routing.module'; | ||||
| import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module'; | ||||
| @ -33,10 +34,18 @@ const routes: Routes = [ | ||||
|     }, | ||||
| ]; | ||||
| 
 | ||||
| const courseIndexRoutes: Routes = [ | ||||
|     { | ||||
|         path: 'grades', | ||||
|         loadChildren: () => import('@features/grades/grades-course-lazy.module').then(m => m.CoreGradesCourseLazyModule), | ||||
|     }, | ||||
| ]; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     imports: [ | ||||
|         CoreMainMenuTabRoutingModule.forChild(routes), | ||||
|         CoreMainMenuRoutingModule.forChild({ children: routes }), | ||||
|         CoreCourseIndexRoutingModule.forChild({ children: courseIndexRoutes }), | ||||
|     ], | ||||
|     providers: [ | ||||
|         { | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|     </ion-toolbar> | ||||
| </ion-header> | ||||
| <ion-content> | ||||
|     <core-split-view> | ||||
|     <core-split-view [mode]="splitViewMode"> | ||||
|         <ion-refresher slot="fixed" [disabled]="!grades.loaded" (ionRefresh)="refreshGrades($event.target)"> | ||||
|             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||
|         </ion-refresher> | ||||
|  | ||||
							
								
								
									
										35
									
								
								src/core/features/grades/pages/course/course.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/core/features/grades/pages/course/course.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| // (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 { CommonModule } from '@angular/common'; | ||||
| import { IonicModule } from '@ionic/angular'; | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { TranslateModule } from '@ngx-translate/core'; | ||||
| 
 | ||||
| import { CoreSharedModule } from '@/core/shared.module'; | ||||
| 
 | ||||
| import { CoreGradesCoursePage } from './course.page'; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     imports: [ | ||||
|         CommonModule, | ||||
|         IonicModule, | ||||
|         TranslateModule.forChild(), | ||||
|         CoreSharedModule, | ||||
|     ], | ||||
|     declarations: [ | ||||
|         CoreGradesCoursePage, | ||||
|     ], | ||||
| }) | ||||
| export class CoreGradesCoursePageModule {} | ||||
| @ -27,9 +27,10 @@ import { | ||||
| } from '@features/grades/services/grades-helper'; | ||||
| import { CoreSites } from '@services/sites'; | ||||
| import { CoreUtils } from '@services/utils/utils'; | ||||
| import { CoreSplitViewComponent } from '@components/split-view/split-view'; | ||||
| import { CoreSplitViewComponent, CoreSplitViewMode } from '@components/split-view/split-view'; | ||||
| import { CoreObject } from '@singletons/object'; | ||||
| import { CorePageItemsListManager } from '@classes/page-items-list-manager'; | ||||
| import { CoreNavigator } from '@services/navigator'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that displays a course grades. | ||||
| @ -42,14 +43,18 @@ import { CorePageItemsListManager } from '@classes/page-items-list-manager'; | ||||
| export class CoreGradesCoursePage implements AfterViewInit, OnDestroy { | ||||
| 
 | ||||
|     grades: CoreGradesCourseManager; | ||||
|     splitViewMode?: CoreSplitViewMode; | ||||
| 
 | ||||
|     @ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent; | ||||
| 
 | ||||
|     constructor(route: ActivatedRoute) { | ||||
|         const courseId = parseInt(route.snapshot.params.courseId); | ||||
|         const courseId = parseInt(route.snapshot.params.courseId ?? route.snapshot.queryParams.courseId); | ||||
|         const userId = parseInt(route.snapshot.queryParams.userId ?? CoreSites.instance.getCurrentSiteUserId()); | ||||
|         const useSplitView = route.snapshot.data.useSplitView ?? true; | ||||
|         const outsideGradesTab = route.snapshot.data.outsideGradesTab ?? false; | ||||
| 
 | ||||
|         this.grades = new CoreGradesCourseManager(CoreGradesCoursePage, courseId, userId); | ||||
|         this.splitViewMode = useSplitView ? undefined : CoreSplitViewMode.MenuOnly; | ||||
|         this.grades = new CoreGradesCourseManager(CoreGradesCoursePage, courseId, userId, outsideGradesTab); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -118,11 +123,14 @@ class CoreGradesCourseManager extends CorePageItemsListManager<CoreGradesFormatt | ||||
|     columns?: CoreGradesFormattedTableColumn[]; | ||||
|     rows?: CoreGradesFormattedTableRow[]; | ||||
| 
 | ||||
|     constructor(pageComponent: unknown, courseId: number, userId: number) { | ||||
|     private outsideGradesTab: boolean; | ||||
| 
 | ||||
|     constructor(pageComponent: unknown, courseId: number, userId: number, outsideGradesTab: boolean) { | ||||
|         super(pageComponent); | ||||
| 
 | ||||
|         this.courseId = courseId; | ||||
|         this.userId = userId; | ||||
|         this.outsideGradesTab = outsideGradesTab; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -137,6 +145,19 @@ class CoreGradesCourseManager extends CorePageItemsListManager<CoreGradesFormatt | ||||
|         this.setItems(table.rows.filter(this.isFilledRow)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @inheritdoc | ||||
|      */ | ||||
|     async select(row: CoreGradesFormattedTableRowFilled): Promise<void> { | ||||
|         if (this.outsideGradesTab) { | ||||
|             await CoreNavigator.instance.navigateToSitePath(`/grades/${this.courseId}/${row.id}`); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         return super.select(row); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @inheritdoc | ||||
|      */ | ||||
| @ -83,19 +83,14 @@ export class CoreGradesCourseOptionHandlerService implements CoreCourseOptionsHa | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the data needed to render the handler. | ||||
|      * | ||||
|      * @return Data or promise resolved with the data. | ||||
|      * @inheritdoc | ||||
|      */ | ||||
|     getDisplayData(): CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> { | ||||
|         throw new Error('CoreGradesCourseOptionHandler.getDisplayData is not implemented'); | ||||
| 
 | ||||
|         // @todo
 | ||||
|         // return {
 | ||||
|         //     title: 'core.grades.grades',
 | ||||
|         //     class: 'core-grades-course-handler',
 | ||||
|         //     component: CoreGradesCourseComponent,
 | ||||
|         // };
 | ||||
|         return { | ||||
|             title: 'core.grades.grades', | ||||
|             class: 'core-grades-course-handler', | ||||
|             page: 'grades', | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user