MOBILE-3814 course: Add action sheet to enrol me on course summary
parent
115ba52984
commit
f184a09550
|
@ -1567,6 +1567,7 @@
|
|||
"core.course.thisweek": "format_weeks/currentsection",
|
||||
"core.course.todo": "completion",
|
||||
"core.course.useactivityonbrowser": "local_moodlemobileapp",
|
||||
"core.course.viewcourse": "block_timeline",
|
||||
"core.course.warningmanualcompletionmodified": "local_moodlemobileapp",
|
||||
"core.course.warningofflinemanualcompletiondeleted": "local_moodlemobileapp",
|
||||
"core.coursedetails": "moodle",
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
:host {
|
||||
--course-storage-max-activity-height: 120px;
|
||||
|
||||
ion-card ion-item {
|
||||
--inner-padding-end: 0px;
|
||||
}
|
||||
|
||||
ion-card.section ion-card-header {
|
||||
margin-bottom: 8px;
|
||||
padding-top: 8px;
|
||||
|
@ -48,7 +52,3 @@ ion-item core-mod-icon {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
ion-item {
|
||||
--inner-padding-end: 0px;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
"thisweek": "This week",
|
||||
"todo": "To do",
|
||||
"useactivityonbrowser": "You can still use it using your device's web browser.",
|
||||
"viewcourse": "View course",
|
||||
"warningmanualcompletionmodified": "The manual completion of an activity was modified on the site.",
|
||||
"warningofflinemanualcompletiondeleted": "Some offline manual completion of course '{{name}}' has been deleted. {{error}}"
|
||||
}
|
||||
|
|
|
@ -130,43 +130,27 @@
|
|||
|
||||
<ion-footer *ngIf="course && dataLoaded">
|
||||
<ng-container *ngIf="canAccessCourse">
|
||||
<ion-button *ngFor="let item of courseMenuHandlers" (click)="openMenuItem(item)" [class]="item.data.class" expand="block">
|
||||
<ion-button *ngFor="let item of courseMenuHandlers" (click)="openMenuItem(item)" [class]="'ion-text-wrap '+ item.data.class"
|
||||
expand="block">
|
||||
<ion-icon *ngIf="item.data.icon" [name]="item.data.icon" slot="start" aria-hidden="true"></ion-icon>
|
||||
<ion-label>{{item.data.title | translate }}</ion-label>
|
||||
</ion-button>
|
||||
</ng-container>
|
||||
|
||||
<!-- Enrol -->
|
||||
<ion-card *ngIf="!isEnrolled && (selfEnrolInstances.length > 0 || paypalEnabled)">
|
||||
<ion-item class="ion-text-wrap" *ngFor="let instance of selfEnrolInstances">
|
||||
<ion-label>
|
||||
<p class="item-heading">{{ instance.name }}</p>
|
||||
<ion-button expand="block" class="ion-margin-top" (click)="selfEnrolClicked(instance.id)">
|
||||
{{ 'core.courses.enrolme' | translate }}
|
||||
</ion-button>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap" *ngIf="paypalEnabled">
|
||||
<ion-label>
|
||||
<p class="item-heading">{{ 'core.courses.otherenrolments' | translate }}</p>
|
||||
<ion-button expand="block" class="ion-margin-top" (click)="browserEnrol()">
|
||||
{{ 'core.courses.completeenrolmentbrowser' | translate }}
|
||||
</ion-button>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
<ion-button expand="block" (click)="enrolMe()" *ngIf="!isEnrolled && (selfEnrolInstances.length > 0 || otherEnrolments)"
|
||||
class="ion-text-wrap">
|
||||
{{ 'core.courses.enrolme' | translate }}
|
||||
</ion-button>
|
||||
|
||||
<ion-card class="core-info-card" *ngIf="!isEnrolled && !selfEnrolInstances.length && !paypalEnabled">
|
||||
<ion-card class="core-info-card ion-text-wrap" *ngIf="!isEnrolled && !selfEnrolInstances.length && !otherEnrolments">
|
||||
<ion-item>
|
||||
<ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
|
||||
<ion-label>{{ 'core.courses.notenrollable' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
|
||||
<ion-button (click)="openCourse()" *ngIf="!isModal && canAccessCourse" expand="block">
|
||||
<ion-icon name="fas-briefcase" slot="start" aria-hidden="true"></ion-icon>
|
||||
<ion-label>
|
||||
{{ 'core.course' | translate }}
|
||||
</ion-label>
|
||||
<ion-button (click)="openCourse()" *ngIf="!isModal && canAccessCourse" expand="block" fill="outline" class="ion-text-wrap">
|
||||
<ion-icon name="fas-eye" slot="start" aria-hidden="true"></ion-icon>
|
||||
{{ 'core.course.viewcourse' | translate }}
|
||||
</ion-button>
|
||||
</ion-footer>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Component, OnDestroy, OnInit, Input, ViewChild, ElementRef } from '@angular/core';
|
||||
import { IonRefresher } from '@ionic/angular';
|
||||
import { ActionSheetButton, IonRefresher } from '@ionic/angular';
|
||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
|
@ -31,7 +31,7 @@ import {
|
|||
CoreCourseOptionsMenuHandlerToDisplay,
|
||||
} from '@features/course/services/course-options-delegate';
|
||||
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||
import { ModalController, NgZone, Platform, Translate } from '@singletons';
|
||||
import { ActionSheetController, ModalController, NgZone, Platform, Translate } from '@singletons';
|
||||
import { CoreCoursesSelfEnrolPasswordComponent } from '../../../courses/components/self-enrol-password/self-enrol-password';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
|
@ -57,7 +57,7 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
|
|||
isEnrolled = false;
|
||||
canAccessCourse = true;
|
||||
selfEnrolInstances: CoreCourseEnrolmentMethod[] = [];
|
||||
paypalEnabled = false;
|
||||
otherEnrolments = false;
|
||||
dataLoaded = false;
|
||||
isModal = false;
|
||||
contactsExpanded = false;
|
||||
|
@ -65,6 +65,8 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
|
|||
courseUrl = '';
|
||||
progress?: number;
|
||||
|
||||
protected actionSheet?: HTMLIonActionSheetElement;
|
||||
|
||||
courseMenuHandlers: CoreCourseOptionsMenuHandlerToDisplay[] = [];
|
||||
|
||||
protected useGuestAccess = false;
|
||||
|
@ -146,18 +148,24 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
|
|||
protected async getCourse(refresh = false): Promise<void> {
|
||||
// Get course enrolment methods.
|
||||
this.selfEnrolInstances = [];
|
||||
this.otherEnrolments = false;
|
||||
|
||||
try {
|
||||
const enrolmentMethods = await CoreCourses.getCourseEnrolmentMethods(this.courseId);
|
||||
this.guestInstanceId = undefined;
|
||||
|
||||
enrolmentMethods.forEach((method) => {
|
||||
if (!method.status) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (method.type === 'self') {
|
||||
this.selfEnrolInstances.push(method);
|
||||
} else if (method.type === 'guest') {
|
||||
this.guestInstanceId = method.id;
|
||||
} else if (method.type === 'paypal') {
|
||||
this.paypalEnabled = true;
|
||||
} else {
|
||||
// Other enrolments that comes from that WS should need user action.
|
||||
this.otherEnrolments = true;
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
|
@ -196,7 +204,10 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
|
|||
this.course = courseByField;
|
||||
}
|
||||
|
||||
this.paypalEnabled = !this.isEnrolled && courseByField.enrollmentmethods?.indexOf('paypal') > -1;
|
||||
// enrollmentmethods contains ALL enrolment methods including manual.
|
||||
if (!this.isEnrolled && courseByField.enrollmentmethods?.some((method) => method === 'paypal')) {
|
||||
this.otherEnrolments = true;
|
||||
}
|
||||
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
|
@ -256,7 +267,7 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
|
|||
try {
|
||||
await CoreDomUtils.showConfirm(
|
||||
Translate.instant('core.courses.browserenrolinstructions'),
|
||||
undefined,
|
||||
Translate.instant('core.courses.completeenrolmentbrowser'),
|
||||
Translate.instant('core.openinbrowser'),
|
||||
);
|
||||
} catch {
|
||||
|
@ -276,15 +287,15 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
/**
|
||||
* User clicked in a self enrol button.
|
||||
* Confirm user to Self enrol in course.
|
||||
*
|
||||
* @param instanceId The instance ID of the enrolment method.
|
||||
* @param enrolMethod The enrolment method.
|
||||
*/
|
||||
async selfEnrolClicked(instanceId: number): Promise<void> {
|
||||
async selfEnrolConfirm(enrolMethod: CoreCourseEnrolmentMethod): Promise<void> {
|
||||
try {
|
||||
await CoreDomUtils.showConfirm(Translate.instant('core.courses.confirmselfenrol'));
|
||||
await CoreDomUtils.showConfirm(Translate.instant('core.courses.confirmselfenrol'), enrolMethod.name);
|
||||
|
||||
this.selfEnrolInCourse('', instanceId);
|
||||
this.selfEnrolInCourse(enrolMethod.id);
|
||||
} catch {
|
||||
// User cancelled.
|
||||
}
|
||||
|
@ -293,11 +304,11 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
|
|||
/**
|
||||
* Self enrol in a course.
|
||||
*
|
||||
* @param password Password to use.
|
||||
* @param instanceId The instance ID.
|
||||
* @param password Password to use.
|
||||
* @return Promise resolved when self enrolled.
|
||||
*/
|
||||
async selfEnrolInCourse(password: string, instanceId: number): Promise<void> {
|
||||
async selfEnrolInCourse(instanceId: number, password = ''): Promise<void> {
|
||||
const modal = await CoreDomUtils.showModalLoading('core.loading', true);
|
||||
|
||||
try {
|
||||
|
@ -336,7 +347,7 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
|
|||
);
|
||||
|
||||
if (modalData !== undefined) {
|
||||
this.selfEnrolInCourse(modalData, instanceId);
|
||||
this.selfEnrolInCourse(instanceId, modalData);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -442,6 +453,51 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open enrol action sheet.
|
||||
*/
|
||||
async enrolMe(): Promise<void> {
|
||||
if (this.selfEnrolInstances.length == 1 && !this.otherEnrolments) {
|
||||
this.selfEnrolConfirm(this.selfEnrolInstances[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.selfEnrolInstances.length == 0 && this.otherEnrolments) {
|
||||
this.browserEnrol();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const buttons: ActionSheetButton[] = this.selfEnrolInstances.map((enrolMethod) => ({
|
||||
text: enrolMethod.name,
|
||||
handler: (): void => {
|
||||
this.selfEnrolConfirm(enrolMethod);
|
||||
},
|
||||
}));
|
||||
|
||||
if (this.otherEnrolments) {
|
||||
buttons.push({
|
||||
text: Translate.instant('core.courses.completeenrolmentbrowser'),
|
||||
handler: (): void => {
|
||||
this.browserEnrol();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
buttons.push({
|
||||
text: Translate.instant('core.cancel'),
|
||||
role: 'cancel',
|
||||
});
|
||||
|
||||
this.actionSheet = await ActionSheetController.create({
|
||||
header: Translate.instant('core.courses.enrolme'),
|
||||
buttons: buttons,
|
||||
});
|
||||
|
||||
await this.actionSheet.present();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle list of contacts.
|
||||
*/
|
||||
|
|
|
@ -114,7 +114,7 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On
|
|||
} else if (instance === 'paypal') {
|
||||
this.enrolmentIcons.push({
|
||||
label: 'core.courses.otherenrolments',
|
||||
icon: 'fab-paypal',
|
||||
icon: 'fas-external-link-alt',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -833,24 +833,23 @@ ion-toolbar h1 .core-bar-button-image img {
|
|||
}
|
||||
|
||||
// Action sheet.
|
||||
.md ion-action-sheet {
|
||||
ion-action-sheet.md {
|
||||
.action-sheet-title {
|
||||
@include padding(4px, null, 4px, 16px);
|
||||
font-size: 12px;
|
||||
min-height: auto;
|
||||
color: var(--medium);
|
||||
line-height: 2em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.action-sheet-group:first-child {
|
||||
border-radius: var(--big-radius) var(--big-radius) 0 0;
|
||||
}
|
||||
|
||||
.action-sheet-group-cancel {
|
||||
box-shadow: var(--drop-shadow-top, none);
|
||||
}
|
||||
|
||||
.action-sheet-title {
|
||||
border-bottom: 2px solid var(--title-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
.ios ion-action-sheet {
|
||||
.action-sheet-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.action-sheet-title {
|
||||
border-bottom: 2px solid var(--title-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
// Radio.
|
||||
|
|
|
@ -216,7 +216,6 @@
|
|||
ion-action-sheet {
|
||||
--button-color: var(--ion-text-color);
|
||||
--button-color-selected: var(--ion-text-color);
|
||||
--title-border-color: var(--primary);
|
||||
|
||||
.action-sheet-title {
|
||||
--color: var(--ion-text-color);
|
||||
|
@ -325,7 +324,7 @@
|
|||
--core-star-color: var(--primary);
|
||||
|
||||
--core-large-avatar-size: 90px;
|
||||
--core-avatar-size: 40px;
|
||||
--core-avatar-size: var(--a11y-min-target-size);
|
||||
|
||||
--core-courseimage-on-course-size: 72px;
|
||||
--core-courseimage-radius: var(--medium-radius);
|
||||
|
|
Loading…
Reference in New Issue