MOBILE-3814 module: Adapt module preview page
parent
5c2eb8fc0a
commit
a34736bc60
|
@ -1517,10 +1517,8 @@
|
||||||
"core.course": "moodle",
|
"core.course": "moodle",
|
||||||
"core.course.activitydisabled": "local_moodlemobileapp",
|
"core.course.activitydisabled": "local_moodlemobileapp",
|
||||||
"core.course.activitynotyetviewableremoteaddon": "local_moodlemobileapp",
|
"core.course.activitynotyetviewableremoteaddon": "local_moodlemobileapp",
|
||||||
"core.course.activitynotyetviewablesiteupgradeneeded": "local_moodlemobileapp",
|
|
||||||
"core.course.allsections": "local_moodlemobileapp",
|
"core.course.allsections": "local_moodlemobileapp",
|
||||||
"core.course.aria:sectionprogress": "local_moodlemobileapp",
|
"core.course.aria:sectionprogress": "local_moodlemobileapp",
|
||||||
"core.course.askadmintosupport": "local_moodlemobileapp",
|
|
||||||
"core.course.availablespace": "local_moodlemobileapp",
|
"core.course.availablespace": "local_moodlemobileapp",
|
||||||
"core.course.cannotdeletewhiledownloading": "local_moodlemobileapp",
|
"core.course.cannotdeletewhiledownloading": "local_moodlemobileapp",
|
||||||
"core.course.completion_automatic:done": "course",
|
"core.course.completion_automatic:done": "course",
|
||||||
|
@ -2357,7 +2355,6 @@
|
||||||
"core.whatisyourage": "moodle",
|
"core.whatisyourage": "moodle",
|
||||||
"core.wheredoyoulive": "moodle",
|
"core.wheredoyoulive": "moodle",
|
||||||
"core.whoissiteadmin": "local_moodlemobileapp",
|
"core.whoissiteadmin": "local_moodlemobileapp",
|
||||||
"core.whoops": "local_moodlemobileapp",
|
|
||||||
"core.whyisthishappening": "local_moodlemobileapp",
|
"core.whyisthishappening": "local_moodlemobileapp",
|
||||||
"core.whyisthisrequired": "moodle",
|
"core.whyisthisrequired": "moodle",
|
||||||
"core.wsfunctionnotavailable": "local_moodlemobileapp",
|
"core.wsfunctionnotavailable": "local_moodlemobileapp",
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
<core-format-text [text]="module.name" contextLevel="module" [component]="component" [componentId]="componentId"
|
<core-format-text [text]="module.name" contextLevel="module" [component]="component" [componentId]="componentId"
|
||||||
[contextInstanceId]="module.id" [courseId]="courseId">
|
[contextInstanceId]="module.id" [courseId]="courseId">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
|
<ion-icon name="fas-lock" *ngIf="module.visible === 0 || module.uservisible === false"
|
||||||
|
[attr.aria-label]="'core.restricted' | translate"></ion-icon>
|
||||||
</h1>
|
</h1>
|
||||||
<ng-content select="[title]"></ng-content>
|
<ng-content select="[title]"></ng-content>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
|
@ -20,22 +22,33 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ng-content select="[description]"></ng-content>
|
<ng-content select="[description]"></ng-content>
|
||||||
|
|
||||||
<ion-item class="ion-text-wrap" *ngIf="showCompletion && (module.dates?.length ||
|
<!-- Module completion. -->
|
||||||
(module.completiondata && module.completiondata.isautomatic && module.uservisible))">
|
<ion-item class="ion-text-wrap" *ngIf="showCompletion && module.completiondata && module.completiondata.isautomatic">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<!-- Activity dates. -->
|
|
||||||
<div *ngIf="module.dates?.length" class="core-module-dates">
|
|
||||||
<p *ngFor="let date of module.dates">
|
|
||||||
<ion-icon name="fas-calendar" aria-hidden="true"></ion-icon><strong>{{ date.label }}</strong> {{ date.timestamp * 1000 |
|
|
||||||
coreFormatDate:'strftimedatetime' }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<!-- Module completion. -->
|
|
||||||
<core-course-module-completion [completion]="module.completiondata" [moduleName]="module.name" [moduleId]="module.id"
|
<core-course-module-completion [completion]="module.completiondata" [moduleName]="module.name" [moduleId]="module.id"
|
||||||
[showCompletionConditions]="true">
|
[showCompletionConditions]="true">
|
||||||
</core-course-module-completion>
|
</core-course-module-completion>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
|
<div class="core-module-dates-availabilityinfo"
|
||||||
|
*ngIf="(module.dates && module.dates.length) || (showAvailabilityInfo && module.availabilityinfo)">
|
||||||
|
<!-- Activity dates. -->
|
||||||
|
<div *ngIf="module.dates && module.dates.length" class="core-module-dates">
|
||||||
|
<p *ngFor="let date of module.dates">
|
||||||
|
<ion-icon name="fas-calendar" aria-hidden="true"></ion-icon><strong>{{ date.label }}</strong> {{ date.timestamp
|
||||||
|
*
|
||||||
|
1000 | coreFormatDate:'strftimedatetime' }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<!-- Availability info space. -->
|
||||||
|
<div class="core-module-availabilityinfo" *ngIf="showAvailabilityInfo">
|
||||||
|
<ion-icon name="fas-lock" [attr.aria-label]="'core.restricted' | translate"></ion-icon>
|
||||||
|
<core-format-text [text]="module.availabilityinfo" contextLevel="module" [contextInstanceId]="module.id" [courseId]="module.course">
|
||||||
|
</core-format-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
|
|
||||||
<!-- Activity has something offline. -->
|
<!-- Activity has something offline. -->
|
||||||
|
|
|
@ -16,15 +16,37 @@
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-module-dates {
|
h1 ion-icon {
|
||||||
|
color: var(--medium);
|
||||||
|
@include margin-horizontal(8px, null);
|
||||||
|
font-size: 80%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.core-module-dates-availabilityinfo {
|
||||||
background: var(--light);
|
background: var(--light);
|
||||||
border-radius: var(--small-radius);
|
border-radius: var(--small-radius);
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
|
margin: 8px;
|
||||||
|
font-size: 90%;
|
||||||
ion-icon {
|
ion-icon {
|
||||||
|
position: static;
|
||||||
@include margin-horizontal(null, 8px);
|
@include margin-horizontal(null, 8px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul {
|
||||||
|
margin-top: 4px;
|
||||||
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.core-module-dates + .core-module-availabilityinfo {
|
||||||
|
border-top: 1px solid var(--stroke);
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,8 @@ export class CoreCourseModuleInfoComponent implements OnInit {
|
||||||
@Input() description?: string | false; // The description to display. If false, no description will be shown.
|
@Input() description?: string | false; // The description to display. If false, no description will be shown.
|
||||||
@Input() expandDescription = false; // If the description should be expanded by default.
|
@Input() expandDescription = false; // If the description should be expanded by default.
|
||||||
|
|
||||||
|
@Input() showAvailabilityInfo = false; // If show availability info on the box.
|
||||||
|
|
||||||
@Input() hasDataToSync = false; // If the activity has any data to be synced.
|
@Input() hasDataToSync = false; // If the activity has any data to be synced.
|
||||||
|
|
||||||
modicon = '';
|
modicon = '';
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
<div class="ion-padding">
|
<ion-card class="core-danger-card">
|
||||||
<h2 *ngIf="!isDisabledInSite && isSupportedByTheApp">{{ 'core.whoops' | translate }}</h2>
|
<ion-item>
|
||||||
<h2 *ngIf="isDisabledInSite || !isSupportedByTheApp">{{ 'core.uhoh' | translate }}</h2>
|
<ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
|
||||||
|
<ion-label>
|
||||||
<p class="core-big" *ngIf="isDisabledInSite">{{ 'core.course.activitydisabled' | translate }}</p>
|
<p><strong>{{ 'core.uhoh' | translate }} </strong>
|
||||||
<p class="core-big" *ngIf="!isDisabledInSite && isSupportedByTheApp">
|
<ng-container *ngIf="isDisabledInSite">{{ 'core.course.activitydisabled' | translate }}</ng-container>
|
||||||
{{ 'core.course.activitynotyetviewablesiteupgradeneeded' | translate }}
|
<ng-container *ngIf="!isDisabledInSite">
|
||||||
</p>
|
|
||||||
<p class="core-big" *ngIf="!isDisabledInSite && !isSupportedByTheApp">
|
|
||||||
{{ 'core.course.activitynotyetviewableremoteaddon' | translate }}
|
{{ 'core.course.activitynotyetviewableremoteaddon' | translate }}
|
||||||
|
</ng-container>
|
||||||
</p>
|
</p>
|
||||||
<p *ngIf="isDisabledInSite || !isSupportedByTheApp"><strong>{{ 'core.course.askadmintosupport' | translate }}</strong></p>
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
<div *ngIf="module && module.url">
|
</ion-card>
|
||||||
<p><strong>{{ 'core.course.useactivityonbrowser' | translate }}</strong></p>
|
<ion-item lines="none" class="ion-text-wrap" *ngIf="module?.url && module?.uservisible">
|
||||||
<ion-button expand="block" [href]="module.url" core-link [showBrowserWarning]="false">
|
<ion-label>
|
||||||
|
<p>{{ 'core.course.useactivityonbrowser' | translate }}</p>
|
||||||
|
<ion-button expand="block" [href]="module?.url" core-link [showBrowserWarning]="false">
|
||||||
{{ 'core.openinbrowser' | translate }}
|
{{ 'core.openinbrowser' | translate }}
|
||||||
<ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</div>
|
</ion-label>
|
||||||
</div>
|
</ion-item>
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
|
|
||||||
import { CoreCourse } from '@features/course/services/course';
|
|
||||||
import { CoreCourseModuleData } from '@features/course/services/course-helper';
|
import { CoreCourseModuleData } from '@features/course/services/course-helper';
|
||||||
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
||||||
|
|
||||||
|
@ -27,12 +26,10 @@ import { CoreCourseModuleDelegate } from '@features/course/services/module-deleg
|
||||||
})
|
})
|
||||||
export class CoreCourseUnsupportedModuleComponent implements OnInit {
|
export class CoreCourseUnsupportedModuleComponent implements OnInit {
|
||||||
|
|
||||||
@Input() courseId?: number; // The course to module belongs to.
|
@Input() courseId?: number; // The course to module belongs to (unused).
|
||||||
@Input() module?: CoreCourseModuleData; // The module to render.
|
@Input() module?: CoreCourseModuleData; // The module to render.
|
||||||
|
|
||||||
isDisabledInSite?: boolean;
|
isDisabledInSite = false; // It is implicit than if not disabled it will be unsupported.
|
||||||
isSupportedByTheApp?: boolean;
|
|
||||||
moduleName?: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
|
@ -43,8 +40,6 @@ export class CoreCourseUnsupportedModuleComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isDisabledInSite = CoreCourseModuleDelegate.isModuleDisabledInSite(this.module.modname);
|
this.isDisabledInSite = CoreCourseModuleDelegate.isModuleDisabledInSite(this.module.modname);
|
||||||
this.isSupportedByTheApp = CoreCourseModuleDelegate.hasHandler(this.module.modname);
|
|
||||||
this.moduleName = CoreCourse.translateModuleName(this.module.modname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
{
|
{
|
||||||
"activitydisabled": "Your organisation has disabled this activity in the mobile app.",
|
"activitydisabled": "Your organisation has disabled this activity in the mobile app.",
|
||||||
"activitynotyetviewableremoteaddon": "Your organisation installed a plugin that is not yet supported.",
|
"activitynotyetviewableremoteaddon": "Your organisation installed a plugin that is not yet supported.",
|
||||||
"activitynotyetviewablesiteupgradeneeded": "Your organisation's Moodle installation needs to be updated.",
|
|
||||||
"allsections": "All sections",
|
"allsections": "All sections",
|
||||||
"aria:sectionprogress": "Section progress:",
|
"aria:sectionprogress": "Section progress:",
|
||||||
"askadmintosupport": "Contact the site administrator and tell them you want to use this activity with the Moodle Mobile app.",
|
|
||||||
"availablespace": " You currently have about {{available}} free space.",
|
"availablespace": " You currently have about {{available}} free space.",
|
||||||
"cannotdeletewhiledownloading": "Files cannot be deleted while the activity is being downloaded. Please wait for the download to finish.",
|
"cannotdeletewhiledownloading": "Files cannot be deleted while the activity is being downloaded. Please wait for the download to finish.",
|
||||||
"completion_automatic:done": "Done:",
|
"completion_automatic:done": "Done:",
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
</ion-title>
|
</ion-title>
|
||||||
|
|
||||||
<ion-buttons slot="end">
|
<ion-buttons slot="end">
|
||||||
<ion-button fill="clear" *ngIf="module.url" [href]="module.url" core-link [showBrowserWarning]="false" color="dark"
|
<ion-button fill="clear" *ngIf="module.url && module.uservisible && !unsupported" [href]="module.url" core-link
|
||||||
[attr.aria-label]="'core.openinbrowser' | translate">
|
[showBrowserWarning]="false" color="dark" [attr.aria-label]="'core.openinbrowser' | translate">
|
||||||
<ion-icon name="fas-external-link-alt" slot="icon-only" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-external-link-alt" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
|
@ -24,44 +24,24 @@
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
<core-course-module-info [module]="module" [courseId]="courseId" [description]="module.description" [component]="module.modname"
|
<core-course-module-info [module]="module" [courseId]="courseId" [description]="module.description" [component]="module.modname"
|
||||||
[componentId]="module.id" [expandDescription]="true">
|
[componentId]="module.id" [expandDescription]="true" [showAvailabilityInfo]="true">
|
||||||
|
<div class="core-module-additional-info" title>
|
||||||
<ion-item class="ion-text-wrap" *ngIf="module.handlerData?.extraBadge ||
|
|
||||||
(module.visible === 0 && (!section || section.visible)) ||
|
|
||||||
(module.visible !== 0 && module.isStealth) ||
|
|
||||||
module.availabilityinfo">
|
|
||||||
<ion-label>
|
|
||||||
<div class="ion-padding" *ngIf="module.handlerData?.extraBadge">
|
|
||||||
<ion-chip *ngIf="module.handlerData?.extraBadge" [color]="module.handlerData?.extraBadgeColor"
|
<ion-chip *ngIf="module.handlerData?.extraBadge" [color]="module.handlerData?.extraBadgeColor"
|
||||||
class="ion-text-wrap ion-text-start" [outline]="true">
|
class="ion-text-wrap ion-text-start" [outline]="true">
|
||||||
<ion-label><span [innerHTML]="module.handlerData?.extraBadge"></span></ion-label>
|
<ion-label><span [innerHTML]="module.handlerData?.extraBadge"></span></ion-label>
|
||||||
</ion-chip>
|
</ion-chip>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Hidden badges -->
|
<!-- Hidden badges -->
|
||||||
<div *ngIf="module.visible === 0 && (!section || section.visible)">
|
<ion-badge color="warning" *ngIf="module.visible === 0">
|
||||||
<ion-badge color="warning">
|
|
||||||
{{ 'core.course.hiddenfromstudents' | translate }}
|
{{ 'core.course.hiddenfromstudents' | translate }}
|
||||||
</ion-badge>
|
</ion-badge>
|
||||||
</div>
|
<ion-badge color="warning" *ngIf="module.visible !== 0 && module.isStealth">
|
||||||
<div *ngIf="module.visible !== 0 && module.isStealth">
|
|
||||||
<ion-badge color="warning">
|
|
||||||
{{ 'core.course.hiddenoncoursepage' | translate }}
|
{{ 'core.course.hiddenoncoursepage' | translate }}
|
||||||
</ion-badge>
|
</ion-badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Availability info -->
|
|
||||||
<div *ngIf="module.availabilityinfo" class="core-module-availabilityinfo">
|
|
||||||
<ion-icon name="fas-lock" [attr.aria-label]="'core.restricted' | translate"></ion-icon>
|
|
||||||
<core-format-text [text]="module.availabilityinfo" contextLevel="module" [contextInstanceId]="module.id"
|
|
||||||
[courseId]="module.course">
|
|
||||||
</core-format-text>
|
|
||||||
</div>
|
|
||||||
</ion-label>
|
|
||||||
</ion-item>
|
|
||||||
|
|
||||||
<core-course-unsupported-module *ngIf="unsupported" [module]="module" [courseId]="courseId"></core-course-unsupported-module>
|
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
|
<core-course-unsupported-module *ngIf="unsupported" [module]="module"></core-course-unsupported-module>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module"
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module"
|
||||||
|
|
|
@ -37,6 +37,7 @@ export class CoreCourseModulePreviewPage implements OnInit {
|
||||||
courseId!: number;
|
courseId!: number;
|
||||||
loaded = false;
|
loaded = false;
|
||||||
unsupported = false;
|
unsupported = false;
|
||||||
|
isDisabledInSite = false;
|
||||||
showManualCompletion = false;
|
showManualCompletion = false;
|
||||||
|
|
||||||
protected debouncedUpdateModule?: () => void; // Update the module after a certain time.
|
protected debouncedUpdateModule?: () => void; // Update the module after a certain time.
|
||||||
|
@ -80,6 +81,8 @@ export class CoreCourseModulePreviewPage implements OnInit {
|
||||||
if (!this.unsupported) {
|
if (!this.unsupported) {
|
||||||
this.module.handlerData =
|
this.module.handlerData =
|
||||||
await CoreCourseModuleDelegate.getModuleDataFor(this.module.modname, this.module, this.courseId);
|
await CoreCourseModuleDelegate.getModuleDataFor(this.module.modname, this.module, this.courseId);
|
||||||
|
} else {
|
||||||
|
this.isDisabledInSite = CoreCourseModuleDelegate.isModuleDisabledInSite(this.module.modname);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.title = this.module.name;
|
this.title = this.module.name;
|
||||||
|
|
|
@ -342,7 +342,6 @@
|
||||||
"whatisyourage": "What is your age?",
|
"whatisyourage": "What is your age?",
|
||||||
"wheredoyoulive": "In which country do you live?",
|
"wheredoyoulive": "In which country do you live?",
|
||||||
"whoissiteadmin": "\"Site Administrators\" are the people who manage the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.",
|
"whoissiteadmin": "\"Site Administrators\" are the people who manage the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.",
|
||||||
"whoops": "Oops!",
|
|
||||||
"whyisthishappening": "Why is this happening?",
|
"whyisthishappening": "Why is this happening?",
|
||||||
"whyisthisrequired": "Why is this required?",
|
"whyisthisrequired": "Why is this required?",
|
||||||
"wsfunctionnotavailable": "The web service function is not available.",
|
"wsfunctionnotavailable": "The web service function is not available.",
|
||||||
|
|
Loading…
Reference in New Issue