diff --git a/src/addons/mod/lesson/components/components.module.ts b/src/addons/mod/lesson/components/components.module.ts index 1db1ad2f5..6daa4ec51 100644 --- a/src/addons/mod/lesson/components/components.module.ts +++ b/src/addons/mod/lesson/components/components.module.ts @@ -18,13 +18,11 @@ import { CoreSharedModule } from '@/core/shared.module'; import { CoreCourseComponentsModule } from '@features/course/components/components.module'; import { AddonModLessonIndexComponent } from './index/index'; import { AddonModLessonMenuModalPage } from './menu-modal/menu-modal'; -import { AddonModLessonPasswordModalComponent } from './password-modal/password-modal'; @NgModule({ declarations: [ AddonModLessonIndexComponent, AddonModLessonMenuModalPage, - AddonModLessonPasswordModalComponent, ], imports: [ CoreSharedModule, @@ -35,7 +33,6 @@ import { AddonModLessonPasswordModalComponent } from './password-modal/password- exports: [ AddonModLessonIndexComponent, AddonModLessonMenuModalPage, - AddonModLessonPasswordModalComponent, ], }) export class AddonModLessonComponentsModule {} diff --git a/src/addons/mod/lesson/services/handlers/prefetch.ts b/src/addons/mod/lesson/services/handlers/prefetch.ts index e5e354f96..af6005197 100644 --- a/src/addons/mod/lesson/services/handlers/prefetch.ts +++ b/src/addons/mod/lesson/services/handlers/prefetch.ts @@ -13,7 +13,6 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { CoreCanceledError } from '@classes/errors/cancelederror'; import { CoreError } from '@classes/errors/error'; import { CoreCourseActivityPrefetchHandlerBase } from '@features/course/classes/activity-prefetch-handler'; @@ -26,7 +25,6 @@ import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; import { CoreWSFile } from '@services/ws'; import { makeSingleton, Translate } from '@singletons'; -import { AddonModLessonPasswordModalComponent } from '../../components/password-modal/password-modal'; import { AddonModLesson, AddonModLessonGetAccessInformationWSResponse, @@ -55,15 +53,11 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref */ protected async askUserPassword(): Promise { // Create and show the modal. - const modalData = await CoreDomUtils.openModal({ - component: AddonModLessonPasswordModalComponent, + return CoreDomUtils.promptPassword({ + title: 'addon.mod_lesson.enterpassword', + placeholder: 'core.login.password', + submit: 'addon.mod_lesson.continue', }); - - if (typeof modalData != 'string') { - throw new CoreCanceledError(); - } - - return modalData; } /** diff --git a/src/addons/mod/lesson/components/password-modal/password-modal.html b/src/core/components/password-modal/password-modal.html similarity index 53% rename from src/addons/mod/lesson/components/password-modal/password-modal.html rename to src/core/components/password-modal/password-modal.html index 4a6ea9fe2..e54e70810 100644 --- a/src/addons/mod/lesson/components/password-modal/password-modal.html +++ b/src/core/components/password-modal/password-modal.html @@ -1,7 +1,7 @@ -

{{ 'core.login.password' | translate }}

+

{{ title | translate }}

@@ -10,19 +10,18 @@
- -
+ + - {{ 'addon.mod_lesson.enterpassword' | translate }} + {{ placeholder | translate }} - + - - {{ 'addon.mod_lesson.continue' | translate }} - + + {{ submit | translate }} diff --git a/src/core/components/password-modal/password-modal.module.ts b/src/core/components/password-modal/password-modal.module.ts new file mode 100644 index 000000000..77018a384 --- /dev/null +++ b/src/core/components/password-modal/password-modal.module.ts @@ -0,0 +1,29 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// 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 { CorePasswordModalComponent } from './password-modal'; +import { CoreSharedModule } from '@/core/shared.module'; + +export { CorePasswordModalComponent }; + +@NgModule({ + declarations: [ + CorePasswordModalComponent, + ], + imports: [ + CoreSharedModule, + ], +}) +export class CorePasswordModalModule {} diff --git a/src/addons/mod/lesson/components/password-modal/password-modal.ts b/src/core/components/password-modal/password-modal.ts similarity index 61% rename from src/addons/mod/lesson/components/password-modal/password-modal.ts rename to src/core/components/password-modal/password-modal.ts index a163b454e..af2e53b4f 100644 --- a/src/addons/mod/lesson/components/password-modal/password-modal.ts +++ b/src/core/components/password-modal/password-modal.ts @@ -12,37 +12,42 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, ViewChild, ElementRef } from '@angular/core'; -import { IonInput } from '@ionic/angular'; +import { Component, ViewChild, ElementRef, Input } from '@angular/core'; import { CoreSites } from '@services/sites'; import { CoreForms } from '@singletons/form'; import { ModalController } from '@singletons'; /** - * Modal that asks the password for a lesson. + * Modal that asks the password. + * + * WARNING: This component is not loaded with components.module.ts. */ @Component({ - selector: 'page-addon-mod-lesson-password-modal', + selector: 'core-password-modal', templateUrl: 'password-modal.html', }) -export class AddonModLessonPasswordModalComponent { +export class CorePasswordModalComponent { @ViewChild('passwordForm') formElement?: ElementRef; + @Input() title? = 'core.login.password'; // Translatable string to be shown on modal title. + @Input() placeholder? = 'core.login.password'; // Translatable string to be shown on password input as placeholder. + @Input() submit? = 'core.submit'; // Translatable string to be shown on submit button. + @Input() password? = ''; // Previous entered password. + /** * Send the password back. * * @param e Event. - * @param password The input element. */ - submitPassword(e: Event, password: IonInput): void { + submitPassword(e: Event): void { e.preventDefault(); e.stopPropagation(); CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); - ModalController.dismiss(password.value); + ModalController.dismiss(this.password); } /** @@ -55,3 +60,5 @@ export class AddonModLessonPasswordModalComponent { } } + +export type CorePasswordModalParams = Pick; diff --git a/src/core/features/course/pages/course-summary/course-summary.page.ts b/src/core/features/course/pages/course-summary/course-summary.page.ts index 502174240..68dd0cb2a 100644 --- a/src/core/features/course/pages/course-summary/course-summary.page.ts +++ b/src/core/features/course/pages/course-summary/course-summary.page.ts @@ -31,7 +31,6 @@ import { } from '@features/course/services/course-options-delegate'; import { CoreCourseHelper } from '@features/course/services/course-helper'; import { ActionSheetController, ModalController, NgZone, 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'; import { CoreCoursesHelper, CoreCourseWithImageAndColor } from '@features/courses/services/courses-helper'; @@ -374,25 +373,23 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy { modal?.dismiss(); if (error && error.errorcode === CoreCoursesProvider.ENROL_INVALID_KEY) { - // Initialize the self enrol modal. - // Invalid password, show the modal to enter the password. - const modalData = await CoreDomUtils.openModal( - { - component: CoreCoursesSelfEnrolPasswordComponent, - componentProps: { password }, - }, - ); - if (modalData !== undefined) { + try { + // Initialize the self enrol modal. + // Invalid password, show the modal to enter the password. + const modalData = await CoreDomUtils.promptPassword({ + password, + title: 'core.courses.selfenrolment', + placeholder: 'core.courses.password', + submit: 'core.courses.enrolme', + }); + this.selfEnrolInCourse(instanceId, modalData); - - return; - } - - if (!password) { + } catch { // No password entered, don't show error. - return; } + + return; } CoreDomUtils.showErrorModalDefault(error, 'core.courses.errorselfenrol', true); diff --git a/src/core/features/courses/components/components.module.ts b/src/core/features/courses/components/components.module.ts index 24068556c..1b596c8fc 100644 --- a/src/core/features/courses/components/components.module.ts +++ b/src/core/features/courses/components/components.module.ts @@ -18,14 +18,12 @@ import { CoreSharedModule } from '@/core/shared.module'; import { CoreCoursesCourseListItemComponent } from './course-list-item/course-list-item'; import { CoreCoursesCourseProgressComponent } from './course-progress/course-progress'; import { CoreCoursesCourseOptionsMenuComponent } from './course-options-menu/course-options-menu'; -import { CoreCoursesSelfEnrolPasswordComponent } from './self-enrol-password/self-enrol-password'; @NgModule({ declarations: [ CoreCoursesCourseListItemComponent, CoreCoursesCourseProgressComponent, CoreCoursesCourseOptionsMenuComponent, - CoreCoursesSelfEnrolPasswordComponent, ], imports: [ CoreSharedModule, @@ -34,7 +32,6 @@ import { CoreCoursesSelfEnrolPasswordComponent } from './self-enrol-password/sel CoreCoursesCourseListItemComponent, CoreCoursesCourseProgressComponent, CoreCoursesCourseOptionsMenuComponent, - CoreCoursesSelfEnrolPasswordComponent, ], }) export class CoreCoursesComponentsModule {} diff --git a/src/core/features/courses/components/self-enrol-password/self-enrol-password.html b/src/core/features/courses/components/self-enrol-password/self-enrol-password.html deleted file mode 100644 index 4a7455323..000000000 --- a/src/core/features/courses/components/self-enrol-password/self-enrol-password.html +++ /dev/null @@ -1,27 +0,0 @@ - - - -

{{ 'core.courses.selfenrolment' | translate }}

-
- - - - - -
-
- - - - {{ 'core.courses.password' | translate }} - - - - - -
- {{ 'core.courses.enrolme' | translate }} -
- -
diff --git a/src/core/features/courses/components/self-enrol-password/self-enrol-password.ts b/src/core/features/courses/components/self-enrol-password/self-enrol-password.ts deleted file mode 100644 index 12d9db4a6..000000000 --- a/src/core/features/courses/components/self-enrol-password/self-enrol-password.ts +++ /dev/null @@ -1,62 +0,0 @@ -// (C) Copyright 2015 Moodle Pty Ltd. -// -// 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, ViewChild, ElementRef } from '@angular/core'; -import { NavParams } from '@ionic/angular'; -import { CoreSites } from '@services/sites'; -import { ModalController } from '@singletons'; -import { CoreForms } from '@singletons/form'; - -/** - * Modal that displays a form to enter a password to self enrol in a course. - */ -@Component({ - selector: 'page-core-courses-self-enrol-password', - templateUrl: 'self-enrol-password.html', -}) -export class CoreCoursesSelfEnrolPasswordComponent { - - @ViewChild('enrolPasswordForm') formElement!: ElementRef; - password = ''; - - constructor( - navParams: NavParams, - ) { - this.password = navParams.get('password') || ''; - } - - /** - * Close help modal. - */ - close(): void { - CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); - - ModalController.dismiss(); - } - - /** - * Submit password. - * - * @param e Event. - */ - submitPassword(e: Event): void { - e.preventDefault(); - e.stopPropagation(); - - CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); - - ModalController.dismiss(this.password); - } - -} diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index 83eb3c62c..9b93de35e 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -59,6 +59,7 @@ import { CoreErrorInfoComponent } from '@components/error-info/error-info'; import { CorePlatform } from '@services/platform'; import { CoreCancellablePromise } from '@classes/cancellable-promise'; import { CoreLang } from '@services/lang'; +import { CorePasswordModalParams } from '@components/password-modal/password-modal'; /* * "Utils" service with helper functions for UI, DOM elements and HTML code. @@ -1880,6 +1881,33 @@ export class CoreDomUtilsProvider { } } + /** + * Prompts password to the user and returns the entered text. + * + * @param passwordParams Params to show the modal. + * @returns Entered password. + */ + async promptPassword(passwordParams?: CorePasswordModalParams): Promise { + const { CorePasswordModalComponent } = + await import('@/core/components/password-modal/password-modal.module'); + + const modalData = await CoreDomUtils.openModal( + { + cssClass: 'core-password-modal', + showBackdrop: true, + backdropDismiss: true, + component: CorePasswordModalComponent, + componentProps: passwordParams, + }, + ); + + if (typeof modalData !== 'string') { + throw new CoreCanceledError(); + } + + return modalData; + } + /** * View an image in a modal. * diff --git a/src/theme/theme.base.scss b/src/theme/theme.base.scss index fb1f62a78..8d2c00e1c 100644 --- a/src/theme/theme.base.scss +++ b/src/theme/theme.base.scss @@ -729,6 +729,21 @@ body.core-iframe-fullscreen ion-router-outlet { } } +.core-password-modal { + --border-radius: var(--medium-radius); + --min-width: auto; + --min-height: 260px; + --width: 320px; + --height: auto; + + form { + display: flex; + flex-direction: column; + height: 100%; + justify-content: space-between; + } +} + // Hidden submit button. .core-submit-hidden-enter { position: absolute; @@ -871,7 +886,7 @@ img.large-avatar, max-width: var(--core-large-avatar-size); max-height: var(--core-large-avatar-size); margin-bottom: 10px; - border-radius : 50%; + border-radius: 50%; padding: 4px; border: 1px solid var(--stroke); background-color: transparent;