MOBILE-3594 sitehome: Add sitehome tab to home page
parent
cc5378aee7
commit
9b41458104
|
@ -20,6 +20,7 @@ import { CoreEmulatorModule } from './emulator/emulator.module';
|
|||
import { CoreFileUploaderInitModule } from './fileuploader/fileuploader-init.module';
|
||||
import { CoreLoginModule } from './login/login.module';
|
||||
import { CoreSettingsInitModule } from './settings/settings-init.module';
|
||||
import { CoreSiteHomeInitModule } from './sitehome/sitehome-init.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -29,6 +30,7 @@ import { CoreSettingsInitModule } from './settings/settings-init.module';
|
|||
CoreCoursesModule,
|
||||
CoreSettingsInitModule,
|
||||
CoreFileUploaderInitModule,
|
||||
CoreSiteHomeInitModule,
|
||||
],
|
||||
})
|
||||
export class CoreFeaturesModule {}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
</ion-button>
|
||||
</ion-item>
|
||||
<ion-list class="core-search-history" [hidden]="!historyShown">
|
||||
<ion-item class="ion-text-wrap" *ngFor="let item of history"
|
||||
(click)="historyClicked($event, item.searchedtext)" class="core-clickable" tabindex="1">
|
||||
<ion-item button class="ion-text-wrap" *ngFor="let item of history"
|
||||
(click)="historyClicked($event, item.searchedtext)" tabindex="1" detail>
|
||||
<ion-icon name="fa-history" slot="start">
|
||||
</ion-icon>
|
||||
{{item.searchedtext}}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<ion-item *ngIf="isIOS"
|
||||
(click)="openHandler('CoreSharedFilesListPage', {manage: true, siteId: siteId, hideSitePicker: true})"
|
||||
[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-label>
|
||||
<h2>{{ 'core.sharedfiles.sharedfiles' | translate }}</h2>
|
||||
|
@ -37,7 +37,7 @@
|
|||
</ion-item>
|
||||
|
||||
<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">
|
||||
<ion-icon [name]="handler.icon" slot="start" *ngIf="handler.icon">
|
||||
</ion-icon>
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"sitehome": "Site home",
|
||||
"sitenews": "Site announcements"
|
||||
}
|
|
@ -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>
|
|
@ -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 {}
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -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) {}
|
||||
|
|
@ -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…
Reference in New Issue