MOBILE-3608 block: Implement site main menu block
parent
f8320f6b58
commit
253d6829a9
|
@ -33,6 +33,7 @@ import { AddonBlockPrivateFilesModule } from './block/privatefiles/privatefiles.
|
||||||
import { AddonBlockRecentlyAccessedCoursesModule } from './block/recentlyaccessedcourses/recentlyaccessedcourses.module';
|
import { AddonBlockRecentlyAccessedCoursesModule } from './block/recentlyaccessedcourses/recentlyaccessedcourses.module';
|
||||||
import { AddonBlockRssClientModule } from './block/rssclient/rssclient.module';
|
import { AddonBlockRssClientModule } from './block/rssclient/rssclient.module';
|
||||||
import { AddonBlockSelfCompletionModule } from './block/selfcompletion/selfcompletion.module';
|
import { AddonBlockSelfCompletionModule } from './block/selfcompletion/selfcompletion.module';
|
||||||
|
import { AddonBlockSiteMainMenuModule } from './block/sitemainmenu/sitemainmenu.module';
|
||||||
import { AddonBlockStarredCoursesModule } from './block/starredcourses/starredcourses.module';
|
import { AddonBlockStarredCoursesModule } from './block/starredcourses/starredcourses.module';
|
||||||
import { AddonBlockTagsModule } from './block/tags/tags.module';
|
import { AddonBlockTagsModule } from './block/tags/tags.module';
|
||||||
import { AddonPrivateFilesModule } from './privatefiles/privatefiles.module';
|
import { AddonPrivateFilesModule } from './privatefiles/privatefiles.module';
|
||||||
|
@ -62,6 +63,7 @@ import { AddonUserProfileFieldModule } from './userprofilefield/userprofilefield
|
||||||
AddonBlockRecentlyAccessedCoursesModule,
|
AddonBlockRecentlyAccessedCoursesModule,
|
||||||
AddonBlockRssClientModule,
|
AddonBlockRssClientModule,
|
||||||
AddonBlockSelfCompletionModule,
|
AddonBlockSelfCompletionModule,
|
||||||
|
AddonBlockSiteMainMenuModule,
|
||||||
AddonBlockStarredCoursesModule,
|
AddonBlockStarredCoursesModule,
|
||||||
AddonBlockTagsModule,
|
AddonBlockTagsModule,
|
||||||
AddonUserProfileFieldModule,
|
AddonUserProfileFieldModule,
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
// (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 { IonicModule } from '@ionic/angular';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { CoreComponentsModule } from '@components/components.module';
|
||||||
|
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||||
|
// import { CoreCourseComponentsModule } from '@features/course/components/components.module';
|
||||||
|
|
||||||
|
import { AddonBlockSiteMainMenuComponent } from './sitemainmenu/sitemainmenu';
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AddonBlockSiteMainMenuComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
IonicModule,
|
||||||
|
TranslateModule.forChild(),
|
||||||
|
CoreComponentsModule,
|
||||||
|
CoreDirectivesModule,
|
||||||
|
// CoreCourseComponentsModule,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
AddonBlockSiteMainMenuComponent,
|
||||||
|
],
|
||||||
|
entryComponents: [
|
||||||
|
AddonBlockSiteMainMenuComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonBlockSiteMainMenuComponentsModule {}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<ion-item-divider>
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{ 'addon.block_sitemainmenu.pluginname' | translate }}</h2>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item-divider>
|
||||||
|
<core-loading [hideUntil]="loaded" class="core-loading-center">
|
||||||
|
<ng-container *ngIf="mainMenuBlock">
|
||||||
|
<ion-item class="ion-text-wrap" *ngIf="mainMenuBlock.summary">
|
||||||
|
<core-format-text [text]="mainMenuBlock.summary" [component]="component" [componentId]="siteHomeId" contextLevel="course" [contextInstanceId]="siteHomeId"></core-format-text>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<!--<core-course-module *ngFor="let module of mainMenuBlock.modules" [module]="module" [courseId]="siteHomeId" [downloadEnabled]="downloadEnabled" [section]="mainMenuBlock"></core-course-module>-->
|
||||||
|
</ng-container>
|
||||||
|
</core-loading>
|
|
@ -0,0 +1,116 @@
|
||||||
|
// (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, Input } from '@angular/core';
|
||||||
|
import { CoreSites } from '@services/sites';
|
||||||
|
import { CoreCourse, CoreCourseSection } from '@features/course/services/course';
|
||||||
|
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||||
|
import { CoreSiteHome, FrontPageItemNames } from '@features/sitehome/services/sitehome';
|
||||||
|
// @todo import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate';
|
||||||
|
import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to render a site main menu block.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'addon-block-sitemainmenu',
|
||||||
|
templateUrl: 'addon-block-sitemainmenu.html',
|
||||||
|
})
|
||||||
|
export class AddonBlockSiteMainMenuComponent extends CoreBlockBaseComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() downloadEnabled = false;
|
||||||
|
|
||||||
|
component = 'AddonBlockSiteMainMenu';
|
||||||
|
mainMenuBlock?: CoreCourseSection;
|
||||||
|
siteHomeId = 1;
|
||||||
|
|
||||||
|
protected fetchContentDefaultError = 'Error getting main menu data.';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super('AddonBlockSiteMainMenuComponent');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component being initialized.
|
||||||
|
*/
|
||||||
|
async ngOnInit(): Promise<void> {
|
||||||
|
this.siteHomeId = CoreSites.instance.getCurrentSite()?.getSiteHomeId() || 1;
|
||||||
|
|
||||||
|
super.ngOnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the invalidate content function.
|
||||||
|
*
|
||||||
|
* @return Resolved when done.
|
||||||
|
*/
|
||||||
|
protected async invalidateContent(): Promise<void> {
|
||||||
|
const promises: Promise<void>[] = [];
|
||||||
|
|
||||||
|
promises.push(CoreCourse.instance.invalidateSections(this.siteHomeId));
|
||||||
|
promises.push(CoreSiteHome.instance.invalidateNewsForum(this.siteHomeId));
|
||||||
|
|
||||||
|
if (this.mainMenuBlock && this.mainMenuBlock.modules) {
|
||||||
|
// Invalidate modules prefetch data.
|
||||||
|
// @todo promises.push(this.prefetchDelegate.invalidateModules(this.mainMenuBlock.modules, this.siteHomeId));
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the data to render the block.
|
||||||
|
*
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
protected async fetchContent(): Promise<void> {
|
||||||
|
const sections = await CoreCourse.instance.getSections(this.siteHomeId, false, true);
|
||||||
|
|
||||||
|
this.mainMenuBlock = sections.find((section) => section.section == 0);
|
||||||
|
if (!this.mainMenuBlock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentSite = CoreSites.instance.getCurrentSite();
|
||||||
|
const config = currentSite ? currentSite.getStoredConfig() || {} : {};
|
||||||
|
if (!config.frontpageloggedin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check if Site Home displays announcements. If so, remove it from the main menu block.
|
||||||
|
const items = config.frontpageloggedin.split(',');
|
||||||
|
const hasNewsItem = items.find((item) => parseInt(item, 10) == FrontPageItemNames['NEWS_ITEMS']);
|
||||||
|
|
||||||
|
const hasContent = CoreCourseHelper.instance.sectionHasContent(this.mainMenuBlock);
|
||||||
|
CoreCourseHelper.instance.addHandlerDataForModules([this.mainMenuBlock], this.siteHomeId, undefined, undefined, true);
|
||||||
|
|
||||||
|
if (!hasNewsItem || !hasContent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove forum activity (news one only) from the main menu block to prevent duplicates.
|
||||||
|
try {
|
||||||
|
const forum = await CoreSiteHome.instance.getNewsForum(this.siteHomeId);
|
||||||
|
// Search the module that belongs to site news.
|
||||||
|
const forumIndex =
|
||||||
|
this.mainMenuBlock.modules.findIndex((mod) => mod.modname == 'forum' && mod.instance == forum.id);
|
||||||
|
|
||||||
|
if (forumIndex >= 0) {
|
||||||
|
this.mainMenuBlock.modules.splice(forumIndex, 1);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Ignore errors.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"pluginname": "Main menu"
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
|
||||||
|
import { AddonBlockSiteMainMenuComponent } from '../components/sitemainmenu/sitemainmenu';
|
||||||
|
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block handler.
|
||||||
|
*/
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class AddonBlockSiteMainMenuHandlerService extends CoreBlockBaseHandler {
|
||||||
|
|
||||||
|
name = 'AddonBlockSiteMainMenu';
|
||||||
|
blockName = 'site_main_menu';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data needed to render the block.
|
||||||
|
*
|
||||||
|
* @return Data or promise resolved with the data.
|
||||||
|
*/
|
||||||
|
getDisplayData(): CoreBlockHandlerData {
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: 'addon.block_sitemainmenu.pluginname',
|
||||||
|
class: 'addon-block-sitemainmenu',
|
||||||
|
component: AddonBlockSiteMainMenuComponent,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AddonBlockSiteMainMenuHandler extends makeSingleton(AddonBlockSiteMainMenuHandlerService) {}
|
|
@ -0,0 +1,42 @@
|
||||||
|
// (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 { APP_INITIALIZER, 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 { AddonBlockSiteMainMenuComponentsModule } from './components/components.module';
|
||||||
|
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
|
||||||
|
import { AddonBlockSiteMainMenuHandler } from './services/block-handler';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
IonicModule,
|
||||||
|
CoreComponentsModule,
|
||||||
|
CoreDirectivesModule,
|
||||||
|
AddonBlockSiteMainMenuComponentsModule,
|
||||||
|
TranslateModule.forChild(),
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
multi: true,
|
||||||
|
useValue: () => {
|
||||||
|
CoreBlockDelegate.instance.registerHandler(AddonBlockSiteMainMenuHandler.instance);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonBlockSiteMainMenuModule {}
|
|
@ -0,0 +1,132 @@
|
||||||
|
// (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 { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||||
|
import { CoreSitesCommonWSOptions, CoreSites } from '@services/sites';
|
||||||
|
import { CoreWSExternalFile } from '@services/ws';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
|
||||||
|
const ROOT_CACHE_KEY = 'mmaModForum:';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service that provides some features for forums.
|
||||||
|
*
|
||||||
|
* @todo Add all content.
|
||||||
|
*/
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class AddonModForumProvider {
|
||||||
|
|
||||||
|
static readonly COMPONENT = 'mmaModForum';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key for forum data WS calls.
|
||||||
|
*
|
||||||
|
* @param courseId Course ID.
|
||||||
|
* @return Cache key.
|
||||||
|
*/
|
||||||
|
protected getForumDataCacheKey(courseId: number): string {
|
||||||
|
return ROOT_CACHE_KEY + 'forum:' + courseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all course forums.
|
||||||
|
*
|
||||||
|
* @param courseId Course ID.
|
||||||
|
* @param options Other options.
|
||||||
|
* @return Promise resolved when the forums are retrieved.
|
||||||
|
*/
|
||||||
|
async getCourseForums(courseId: number, options: CoreSitesCommonWSOptions = {}): Promise<AddonModForumData[]> {
|
||||||
|
const site = await CoreSites.instance.getSite(options.siteId);
|
||||||
|
|
||||||
|
const params: AddonModForumGetForumsByCoursesWSParams = {
|
||||||
|
courseids: [courseId],
|
||||||
|
};
|
||||||
|
const preSets: CoreSiteWSPreSets = {
|
||||||
|
cacheKey: this.getForumDataCacheKey(courseId),
|
||||||
|
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||||
|
component: AddonModForumProvider.COMPONENT,
|
||||||
|
...CoreSites.instance.getReadingStrategyPreSets(options.readingStrategy),
|
||||||
|
};
|
||||||
|
|
||||||
|
return site.read('mod_forum_get_forums_by_courses', params, preSets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates forum data.
|
||||||
|
*
|
||||||
|
* @param courseId Course ID.
|
||||||
|
* @return Promise resolved when the data is invalidated.
|
||||||
|
*/
|
||||||
|
async invalidateForumData(courseId: number): Promise<void> {
|
||||||
|
await CoreSites.instance.getCurrentSite()?.invalidateWsCacheForKey(this.getForumDataCacheKey(courseId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AddonModForum extends makeSingleton(AddonModForumProvider) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params of mod_forum_get_forums_by_courses WS.
|
||||||
|
*/
|
||||||
|
type AddonModForumGetForumsByCoursesWSParams = {
|
||||||
|
courseids?: number[]; // Array of Course IDs.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General forum activity data.
|
||||||
|
*/
|
||||||
|
export type AddonModForumData = {
|
||||||
|
id: number; // Forum id.
|
||||||
|
course: number; // Course id.
|
||||||
|
type: string; // The forum type.
|
||||||
|
name: string; // Forum name.
|
||||||
|
intro: string; // The forum intro.
|
||||||
|
introformat: number; // Intro format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
|
||||||
|
introfiles?: CoreWSExternalFile[];
|
||||||
|
duedate?: number; // Duedate for the user.
|
||||||
|
cutoffdate?: number; // Cutoffdate for the user.
|
||||||
|
assessed: number; // Aggregate type.
|
||||||
|
assesstimestart: number; // Assess start time.
|
||||||
|
assesstimefinish: number; // Assess finish time.
|
||||||
|
scale: number; // Scale.
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
grade_forum: number; // Whole forum grade.
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
grade_forum_notify: number; // Whether to send notifications to students upon grading by default.
|
||||||
|
maxbytes: number; // Maximum attachment size.
|
||||||
|
maxattachments: number; // Maximum number of attachments.
|
||||||
|
forcesubscribe: number; // Force users to subscribe.
|
||||||
|
trackingtype: number; // Subscription mode.
|
||||||
|
rsstype: number; // RSS feed for this activity.
|
||||||
|
rssarticles: number; // Number of RSS recent articles.
|
||||||
|
timemodified: number; // Time modified.
|
||||||
|
warnafter: number; // Post threshold for warning.
|
||||||
|
blockafter: number; // Post threshold for blocking.
|
||||||
|
blockperiod: number; // Time period for blocking.
|
||||||
|
completiondiscussions: number; // Student must create discussions.
|
||||||
|
completionreplies: number; // Student must post replies.
|
||||||
|
completionposts: number; // Student must post discussions or replies.
|
||||||
|
cmid: number; // Course module id.
|
||||||
|
numdiscussions?: number; // Number of discussions in the forum.
|
||||||
|
cancreatediscussions?: boolean; // If the user can create discussions.
|
||||||
|
lockdiscussionafter?: number; // After what period a discussion is locked.
|
||||||
|
istracked?: boolean; // If the user is tracking the forum.
|
||||||
|
unreadpostscount?: number; // The number of unread posts for tracked forums.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data returned by mod_forum_get_forums_by_courses WS.
|
||||||
|
*/
|
||||||
|
export type AddonModForumGetForumsByCoursesWSResponse = AddonModForumData[];
|
|
@ -134,8 +134,52 @@ export class CoreCourseHelperProvider {
|
||||||
* @param forCoursePage Whether the data will be used to render the course page.
|
* @param forCoursePage Whether the data will be used to render the course page.
|
||||||
* @return Whether the sections have content.
|
* @return Whether the sections have content.
|
||||||
*/
|
*/
|
||||||
addHandlerDataForModules(): void {
|
addHandlerDataForModules(
|
||||||
// @todo params and logic
|
sections: CoreCourseSection[],
|
||||||
|
courseId: number,
|
||||||
|
completionStatus?: any, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
courseName?: string, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
forCoursePage = false, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
): boolean {
|
||||||
|
|
||||||
|
let hasContent = false;
|
||||||
|
|
||||||
|
sections.forEach((section) => {
|
||||||
|
if (!section || !this.sectionHasContent(section) || !section.modules) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasContent = true;
|
||||||
|
|
||||||
|
/* @todo
|
||||||
|
section.modules.forEach((module) => {
|
||||||
|
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, courseId, section.id,
|
||||||
|
forCoursePage);
|
||||||
|
|
||||||
|
if (module.completiondata && module.completion > 0) {
|
||||||
|
module.completiondata.courseId = courseId;
|
||||||
|
module.completiondata.courseName = courseName;
|
||||||
|
module.completiondata.tracking = module.completion;
|
||||||
|
module.completiondata.cmid = module.id;
|
||||||
|
|
||||||
|
// Use of completionstatus is deprecated, use completiondata instead.
|
||||||
|
module.completionstatus = module.completiondata;
|
||||||
|
} else if (completionStatus && typeof completionStatus[module.id] != 'undefined') {
|
||||||
|
// Should not happen on > 3.6. Check if activity has completions and if it's marked.
|
||||||
|
module.completiondata = completionStatus[module.id];
|
||||||
|
module.completiondata.courseId = courseId;
|
||||||
|
module.completiondata.courseName = courseName;
|
||||||
|
|
||||||
|
// Use of completionstatus is deprecated, use completiondata instead.
|
||||||
|
module.completionstatus = module.completiondata;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the module is stealth.
|
||||||
|
module.isStealth = module.visibleoncoursepage === 0 || (module.visible && !section.visible);
|
||||||
|
});*/
|
||||||
|
});
|
||||||
|
|
||||||
|
return hasContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -913,7 +957,7 @@ export class CoreCourseHelperProvider {
|
||||||
* @return Whether the section has content.
|
* @return Whether the section has content.
|
||||||
* @todo section type.
|
* @todo section type.
|
||||||
*/
|
*/
|
||||||
sectionHasContent(section: any): boolean {
|
sectionHasContent(section: CoreCourseSection): boolean {
|
||||||
if (section.hiddenbynumsections) {
|
if (section.hiddenbynumsections) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-label>News (TODO)</ion-label>
|
<ion-label>News (TODO)</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<!-- @todo <core-course-module class="core-sitehome-news" *ngIf="show" [module]="module" [courseId]="siteHomeId"></core-course-module> -->
|
<!-- @todo <core-course-module class="core-sitehome-news" *ngIf="newsForumModule" [module]="module" [courseId]="siteHomeId"></core-course-module> -->
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template #categories>
|
<ng-template #categories>
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { ActivatedRoute } from '@angular/router';
|
||||||
import { IonRefresher, NavController } from '@ionic/angular';
|
import { IonRefresher, NavController } from '@ionic/angular';
|
||||||
|
|
||||||
import { CoreSite, CoreSiteConfig } from '@classes/site';
|
import { CoreSite, CoreSiteConfig } from '@classes/site';
|
||||||
import { CoreCourse, CoreCourseSection } from '@features/course/services/course';
|
import { CoreCourse, CoreCourseModuleBasicInfo, CoreCourseSection } from '@features/course/services/course';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreSiteHome } from '@features/sitehome/services/sitehome';
|
import { CoreSiteHome } from '@features/sitehome/services/sitehome';
|
||||||
|
@ -44,13 +44,14 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
hasContent = false;
|
hasContent = false;
|
||||||
items: string[] = [];
|
items: string[] = [];
|
||||||
siteHomeId?: number;
|
siteHomeId = 1;
|
||||||
currentSite?: CoreSite;
|
currentSite?: CoreSite;
|
||||||
searchEnabled = false;
|
searchEnabled = false;
|
||||||
downloadEnabled = false;
|
downloadEnabled = false;
|
||||||
downloadCourseEnabled = false;
|
downloadCourseEnabled = false;
|
||||||
downloadCoursesEnabled = false;
|
downloadCoursesEnabled = false;
|
||||||
downloadEnabledIcon = 'far-square';
|
downloadEnabledIcon = 'far-square';
|
||||||
|
newsForumModule?: CoreCourseModuleBasicInfo;
|
||||||
|
|
||||||
protected updateSiteObserver?: CoreEventObserver;
|
protected updateSiteObserver?: CoreEventObserver;
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy {
|
||||||
}, CoreSites.instance.getCurrentSiteId());
|
}, CoreSites.instance.getCurrentSiteId());
|
||||||
|
|
||||||
this.currentSite = CoreSites.instance.getCurrentSite()!;
|
this.currentSite = CoreSites.instance.getCurrentSite()!;
|
||||||
this.siteHomeId = this.currentSite.getSiteHomeId();
|
this.siteHomeId = this.currentSite?.getSiteHomeId() || 1;
|
||||||
|
|
||||||
const module = navParams['module'];
|
const module = navParams['module'];
|
||||||
if (module) {
|
if (module) {
|
||||||
|
@ -106,6 +107,23 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy {
|
||||||
this.items = await CoreSiteHome.instance.getFrontPageItems(config.frontpageloggedin);
|
this.items = await CoreSiteHome.instance.getFrontPageItems(config.frontpageloggedin);
|
||||||
this.hasContent = this.items.length > 0;
|
this.hasContent = this.items.length > 0;
|
||||||
|
|
||||||
|
if (this.items.some((item) => item == 'NEWS_ITEMS')) {
|
||||||
|
// Get the news forum.
|
||||||
|
try {
|
||||||
|
const forum = await CoreSiteHome.instance.getNewsForum();
|
||||||
|
this.newsForumModule = await CoreCourse.instance.getModuleBasicInfo(forum.cmid);
|
||||||
|
/* @todo this.newsForumModule.handlerData = this.moduleDelegate.getModuleDataFor(
|
||||||
|
this.newsForumModule.modname,
|
||||||
|
this.newsForumModule,
|
||||||
|
this.siteHomeId,
|
||||||
|
this.newsForumModule.section,
|
||||||
|
true,
|
||||||
|
);*/
|
||||||
|
} catch {
|
||||||
|
// Ignore errors.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const sections = await CoreCourse.instance.getSections(this.siteHomeId!, false, true);
|
const sections = await CoreCourse.instance.getSections(this.siteHomeId!, false, true);
|
||||||
|
|
||||||
|
@ -114,13 +132,13 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy {
|
||||||
if (this.section) {
|
if (this.section) {
|
||||||
this.section.hasContent = false;
|
this.section.hasContent = false;
|
||||||
this.section.hasContent = CoreCourseHelper.instance.sectionHasContent(this.section);
|
this.section.hasContent = CoreCourseHelper.instance.sectionHasContent(this.section);
|
||||||
/* @todo this.hasContent = CoreCourseHelper.instance.addHandlerDataForModules(
|
this.hasContent = CoreCourseHelper.instance.addHandlerDataForModules(
|
||||||
[this.section],
|
[this.section],
|
||||||
this.siteHomeId,
|
this.siteHomeId,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
true,
|
true,
|
||||||
) || this.hasContent;*/
|
) || this.hasContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add log in Moodle.
|
// Add log in Moodle.
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { CoreCourse, CoreCourseSection } from '../../course/services/course';
|
import { CoreCourse, CoreCourseSection } from '../../course/services/course';
|
||||||
import { CoreCourses } from '../../courses/services/courses';
|
import { CoreCourses } from '../../courses/services/courses';
|
||||||
|
import { AddonModForum, AddonModForumData } from '@/addons/mod/forum/services/forum';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Items with index 1 and 3 were removed on 2.5 and not being supported in the app.
|
* Items with index 1 and 3 were removed on 2.5 and not being supported in the app.
|
||||||
|
@ -44,8 +45,19 @@ export class CoreSiteHomeProvider {
|
||||||
* @param siteHomeId Site Home ID.
|
* @param siteHomeId Site Home ID.
|
||||||
* @return Promise resolved with the forum if found, rejected otherwise.
|
* @return Promise resolved with the forum if found, rejected otherwise.
|
||||||
*/
|
*/
|
||||||
getNewsForum(): void {
|
async getNewsForum(siteHomeId?: number): Promise<AddonModForumData> {
|
||||||
// @todo params and logic.
|
if (!siteHomeId) {
|
||||||
|
siteHomeId = CoreSites.instance.getCurrentSite()?.getSiteHomeId() || 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const forums = await AddonModForum.instance.getCourseForums(siteHomeId);
|
||||||
|
const forum = forums.find((forum) => forum.type == 'news');
|
||||||
|
|
||||||
|
if (forum) {
|
||||||
|
return forum;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,8 +66,8 @@ export class CoreSiteHomeProvider {
|
||||||
* @param siteHomeId Site Home ID.
|
* @param siteHomeId Site Home ID.
|
||||||
* @return Promise resolved when invalidated.
|
* @return Promise resolved when invalidated.
|
||||||
*/
|
*/
|
||||||
invalidateNewsForum(): void {
|
async invalidateNewsForum(siteHomeId: number): Promise<void> {
|
||||||
// @todo params and logic.
|
await AddonModForum.instance.invalidateForumData(siteHomeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,8 +166,8 @@ export class CoreSiteHomeProvider {
|
||||||
let add = false;
|
let add = false;
|
||||||
switch (itemNumber) {
|
switch (itemNumber) {
|
||||||
case FrontPageItemNames['NEWS_ITEMS']:
|
case FrontPageItemNames['NEWS_ITEMS']:
|
||||||
// @todo
|
// Get number of news items to show.
|
||||||
add = true;
|
add = !!CoreSites.instance.getCurrentSite()?.getStoredConfig('newsitems');
|
||||||
break;
|
break;
|
||||||
case FrontPageItemNames['LIST_OF_CATEGORIES']:
|
case FrontPageItemNames['LIST_OF_CATEGORIES']:
|
||||||
case FrontPageItemNames['COMBO_LIST']:
|
case FrontPageItemNames['COMBO_LIST']:
|
||||||
|
|
|
@ -1618,7 +1618,7 @@ export class CoreSitesProvider {
|
||||||
* @param strategy Reading strategy.
|
* @param strategy Reading strategy.
|
||||||
* @return PreSets options object.
|
* @return PreSets options object.
|
||||||
*/
|
*/
|
||||||
getReadingStrategyPreSets(strategy: CoreSitesReadingStrategy): CoreSiteWSPreSets {
|
getReadingStrategyPreSets(strategy?: CoreSitesReadingStrategy): CoreSiteWSPreSets {
|
||||||
switch (strategy) {
|
switch (strategy) {
|
||||||
case CoreSitesReadingStrategy.PreferCache:
|
case CoreSitesReadingStrategy.PreferCache:
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in New Issue