From fd67797ff1cb5ceb2ffbe46edbec7bf9486ea310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 1 Feb 2021 17:03:48 +0100 Subject: [PATCH] MOBILE-3625 blocks: Activity modules block --- .../activitymodules/activitymodules.module.ts | 38 +++++ .../activitymodules/activitymodules.ts | 149 ++++++++++++++++++ .../addon-block-activitymodules.html | 11 ++ .../components/components.module.ts | 43 +++++ src/addons/block/activitymodules/lang.json | 3 + .../activitymodules/services/block-handler.ts | 46 ++++++ src/addons/block/block.module.ts | 2 + .../block/classes/base-block-component.ts | 3 +- .../features/course/course-lazy.module.ts | 2 +- 9 files changed, 295 insertions(+), 2 deletions(-) create mode 100644 src/addons/block/activitymodules/activitymodules.module.ts create mode 100644 src/addons/block/activitymodules/components/activitymodules/activitymodules.ts create mode 100644 src/addons/block/activitymodules/components/activitymodules/addon-block-activitymodules.html create mode 100644 src/addons/block/activitymodules/components/components.module.ts create mode 100644 src/addons/block/activitymodules/lang.json create mode 100644 src/addons/block/activitymodules/services/block-handler.ts diff --git a/src/addons/block/activitymodules/activitymodules.module.ts b/src/addons/block/activitymodules/activitymodules.module.ts new file mode 100644 index 000000000..a94a20a03 --- /dev/null +++ b/src/addons/block/activitymodules/activitymodules.module.ts @@ -0,0 +1,38 @@ +// (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 { CoreBlockDelegate } from '@features/block/services/block-delegate'; +import { AddonBlockActivityModulesHandler } from './services/block-handler'; +import { AddonBlockActivityModulesComponentsModule } from './components/components.module'; + +@NgModule({ + imports: [ + IonicModule, + AddonBlockActivityModulesComponentsModule, + TranslateModule.forChild(), + ], + providers: [ + { + provide: APP_INITIALIZER, + multi: true, + useValue: () => { + CoreBlockDelegate.instance.registerHandler(AddonBlockActivityModulesHandler.instance); + }, + }, + ], +}) +export class AddonBlockActivityModulesModule {} diff --git a/src/addons/block/activitymodules/components/activitymodules/activitymodules.ts b/src/addons/block/activitymodules/components/activitymodules/activitymodules.ts new file mode 100644 index 000000000..edcb45111 --- /dev/null +++ b/src/addons/block/activitymodules/components/activitymodules/activitymodules.ts @@ -0,0 +1,149 @@ +// (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 { CoreCourse } from '@features/course/services/course'; +import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate'; +import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component'; +import { CoreSites } from '@services/sites'; +import { ContextLevel, CoreConstants } from '@/core/constants'; +import { Translate } from '@singletons'; +import { CoreUtils } from '@services/utils/utils'; +import { CoreNavigator } from '@services/navigator'; + +/** + * Component to render an "activity modules" block. + */ +@Component({ + selector: 'addon-block-activitymodules', + templateUrl: 'addon-block-activitymodules.html', +}) +export class AddonBlockActivityModulesComponent extends CoreBlockBaseComponent implements OnInit { + + entries: AddonBlockActivityModuleEntry[] = []; + + protected fetchContentDefaultError = 'Error getting activity modules data.'; + + constructor() { + super('AddonBlockActivityModulesComponent'); + } + + /** + * Perform the invalidate content function. + * + * @return Resolved when done. + */ + protected async invalidateContent(): Promise { + await CoreCourse.instance.invalidateSections(this.instanceId); + } + + /** + * Fetch the data to render the block. + * + * @return Promise resolved when done. + */ + protected async fetchContent(): Promise { + const sections = await CoreCourse.instance.getSections(this.getCourseId(), false, true); + + this.entries = []; + const archetypes: Record = {}; + const modIcons: Record = {}; + let modFullNames: Record = {}; + sections.forEach((section) => { + if (!section.modules) { + return; + } + + section.modules.forEach((mod) => { + if (mod.uservisible === false || !CoreCourse.instance.moduleHasView(mod) || + typeof modFullNames[mod.modname] != 'undefined') { + // Ignore this module. + return; + } + + // Get the archetype of the module type. + if (typeof archetypes[mod.modname] == 'undefined') { + archetypes[mod.modname] = CoreCourseModuleDelegate.instance.supportsFeature( + mod.modname, + CoreConstants.FEATURE_MOD_ARCHETYPE, + CoreConstants.MOD_ARCHETYPE_OTHER, + ); + } + + // Get the full name of the module type. + if (archetypes[mod.modname] == CoreConstants.MOD_ARCHETYPE_RESOURCE) { + // All resources are gathered in a single "Resources" option. + if (!modFullNames['resources']) { + modFullNames['resources'] = Translate.instance.instant('core.resources'); + } + } else { + modFullNames[mod.modname] = mod.modplural; + } + modIcons[mod.modname] = mod.modicon; + }); + }); + // Sort the modnames alphabetically. + modFullNames = CoreUtils.instance.sortValues(modFullNames); + for (const modName in modFullNames) { + let icon: string; + + if (modName === 'resources') { + icon = CoreCourse.instance.getModuleIconSrc('page', modIcons['page']); + } else { + icon = CoreCourseModuleDelegate.instance.getModuleIconSrc(modName, modIcons[modName]); + } + + this.entries.push({ + icon: icon, + name: modFullNames[modName], + modName, + }); + } + } + + /** + * Obtain the appropiate course id for the block. + * + * @return Course id. + */ + protected getCourseId(): number { + if (this.contextLevel == ContextLevel.COURSE) { + return this.instanceId; + } + + return CoreSites.instance.getCurrentSiteHomeId(); + } + + /** + * Navigate to the activity list. + * + * @param entry Selected entry. + */ + gotoCoureListModType(entry: AddonBlockActivityModuleEntry): void { + CoreNavigator.instance.navigateToSitePath('course/list-mod-type', { + params: { + courseId: this.getCourseId(), + modName: entry.modName, + title: entry.name, + }, + }); + } + +} + +type AddonBlockActivityModuleEntry = { + icon: string; + name: string; + modName: string; +}; diff --git a/src/addons/block/activitymodules/components/activitymodules/addon-block-activitymodules.html b/src/addons/block/activitymodules/components/activitymodules/addon-block-activitymodules.html new file mode 100644 index 000000000..ea3b50dea --- /dev/null +++ b/src/addons/block/activitymodules/components/activitymodules/addon-block-activitymodules.html @@ -0,0 +1,11 @@ + + +

{{ 'addon.block_activitymodules.pluginname' | translate }}

+
+
+ + + + {{ entry.name }} + + diff --git a/src/addons/block/activitymodules/components/components.module.ts b/src/addons/block/activitymodules/components/components.module.ts new file mode 100644 index 000000000..3449dbce6 --- /dev/null +++ b/src/addons/block/activitymodules/components/components.module.ts @@ -0,0 +1,43 @@ +// (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 { FormsModule } from '@angular/forms'; +import { TranslateModule } from '@ngx-translate/core'; + +import { CoreSharedModule } from '@/core/shared.module'; + +import { AddonBlockActivityModulesComponent } from './activitymodules/activitymodules'; + +@NgModule({ + declarations: [ + AddonBlockActivityModulesComponent, + ], + imports: [ + CommonModule, + IonicModule, + FormsModule, + TranslateModule.forChild(), + CoreSharedModule, + ], + exports: [ + AddonBlockActivityModulesComponent, + ], + entryComponents: [ + AddonBlockActivityModulesComponent, + ], +}) +export class AddonBlockActivityModulesComponentsModule {} diff --git a/src/addons/block/activitymodules/lang.json b/src/addons/block/activitymodules/lang.json new file mode 100644 index 000000000..7f1c7ab21 --- /dev/null +++ b/src/addons/block/activitymodules/lang.json @@ -0,0 +1,3 @@ +{ + "pluginname": "Activities" +} diff --git a/src/addons/block/activitymodules/services/block-handler.ts b/src/addons/block/activitymodules/services/block-handler.ts new file mode 100644 index 000000000..a6f7885a2 --- /dev/null +++ b/src/addons/block/activitymodules/services/block-handler.ts @@ -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 { AddonBlockActivityModulesComponent } from '../components/activitymodules/activitymodules'; +import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler'; +import { makeSingleton } from '@singletons'; + +/** + * Block handler. + */ +@Injectable({ providedIn: 'root' }) +export class AddonBlockActivityModulesHandlerService extends CoreBlockBaseHandler { + + name = 'AddonBlockActivityModules'; + blockName = 'activity_modules'; + + /** + * Returns the data needed to render the block. + * + * @return Data or promise resolved with the data. + */ + getDisplayData(): CoreBlockHandlerData { + + return { + title: 'addon.block_activitymodules.pluginname', + class: 'addon-block-activitymodules', + component: AddonBlockActivityModulesComponent, + }; + } + +} + +export class AddonBlockActivityModulesHandler extends makeSingleton(AddonBlockActivityModulesHandlerService) {} diff --git a/src/addons/block/block.module.ts b/src/addons/block/block.module.ts index 420c0e632..e1f0a96c7 100644 --- a/src/addons/block/block.module.ts +++ b/src/addons/block/block.module.ts @@ -36,6 +36,7 @@ import { AddonBlockSelfCompletionModule } from './selfcompletion/selfcompletion. import { AddonBlockSiteMainMenuModule } from './sitemainmenu/sitemainmenu.module'; import { AddonBlockStarredCoursesModule } from './starredcourses/starredcourses.module'; import { AddonBlockTagsModule } from './tags/tags.module'; +import { AddonBlockActivityModulesModule } from './activitymodules/activitymodules.module'; @NgModule({ declarations: [], @@ -62,6 +63,7 @@ import { AddonBlockTagsModule } from './tags/tags.module'; AddonBlockSiteMainMenuModule, AddonBlockStarredCoursesModule, AddonBlockTagsModule, + AddonBlockActivityModulesModule, ], providers: [], exports: [], diff --git a/src/core/features/block/classes/base-block-component.ts b/src/core/features/block/classes/base-block-component.ts index aac65bba4..20c020c08 100644 --- a/src/core/features/block/classes/base-block-component.ts +++ b/src/core/features/block/classes/base-block-component.ts @@ -20,6 +20,7 @@ import { CoreTextUtils } from '@services/utils/text'; import { CoreCourseBlock } from '../../course/services/course'; import { IonRefresher } from '@ionic/angular'; import { Params } from '@angular/router'; +import { ContextLevel } from '@/core/constants'; /** * Template class to easily create components for blocks. @@ -31,7 +32,7 @@ export abstract class CoreBlockBaseComponent implements OnInit { @Input() title!: string; // The block title. @Input() block!: CoreCourseBlock; // The block to render. - @Input() contextLevel!: string; // The context where the block will be used. + @Input() contextLevel!: ContextLevel; // The context where the block will be used. @Input() instanceId!: number; // The instance ID associated with the context level. @Input() link?: string; // Link to go when clicked. @Input() linkParams?: Params; // Link params to go when clicked. diff --git a/src/core/features/course/course-lazy.module.ts b/src/core/features/course/course-lazy.module.ts index fa42b82c0..a6b626437 100644 --- a/src/core/features/course/course-lazy.module.ts +++ b/src/core/features/course/course-lazy.module.ts @@ -32,7 +32,7 @@ const routes: Routes = [ }, { path: 'list-mod-type', - loadChildren: () => import('./pages/list-mod-type/list-mod-type').then( m => m.CoreCourseListModTypePage), + loadChildren: () => import('./pages/list-mod-type/list-mod-type.module').then(m => m.CoreCourseListModTypePageModule), }, ];