MOBILE-2310 course: Implement unsupported module page
parent
2e73942083
commit
cbc9bc715c
|
@ -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.
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<ion-card *ngIf="description">
|
||||
<ion-item text-wrap>
|
||||
<core-format-text [text]="description" [component]="component" [componentId]="componentId" [maxHeight]="showFull && showFull !== 'false' ? 0 : 120" fullOnClick="true"></core-format-text>
|
||||
<ion-note *ngIf="note" item-end>{{ note }}</ion-note>
|
||||
</ion-item>
|
||||
</ion-card>
|
|
@ -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:
|
||||
*
|
||||
* <core-course-module-description [description]="myDescription"></core-course-module-description
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-course-module-description',
|
||||
templateUrl: 'module-description.html'
|
||||
})
|
||||
export class CoreCourseModuleDescriptionComponent {
|
||||
@Input() description: string; // The description to display.
|
||||
@Input() note?: string; // A note to display along with the description.
|
||||
@Input() component?: string; // Component for format text directive.
|
||||
@Input() componentId?: string|number; // Component ID to use in conjunction with the component.
|
||||
@Input() showFull?: string|boolean; // Whether to always display the full description.
|
||||
|
||||
constructor() {}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
<a *ngIf="module && module.visibleoncoursepage !== 0" ion-item text-wrap id="mm-course-module-{{module.id}}" class="mm-course-module-handler {{module.handlerData.class}}" (click)="moduleClicked($event)" [ngClass]="{'item-media': module.handlerData.icon, 'mm-not-clickable': !module.handlerData.action || !module.uservisible === false, 'item-dimmed': module.visible === 0 || module.uservisible === false}" title="{{ module.handlerData.title }}">
|
||||
<a *ngIf="module && module.visibleoncoursepage !== 0" ion-item text-wrap id="core-course-module-{{module.id}}" class="core-course-module-handler {{module.handlerData.class}}" (click)="moduleClicked($event)" [ngClass]="{'item-media': module.handlerData.icon, 'core-not-clickable': !module.handlerData.action || !module.uservisible === false, 'item-dimmed': module.visible === 0 || module.uservisible === false}" title="{{ module.handlerData.title }}">
|
||||
|
||||
<img item-start *ngIf="module.handlerData.icon" [src]="module.handlerData.icon" alt="" role="presentation">
|
||||
|
||||
<core-format-text [text]="module.handlerData.title"></core-format-text>
|
||||
|
||||
<div item-end *ngIf="module.uservisible !== false && ((module.handlerData.buttons && module.handlerData.buttons.length > 0) || spinner || module.completionstatus)" class="buttons mm-module-buttons" [ngClass]="{'mm-button-completion': module.completionstatus}">
|
||||
<div item-end *ngIf="module.uservisible !== false && ((module.handlerData.buttons && module.handlerData.buttons.length > 0) || spinner || module.completionstatus)" class="buttons core-module-buttons" [ngClass]="{'core-button-completion': module.completionstatus}">
|
||||
<core-course-module-completion *ngIf="module.completionstatus" [completion]="module.completionstatus" [moduleName]="module.name" (completionChanged)="completionChanged.emit()"></core-course-module-completion>
|
||||
|
||||
<button ion-button icon-only clear *ngFor="let button of module.handlerData.buttons" [hidden]="button.hidden" (click)="button.action($event, module, courseId)" class="mm-animate-show-hide" [attr.aria-label]="button.label | translate">
|
||||
<button ion-button icon-only clear *ngFor="let button of module.handlerData.buttons" [hidden]="button.hidden" (click)="buttonClicked($event, button)" class="core-animate-show-hide" [attr.aria-label]="button.label | translate">
|
||||
<ion-icon [name]="button.icon" [ios]="button.iosIcon || ''" [md]="button.mdIcon || ''"></ion-icon>
|
||||
</button>
|
||||
|
||||
<ion-spinner *ngIf="module.handlerData.spinner" class="mm-animate-show-hide"></ion-spinner>
|
||||
<ion-spinner *ngIf="module.handlerData.spinner" class="core-animate-show-hide"></ion-spinner>
|
||||
</div>
|
||||
|
||||
<div *ngIf="module.visible === 0 || module.availabilityinfo">
|
||||
|
|
|
@ -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<void>; // 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title><core-format-text [text]="module.name"></core-format-text></ion-title>
|
||||
|
||||
<ion-buttons end>
|
||||
<core-context-menu>
|
||||
<core-context-menu-item [priority]="900" *ngIf="module.url" [href]="module.url" [content]="'core.openinbrowser' | translate" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item [priority]="800" *ngIf="module.description" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
</core-context-menu>
|
||||
</ion-buttons>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<core-course-module-description [description]="module.description"></core-course-module-description>
|
||||
<h2 *ngIf="!isDisabledInSite && isSupportedByTheApp">{{ 'core.whoops' | translate }}</h2>
|
||||
<h2 *ngIf="isDisabledInSite || !isSupportedByTheApp">{{ 'core.uhoh' | translate }}</h2>
|
||||
|
||||
<p class="core-big" *ngIf="isDisabledInSite">{{ 'core.course.activitydisabled' | translate }}</p>
|
||||
<p class="core-big" *ngIf="!isDisabledInSite && isSupportedByTheApp">{{ 'core.course.activitynotyetviewablesiteupgradeneeded' | translate }}</p>
|
||||
<p class="core-big" *ngIf="!isDisabledInSite && !isSupportedByTheApp">{{ 'core.course.activitynotyetviewableremoteaddon' | translate }}</p>
|
||||
<p *ngIf="isDisabledInSite || !isSupportedByTheApp"><strong>{{ 'core.course.askadmintosupport' | translate }}</strong></p>
|
||||
|
||||
<div *ngIf="module.url">
|
||||
<p><strong>{{ 'core.course.useactivityonbrowser' | translate }}</strong></p>
|
||||
<a ion-button block icon-end [href]="module.url" core-link>
|
||||
{{ 'core.openinbrowser' | translate }}
|
||||
<ion-icon name="open"></ion-icon>
|
||||
</a>
|
||||
</div>
|
||||
</ion-content>
|
|
@ -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 {}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 += '<div class="core-show-more">' + this.translate.instant('core.showmore') + '</div>';
|
||||
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');
|
||||
|
|
Loading…
Reference in New Issue