forked from EVOgeek/Vmeda.Online
		
	MOBILE-3565 home: Add a Hello World as Home page
This commit is contained in:
		
							parent
							
								
									06c7035834
								
							
						
					
					
						commit
						3a831c3ef1
					
				| @ -53,6 +53,7 @@ import { CoreUtilsProvider } from '@services/utils/utils'; | ||||
| // Import core modules.
 | ||||
| import { CoreEmulatorModule } from '@core/emulator/emulator.module'; | ||||
| import { CoreLoginModule } from '@core/login/login.module'; | ||||
| import { CoreCoursesModule } from '@core/courses/courses.module'; | ||||
| 
 | ||||
| import { setSingletonsInjector } from '@singletons/core.singletons'; | ||||
| 
 | ||||
| @ -81,6 +82,7 @@ export function createTranslateLoader(http: HttpClient): TranslateHttpLoader { | ||||
|         AppRoutingModule, | ||||
|         CoreEmulatorModule, | ||||
|         CoreLoginModule, | ||||
|         CoreCoursesModule, | ||||
|     ], | ||||
|     providers: [ | ||||
|         { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, | ||||
|  | ||||
							
								
								
									
										45
									
								
								src/app/core/courses/courses.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/app/core/courses/courses.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| // (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 { NgModule } from '@angular/core'; | ||||
| import { IonicModule } from '@ionic/angular'; | ||||
| import { TranslateModule } from '@ngx-translate/core'; | ||||
| 
 | ||||
| import { CoreComponentsModule } from '@components/components.module'; | ||||
| import { CoreDirectivesModule } from '@directives/directives.module'; | ||||
| import { CoreMainMenuDelegate } from '@core/mainmenu/services/delegate'; | ||||
| 
 | ||||
| import { CoreHomeMainMenuHandler } from './handlers/mainmenu'; | ||||
| import { CoreCoursesHomePage } from './pages/home/home.page'; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     imports: [ | ||||
|         CommonModule, | ||||
|         IonicModule, | ||||
|         TranslateModule.forChild(), | ||||
|         CoreComponentsModule, | ||||
|         CoreDirectivesModule, | ||||
|     ], | ||||
|     declarations: [ | ||||
|         CoreCoursesHomePage, | ||||
|     ], | ||||
| }) | ||||
| export class CoreCoursesModule { | ||||
| 
 | ||||
|     constructor(mainMenuDelegate: CoreMainMenuDelegate) { | ||||
|         mainMenuDelegate.registerHandler(new CoreHomeMainMenuHandler()); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										60
									
								
								src/app/core/courses/handlers/mainmenu.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/app/core/courses/handlers/mainmenu.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | ||||
| // (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 { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@core/mainmenu/services/delegate'; | ||||
| 
 | ||||
| /** | ||||
|  * Handler to add Home into main menu. | ||||
|  */ | ||||
| export class CoreHomeMainMenuHandler implements CoreMainMenuHandler { | ||||
| 
 | ||||
|     name = 'CoreHome'; | ||||
|     priority = 1100; | ||||
| 
 | ||||
|     /** | ||||
|      * Check if the handler is enabled on a site level. | ||||
|      * | ||||
|      * @return Whether or not the handler is enabled on a site level. | ||||
|      */ | ||||
|     isEnabled(): Promise<boolean> { | ||||
|         return this.isEnabledForSite(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if the handler is enabled on a certain site. | ||||
|      * | ||||
|      * @param siteId Site ID. If not defined, current site. | ||||
|      * @return Whether or not the handler is enabled on a site level. | ||||
|      */ | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||
|     async isEnabledForSite(siteId?: string): Promise<boolean> { | ||||
|         // @todo
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the data needed to render the handler. | ||||
|      * | ||||
|      * @return Data needed to render the handler. | ||||
|      */ | ||||
|     getDisplayData(): CoreMainMenuHandlerData { | ||||
|         return { | ||||
|             icon: 'fa-home', | ||||
|             title: 'core.courses.mymoodle', | ||||
|             page: 'home', | ||||
|             class: 'core-home-handler', | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										39
									
								
								src/app/core/courses/lang/en.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/app/core/courses/lang/en.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| { | ||||
|     "addtofavourites": "Star this course", | ||||
|     "allowguests": "This course allows guest users to enter", | ||||
|     "availablecourses": "Available courses", | ||||
|     "cannotretrievemorecategories": "Categories deeper than level {{$a}} cannot be retrieved.", | ||||
|     "categories": "Course categories", | ||||
|     "confirmselfenrol": "Are you sure you want to enrol yourself in this course?", | ||||
|     "courses": "Courses", | ||||
|     "downloadcourses": "Download courses", | ||||
|     "enrolme": "Enrol me", | ||||
|     "errorloadcategories": "An error occurred while loading categories.", | ||||
|     "errorloadcourses": "An error occurred while loading courses.", | ||||
|     "errorloadplugins": "The plugins required by this course could not be loaded correctly. Please reload the app to try again.", | ||||
|     "errorsearching": "An error occurred while searching.", | ||||
|     "errorselfenrol": "An error occurred while self enrolling.", | ||||
|     "filtermycourses": "Filter my courses", | ||||
|     "frontpage": "Front page", | ||||
|     "hidecourse": "Remove from view", | ||||
|     "ignore": "Ignore", | ||||
|     "mycourses": "My courses", | ||||
|     "mymoodle": "Dashboard", | ||||
|     "nocourses": "No course information to show.", | ||||
|     "nocoursesyet": "No courses in this category", | ||||
|     "nosearchresults": "No results", | ||||
|     "notenroled": "You are not enrolled in this course", | ||||
|     "notenrollable": "You cannot enrol yourself in this course.", | ||||
|     "password": "Enrolment key", | ||||
|     "paymentrequired": "This course requires a payment for entry.", | ||||
|     "paypalaccepted": "PayPal payments accepted", | ||||
|     "reload": "Reload", | ||||
|     "removefromfavourites": "Unstar this course", | ||||
|     "search": "Search", | ||||
|     "searchcourses": "Search courses", | ||||
|     "searchcoursesadvice": "You can use the search courses button to find courses to access as a  guest or enrol yourself in courses that allow it.", | ||||
|     "selfenrolment": "Self enrolment", | ||||
|     "sendpaymentbutton": "Send payment via PayPal", | ||||
|     "show": "Restore to view", | ||||
|     "totalcoursesearchresults": "Total courses: {{$a}}" | ||||
| } | ||||
							
								
								
									
										20
									
								
								src/app/core/courses/pages/home/home.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/app/core/courses/pages/home/home.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| <ion-header> | ||||
|     <ion-toolbar> | ||||
|         <ion-buttons slot="start"> | ||||
|             <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button> | ||||
|         </ion-buttons> | ||||
| 
 | ||||
|         <ion-title> | ||||
|             <core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0"></core-format-text> | ||||
|             <img src="assets/img/login_logo.png" class="core-header-logo" [alt]="siteName"> | ||||
|         </ion-title> | ||||
| 
 | ||||
|         <ion-buttons slot="end"> | ||||
|             <!-- @todo --> | ||||
|         </ion-buttons> | ||||
|     </ion-toolbar> | ||||
| </ion-header> | ||||
| <ion-content> | ||||
|     <!-- @todo --> | ||||
|     Home page. | ||||
| </ion-content> | ||||
							
								
								
									
										36
									
								
								src/app/core/courses/pages/home/home.page.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/app/core/courses/pages/home/home.page.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| // (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'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that displays the Home. | ||||
|  */ | ||||
| @Component({ | ||||
|     selector: 'page-core-courses-home', | ||||
|     templateUrl: 'home.html', | ||||
|     styleUrls: ['home.scss'], | ||||
| }) | ||||
| export class CoreCoursesHomePage implements OnInit { | ||||
| 
 | ||||
|     siteName = 'Hello world'; | ||||
| 
 | ||||
|     /** | ||||
|      * Initialize the component. | ||||
|      */ | ||||
|     ngOnInit(): void { | ||||
|         // @todo
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/app/core/courses/pages/home/home.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/app/core/courses/pages/home/home.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| $core-dashboard-logo: false !default; | ||||
| 
 | ||||
| @if $core-dashboard-logo { | ||||
|     .toolbar-title-default.md .title-default .core-header-logo { | ||||
|         max-height: $toolbar-md-height - 24; | ||||
|     } | ||||
| 
 | ||||
|     .toolbar-title-default.ios .title-default .core-header-logo { | ||||
|         max-height: $toolbar-ios-height - 24; | ||||
|     } | ||||
| 
 | ||||
|     .toolbar-title-default .title-default core-format-text { | ||||
|         display: none; | ||||
|     } | ||||
| } @else { | ||||
|     .toolbar-title-default .core-header-logo { | ||||
|         display: none; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| ion-badge.core-course-download-courses-progress { | ||||
|     display: block; | ||||
|     // @include float(start); | ||||
|     // @include margin(12px, 12px, null, 12px); | ||||
| } | ||||
| 
 | ||||
| @ -17,15 +17,25 @@ import { RouterModule, Routes } from '@angular/router'; | ||||
| 
 | ||||
| import { CoreMainMenuPage } from './pages/menu/menu.page'; | ||||
| import { CoreMainMenuMorePage } from './pages/more/more.page'; | ||||
| import { CoreCoursesHomePage } from '../courses/pages/home/home.page'; | ||||
| 
 | ||||
| const routes: Routes = [ | ||||
|     { | ||||
|         path: '', | ||||
|         component: CoreMainMenuPage, | ||||
|         children: [ | ||||
|             { | ||||
|                 path: 'home', // @todo: Add this route dynamically.
 | ||||
|                 component: CoreCoursesHomePage, | ||||
|             }, | ||||
|             { | ||||
|                 path: 'more', | ||||
|                 component: CoreMainMenuMorePage, | ||||
|                 children: [ | ||||
|                     { | ||||
|                         path: '', | ||||
|                         component: CoreMainMenuMorePage, | ||||
|                     }, | ||||
|                 ], | ||||
|             }, | ||||
|         ], | ||||
|     }, | ||||
|  | ||||
| @ -1,13 +1,17 @@ | ||||
| <ion-tabs #mainTabs [hidden]="!showTabs"> <!-- [loaded]="loaded" --> | ||||
|     <ion-tab-bar slot="bottom"> | ||||
|         <ion-tab-button tab="redirect" [disabled]="true" [hidden]="true"></ion-tab-button> <!-- [show]="false" [root]="redirectPage" [rootParams]="redirectParams" --> | ||||
| <ion-tabs #mainTabs [hidden]="!showTabs"> | ||||
| 
 | ||||
|         <ion-tab-button *ngFor="let tab of tabs" [tab]="tab.page" [disabled]="tab.hide" layout="label-hide"> <!-- [rootParams]="tab.pageParams" [tabBadge]="tab.badge" class="{{tab.class}}" [enabled]="!tab.hide" [show]="!tab.hide" --> | ||||
|     <ion-tab-bar slot="bottom"> | ||||
|         <ion-spinner *ngIf="!loaded"></ion-spinner> | ||||
| 
 | ||||
|         <ion-tab-button tab="redirect" [disabled]="true" [hidden]="true"></ion-tab-button> <!-- [root]="redirectPage" [rootParams]="redirectParams" --> | ||||
| 
 | ||||
|         <ion-tab-button (ionTabButtonClick)="tabClicked($event, tab.page)" [hidden]="!loaded && tab.hide" *ngFor="let tab of tabs" [tab]="tab.page" [disabled]="tab.hide" layout="label-hide"  class="{{tab.class}}"> | ||||
|             <core-icon [name]="tab.icon"></core-icon> | ||||
|             <ion-label>{{ tab.title | translate }}</ion-label> | ||||
|             <ion-badge *ngIf="tab.badge">{{ tab.badge }}</ion-badge> | ||||
|         </ion-tab-button> | ||||
| 
 | ||||
|         <ion-tab-button tab="more" layout="label-hide"> | ||||
|         <ion-tab-button (ionTabButtonClick)="tabClicked($event, 'more')" [hidden]="!loaded" tab="more" layout="label-hide"> | ||||
|             <core-icon name="fa-bars"></core-icon> | ||||
|             <ion-label>{{ 'core.more' | translate }}</ion-label> | ||||
|         </ion-tab-button> | ||||
|  | ||||
| @ -13,8 +13,8 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Component, OnInit, OnDestroy, ViewChild, ChangeDetectorRef } from '@angular/core'; | ||||
| import { ActivatedRoute, Params } from '@angular/router'; | ||||
| import { NavController } from '@ionic/angular'; | ||||
| import { ActivatedRoute, Params, Router } from '@angular/router'; | ||||
| import { NavController, IonTabs } from '@ionic/angular'; | ||||
| import { Subscription } from 'rxjs'; | ||||
| 
 | ||||
| import { CoreApp } from '@services/app'; | ||||
| @ -22,6 +22,9 @@ import { CoreSites } from '@services/sites'; | ||||
| import { CoreEvents, CoreEventObserver, CoreEventLoadPageMainMenuData } from '@singletons/events'; | ||||
| import { CoreMainMenu } from '../../services/mainmenu'; | ||||
| import { CoreMainMenuDelegate, CoreMainMenuHandlerToDisplay } from '../../services/delegate'; | ||||
| import { CoreUtils } from '@/app/services/utils/utils'; | ||||
| import { CoreDomUtils } from '@/app/services/utils/dom'; | ||||
| import { Translate } from '@/app/singletons/core.singletons'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that displays the main menu of the app. | ||||
| @ -48,13 +51,14 @@ export class CoreMainMenuPage implements OnInit, OnDestroy { | ||||
|     protected mainMenuId: number; | ||||
|     protected keyboardObserver?: CoreEventObserver; | ||||
| 
 | ||||
|     @ViewChild('mainTabs') mainTabs?: any; // CoreIonTabsComponent;
 | ||||
|     @ViewChild('mainTabs') mainTabs?: IonTabs; | ||||
| 
 | ||||
|     constructor( | ||||
|         protected route: ActivatedRoute, | ||||
|         protected navCtrl: NavController, | ||||
|         protected menuDelegate: CoreMainMenuDelegate, | ||||
|         protected changeDetector: ChangeDetectorRef, | ||||
|         protected router: Router, | ||||
|     ) { | ||||
|         this.mainMenuId = CoreApp.instance.getMainMenuId(); | ||||
|     } | ||||
| @ -154,28 +158,19 @@ export class CoreMainMenuPage implements OnInit, OnDestroy { | ||||
|                 newTabs.push(tab || handler); | ||||
|             } | ||||
| 
 | ||||
|             // Maintain tab in phantom mode in case is not visible.
 | ||||
|             const selectedTab = this.mainTabs?.getSelected(); | ||||
|             if (selectedTab) { | ||||
|                 const oldTab = this.tabs.find((tab) => tab.page == selectedTab.root && tab.icon == selectedTab.tabIcon); | ||||
| 
 | ||||
|                 if (oldTab) { | ||||
|                     // Check if the selected handler is visible.
 | ||||
|                     const isVisible = newTabs.some((newTab) => oldTab.title == newTab.title && oldTab.icon == newTab.icon); | ||||
| 
 | ||||
|                     if (!isVisible) { | ||||
|                         oldTab.hide = true; | ||||
|                         newTabs.push(oldTab); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             this.tabs = newTabs; | ||||
| 
 | ||||
|             // Sort them by priority so new handlers are in the right position.
 | ||||
|             this.tabs.sort((a, b) => (b.priority || 0) - (a.priority || 0)); | ||||
| 
 | ||||
|             this.loaded = this.menuDelegate.areHandlersLoaded(); | ||||
| 
 | ||||
|             if (this.loaded && this.mainTabs && !this.mainTabs.getSelected()) { | ||||
|                 // Select the first tab.
 | ||||
|                 setTimeout(() => { | ||||
|                     this.mainTabs!.select(this.tabs[0]?.page || 'more'); | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (this.urlToOpen) { | ||||
| @ -194,21 +189,18 @@ export class CoreMainMenuPage implements OnInit, OnDestroy { | ||||
|         const i = this.tabs.findIndex((tab) => tab.page == data.redirectPage); | ||||
| 
 | ||||
|         if (i >= 0) { | ||||
|             // Tab found. Set the params.
 | ||||
|             this.tabs[i].pageParams = Object.assign({}, data.redirectParams); | ||||
|             // Tab found. Open it with the params.
 | ||||
|             this.navCtrl.navigateForward(data.redirectPage, { | ||||
|                 queryParams: data.redirectParams, | ||||
|                 animated: false, | ||||
|             }); | ||||
|         } else { | ||||
|             // Tab not found, use a phantom tab.
 | ||||
|             this.redirectPage = data.redirectPage; | ||||
|             this.redirectParams = data.redirectParams; | ||||
|             // @todo
 | ||||
|         } | ||||
| 
 | ||||
|         // Force change detection, otherwise sometimes the tab was selected before the params were applied.
 | ||||
|         this.changeDetector.detectChanges(); | ||||
| 
 | ||||
|         setTimeout(() => { | ||||
|             // Let the tab load the params before navigating.
 | ||||
|             this.mainTabs?.selectTabRootByIndex(i + 1); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -222,4 +214,42 @@ export class CoreMainMenuPage implements OnInit, OnDestroy { | ||||
|         this.keyboardObserver?.off(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Tab clicked. | ||||
|      * | ||||
|      * @param e Event. | ||||
|      * @param page Page of the tab. | ||||
|      */ | ||||
|     async tabClicked(e: Event, page: string): Promise<void> { | ||||
|         if (this.mainTabs?.getSelected() != page) { | ||||
|             // Just change the tab.
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Current tab was clicked. Check if user is already at root level.
 | ||||
|         if (this.router.url == '/mainmenu/' + page) { | ||||
|             // Already at root level, nothing to do.
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Ask the user if he wants to go back to the root page of the tab.
 | ||||
|         e.preventDefault(); | ||||
|         e.stopPropagation(); | ||||
| 
 | ||||
|         try { | ||||
|             const tab = this.tabs.find((tab) => tab.page == page); | ||||
| 
 | ||||
|             if (tab?.title) { | ||||
|                 await CoreDomUtils.instance.showConfirm(Translate.instance.instant('core.confirmgotabroot', { name: tab.title })); | ||||
|             } else { | ||||
|                 await CoreDomUtils.instance.showConfirm(Translate.instance.instant('core.confirmgotabrootdefault')); | ||||
|             } | ||||
| 
 | ||||
|             // User confirmed, go to root.
 | ||||
|             this.mainTabs?.select(page); | ||||
|         } catch (error) { | ||||
|             // User canceled.
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -163,6 +163,8 @@ export class CoreMainMenuDelegate extends CoreDelegate { | ||||
| 
 | ||||
|             data.name = name; | ||||
|             data.priority = handler.priority; | ||||
| 
 | ||||
|             displayData.push(data); | ||||
|         } | ||||
| 
 | ||||
|         // Sort them by priority.
 | ||||
|  | ||||
| @ -303,6 +303,43 @@ | ||||
|     "core.back": "Back", | ||||
|     "core.browser": "Browser", | ||||
|     "core.copiedtoclipboard": "Text copied to clipboard", | ||||
|     "core.courses.addtofavourites": "Star this course", | ||||
|     "core.courses.allowguests": "This course allows guest users to enter", | ||||
|     "core.courses.availablecourses": "Available courses", | ||||
|     "core.courses.cannotretrievemorecategories": "Categories deeper than level {{$a}} cannot be retrieved.", | ||||
|     "core.courses.categories": "Course categories", | ||||
|     "core.courses.confirmselfenrol": "Are you sure you want to enrol yourself in this course?", | ||||
|     "core.courses.courses": "Courses", | ||||
|     "core.courses.downloadcourses": "Download courses", | ||||
|     "core.courses.enrolme": "Enrol me", | ||||
|     "core.courses.errorloadcategories": "An error occurred while loading categories.", | ||||
|     "core.courses.errorloadcourses": "An error occurred while loading courses.", | ||||
|     "core.courses.errorloadplugins": "The plugins required by this course could not be loaded correctly. Please reload the app to try again.", | ||||
|     "core.courses.errorsearching": "An error occurred while searching.", | ||||
|     "core.courses.errorselfenrol": "An error occurred while self enrolling.", | ||||
|     "core.courses.filtermycourses": "Filter my courses", | ||||
|     "core.courses.frontpage": "Front page", | ||||
|     "core.courses.hidecourse": "Remove from view", | ||||
|     "core.courses.ignore": "Ignore", | ||||
|     "core.courses.mycourses": "My courses", | ||||
|     "core.courses.mymoodle": "Dashboard", | ||||
|     "core.courses.nocourses": "No course information to show.", | ||||
|     "core.courses.nocoursesyet": "No courses in this category", | ||||
|     "core.courses.nosearchresults": "No results", | ||||
|     "core.courses.notenroled": "You are not enrolled in this course", | ||||
|     "core.courses.notenrollable": "You cannot enrol yourself in this course.", | ||||
|     "core.courses.password": "Enrolment key", | ||||
|     "core.courses.paymentrequired": "This course requires a payment for entry.", | ||||
|     "core.courses.paypalaccepted": "PayPal payments accepted", | ||||
|     "core.courses.reload": "Reload", | ||||
|     "core.courses.removefromfavourites": "Unstar this course", | ||||
|     "core.courses.search": "Search", | ||||
|     "core.courses.searchcourses": "Search courses", | ||||
|     "core.courses.searchcoursesadvice": "You can use the search courses button to find courses to access as a  guest or enrol yourself in courses that allow it.", | ||||
|     "core.courses.selfenrolment": "Self enrolment", | ||||
|     "core.courses.sendpaymentbutton": "Send payment via PayPal", | ||||
|     "core.courses.show": "Restore to view", | ||||
|     "core.courses.totalcoursesearchresults": "Total courses: {{$a}}", | ||||
|     "core.login.yourenteredsite": "Connect to your site", | ||||
|     "core.mainmenu.changesite": "Change site", | ||||
|     "core.mainmenu.help": "Help", | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user