From cbc9bc715cecd788def366762e1ee331c58be377 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 2 Jan 2018 15:30:50 +0100 Subject: [PATCH] MOBILE-2310 course: Implement unsupported module page --- src/app/app.scss | 6 ++ .../course/components/components.module.ts | 7 ++- .../module-description.html | 6 ++ .../module-description/module-description.ts | 45 +++++++++++++++ src/core/course/components/module/module.html | 8 +-- src/core/course/components/module/module.ts | 18 +++++- .../unsupported-module.html | 30 ++++++++++ .../unsupported-module.module.ts | 35 ++++++++++++ .../unsupported-module/unsupported-module.ts | 57 +++++++++++++++++++ src/core/course/providers/module-delegate.ts | 12 ++-- src/directives/format-text.ts | 7 ++- 11 files changed, 217 insertions(+), 14 deletions(-) create mode 100644 src/core/course/components/module-description/module-description.html create mode 100644 src/core/course/components/module-description/module-description.ts create mode 100644 src/core/course/pages/unsupported-module/unsupported-module.html create mode 100644 src/core/course/pages/unsupported-module/unsupported-module.module.ts create mode 100644 src/core/course/pages/unsupported-module/unsupported-module.ts diff --git a/src/app/app.scss b/src/app/app.scss index 8c06237ba..3149f8c43 100644 --- a/src/app/app.scss +++ b/src/app/app.scss @@ -226,6 +226,12 @@ core-format-text, *[core-format-text] { .badge { position: initial !important; } + + // Images in ion-card have width 100% and display block. Remove that when the image is in core-format-text. + img { + width: initial; + display: inline; + } } // Message item. diff --git a/src/core/course/components/components.module.ts b/src/core/course/components/components.module.ts index 9e521a82b..68401536c 100644 --- a/src/core/course/components/components.module.ts +++ b/src/core/course/components/components.module.ts @@ -21,12 +21,14 @@ import { CoreDirectivesModule } from '../../../directives/directives.module'; import { CoreCourseFormatComponent } from './format/format'; import { CoreCourseModuleComponent } from './module/module'; import { CoreCourseModuleCompletionComponent } from './module-completion/module-completion'; +import { CoreCourseModuleDescriptionComponent } from './module-description/module-description'; @NgModule({ declarations: [ CoreCourseFormatComponent, CoreCourseModuleComponent, - CoreCourseModuleCompletionComponent + CoreCourseModuleCompletionComponent, + CoreCourseModuleDescriptionComponent ], imports: [ CommonModule, @@ -40,7 +42,8 @@ import { CoreCourseModuleCompletionComponent } from './module-completion/module- exports: [ CoreCourseFormatComponent, CoreCourseModuleComponent, - CoreCourseModuleCompletionComponent + CoreCourseModuleCompletionComponent, + CoreCourseModuleDescriptionComponent ] }) export class CoreCourseComponentsModule {} diff --git a/src/core/course/components/module-description/module-description.html b/src/core/course/components/module-description/module-description.html new file mode 100644 index 000000000..8ccd37fc2 --- /dev/null +++ b/src/core/course/components/module-description/module-description.html @@ -0,0 +1,6 @@ + + + + {{ note }} + + \ No newline at end of file diff --git a/src/core/course/components/module-description/module-description.ts b/src/core/course/components/module-description/module-description.ts new file mode 100644 index 000000000..d10994df4 --- /dev/null +++ b/src/core/course/components/module-description/module-description.ts @@ -0,0 +1,45 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// 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, Input } from '@angular/core'; + +/** + * Component to display the description of a module. + * + * This directive is meant to display a module description in a similar way throughout all the app. + * + * You can add a note at the right side of the description by using the 'note' attribute. + * + * You can also pass a component and componentId to be used in format-text. + * + * Module descriptions are shortened by default, allowing the user to see the full description by clicking in it. + * If you want the whole description to be shown you can use the 'showFull' attribute. + * + * Example usage: + * + * + -
+
- - +
diff --git a/src/core/course/components/module/module.ts b/src/core/course/components/module/module.ts index 2fbf2a670..1353c4d64 100644 --- a/src/core/course/components/module/module.ts +++ b/src/core/course/components/module/module.ts @@ -13,6 +13,8 @@ // limitations under the License. import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core'; +import { NavController } from 'ionic-angular'; +import { CoreCourseModuleHandlerButton } from '../../providers/module-delegate'; /** * Component to display a module entry in a list of modules. @@ -30,7 +32,7 @@ export class CoreCourseModuleComponent implements OnInit { @Input() courseId: number; // The course the module belongs to. @Output() completionChanged?: EventEmitter; // Will emit an event when the module completion changes. - constructor() { + constructor(private navCtrl: NavController) { this.completionChanged = new EventEmitter(); } @@ -51,7 +53,19 @@ export class CoreCourseModuleComponent implements OnInit { */ moduleClicked(event: Event) { if (this.module.uservisible !== false && this.module.handlerData.action) { - this.module.handlerData.action(event, this.module, this.courseId); + this.module.handlerData.action(event, this.navCtrl, this.module, this.courseId); + } + } + + /** + * Function called when a button is clicked. + * + * @param {Event} event Click event. + * @param {CoreCourseModuleHandlerButton} button The clicked button. + */ + buttonClicked(event: Event, button: CoreCourseModuleHandlerButton) { + if (button && button.action) { + button.action(event, this.navCtrl, this.module, this.courseId); } } } diff --git a/src/core/course/pages/unsupported-module/unsupported-module.html b/src/core/course/pages/unsupported-module/unsupported-module.html new file mode 100644 index 000000000..32a4c3b9f --- /dev/null +++ b/src/core/course/pages/unsupported-module/unsupported-module.html @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + +

{{ 'core.whoops' | translate }}

+

{{ 'core.uhoh' | translate }}

+ +

{{ 'core.course.activitydisabled' | translate }}

+

{{ 'core.course.activitynotyetviewablesiteupgradeneeded' | translate }}

+

{{ 'core.course.activitynotyetviewableremoteaddon' | translate }}

+

{{ 'core.course.askadmintosupport' | translate }}

+ +
+

{{ 'core.course.useactivityonbrowser' | translate }}

+
+ {{ 'core.openinbrowser' | translate }} + + +
+ diff --git a/src/core/course/pages/unsupported-module/unsupported-module.module.ts b/src/core/course/pages/unsupported-module/unsupported-module.module.ts new file mode 100644 index 000000000..d45906da4 --- /dev/null +++ b/src/core/course/pages/unsupported-module/unsupported-module.module.ts @@ -0,0 +1,35 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// 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 { IonicPageModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { CoreCourseUnsupportedModulePage } from './unsupported-module'; +import { CoreComponentsModule } from '../../../../components/components.module'; +import { CoreDirectivesModule } from '../../../../directives/directives.module'; +import { CoreCourseComponentsModule } from '../../components/components.module'; + +@NgModule({ + declarations: [ + CoreCourseUnsupportedModulePage, + ], + imports: [ + CoreComponentsModule, + CoreDirectivesModule, + CoreCourseComponentsModule, + IonicPageModule.forChild(CoreCourseUnsupportedModulePage), + TranslateModule.forChild() + ], +}) +export class CoreCourseUnsupportedModulePageModule {} diff --git a/src/core/course/pages/unsupported-module/unsupported-module.ts b/src/core/course/pages/unsupported-module/unsupported-module.ts new file mode 100644 index 000000000..3489c7128 --- /dev/null +++ b/src/core/course/pages/unsupported-module/unsupported-module.ts @@ -0,0 +1,57 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// 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 } from '@angular/core'; +import { IonicPage, NavParams } from 'ionic-angular'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreTextUtilsProvider } from '../../../../providers/utils/text'; +import { CoreCourseProvider } from '../../providers/course'; +import { CoreCourseModuleDelegate } from '../../providers/module-delegate'; + +/** + * Page that displays info about an unsupported module. + */ +@IonicPage({segment: 'core-course-unsupported-module'}) +@Component({ + selector: 'page-core-course-unsupported-module', + templateUrl: 'unsupported-module.html', +}) +export class CoreCourseUnsupportedModulePage { + + module: any; + isDisabledInSite: boolean; + isSupportedByTheApp: boolean; + moduleName: string; + + constructor(navParams: NavParams, private translate: TranslateService, private textUtils: CoreTextUtilsProvider, + private moduleDelegate: CoreCourseModuleDelegate, private courseProvider: CoreCourseProvider) { + this.module = navParams.get('module') || {}; + } + + /** + * View loaded. + */ + ionViewDidLoad() { + this.isDisabledInSite = this.moduleDelegate.isModuleDisabledInSite(this.module.modname); + this.isSupportedByTheApp = this.moduleDelegate.hasHandler(this.module.modname); + this.moduleName = this.courseProvider.translateModuleName(this.module.modname); + } + + /** + * Expand the description. + */ + expandDescription() { + this.textUtils.expandText(this.translate.instant('core.description'), this.module.description, false); + } +} diff --git a/src/core/course/providers/module-delegate.ts b/src/core/course/providers/module-delegate.ts index 452021076..34ba15b49 100644 --- a/src/core/course/providers/module-delegate.ts +++ b/src/core/course/providers/module-delegate.ts @@ -13,6 +13,7 @@ // limitations under the License. import { Injectable } from '@angular/core'; +import { NavController } from 'ionic-angular'; import { CoreEventsProvider } from '../../../providers/events'; import { CoreLoggerProvider } from '../../../providers/logger'; import { CoreSitesProvider } from '../../../providers/sites'; @@ -91,10 +92,11 @@ export interface CoreCourseModuleHandlerData { * Action to perform when the module is clicked. * * @param {Event} event The click event. + * @param {NavController} navCtrl NavController instance. * @param {any} module The module object. * @param {number} courseId The course ID. */ - action?(event: Event, module: any, courseId: number) : void; + action?(event: Event, navCtrl: NavController, module: any, courseId: number) : void; }; /** @@ -135,10 +137,11 @@ export interface CoreCourseModuleHandlerButton { * Action to perform when the button is clicked. * * @param {Event} event The click event. + * @param {NavController} navCtrl NavController instance. * @param {any} module The module object. * @param {number} courseId The course ID. */ - action?(event: Event, module: any, courseId: number) : void; + action(event: Event, navCtrl: NavController, module: any, courseId: number) : void; }; /** @@ -179,10 +182,11 @@ export class CoreCourseModuleDelegate { icon: this.courseProvider.getModuleIconSrc(module.modname), title: module.name, class: 'core-course-default-handler core-course-module-' + module.modname + '-handler', - action: (event: Event, module: any, courseId: number) => { + action: (event: Event, navCtrl: NavController, module: any, courseId: number) => { event.preventDefault(); event.stopPropagation(); - // @todo: Default content. + + navCtrl.push('CoreCourseUnsupportedModulePage', {module: module}); } }; diff --git a/src/directives/format-text.ts b/src/directives/format-text.ts index 19fd36c34..119985bd8 100644 --- a/src/directives/format-text.ts +++ b/src/directives/format-text.ts @@ -171,9 +171,12 @@ export class CoreFormatTextDirective implements OnChanges { // If cannot calculate height, shorten always. if (!height || height > this.maxHeight) { - let expandInFullview = this.utils.isTrueOrOne(this.fullOnClick) || false; + let expandInFullview = this.utils.isTrueOrOne(this.fullOnClick) || false, + showMoreDiv = document.createElement('div'); - this.element.innerHTML += '
' + this.translate.instant('core.showmore') + '
'; + showMoreDiv.classList.add('core-show-more'); + showMoreDiv.innerHTML = this.translate.instant('core.showmore'); + this.element.appendChild(showMoreDiv); if (expandInFullview) { this.element.classList.add('core-expand-in-fullview');