forked from EVOgeek/Vmeda.Online
		
	MOBILE-3594 sitehome: Add sitehome tab to home page
This commit is contained in:
		
							parent
							
								
									cc5378aee7
								
							
						
					
					
						commit
						9b41458104
					
				| @ -20,6 +20,7 @@ import { CoreEmulatorModule } from './emulator/emulator.module'; | |||||||
| import { CoreFileUploaderInitModule } from './fileuploader/fileuploader-init.module'; | import { CoreFileUploaderInitModule } from './fileuploader/fileuploader-init.module'; | ||||||
| import { CoreLoginModule } from './login/login.module'; | import { CoreLoginModule } from './login/login.module'; | ||||||
| import { CoreSettingsInitModule } from './settings/settings-init.module'; | import { CoreSettingsInitModule } from './settings/settings-init.module'; | ||||||
|  | import { CoreSiteHomeInitModule } from './sitehome/sitehome-init.module'; | ||||||
| 
 | 
 | ||||||
| @NgModule({ | @NgModule({ | ||||||
|     imports: [ |     imports: [ | ||||||
| @ -29,6 +30,7 @@ import { CoreSettingsInitModule } from './settings/settings-init.module'; | |||||||
|         CoreCoursesModule, |         CoreCoursesModule, | ||||||
|         CoreSettingsInitModule, |         CoreSettingsInitModule, | ||||||
|         CoreFileUploaderInitModule, |         CoreFileUploaderInitModule, | ||||||
|  |         CoreSiteHomeInitModule, | ||||||
|     ], |     ], | ||||||
| }) | }) | ||||||
| export class CoreFeaturesModule {} | export class CoreFeaturesModule {} | ||||||
|  | |||||||
| @ -17,8 +17,8 @@ | |||||||
|             </ion-button> |             </ion-button> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|         <ion-list class="core-search-history" [hidden]="!historyShown"> |         <ion-list class="core-search-history" [hidden]="!historyShown"> | ||||||
|             <ion-item class="ion-text-wrap" *ngFor="let item of history" |             <ion-item button class="ion-text-wrap" *ngFor="let item of history" | ||||||
|                 (click)="historyClicked($event, item.searchedtext)" class="core-clickable" tabindex="1"> |                 (click)="historyClicked($event, item.searchedtext)" tabindex="1" detail> | ||||||
|                 <ion-icon name="fa-history" slot="start"> |                 <ion-icon name="fa-history" slot="start"> | ||||||
|                 </ion-icon> |                 </ion-icon> | ||||||
|                 {{item.searchedtext}} |                 {{item.searchedtext}} | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ | |||||||
|             <ion-item *ngIf="isIOS" |             <ion-item *ngIf="isIOS" | ||||||
|                 (click)="openHandler('CoreSharedFilesListPage', {manage: true, siteId: siteId, hideSitePicker: true})" |                 (click)="openHandler('CoreSharedFilesListPage', {manage: true, siteId: siteId, hideSitePicker: true})" | ||||||
|                 [title]="'core.sharedfiles.sharedfiles' | translate" |                 [title]="'core.sharedfiles.sharedfiles' | translate" | ||||||
|                 [class.core-split-item-selected]="'CoreSharedFilesListPage' == selectedPage" details> |                 [class.core-split-item-selected]="'CoreSharedFilesListPage' == selectedPage" detail> | ||||||
|                 <ion-icon name="fas-folder" slot="start"></ion-icon> |                 <ion-icon name="fas-folder" slot="start"></ion-icon> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <h2>{{ 'core.sharedfiles.sharedfiles' | translate }}</h2> |                     <h2>{{ 'core.sharedfiles.sharedfiles' | translate }}</h2> | ||||||
| @ -37,7 +37,7 @@ | |||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <ion-item *ngFor="let handler of handlers" [ngClass]="['core-settings-handler', handler.class]" |             <ion-item *ngFor="let handler of handlers" [ngClass]="['core-settings-handler', handler.class]" | ||||||
|                 (click)="openHandler(handler.page, handler.params)" [title]="handler.title | translate" details |                 (click)="openHandler(handler.page, handler.params)" [title]="handler.title | translate" detail | ||||||
|                 [class.core-split-item-selected]="handler.page == selectedPage"> |                 [class.core-split-item-selected]="handler.page == selectedPage"> | ||||||
|                 <ion-icon [name]="handler.icon" slot="start" *ngIf="handler.icon"> |                 <ion-icon [name]="handler.icon" slot="start" *ngIf="handler.icon"> | ||||||
|                 </ion-icon> |                 </ion-icon> | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								src/core/features/sitehome/lang/en.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/core/features/sitehome/lang/en.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | { | ||||||
|  |     "sitehome": "Site home", | ||||||
|  |     "sitenews": "Site announcements" | ||||||
|  | } | ||||||
							
								
								
									
										85
									
								
								src/core/features/sitehome/pages/index/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/core/features/sitehome/pages/index/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,85 @@ | |||||||
|  | <ion-content> | ||||||
|  |     <ion-refresher slot="fixed" [disabled]="!dataLoaded" | ||||||
|  |         (ionRefresh)="doRefresh($event)"> | ||||||
|  |         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|  |     </ion-refresher> | ||||||
|  |     <!-- @todo  <core-block-course-blocks [courseId]="siteHomeId" [downloadEnabled]="downloadEnabled">--> | ||||||
|  |         <core-loading [hideUntil]="dataLoaded"> | ||||||
|  |                 <ion-list> | ||||||
|  |                     <!-- Site home main contents. --> | ||||||
|  |                     <!-- @todo <ng-container *ngIf="section && section.hasContent"> | ||||||
|  |                         <ion-item class="ion-text-wrap" *ngIf="section.summary"> | ||||||
|  |                             <core-format-text [text]="section.summary" contextLevel="course" [contextInstanceId]="siteHomeId"></core-format-text> | ||||||
|  |                         </ion-item> | ||||||
|  | 
 | ||||||
|  |                         <core-course-module *ngFor="let module of section.modules" [module]="module" [courseId]="siteHomeId" [downloadEnabled]="downloadEnabled" [section]="section"></core-course-module> | ||||||
|  |                     </ng-container> --> | ||||||
|  | 
 | ||||||
|  |                     <!-- Site home items: news, categories, courses, etc. --> | ||||||
|  |                     <ng-container *ngIf="items.length > 0"> | ||||||
|  |                         <ion-item-divider *ngIf="section && section!.hasContent"></ion-item-divider> | ||||||
|  |                         <ng-container *ngFor="let item of items"> | ||||||
|  |                             <ng-container [ngSwitch]="item"> | ||||||
|  |                                 <ng-container *ngSwitchCase="'LIST_OF_COURSE'"> | ||||||
|  |                                     <ng-template *ngTemplateOutlet="allCourseList"></ng-template> | ||||||
|  |                                 </ng-container> | ||||||
|  |                                 <ng-container *ngSwitchCase="'LIST_OF_CATEGORIES'"> | ||||||
|  |                                     <ng-template *ngTemplateOutlet="categories"></ng-template> | ||||||
|  |                                 </ng-container> | ||||||
|  |                                 <ng-container *ngSwitchCase="'COURSE_SEARCH_BOX'"> | ||||||
|  |                                     <ng-template *ngTemplateOutlet="courseSearch"></ng-template> | ||||||
|  |                                 </ng-container> | ||||||
|  |                                 <ng-container *ngSwitchCase="'ENROLLED_COURSES'"> | ||||||
|  |                                     <ng-template *ngTemplateOutlet="enrolledCourseList"></ng-template> | ||||||
|  |                                 </ng-container> | ||||||
|  |                                 <ng-container *ngSwitchCase="'NEWS_ITEMS'"> | ||||||
|  |                                     <ng-template *ngTemplateOutlet="news"></ng-template> | ||||||
|  |                                 </ng-container> | ||||||
|  |                             </ng-container> | ||||||
|  |                         </ng-container> | ||||||
|  |                     </ng-container> | ||||||
|  |                 </ion-list> | ||||||
|  |             <core-empty-box *ngIf="!hasContent" icon="qr-scanner" [message]="'core.course.nocontentavailable' | translate"></core-empty-box> | ||||||
|  |         </core-loading> | ||||||
|  |     <!-- @todo </core-block-course-blocks> --> | ||||||
|  | </ion-content> | ||||||
|  | 
 | ||||||
|  | <ng-template #allCourseList> | ||||||
|  |     <ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/courses/all" detail> | ||||||
|  |         <ion-icon name="fas-graduation-cap" fixed-width slot="start"></ion-icon> | ||||||
|  |         <ion-label> | ||||||
|  |             <h2>{{ 'core.courses.availablecourses' | translate}}</h2> | ||||||
|  |         </ion-label> | ||||||
|  |     </ion-item> | ||||||
|  | </ng-template> | ||||||
|  | 
 | ||||||
|  | <ng-template #news> | ||||||
|  |     <ion-item> | ||||||
|  |         <ion-label>News (TODO)</ion-label> | ||||||
|  |     </ion-item> | ||||||
|  |     <!-- @todo <core-course-module class="core-sitehome-news" *ngIf="show" [module]="module" [courseId]="siteHomeId"></core-course-module> --> | ||||||
|  | </ng-template> | ||||||
|  | 
 | ||||||
|  | <ng-template #categories> | ||||||
|  |     <ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/courses/categories" detail> | ||||||
|  |         <ion-icon name="folder" slot="start"></ion-icon> | ||||||
|  |         <ion-label> | ||||||
|  |             <h2>{{ 'core.courses.categories' | translate}}</h2> | ||||||
|  |         </ion-label> | ||||||
|  |     </ion-item> | ||||||
|  | </ng-template> | ||||||
|  | 
 | ||||||
|  | <ng-template #enrolledCourseList> | ||||||
|  |     <ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/courses/my" detail> | ||||||
|  |         <ion-icon name="fa-graduation-cap" fixed-width slot="start"> | ||||||
|  |         </ion-icon> | ||||||
|  |         <ion-label><h2>{{ 'core.courses.mycourses' | translate}}</h2></ion-label> | ||||||
|  |     </ion-item> | ||||||
|  | </ng-template> | ||||||
|  | 
 | ||||||
|  | <ng-template #courseSearch> | ||||||
|  |     <ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/courses/search" detail> | ||||||
|  |         <ion-icon name="search" slot="start"></ion-icon> | ||||||
|  |         <ion-label><h2>{{ 'core.courses.searchcourses' | translate}}</h2></ion-label> | ||||||
|  |     </ion-item> | ||||||
|  | </ng-template> | ||||||
							
								
								
									
										47
									
								
								src/core/features/sitehome/pages/index/index.page.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/core/features/sitehome/pages/index/index.page.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | // (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 { CommonModule } from '@angular/common'; | ||||||
|  | import { RouterModule, Routes } from '@angular/router'; | ||||||
|  | import { IonicModule } from '@ionic/angular'; | ||||||
|  | import { TranslateModule } from '@ngx-translate/core'; | ||||||
|  | 
 | ||||||
|  | import { CoreDirectivesModule } from '@directives/directives.module'; | ||||||
|  | import { CoreComponentsModule } from '@components/components.module'; | ||||||
|  | 
 | ||||||
|  | import { CoreSiteHomeIndexPage } from './index.page'; | ||||||
|  | 
 | ||||||
|  | const routes: Routes = [ | ||||||
|  |     { | ||||||
|  |         path: '', | ||||||
|  |         component: CoreSiteHomeIndexPage, | ||||||
|  |     }, | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     imports: [ | ||||||
|  |         RouterModule.forChild(routes), | ||||||
|  |         CommonModule, | ||||||
|  |         IonicModule, | ||||||
|  |         TranslateModule.forChild(), | ||||||
|  |         CoreDirectivesModule, | ||||||
|  |         CoreComponentsModule, | ||||||
|  |     ], | ||||||
|  |     declarations: [ | ||||||
|  |         CoreSiteHomeIndexPage, | ||||||
|  |     ], | ||||||
|  |     exports: [RouterModule], | ||||||
|  | }) | ||||||
|  | export class CoreSiteHomeIndexPageModule {} | ||||||
							
								
								
									
										155
									
								
								src/core/features/sitehome/pages/index/index.page.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/core/features/sitehome/pages/index/index.page.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,155 @@ | |||||||
|  | // (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 { ActivatedRoute } from '@angular/router'; | ||||||
|  | import { IonRefresher } from '@ionic/angular'; | ||||||
|  | 
 | ||||||
|  | import { CoreSite, CoreSiteConfig } from '@classes/site'; | ||||||
|  | import { CoreCourse, CoreCourseSection } from '@features/course/services/course'; | ||||||
|  | import { CoreDomUtils } from '@services/utils/dom'; | ||||||
|  | import { CoreSites } from '@services/sites'; | ||||||
|  | import { CoreSiteHome } from '@features/sitehome/services/sitehome'; | ||||||
|  | // import { CoreCourseHelperProvider } from '@features/course/services/helper';
 | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Page that displays site home index. | ||||||
|  |  */ | ||||||
|  | @Component({ | ||||||
|  |     selector: 'page-core-sitehome-index', | ||||||
|  |     templateUrl: 'index.html', | ||||||
|  | }) | ||||||
|  | export class CoreSiteHomeIndexPage implements OnInit { | ||||||
|  | 
 | ||||||
|  |     // @todo @Input() downloadEnabled: boolean;
 | ||||||
|  |     // @todo  @ViewChild(CoreBlockCourseBlocksComponent) courseBlocksComponent: CoreBlockCourseBlocksComponent;
 | ||||||
|  | 
 | ||||||
|  |     dataLoaded = false; | ||||||
|  |     section?: CoreCourseSection & { | ||||||
|  |         hasContent?: boolean; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     hasContent = false; | ||||||
|  |     items: string[] = []; | ||||||
|  |     siteHomeId?: number; | ||||||
|  |     currentSite?: CoreSite; | ||||||
|  | 
 | ||||||
|  |     constructor( | ||||||
|  |         protected route: ActivatedRoute, | ||||||
|  |         // @todo private prefetchDelegate: CoreCourseModulePrefetchDelegate,
 | ||||||
|  |     ) { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Page being initialized. | ||||||
|  |      */ | ||||||
|  |     ngOnInit(): void { | ||||||
|  |         const navParams = this.route.snapshot.queryParams; | ||||||
|  | 
 | ||||||
|  |         this.currentSite = CoreSites.instance.getCurrentSite()!; | ||||||
|  |         this.siteHomeId = this.currentSite.getSiteHomeId(); | ||||||
|  | 
 | ||||||
|  |         const module = navParams['module']; | ||||||
|  |         if (module) { | ||||||
|  |             // @todo const modParams = navParams.get('modParams');
 | ||||||
|  |             // courseHelper.openModule(module, this.siteHomeId, undefined, modParams);
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.loadContent().finally(() => { | ||||||
|  |             this.dataLoaded = true; | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Convenience function to fetch the data. | ||||||
|  |      * | ||||||
|  |      * @return Promise resolved when done. | ||||||
|  |      */ | ||||||
|  |     protected async loadContent(): Promise<void> { | ||||||
|  |         this.hasContent = false; | ||||||
|  | 
 | ||||||
|  |         const config = this.currentSite!.getStoredConfig() || { numsections: 1, frontpageloggedin: undefined }; | ||||||
|  | 
 | ||||||
|  |         this.items = await CoreSiteHome.instance.getFrontPageItems(config.frontpageloggedin); | ||||||
|  |         this.hasContent = this.items.length > 0; | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             const sections = await CoreCourse.instance.getSections(this.siteHomeId!, false, true); | ||||||
|  | 
 | ||||||
|  |             // Check "Include a topic section" setting from numsections.
 | ||||||
|  |             this.section = config.numsections ? sections.find((section) => section.section == 1) : undefined; | ||||||
|  |             if (this.section) { | ||||||
|  |                 this.section.hasContent = false; | ||||||
|  |                 /* @todo this.section.hasContent = this.courseHelper.sectionHasContent(this.section); | ||||||
|  |                 this.hasContent = this.courseHelper.addHandlerDataForModules( | ||||||
|  |                     [this.section], | ||||||
|  |                     this.siteHomeId, | ||||||
|  |                     undefined, | ||||||
|  |                     undefined, | ||||||
|  |                     true, | ||||||
|  |                 ) || this.hasContent;*/ | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Add log in Moodle.
 | ||||||
|  |             CoreCourse.instance.logView( | ||||||
|  |                 this.siteHomeId!, | ||||||
|  |                 undefined, | ||||||
|  |                 undefined, | ||||||
|  |                 this.currentSite!.getInfo()?.sitename, | ||||||
|  |             ).catch(() => { | ||||||
|  |                 // Ignore errors.
 | ||||||
|  |             }); | ||||||
|  |         } catch (error) { | ||||||
|  |             CoreDomUtils.instance.showErrorModalDefault(error, 'core.course.couldnotloadsectioncontent', true); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Refresh the data. | ||||||
|  |      * | ||||||
|  |      * @param refresher Refresher. | ||||||
|  |      */ | ||||||
|  |     doRefresh(refresher?: CustomEvent<IonRefresher>): void { | ||||||
|  |         const promises: Promise<unknown>[] = []; | ||||||
|  | 
 | ||||||
|  |         promises.push(CoreCourse.instance.invalidateSections(this.siteHomeId!)); | ||||||
|  |         promises.push(this.currentSite!.invalidateConfig().then(async () => { | ||||||
|  |             // Config invalidated, fetch it again.
 | ||||||
|  |             const config: CoreSiteConfig = await this.currentSite!.getConfig(); | ||||||
|  |             this.currentSite!.setConfig(config); | ||||||
|  | 
 | ||||||
|  |             return; | ||||||
|  |         })); | ||||||
|  | 
 | ||||||
|  |         if (this.section && this.section.modules) { | ||||||
|  |             // Invalidate modules prefetch data.
 | ||||||
|  |             //  @todo promises.push(this.prefetchDelegate.invalidateModules(this.section.modules, this.siteHomeId));
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // @todo promises.push(this.courseBlocksComponent.invalidateBlocks());
 | ||||||
|  | 
 | ||||||
|  |         Promise.all(promises).finally(async () => { | ||||||
|  |             const p2: Promise<unknown>[] = []; | ||||||
|  | 
 | ||||||
|  |             p2.push(this.loadContent()); | ||||||
|  |             // @todo  p2.push(this.courseBlocksComponent.loadContent());
 | ||||||
|  | 
 | ||||||
|  |             await Promise.all(p2).finally(() => { | ||||||
|  |                 refresher?.detail.complete(); | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										75
									
								
								src/core/features/sitehome/services/handlers/index.link.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/core/features/sitehome/services/handlers/index.link.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | |||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { Params } from '@angular/router'; | ||||||
|  | import { CoreSites } from '@services/sites'; | ||||||
|  | import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base-handler'; | ||||||
|  | import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks.helper'; | ||||||
|  | import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks.delegate'; | ||||||
|  | import { CoreSiteHome } from '../sitehome'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to treat links to site home index. | ||||||
|  |  */ | ||||||
|  | Injectable(); | ||||||
|  | export class CoreSiteHomeIndexLinkHandler extends CoreContentLinksHandlerBase { | ||||||
|  | 
 | ||||||
|  |     name = 'CoreSiteHomeIndexLinkHandler'; | ||||||
|  |     featureName = 'CoreMainMenuDelegate_CoreSiteHome'; | ||||||
|  |     pattern = /\/course\/view\.php.*([?&]id=\d+)/; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the list of actions for a link (url). | ||||||
|  |      * | ||||||
|  |      * @param siteIds List of sites the URL belongs to. | ||||||
|  |      * @param url The URL to treat. | ||||||
|  |      * @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} | ||||||
|  |      * @param courseId Course ID related to the URL. Optional but recommended. | ||||||
|  |      * @return List of (or promise resolved with list of) actions. | ||||||
|  |      */ | ||||||
|  |     getActions(): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> { | ||||||
|  |         return [{ | ||||||
|  |             action: (siteId: string): void => { | ||||||
|  |                 CoreContentLinksHelper.instance.goInSite('sitehome', [], siteId); | ||||||
|  |             }, | ||||||
|  |         }]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the handler is enabled for a certain site (site + user) and a URL. | ||||||
|  |      * If not defined, defaults to true. | ||||||
|  |      * | ||||||
|  |      * @param siteId The site ID. | ||||||
|  |      * @param url The URL to treat. | ||||||
|  |      * @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} | ||||||
|  |      * @param courseId Course ID related to the URL. Optional but recommended. | ||||||
|  |      * @return Whether the handler is enabled for the URL and site. | ||||||
|  |      */ | ||||||
|  |     async isEnabled(siteId: string, url: string, params: Params, courseId?: number): Promise<boolean> { | ||||||
|  |         courseId = parseInt(params.id, 10); | ||||||
|  |         if (!courseId) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const site = await CoreSites.instance.getSite(siteId); | ||||||
|  |         if (courseId != site.getSiteHomeId()) { | ||||||
|  |             // The course is not site home.
 | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return CoreSiteHome.instance.isAvailable(siteId).then(() => true).catch(() => false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,66 @@ | |||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreSites } from '@services/sites'; | ||||||
|  | import { CoreHomeHandler, CoreHomeHandlerToDisplay } from '@features/mainmenu/services/home.delegate'; | ||||||
|  | import { CoreSiteHome } from '../sitehome'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to add Home into main menu. | ||||||
|  |  */ | ||||||
|  | Injectable(); | ||||||
|  | export class CoreSiteHomeHomeHandler implements CoreHomeHandler { | ||||||
|  | 
 | ||||||
|  |     name = 'CoreSiteHomeDashboard'; | ||||||
|  |     priority = 1200; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 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. | ||||||
|  |      */ | ||||||
|  |     async isEnabledForSite(siteId?: string): Promise<boolean> { | ||||||
|  |         return CoreSiteHome.instance.isAvailable(siteId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Returns the data needed to render the handler. | ||||||
|  |      * | ||||||
|  |      * @return Data needed to render the handler. | ||||||
|  |      */ | ||||||
|  |     getDisplayData(): CoreHomeHandlerToDisplay { | ||||||
|  |         const site = CoreSites.instance.getCurrentSite(); | ||||||
|  |         const displaySiteHome = site?.getInfo() && site?.getInfo()?.userhomepage === 0; | ||||||
|  | 
 | ||||||
|  |         return { | ||||||
|  |             title: 'core.sitehome.sitehome', | ||||||
|  |             page: 'sitehome', | ||||||
|  |             class: 'core-sitehome-dashboard-handler', | ||||||
|  |             icon: 'fas-home', | ||||||
|  |             selectPriority: displaySiteHome ? 1100 : 900, | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										196
									
								
								src/core/features/sitehome/services/sitehome.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								src/core/features/sitehome/services/sitehome.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,196 @@ | |||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | 
 | ||||||
|  | import { CoreSites } from '@services/sites'; | ||||||
|  | import { CoreSite, CoreSiteWSPreSets } from '@classes/site'; | ||||||
|  | import { makeSingleton } from '@singletons/core.singletons'; | ||||||
|  | import { CoreCourse, CoreCourseSection } from '../../course/services/course'; | ||||||
|  | import { CoreCourses } from '../../courses/services/courses'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Items with index 1 and 3 were removed on 2.5 and not being supported in the app. | ||||||
|  |  */ | ||||||
|  | export enum FrontPageItemNames { | ||||||
|  |     NEWS_ITEMS = 0, | ||||||
|  |     LIST_OF_CATEGORIES = 2, | ||||||
|  |     COMBO_LIST = 3, | ||||||
|  |     ENROLLED_COURSES = 5, | ||||||
|  |     LIST_OF_COURSE = 6, | ||||||
|  |     COURSE_SEARCH_BOX = 7, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Service that provides some features regarding site home. | ||||||
|  |  */ | ||||||
|  | @Injectable({ | ||||||
|  |     providedIn: 'root', | ||||||
|  | }) | ||||||
|  | export class CoreSiteHomeProvider { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the news forum for the Site Home. | ||||||
|  |      * | ||||||
|  |      * @param siteHomeId Site Home ID. | ||||||
|  |      * @return Promise resolved with the forum if found, rejected otherwise. | ||||||
|  |      */ | ||||||
|  |     getNewsForum(): void { | ||||||
|  |         // @todo params and logic.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Invalidate the WS call to get the news forum for the Site Home. | ||||||
|  |      * | ||||||
|  |      * @param siteHomeId Site Home ID. | ||||||
|  |      * @return Promise resolved when invalidated. | ||||||
|  |      */ | ||||||
|  |     invalidateNewsForum(): void { | ||||||
|  |         // @todo params and logic.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Returns whether or not the frontpage is available for the current site. | ||||||
|  |      * | ||||||
|  |      * @param siteId The site ID. If not defined, current site. | ||||||
|  |      * @return Promise resolved with boolean: whether it's available. | ||||||
|  |      */ | ||||||
|  |     async isAvailable(siteId?: string): Promise<boolean> { | ||||||
|  |         try { | ||||||
|  |             const site = await CoreSites.instance.getSite(siteId); | ||||||
|  | 
 | ||||||
|  |             // First check if it's disabled.
 | ||||||
|  |             if (this.isDisabledInSite(site)) { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Use a WS call to check if there's content in the site home.
 | ||||||
|  |             const siteHomeId = site.getSiteHomeId(); | ||||||
|  |             const preSets: CoreSiteWSPreSets = { emergencyCache: false }; | ||||||
|  | 
 | ||||||
|  |             try { | ||||||
|  |                 const sections: CoreCourseSection[] = | ||||||
|  |                     await CoreCourse.instance.getSections(siteHomeId, false, true, preSets, site.id); | ||||||
|  | 
 | ||||||
|  |                 if (!sections || !sections.length) { | ||||||
|  |                     throw Error('No sections found'); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const hasContent = sections.some((section) => section.summary || (section.modules && section.modules.length)); | ||||||
|  | 
 | ||||||
|  |                 if (hasContent) { | ||||||
|  |                     // There's a section with content.
 | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  |             } catch { | ||||||
|  |                 // Ignore errors.
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const config = site.getStoredConfig(); | ||||||
|  |             if (config && config.frontpageloggedin) { | ||||||
|  |                 const items = await this.getFrontPageItems(config.frontpageloggedin); | ||||||
|  | 
 | ||||||
|  |                 // There are items to show.
 | ||||||
|  |                 return items.length > 0; | ||||||
|  |             } | ||||||
|  |         } catch { | ||||||
|  |             // Ignore errors.
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if Site Home is disabled in a certain site. | ||||||
|  |      * | ||||||
|  |      * @param siteId Site Id. If not defined, use current site. | ||||||
|  |      * @return Promise resolved with true if disabled, rejected or resolved with false otherwise. | ||||||
|  |      */ | ||||||
|  |     async isDisabled(siteId?: string): Promise<boolean> { | ||||||
|  |         const site = await CoreSites.instance.getSite(siteId); | ||||||
|  | 
 | ||||||
|  |         return this.isDisabledInSite(site); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if Site Home is disabled in a certain site. | ||||||
|  |      * | ||||||
|  |      * @param site Site. If not defined, use current site. | ||||||
|  |      * @return Whether it's disabled. | ||||||
|  |      */ | ||||||
|  |     isDisabledInSite(site: CoreSite): boolean { | ||||||
|  |         site = site || CoreSites.instance.getCurrentSite(); | ||||||
|  | 
 | ||||||
|  |         return site.isFeatureDisabled('CoreMainMenuDelegate_CoreSiteHome'); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the nams of the valid frontpage items. | ||||||
|  |      * | ||||||
|  |      * @param frontpageItemIds CSV string with indexes of site home components. | ||||||
|  |      * @return Valid names for each item. | ||||||
|  |      */ | ||||||
|  |     async getFrontPageItems(frontpageItemIds?: string): Promise<string[]> { | ||||||
|  |         if (!frontpageItemIds) { | ||||||
|  |             return []; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const items = frontpageItemIds.split(','); | ||||||
|  | 
 | ||||||
|  |         const filteredItems: string[] = []; | ||||||
|  | 
 | ||||||
|  |         for (const item of items) { | ||||||
|  |             let itemNumber = parseInt(item, 10); | ||||||
|  | 
 | ||||||
|  |             let add = false; | ||||||
|  |             switch (itemNumber) { | ||||||
|  |                 case FrontPageItemNames['NEWS_ITEMS']: | ||||||
|  |                     // @todo
 | ||||||
|  |                     add = true; | ||||||
|  |                     break; | ||||||
|  |                 case FrontPageItemNames['LIST_OF_CATEGORIES']: | ||||||
|  |                 case FrontPageItemNames['COMBO_LIST']: | ||||||
|  |                 case FrontPageItemNames['LIST_OF_COURSE']: | ||||||
|  |                     add = CoreCourses.instance.isGetCoursesByFieldAvailable(); | ||||||
|  |                     if (add && itemNumber == FrontPageItemNames['COMBO_LIST']) { | ||||||
|  |                         itemNumber = FrontPageItemNames['LIST_OF_CATEGORIES']; | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|  |                 case FrontPageItemNames['ENROLLED_COURSES']: | ||||||
|  |                     if (!CoreCourses.instance.isMyCoursesDisabledInSite()) { | ||||||
|  |                         const courses = await CoreCourses.instance.getUserCourses(); | ||||||
|  | 
 | ||||||
|  |                         add = courses.length > 0; | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|  |                 case FrontPageItemNames['COURSE_SEARCH_BOX']: | ||||||
|  |                     add = !CoreCourses.instance.isSearchCoursesDisabledInSite(); | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Do not add an item twice.
 | ||||||
|  |             if (add && filteredItems.indexOf(FrontPageItemNames[itemNumber]) < 0) { | ||||||
|  |                 filteredItems.push(FrontPageItemNames[itemNumber]); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return filteredItems; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class CoreSiteHome extends makeSingleton(CoreSiteHomeProvider) {} | ||||||
|  | 
 | ||||||
							
								
								
									
										53
									
								
								src/core/features/sitehome/sitehome-init.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/core/features/sitehome/sitehome-init.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | |||||||
|  | // (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 { Routes } from '@angular/router'; | ||||||
|  | 
 | ||||||
|  | import { CoreSiteHomeIndexLinkHandler } from './services/handlers/index.link'; | ||||||
|  | import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks.delegate'; | ||||||
|  | import { CoreSiteHomeHomeHandler } from './services/handlers/sitehome.home'; | ||||||
|  | import { CoreHomeDelegate } from '@features/mainmenu/services/home.delegate'; | ||||||
|  | import { CoreHomeRoutingModule } from '@features/mainmenu/pages/home/home-routing.module'; | ||||||
|  | 
 | ||||||
|  | const routes: Routes = [ | ||||||
|  |     { | ||||||
|  |         path: 'sitehome', | ||||||
|  |         loadChildren: () => | ||||||
|  |             import('@features/sitehome/pages/index/index.page.module').then(m => m.CoreSiteHomeIndexPageModule), | ||||||
|  |     }, | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     imports: [CoreHomeRoutingModule.forChild(routes)], | ||||||
|  |     exports: [CoreHomeRoutingModule], | ||||||
|  |     providers: [ | ||||||
|  |         CoreSiteHomeIndexLinkHandler, | ||||||
|  |         CoreSiteHomeHomeHandler, | ||||||
|  |     ], | ||||||
|  | }) | ||||||
|  | export class CoreSiteHomeInitModule { | ||||||
|  | 
 | ||||||
|  |     constructor( | ||||||
|  |         contentLinksDelegate: CoreContentLinksDelegate, | ||||||
|  |         homeDelegate: CoreHomeDelegate, | ||||||
|  |         siteHomeIndexLinkHandler: CoreSiteHomeIndexLinkHandler, | ||||||
|  |         siteHomeDashboardHandler: CoreSiteHomeHomeHandler, | ||||||
|  |     ) { | ||||||
|  |         contentLinksDelegate.registerHandler(siteHomeIndexLinkHandler); | ||||||
|  |         homeDelegate.registerHandler(siteHomeDashboardHandler); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user