forked from EVOgeek/Vmeda.Online
		
	MOBILE-3686 courses: Merge available courses and search courses pages
This commit is contained in:
		
							parent
							
								
									55b6d9f76a
								
							
						
					
					
						commit
						5ac62106bf
					
				| @ -33,16 +33,10 @@ const routes: Routes = [ | ||||
|                 .then(m => m.CoreCoursesCategoriesPageModule), | ||||
|     }, | ||||
|     { | ||||
|         path: 'all', | ||||
|         path: 'list', | ||||
|         loadChildren: () => | ||||
|             import('./pages/available-courses/available-courses.module') | ||||
|                 .then(m => m.CoreCoursesAvailableCoursesPageModule), | ||||
|     }, | ||||
|     { | ||||
|         path: 'search', | ||||
|         loadChildren: () => | ||||
|             import('./pages/search/search.module') | ||||
|                 .then(m => m.CoreCoursesSearchPageModule), | ||||
|             import('./pages/list/list.module') | ||||
|                 .then(m => m.CoreCoursesListPageModule), | ||||
|     }, | ||||
|     { | ||||
|         path: 'my', | ||||
|  | ||||
| @ -1,19 +0,0 @@ | ||||
| <ion-header> | ||||
|     <ion-toolbar> | ||||
|         <ion-buttons slot="start"> | ||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||
|         </ion-buttons> | ||||
|         <h1>{{ 'core.courses.availablecourses' | translate }}</h1> | ||||
|     </ion-toolbar> | ||||
| </ion-header> | ||||
| <ion-content> | ||||
|     <ion-refresher slot="fixed" [disabled]="!coursesLoaded" (ionRefresh)="refreshCourses($event.target)"> | ||||
|         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||
|     </ion-refresher> | ||||
|     <core-loading [hideUntil]="coursesLoaded"> | ||||
|         <ng-container *ngIf="courses.length > 0"> | ||||
|             <core-courses-course-list-item *ngFor="let course of courses" [course]="course"></core-courses-course-list-item> | ||||
|         </ng-container> | ||||
|         <core-empty-box *ngIf="!courses.length" icon="fas-graduation-cap" [message]="'core.courses.nocourses' | translate"></core-empty-box> | ||||
|     </core-loading> | ||||
| </ion-content> | ||||
| @ -1,41 +0,0 @@ | ||||
| // (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 { CoreSharedModule } from '@/core/shared.module'; | ||||
| import { CoreCoursesComponentsModule } from '../../components/components.module'; | ||||
| 
 | ||||
| import { CoreCoursesAvailableCoursesPage } from './available-courses'; | ||||
| 
 | ||||
| const routes: Routes = [ | ||||
|     { | ||||
|         path: '', | ||||
|         component: CoreCoursesAvailableCoursesPage, | ||||
|     }, | ||||
| ]; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     imports: [ | ||||
|         RouterModule.forChild(routes), | ||||
|         CoreSharedModule, | ||||
|         CoreCoursesComponentsModule, | ||||
|     ], | ||||
|     declarations: [ | ||||
|         CoreCoursesAvailableCoursesPage, | ||||
|     ], | ||||
|     exports: [RouterModule], | ||||
| }) | ||||
| export class CoreCoursesAvailableCoursesPageModule { } | ||||
| @ -1,78 +0,0 @@ | ||||
| // (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 { Component, OnInit } from '@angular/core'; | ||||
| import { IonRefresher } from '@ionic/angular'; | ||||
| 
 | ||||
| import { CoreSites } from '@services/sites'; | ||||
| import { CoreDomUtils } from '@services/utils/dom'; | ||||
| import { CoreCourses, CoreCourseSearchedData } from '../../services/courses'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that displays available courses in current site. | ||||
|  */ | ||||
| @Component({ | ||||
|     selector: 'page-core-courses-available-courses', | ||||
|     templateUrl: 'available-courses.html', | ||||
| }) | ||||
| export class CoreCoursesAvailableCoursesPage implements OnInit { | ||||
| 
 | ||||
|     courses: CoreCourseSearchedData[] = []; | ||||
|     coursesLoaded = false; | ||||
| 
 | ||||
|     /** | ||||
|      * View loaded. | ||||
|      */ | ||||
|     ngOnInit(): void { | ||||
|         this.loadCourses().finally(() => { | ||||
|             this.coursesLoaded = true; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load the courses. | ||||
|      * | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     protected async loadCourses(): Promise<void> { | ||||
|         const frontpageCourseId = CoreSites.getCurrentSiteHomeId(); | ||||
| 
 | ||||
|         try { | ||||
|             const courses = await CoreCourses.getCoursesByField(); | ||||
| 
 | ||||
|             this.courses = courses.filter((course) => course.id != frontpageCourseId); | ||||
|         } catch (error) { | ||||
|             CoreDomUtils.showErrorModalDefault(error, 'core.courses.errorloadcourses', true); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Refresh the courses. | ||||
|      * | ||||
|      * @param refresher Refresher. | ||||
|      */ | ||||
|     refreshCourses(refresher: IonRefresher): void { | ||||
|         const promises: Promise<void>[] = []; | ||||
| 
 | ||||
|         promises.push(CoreCourses.invalidateUserCourses()); | ||||
|         promises.push(CoreCourses.invalidateCoursesByField()); | ||||
| 
 | ||||
|         Promise.all(promises).finally(() => { | ||||
|             this.loadCourses().finally(() => { | ||||
|                 refresher?.complete(); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -167,7 +167,7 @@ export class CoreCoursesDashboardPage implements OnInit, OnDestroy { | ||||
|      * Go to search courses. | ||||
|      */ | ||||
|     async openSearch(): Promise<void> { | ||||
|         CoreNavigator.navigateToSitePath('/courses/search'); | ||||
|         CoreNavigator.navigateToSitePath('/courses/list', { params : { mode: 'search' } }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
							
								
								
									
										36
									
								
								src/core/features/courses/pages/list/list.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/core/features/courses/pages/list/list.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| <ion-header> | ||||
|     <ion-toolbar> | ||||
|         <ion-buttons slot="start"> | ||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||
|         </ion-buttons> | ||||
|         <h1>{{ 'core.courses.availablecourses' | translate }}</h1> | ||||
|     </ion-toolbar> | ||||
| </ion-header> | ||||
| <ion-content> | ||||
|     <ion-refresher slot="fixed" [disabled]="!coursesLoaded" (ionRefresh)="refreshCourses($event.target)"> | ||||
|         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||
|     </ion-refresher> | ||||
|      | ||||
|     <core-search-box *ngIf="searchEnabled" (onSubmit)="search($event)" (onClear)="clearSearch()" | ||||
|         [placeholder]="'core.courses.search' | translate" [searchLabel]="'core.courses.search' | translate" [autoFocus]="searchMode" | ||||
|         searchArea="CoreCoursesSearch"></core-search-box> | ||||
| 
 | ||||
|     <core-loading [hideUntil]="coursesLoaded"> | ||||
|         <ng-container *ngIf="searchMode && searchTotal > 0"> | ||||
|             <ion-item-divider> | ||||
|                 <ion-label><h2>{{ 'core.courses.totalcoursesearchresults' | translate:{$a: searchTotal} }}</h2></ion-label> | ||||
|             </ion-item-divider> | ||||
|         </ng-container> | ||||
|          | ||||
|         <core-courses-course-list-item *ngFor="let course of courses" [course]="course"></core-courses-course-list-item> | ||||
| 
 | ||||
|         <core-infinite-loading [enabled]="searchMode && searchCanLoadMore" (action)="loadMoreResults($event)" [error]="searchLoadMoreError"> | ||||
|         </core-infinite-loading> | ||||
|         <core-empty-box *ngIf="searchMode && !courses.length" icon="fas-search" [message]="'core.courses.nosearchresults' | translate"> | ||||
|         </core-empty-box> | ||||
| 
 | ||||
|         <core-empty-box *ngIf="!searchMode && !courses.length" icon="fas-graduation-cap" [message]="'core.courses.nocourses' | translate"> | ||||
|         </core-empty-box> | ||||
|          | ||||
|     </core-loading> | ||||
| </ion-content> | ||||
| @ -19,12 +19,12 @@ import { CoreSharedModule } from '@/core/shared.module'; | ||||
| import { CoreCoursesComponentsModule } from '../../components/components.module'; | ||||
| import { CoreSearchComponentsModule } from '@features/search/components/components.module'; | ||||
| 
 | ||||
| import { CoreCoursesSearchPage } from './search'; | ||||
| import { CoreCoursesListPage } from './list'; | ||||
| 
 | ||||
| const routes: Routes = [ | ||||
|     { | ||||
|         path: '', | ||||
|         component: CoreCoursesSearchPage, | ||||
|         component: CoreCoursesListPage, | ||||
|     }, | ||||
| ]; | ||||
| 
 | ||||
| @ -36,8 +36,8 @@ const routes: Routes = [ | ||||
|         CoreSearchComponentsModule, | ||||
|     ], | ||||
|     declarations: [ | ||||
|         CoreCoursesSearchPage, | ||||
|         CoreCoursesListPage, | ||||
|     ], | ||||
|     exports: [RouterModule], | ||||
| }) | ||||
| export class CoreCoursesSearchPageModule { } | ||||
| export class CoreCoursesListPageModule { } | ||||
							
								
								
									
										211
									
								
								src/core/features/courses/pages/list/list.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								src/core/features/courses/pages/list/list.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,211 @@ | ||||
| // (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 { Component, OnDestroy, OnInit } from '@angular/core'; | ||||
| import { IonRefresher } from '@ionic/angular'; | ||||
| import { CoreNavigator } from '@services/navigator'; | ||||
| import { CoreSites } from '@services/sites'; | ||||
| import { CoreDomUtils } from '@services/utils/dom'; | ||||
| import { CoreEventObserver, CoreEvents } from '@singletons/events'; | ||||
| import { CoreCourseBasicSearchedData, CoreCourses } from '../../services/courses'; | ||||
| 
 | ||||
| type CoreCoursesListMode = 'search' | 'all'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that shows a list of courses. | ||||
|  */ | ||||
| @Component({ | ||||
|     selector: 'page-core-courses-list', | ||||
|     templateUrl: 'list.html', | ||||
| }) | ||||
| export class CoreCoursesListPage implements OnInit, OnDestroy { | ||||
| 
 | ||||
|     searchEnabled = false; | ||||
|     searchMode = false; | ||||
|     searchCanLoadMore = false; | ||||
|     searchLoadMoreError = false; | ||||
|     searchTotal = 0; | ||||
| 
 | ||||
|     mode: CoreCoursesListMode = 'all'; | ||||
| 
 | ||||
|     courses: CoreCourseBasicSearchedData[] = []; | ||||
|     coursesLoaded = false; | ||||
| 
 | ||||
|     protected currentSiteId: string; | ||||
|     protected frontpageCourseId: number; | ||||
|     protected searchPage = 0; | ||||
|     protected searchText = ''; | ||||
|     protected siteUpdatedObserver: CoreEventObserver; | ||||
| 
 | ||||
|     constructor() { | ||||
|         this.currentSiteId = CoreSites.getRequiredCurrentSite().getId(); | ||||
|         this.frontpageCourseId = CoreSites.getRequiredCurrentSite().getSiteHomeId(); | ||||
| 
 | ||||
|         // Refresh the enabled flags if site is updated.
 | ||||
|         this.siteUpdatedObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => { | ||||
|             this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite(); | ||||
| 
 | ||||
|             if (!this.searchEnabled) { | ||||
|                 this.searchMode = false; | ||||
| 
 | ||||
|                 this.fetchCourses(); | ||||
|             } | ||||
|         }, this.currentSiteId); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @inheritdoc | ||||
|      */ | ||||
|     ngOnInit(): void { | ||||
|         this.mode = CoreNavigator.getRouteParam<CoreCoursesListMode>('mode') || this.mode; | ||||
| 
 | ||||
|         if (this.mode == 'search') { | ||||
|             this.searchMode = true; | ||||
|         } | ||||
| 
 | ||||
|         this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite(); | ||||
|         if (!this.searchEnabled) { | ||||
|             this.searchMode = false; | ||||
|         } | ||||
| 
 | ||||
|         this.fetchCourses(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load the course list. | ||||
|      * | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     protected async fetchCourses(): Promise<void> { | ||||
|         try { | ||||
|             if (this.searchMode && this.searchText) { | ||||
|                 await this.search(this.searchText); | ||||
|             } else { | ||||
|                 await this.loadAvailableCourses(); | ||||
|             } | ||||
|         } finally { | ||||
|             this.coursesLoaded = true; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load the courses. | ||||
|      * | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     protected async loadAvailableCourses(): Promise<void> { | ||||
|         try { | ||||
|             const courses = await CoreCourses.getCoursesByField(); | ||||
| 
 | ||||
|             this.courses = courses.filter((course) => course.id != this.frontpageCourseId); | ||||
|         } catch (error) { | ||||
|             CoreDomUtils.showErrorModalDefault(error, 'core.courses.errorloadcourses', true); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Refresh the courses. | ||||
|      * | ||||
|      * @param refresher Refresher. | ||||
|      */ | ||||
|     refreshCourses(refresher: IonRefresher): void { | ||||
|         const promises: Promise<void>[] = []; | ||||
| 
 | ||||
|         promises.push(CoreCourses.invalidateUserCourses()); | ||||
|         promises.push(CoreCourses.invalidateCoursesByField()); | ||||
| 
 | ||||
|         Promise.all(promises).finally(() => { | ||||
|             this.fetchCourses().finally(() => { | ||||
|                 refresher?.complete(); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Search a new text. | ||||
|      * | ||||
|      * @param text The text to search. | ||||
|      */ | ||||
|     async search(text: string): Promise<void> { | ||||
|         this.searchMode = true; | ||||
|         this.searchText = text; | ||||
|         this.courses = []; | ||||
|         this.searchPage = 0; | ||||
|         this.searchTotal = 0; | ||||
| 
 | ||||
|         const modal = await CoreDomUtils.showModalLoading('core.searching', true); | ||||
|         this.searchCourses().finally(() => { | ||||
|             modal.dismiss(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Clear search box. | ||||
|      */ | ||||
|     clearSearch(): void { | ||||
|         this.searchText = ''; | ||||
|         this.courses = []; | ||||
|         this.searchPage = 0; | ||||
|         this.searchTotal = 0; | ||||
|         this.searchMode = false; | ||||
| 
 | ||||
|         this.coursesLoaded = false; | ||||
|         this.fetchCourses(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load more results. | ||||
|      * | ||||
|      * @param infiniteComplete Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      */ | ||||
|     loadMoreResults(infiniteComplete?: () => void ): void { | ||||
|         this.searchCourses().finally(() => { | ||||
|             infiniteComplete && infiniteComplete(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Search courses or load the next page of current search. | ||||
|      * | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     protected async searchCourses(): Promise<void> { | ||||
|         this.searchLoadMoreError = false; | ||||
| 
 | ||||
|         try { | ||||
|             const response = await CoreCourses.search(this.searchText, this.searchPage); | ||||
| 
 | ||||
|             if (this.searchPage === 0) { | ||||
|                 this.courses = response.courses; | ||||
|             } else { | ||||
|                 this.courses = this.courses.concat(response.courses); | ||||
|             } | ||||
|             this.searchTotal = response.total; | ||||
| 
 | ||||
|             this.searchPage++; | ||||
|             this.searchCanLoadMore = this.courses.length < this.searchTotal; | ||||
|         } catch (error) { | ||||
|             this.searchLoadMoreError = true; // Set to prevent infinite calls with infinite-loading.
 | ||||
|             CoreDomUtils.showErrorModalDefault(error, 'core.courses.errorsearching', true); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @inheritdoc | ||||
|      */ | ||||
|     ngOnDestroy(): void { | ||||
|         this.siteUpdatedObserver?.off(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -204,7 +204,7 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy { | ||||
|      * Go to search courses. | ||||
|      */ | ||||
|     openSearch(): void { | ||||
|         CoreNavigator.navigateToSitePath('courses/search'); | ||||
|         CoreNavigator.navigateToSitePath('courses/list', { params : { mode: 'search' } }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -1,23 +0,0 @@ | ||||
| <ion-header> | ||||
|     <ion-toolbar> | ||||
|         <ion-buttons slot="start"> | ||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||
|         </ion-buttons> | ||||
|         <h1>{{ 'core.courses.searchcourses' | translate }}</h1> | ||||
|     </ion-toolbar> | ||||
| </ion-header> | ||||
| <ion-content> | ||||
|     <core-search-box (onSubmit)="search($event)" (onClear)="clearSearch()" | ||||
|     [placeholder]="'core.courses.search' | translate" [searchLabel]="'core.courses.search' | translate" autoFocus="true" | ||||
|     searchArea="CoreCoursesSearch"></core-search-box> | ||||
| 
 | ||||
|     <ng-container *ngIf="total > 0"> | ||||
|         <ion-item-divider> | ||||
|             <ion-label><h2>{{ 'core.courses.totalcoursesearchresults' | translate:{$a: total} }}</h2></ion-label> | ||||
|         </ion-item-divider> | ||||
|         <core-courses-course-list-item *ngFor="let course of courses" [course]="course"></core-courses-course-list-item> | ||||
|         <core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreResults($event)" [error]="loadMoreError"> | ||||
|         </core-infinite-loading> | ||||
|     </ng-container> | ||||
|     <core-empty-box *ngIf="total == 0" icon="search" [message]="'core.courses.nosearchresults' | translate"></core-empty-box> | ||||
| </ion-content> | ||||
| @ -1,100 +0,0 @@ | ||||
| // (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 { Component } from '@angular/core'; | ||||
| import { CoreDomUtils } from '@services/utils/dom'; | ||||
| import { CoreCourseBasicSearchedData, CoreCourses } from '../../services/courses'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that allows searching for courses. | ||||
|  */ | ||||
| @Component({ | ||||
|     selector: 'page-core-courses-search', | ||||
|     templateUrl: 'search.html', | ||||
| }) | ||||
| export class CoreCoursesSearchPage { | ||||
| 
 | ||||
|     total = 0; | ||||
|     courses: CoreCourseBasicSearchedData[] = []; | ||||
|     canLoadMore = false; | ||||
|     loadMoreError = false; | ||||
| 
 | ||||
|     protected page = 0; | ||||
|     protected currentSearch = ''; | ||||
| 
 | ||||
|     /** | ||||
|      * Search a new text. | ||||
|      * | ||||
|      * @param text The text to search. | ||||
|      */ | ||||
|     async search(text: string): Promise<void> { | ||||
|         this.currentSearch = text; | ||||
|         this.courses = []; | ||||
|         this.page = 0; | ||||
|         this.total = 0; | ||||
| 
 | ||||
|         const modal = await CoreDomUtils.showModalLoading('core.searching', true); | ||||
|         this.searchCourses().finally(() => { | ||||
|             modal.dismiss(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Clear search box. | ||||
|      */ | ||||
|     clearSearch(): void { | ||||
|         this.currentSearch = ''; | ||||
|         this.courses = []; | ||||
|         this.page = 0; | ||||
|         this.total = 0; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load more results. | ||||
|      * | ||||
|      * @param infiniteComplete Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      */ | ||||
|     loadMoreResults(infiniteComplete?: () => void ): void { | ||||
|         this.searchCourses().finally(() => { | ||||
|             infiniteComplete && infiniteComplete(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Search courses or load the next page of current search. | ||||
|      * | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     protected async searchCourses(): Promise<void> { | ||||
|         this.loadMoreError = false; | ||||
| 
 | ||||
|         try { | ||||
|             const response = await CoreCourses.search(this.currentSearch, this.page); | ||||
| 
 | ||||
|             if (this.page === 0) { | ||||
|                 this.courses = response.courses; | ||||
|             } else { | ||||
|                 this.courses = this.courses.concat(response.courses); | ||||
|             } | ||||
|             this.total = response.total; | ||||
| 
 | ||||
|             this.page++; | ||||
|             this.canLoadMore = this.courses.length < this.total; | ||||
|         } catch (error) { | ||||
|             this.loadMoreError = true; // Set to prevent infinite calls with infinite-loading.
 | ||||
|             CoreDomUtils.showErrorModalDefault(error, 'core.courses.errorsearching', true); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -42,14 +42,17 @@ export class CoreCoursesIndexLinkHandlerService extends CoreContentLinksHandlerB | ||||
|         return [{ | ||||
|             action: (siteId): void => { | ||||
|                 let pageName = CoreCoursesMyCoursesHomeHandlerService.PAGE_NAME; | ||||
|                 const pageParams: Params = {}; | ||||
| 
 | ||||
|                 if (params.categoryid) { | ||||
|                     pageName += '/categories/' + params.categoryid; | ||||
|                 } else { | ||||
|                     pageName += '/all'; | ||||
|                     pageName += '/list'; | ||||
|                     pageParams.mode = 'all'; | ||||
|                 } | ||||
| 
 | ||||
|                 CoreNavigator.navigateToSitePath(pageName, { siteId }); | ||||
| 
 | ||||
|                 CoreNavigator.navigateToSitePath(pageName, { params: pageParams, siteId }); | ||||
|             }, | ||||
|         }]; | ||||
|     } | ||||
|  | ||||
| @ -218,14 +218,14 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { | ||||
|      * Go to search courses. | ||||
|      */ | ||||
|     openSearch(): void { | ||||
|         CoreNavigator.navigateToSitePath('courses/search'); | ||||
|         CoreNavigator.navigateToSitePath('courses/list', { params : { mode: 'search' } }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Go to available courses. | ||||
|      */ | ||||
|     openAvailableCourses(): void { | ||||
|         CoreNavigator.navigateToSitePath('courses/all'); | ||||
|         CoreNavigator.navigateToSitePath('courses/list', { params : { mode: 'all' } }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user