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> | <ion-app> | ||||||
|     <!-- @todo move /login/init UI here --> |  | ||||||
| 
 |  | ||||||
|     <ion-router-outlet></ion-router-outlet> |     <ion-router-outlet></ion-router-outlet> | ||||||
| </ion-app> | </ion-app> | ||||||
|  | |||||||
| @ -520,12 +520,12 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft | |||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     async selectByIndex(index: number, e?: Event): Promise<void> { |     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?.preventDefault(); | ||||||
|         e?.stopPropagation(); |         e?.stopPropagation(); | ||||||
| 
 | 
 | ||||||
|  |         if (index < 0 || index >= this.tabs.length) { | ||||||
|  |             if (this.selected) { | ||||||
|  |                 // Invalid index do not change tab.
 | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -536,9 +536,6 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft | |||||||
|         const tabToSelect = this.tabs[index]; |         const tabToSelect = this.tabs[index]; | ||||||
|         if (!tabToSelect || !tabToSelect.enabled || tabToSelect.id == this.selected) { |         if (!tabToSelect || !tabToSelect.enabled || tabToSelect.id == this.selected) { | ||||||
|             // Already selected or not enabled.
 |             // Already selected or not enabled.
 | ||||||
|             e?.preventDefault(); |  | ||||||
|             e?.stopPropagation(); |  | ||||||
| 
 |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ import { IonRouterOutlet } from '@ionic/angular'; | |||||||
| import { CoreScreen } from '@services/screen'; | import { CoreScreen } from '@services/screen'; | ||||||
| import { BehaviorSubject, Observable, Subscription } from 'rxjs'; | import { BehaviorSubject, Observable, Subscription } from 'rxjs'; | ||||||
| 
 | 
 | ||||||
| enum CoreSplitViewMode { | export enum CoreSplitViewMode { | ||||||
|     MenuOnly = 'menu-only', // Hides content.
 |     MenuOnly = 'menu-only', // Hides content.
 | ||||||
|     ContentOnly = 'content-only', // Hides menu.
 |     ContentOnly = 'content-only', // Hides menu.
 | ||||||
|     MenuAndContent = 'menu-and-content', // Shows both menu and content.
 |     MenuAndContent = 'menu-and-content', // Shows both menu and content.
 | ||||||
| @ -34,6 +34,7 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy { | |||||||
|     @ViewChild(IonRouterOutlet) outlet!: IonRouterOutlet; |     @ViewChild(IonRouterOutlet) outlet!: IonRouterOutlet; | ||||||
|     @HostBinding('class') classes = ''; |     @HostBinding('class') classes = ''; | ||||||
|     @Input() placeholderText = 'core.emptysplit'; |     @Input() placeholderText = 'core.emptysplit'; | ||||||
|  |     @Input() mode?: CoreSplitViewMode; | ||||||
|     isNested = false; |     isNested = false; | ||||||
| 
 | 
 | ||||||
|     private outletRouteSubject: BehaviorSubject<ActivatedRouteSnapshot | null> = new BehaviorSubject(null); |     private outletRouteSubject: BehaviorSubject<ActivatedRouteSnapshot | null> = new BehaviorSubject(null); | ||||||
| @ -100,6 +101,10 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy { | |||||||
|      * @return Split view mode. |      * @return Split view mode. | ||||||
|      */ |      */ | ||||||
|     private getCurrentMode(): CoreSplitViewMode { |     private getCurrentMode(): CoreSplitViewMode { | ||||||
|  |         if (this.mode) { | ||||||
|  |             return this.mode; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (this.isNested) { |         if (this.isNested) { | ||||||
|             return CoreSplitViewMode.MenuOnly; |             return CoreSplitViewMode.MenuOnly; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -43,8 +43,8 @@ import { CoreTabBase, CoreTabsBaseComponent } from '@classes/tabs'; | |||||||
|  * |  * | ||||||
|  * Tab contents will only be shown if that tab is selected. |  * 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: 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({ | @Component({ | ||||||
|     selector: 'core-tabs-outlet', |     selector: 'core-tabs-outlet', | ||||||
|  | |||||||
| @ -115,7 +115,7 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy { | |||||||
|         // Load the course handlers.
 |         // Load the course handlers.
 | ||||||
|         const handlers = await CoreCourseOptionsDelegate.instance.getHandlersToDisplay(this.course!, false, false); |         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; |         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 { RouterModule, Routes } from '@angular/router'; | ||||||
| import { TranslateModule } from '@ngx-translate/core'; | 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 { 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 { CoreGradesCoursesPage } from './pages/courses/courses'; | ||||||
| import { CoreGradesGradePage } from './pages/grade/grade'; | import { CoreGradesGradePage } from './pages/grade/grade'; | ||||||
| import { conditionalRoutes } from '@/app/app-routing.module'; |  | ||||||
| 
 | 
 | ||||||
| const mobileRoutes: Routes = [ | const mobileRoutes: Routes = [ | ||||||
|     { |     { | ||||||
| @ -76,10 +77,10 @@ const routes: Routes = [ | |||||||
|         IonicModule, |         IonicModule, | ||||||
|         TranslateModule.forChild(), |         TranslateModule.forChild(), | ||||||
|         CoreSharedModule, |         CoreSharedModule, | ||||||
|  |         CoreGradesCoursePageModule, | ||||||
|     ], |     ], | ||||||
|     declarations: [ |     declarations: [ | ||||||
|         CoreGradesCoursesPage, |         CoreGradesCoursesPage, | ||||||
|         CoreGradesCoursePage, |  | ||||||
|         CoreGradesGradePage, |         CoreGradesGradePage, | ||||||
|     ], |     ], | ||||||
| }) | }) | ||||||
|  | |||||||
| @ -15,6 +15,7 @@ | |||||||
| import { APP_INITIALIZER, NgModule } from '@angular/core'; | import { APP_INITIALIZER, NgModule } from '@angular/core'; | ||||||
| import { Routes } from '@angular/router'; | import { Routes } from '@angular/router'; | ||||||
| import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate'; | 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 { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate'; | ||||||
| import { CoreMainMenuRoutingModule } from '@features/mainmenu/mainmenu-routing.module'; | import { CoreMainMenuRoutingModule } from '@features/mainmenu/mainmenu-routing.module'; | ||||||
| import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-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({ | @NgModule({ | ||||||
|     imports: [ |     imports: [ | ||||||
|         CoreMainMenuTabRoutingModule.forChild(routes), |         CoreMainMenuTabRoutingModule.forChild(routes), | ||||||
|         CoreMainMenuRoutingModule.forChild({ children: routes }), |         CoreMainMenuRoutingModule.forChild({ children: routes }), | ||||||
|  |         CoreCourseIndexRoutingModule.forChild({ children: courseIndexRoutes }), | ||||||
|     ], |     ], | ||||||
|     providers: [ |     providers: [ | ||||||
|         { |         { | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|     <core-split-view> |     <core-split-view [mode]="splitViewMode"> | ||||||
|         <ion-refresher slot="fixed" [disabled]="!grades.loaded" (ionRefresh)="refreshGrades($event.target)"> |         <ion-refresher slot="fixed" [disabled]="!grades.loaded" (ionRefresh)="refreshGrades($event.target)"> | ||||||
|             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> |             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|         </ion-refresher> |         </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'; | } from '@features/grades/services/grades-helper'; | ||||||
| import { CoreSites } from '@services/sites'; | import { CoreSites } from '@services/sites'; | ||||||
| import { CoreUtils } from '@services/utils/utils'; | 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 { CoreObject } from '@singletons/object'; | ||||||
| import { CorePageItemsListManager } from '@classes/page-items-list-manager'; | import { CorePageItemsListManager } from '@classes/page-items-list-manager'; | ||||||
|  | import { CoreNavigator } from '@services/navigator'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Page that displays a course grades. |  * Page that displays a course grades. | ||||||
| @ -42,14 +43,18 @@ import { CorePageItemsListManager } from '@classes/page-items-list-manager'; | |||||||
| export class CoreGradesCoursePage implements AfterViewInit, OnDestroy { | export class CoreGradesCoursePage implements AfterViewInit, OnDestroy { | ||||||
| 
 | 
 | ||||||
|     grades: CoreGradesCourseManager; |     grades: CoreGradesCourseManager; | ||||||
|  |     splitViewMode?: CoreSplitViewMode; | ||||||
| 
 | 
 | ||||||
|     @ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent; |     @ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent; | ||||||
| 
 | 
 | ||||||
|     constructor(route: ActivatedRoute) { |     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 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[]; |     columns?: CoreGradesFormattedTableColumn[]; | ||||||
|     rows?: CoreGradesFormattedTableRow[]; |     rows?: CoreGradesFormattedTableRow[]; | ||||||
| 
 | 
 | ||||||
|     constructor(pageComponent: unknown, courseId: number, userId: number) { |     private outsideGradesTab: boolean; | ||||||
|  | 
 | ||||||
|  |     constructor(pageComponent: unknown, courseId: number, userId: number, outsideGradesTab: boolean) { | ||||||
|         super(pageComponent); |         super(pageComponent); | ||||||
| 
 | 
 | ||||||
|         this.courseId = courseId; |         this.courseId = courseId; | ||||||
|         this.userId = userId; |         this.userId = userId; | ||||||
|  |         this.outsideGradesTab = outsideGradesTab; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -137,6 +145,19 @@ class CoreGradesCourseManager extends CorePageItemsListManager<CoreGradesFormatt | |||||||
|         this.setItems(table.rows.filter(this.isFilledRow)); |         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 |      * @inheritdoc | ||||||
|      */ |      */ | ||||||
| @ -83,19 +83,14 @@ export class CoreGradesCourseOptionHandlerService implements CoreCourseOptionsHa | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Returns the data needed to render the handler. |      * @inheritdoc | ||||||
|      * |  | ||||||
|      * @return Data or promise resolved with the data. |  | ||||||
|      */ |      */ | ||||||
|     getDisplayData(): CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> { |     getDisplayData(): CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> { | ||||||
|         throw new Error('CoreGradesCourseOptionHandler.getDisplayData is not implemented'); |         return { | ||||||
| 
 |             title: 'core.grades.grades', | ||||||
|         // @todo
 |             class: 'core-grades-course-handler', | ||||||
|         // return {
 |             page: 'grades', | ||||||
|         //     title: 'core.grades.grades',
 |         }; | ||||||
|         //     class: 'core-grades-course-handler',
 |  | ||||||
|         //     component: CoreGradesCourseComponent,
 |  | ||||||
|         // };
 |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user