MOBILE-3814 module: Adapt module preview page

main
Pau Ferrer Ocaña 2022-02-18 12:41:04 +01:00
parent 5c2eb8fc0a
commit a34736bc60
10 changed files with 91 additions and 81 deletions

View File

@ -1517,10 +1517,8 @@
"core.course": "moodle",
"core.course.activitydisabled": "local_moodlemobileapp",
"core.course.activitynotyetviewableremoteaddon": "local_moodlemobileapp",
"core.course.activitynotyetviewablesiteupgradeneeded": "local_moodlemobileapp",
"core.course.allsections": "local_moodlemobileapp",
"core.course.aria:sectionprogress": "local_moodlemobileapp",
"core.course.askadmintosupport": "local_moodlemobileapp",
"core.course.availablespace": "local_moodlemobileapp",
"core.course.cannotdeletewhiledownloading": "local_moodlemobileapp",
"core.course.completion_automatic:done": "course",
@ -2357,7 +2355,6 @@
"core.whatisyourage": "moodle",
"core.wheredoyoulive": "moodle",
"core.whoissiteadmin": "local_moodlemobileapp",
"core.whoops": "local_moodlemobileapp",
"core.whyisthishappening": "local_moodlemobileapp",
"core.whyisthisrequired": "moodle",
"core.wsfunctionnotavailable": "local_moodlemobileapp",

View File

@ -7,6 +7,8 @@
<core-format-text [text]="module.name" contextLevel="module" [component]="component" [componentId]="componentId"
[contextInstanceId]="module.id" [courseId]="courseId">
</core-format-text>
<ion-icon name="fas-lock" *ngIf="module.visible === 0 || module.uservisible === false"
[attr.aria-label]="'core.restricted' | translate"></ion-icon>
</h1>
<ng-content select="[title]"></ng-content>
</ion-label>
@ -20,22 +22,33 @@
</ion-item>
<ng-content select="[description]"></ng-content>
<ion-item class="ion-text-wrap" *ngIf="showCompletion && (module.dates?.length ||
(module.completiondata && module.completiondata.isautomatic && module.uservisible))">
<!-- Module completion. -->
<ion-item class="ion-text-wrap" *ngIf="showCompletion && module.completiondata && module.completiondata.isautomatic">
<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"
[showCompletionConditions]="true">
</core-course-module-completion>
</ion-label>
</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>
<!-- Activity has something offline. -->

View File

@ -16,16 +16,38 @@
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);
border-radius: var(--small-radius);
padding: 8px;
margin: 8px;
font-size: 90%;
ion-icon {
position: static;
@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;
}
}
:host-context(.core-iframe-fullscreen) {

View File

@ -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() 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.
modicon = '';

View File

@ -1,21 +1,22 @@
<div class="ion-padding">
<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 && module.url">
<p><strong>{{ 'core.course.useactivityonbrowser' | translate }}</strong></p>
<ion-button expand="block" [href]="module.url" core-link [showBrowserWarning]="false">
<ion-card class="core-danger-card">
<ion-item>
<ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<p><strong>{{ 'core.uhoh' | translate }} </strong>
<ng-container *ngIf="isDisabledInSite">{{ 'core.course.activitydisabled' | translate }}</ng-container>
<ng-container *ngIf="!isDisabledInSite">
{{ 'core.course.activitynotyetviewableremoteaddon' | translate }}
</ng-container>
</p>
</ion-label>
</ion-item>
</ion-card>
<ion-item lines="none" class="ion-text-wrap" *ngIf="module?.url && module?.uservisible">
<ion-label>
<p>{{ 'core.course.useactivityonbrowser' | translate }}</p>
<ion-button expand="block" [href]="module?.url" core-link [showBrowserWarning]="false">
{{ 'core.openinbrowser' | translate }}
<ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
</div>
</div>
</ion-label>
</ion-item>

View File

@ -14,7 +14,6 @@
import { Component, Input, OnInit } from '@angular/core';
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleData } from '@features/course/services/course-helper';
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 {
@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.
isDisabledInSite?: boolean;
isSupportedByTheApp?: boolean;
moduleName?: string;
isDisabledInSite = false; // It is implicit than if not disabled it will be unsupported.
/**
* Component being initialized.
@ -43,8 +40,6 @@ export class CoreCourseUnsupportedModuleComponent implements OnInit {
}
this.isDisabledInSite = CoreCourseModuleDelegate.isModuleDisabledInSite(this.module.modname);
this.isSupportedByTheApp = CoreCourseModuleDelegate.hasHandler(this.module.modname);
this.moduleName = CoreCourse.translateModuleName(this.module.modname);
}
}

View File

@ -1,10 +1,8 @@
{
"activitydisabled": "Your organisation has disabled this activity in the mobile app.",
"activitynotyetviewableremoteaddon": "Your organisation installed a plugin that is not yet supported.",
"activitynotyetviewablesiteupgradeneeded": "Your organisation's Moodle installation needs to be updated.",
"allsections": "All sections",
"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.",
"cannotdeletewhiledownloading": "Files cannot be deleted while the activity is being downloaded. Please wait for the download to finish.",
"completion_automatic:done": "Done:",

View File

@ -11,8 +11,8 @@
</ion-title>
<ion-buttons slot="end">
<ion-button fill="clear" *ngIf="module.url" [href]="module.url" core-link [showBrowserWarning]="false" color="dark"
[attr.aria-label]="'core.openinbrowser' | translate">
<ion-button fill="clear" *ngIf="module.url && module.uservisible && !unsupported" [href]="module.url" core-link
[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-button>
</ion-buttons>
@ -24,44 +24,24 @@
</ion-refresher>
<core-loading [hideUntil]="loaded">
<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-chip *ngIf="module.handlerData?.extraBadge" [color]="module.handlerData?.extraBadgeColor"
class="ion-text-wrap ion-text-start" [outline]="true">
<ion-label><span [innerHTML]="module.handlerData?.extraBadge"></span></ion-label>
</ion-chip>
<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"
class="ion-text-wrap ion-text-start" [outline]="true">
<ion-label><span [innerHTML]="module.handlerData?.extraBadge"></span></ion-label>
</ion-chip>
</div>
<!-- Hidden badges -->
<div *ngIf="module.visible === 0 && (!section || section.visible)">
<ion-badge color="warning">
{{ 'core.course.hiddenfromstudents' | translate }}
</ion-badge>
</div>
<div *ngIf="module.visible !== 0 && module.isStealth">
<ion-badge color="warning">
{{ 'core.course.hiddenoncoursepage' | translate }}
</ion-badge>
</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>
<!-- Hidden badges -->
<ion-badge color="warning" *ngIf="module.visible === 0">
{{ 'core.course.hiddenfromstudents' | translate }}
</ion-badge>
<ion-badge color="warning" *ngIf="module.visible !== 0 && module.isStealth">
{{ 'core.course.hiddenoncoursepage' | translate }}
</ion-badge>
</div>
</core-course-module-info>
<core-course-unsupported-module *ngIf="unsupported" [module]="module"></core-course-unsupported-module>
</core-loading>
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module"

View File

@ -37,6 +37,7 @@ export class CoreCourseModulePreviewPage implements OnInit {
courseId!: number;
loaded = false;
unsupported = false;
isDisabledInSite = false;
showManualCompletion = false;
protected debouncedUpdateModule?: () => void; // Update the module after a certain time.
@ -80,6 +81,8 @@ export class CoreCourseModulePreviewPage implements OnInit {
if (!this.unsupported) {
this.module.handlerData =
await CoreCourseModuleDelegate.getModuleDataFor(this.module.modname, this.module, this.courseId);
} else {
this.isDisabledInSite = CoreCourseModuleDelegate.isModuleDisabledInSite(this.module.modname);
}
this.title = this.module.name;

View File

@ -342,7 +342,6 @@
"whatisyourage": "What is your age?",
"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.",
"whoops": "Oops!",
"whyisthishappening": "Why is this happening?",
"whyisthisrequired": "Why is this required?",
"wsfunctionnotavailable": "The web service function is not available.",