From 8cda49f72022e96bda36650bb4375b9e769ef0e5 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Mon, 30 Oct 2023 08:25:09 +0100 Subject: [PATCH 1/6] MOBILE-4362 signup: Display required error in recaptcha --- src/core/components/recaptcha/core-recaptcha.html | 5 ++++- src/core/components/recaptcha/recaptcha.ts | 1 + src/core/features/login/pages/email-signup/email-signup.html | 3 ++- src/core/features/login/pages/email-signup/email-signup.ts | 3 +++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/components/recaptcha/core-recaptcha.html b/src/core/components/recaptcha/core-recaptcha.html index 102ddefc2..3e96f751d 100644 --- a/src/core/components/recaptcha/core-recaptcha.html +++ b/src/core/components/recaptcha/core-recaptcha.html @@ -7,7 +7,10 @@ {{ 'core.answered' | translate }} - + {{ 'core.login.recaptchaexpired' | translate }} + + {{ 'core.required' | translate }} + diff --git a/src/core/components/recaptcha/recaptcha.ts b/src/core/components/recaptcha/recaptcha.ts index fb6e1f260..ef4608f4a 100644 --- a/src/core/components/recaptcha/recaptcha.ts +++ b/src/core/components/recaptcha/recaptcha.ts @@ -32,6 +32,7 @@ export class CoreRecaptchaComponent implements OnInit { @Input() publicKey?: string; // The site public key. @Input() modelValueName = 'recaptcharesponse'; // Name of the model property where to store the response. @Input() siteUrl = ''; // The site URL. If not defined, current site. + @Input() showRequiredError = false; // Whether to display the required error if recaptcha hasn't been answered. expired = false; diff --git a/src/core/features/login/pages/email-signup/email-signup.html b/src/core/features/login/pages/email-signup/email-signup.html index b1bafd6f5..3ef4627f0 100644 --- a/src/core/features/login/pages/email-signup/email-signup.html +++ b/src/core/features/login/pages/email-signup/email-signup.html @@ -186,7 +186,8 @@

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

- + diff --git a/src/core/features/login/pages/email-signup/email-signup.ts b/src/core/features/login/pages/email-signup/email-signup.ts index 253d20fdc..f0d0f3f3f 100644 --- a/src/core/features/login/pages/email-signup/email-signup.ts +++ b/src/core/features/login/pages/email-signup/email-signup.ts @@ -60,6 +60,7 @@ export class CoreLoginEmailSignupPage implements OnInit { settingsLoaded = false; allRequiredSupported = true; signupUrl?: string; + formSubmitClicked = false; captcha = { recaptcharesponse: '', }; @@ -265,6 +266,8 @@ export class CoreLoginEmailSignupPage implements OnInit { e.preventDefault(); e.stopPropagation(); + this.formSubmitClicked = true; + if (!this.signupForm.valid || (this.settings?.recaptchapublickey && !this.captcha.recaptcharesponse)) { // Form not valid. Mark all controls as dirty to display errors. for (const name in this.signupForm.controls) { From 44f8a8e91f1ede359be1b99a70fb4edbe8234bfe Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Mon, 30 Oct 2023 08:43:44 +0100 Subject: [PATCH 2/6] MOBILE-4362 signup: Fix buttons margin --- .../pages/email-signup/email-signup.html | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/core/features/login/pages/email-signup/email-signup.html b/src/core/features/login/pages/email-signup/email-signup.html index 3ef4627f0..e7d5c0b7d 100644 --- a/src/core/features/login/pages/email-signup/email-signup.html +++ b/src/core/features/login/pages/email-signup/email-signup.html @@ -21,13 +21,13 @@
- + {{ 'core.login.signuprequiredfieldnotsupported' | translate }} - + {{ 'core.openinbrowser' | translate }} @@ -62,9 +62,11 @@ - - {{ 'core.proceed' | translate }} - +
+ + {{ 'core.proceed' | translate }} + +
@@ -214,10 +216,12 @@ - - {{ 'core.login.createaccount' | translate }} - - +
+ + {{ 'core.login.createaccount' | translate }} + + +
@@ -240,9 +244,11 @@

{{ supportEmail }}

- - {{ 'core.openinbrowser' | translate }} - +
+ + {{ 'core.openinbrowser' | translate }} + +
From d59b175314eac1da501232727daca03437aa164b Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Mon, 30 Oct 2023 15:08:09 +0100 Subject: [PATCH 3/6] MOBILE-4362 assign: Fix outcome not selected This is related to MOBILE-3958, it was fixed in scaled but not in outcomes --- src/addons/mod/assign/components/submission/submission.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/addons/mod/assign/components/submission/submission.ts b/src/addons/mod/assign/components/submission/submission.ts index 7305092ad..4bf833519 100644 --- a/src/addons/mod/assign/components/submission/submission.ts +++ b/src/addons/mod/assign/components/submission/submission.ts @@ -1089,11 +1089,11 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can // Only show outcomes with info on it, outcomeid could be null if outcomes are disabled on site. gradeInfo.outcomes?.forEach((outcome) => { if (outcome.id == String(grade.outcomeid)) { - outcome.selected = grade.gradeformatted; + // Clean HTML tags, grade can contain an icon. + outcome.selected = CoreTextUtils.cleanTags(grade.gradeformatted || ''); outcome.modified = grade.gradedategraded; if (outcome.options) { - outcome.selectedId = - CoreGradesHelper.getGradeValueFromLabel(outcome.options, outcome.selected || ''); + outcome.selectedId = CoreGradesHelper.getGradeValueFromLabel(outcome.options, outcome.selected); this.originalGrades.outcomes[outcome.id] = outcome.selectedId; outcome.itemNumber = grade.itemnumber; } From b9e9dade0baa1c71d9272ba252a38e759566fc0e Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 31 Oct 2023 11:14:03 +0100 Subject: [PATCH 4/6] MOBILE-4362 login: Hide authinstructions when not needed --- .../login/pages/credentials/credentials.ts | 3 ++- ...-displayed-when-adding-a-new-account_9.png | Bin 37997 -> 30238 bytes 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/features/login/pages/credentials/credentials.ts b/src/core/features/login/pages/credentials/credentials.ts index e6b995c06..7039451f3 100644 --- a/src/core/features/login/pages/credentials/credentials.ts +++ b/src/core/features/login/pages/credentials/credentials.ts @@ -193,7 +193,6 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { this.siteName = this.siteConfig.sitename; this.logoUrl = CoreLoginHelper.getLogoUrl(this.siteConfig); - this.authInstructions = this.siteConfig.authinstructions || Translate.instant('core.login.loginsteps'); this.showScanQR = await CoreLoginHelper.displayQRInCredentialsScreen(this.siteConfig.tool_mobile_qrcodetype); const disabledFeatures = CoreLoginHelper.getDisabledFeatures(this.siteConfig); @@ -204,6 +203,8 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { !!this.supportConfig?.canContactSupport(), this.showForgottenPassword, ); + this.authInstructions = this.siteConfig.authinstructions || + (this.canSignup ? Translate.instant('core.login.loginsteps') : ''); if (!this.eventThrown && !this.viewLeft) { this.eventThrown = true; diff --git a/src/core/features/login/tests/behat/snapshots/test-basic-usage-of-login-in-app-add-a-new-account-in-the-app--site-name-in-displayed-when-adding-a-new-account_9.png b/src/core/features/login/tests/behat/snapshots/test-basic-usage-of-login-in-app-add-a-new-account-in-the-app--site-name-in-displayed-when-adding-a-new-account_9.png index 727cbb0e14c4dbd1915bb46a25f3b5d693909394..6abd7693ad050e0fab6d30055d09c3c2069ce832 100644 GIT binary patch delta 13030 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 Woml6mnSqVPV3jp*kgwl+^1lEZWe5KN delta 20850 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 bnq!=S@t1Nd>RJ*A{PXyMta$c4-PivY{zv6) From 93b8ce274cf41907dd6a71398d553da5688df41c Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 31 Oct 2023 11:24:31 +0100 Subject: [PATCH 5/6] MOBILE-4362 mycourses: Fix category disappear after PTR --- .../components/myoverview/myoverview.ts | 2 ++ .../block/classes/base-block-component.ts | 32 ++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/addons/block/myoverview/components/myoverview/myoverview.ts b/src/addons/block/myoverview/components/myoverview/myoverview.ts index e31ff0d1d..bbf812037 100644 --- a/src/addons/block/myoverview/components/myoverview/myoverview.ts +++ b/src/addons/block/myoverview/components/myoverview/myoverview.ts @@ -176,6 +176,8 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem * @inheritdoc */ ngOnChanges(changes: SimpleChanges): void { + super.ngOnChanges(changes); + if (this.loaded && changes.block) { // Block was re-fetched, load content. this.reloadContent(); diff --git a/src/core/features/block/classes/base-block-component.ts b/src/core/features/block/classes/base-block-component.ts index c6073cac6..05bec595c 100644 --- a/src/core/features/block/classes/base-block-component.ts +++ b/src/core/features/block/classes/base-block-component.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { OnInit, Input, Component, Optional, Inject } from '@angular/core'; +import { OnInit, Input, Component, Optional, Inject, OnChanges, SimpleChanges } from '@angular/core'; import { CoreLogger } from '@singletons/logger'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; @@ -30,7 +30,7 @@ import { CorePromisedValue } from '@classes/promised-value'; @Component({ template: '', }) -export abstract class CoreBlockBaseComponent implements OnInit, ICoreBlockComponent, AsyncDirective { +export abstract class CoreBlockBaseComponent implements OnInit, OnChanges, ICoreBlockComponent, AsyncDirective { @Input() title!: string; // The block title. @Input() block!: CoreCourseBlock; // The block to render. @@ -54,15 +54,31 @@ export abstract class CoreBlockBaseComponent implements OnInit, ICoreBlockCompon * @inheritdoc */ async ngOnInit(): Promise { - if (this.block.configs && this.block.configs.length > 0) { - this.block.configs.forEach((config) => { - config.value = CoreTextUtils.parseJSON(config.value); - }); + await this.loadContent(); + } - this.block.configsRecord = CoreUtils.arrayToObject(this.block.configs, 'name'); + /** + * @inheritdoc + */ + ngOnChanges(changes: SimpleChanges): void { + if (changes.block) { + this.parseConfigs(); + } + } + + /** + * Parse configs if needed. + */ + protected parseConfigs(): void { + if (!this.block.configs?.length || this.block.configsRecord) { + return; } - await this.loadContent(); + this.block.configs.forEach((config) => { + config.value = CoreTextUtils.parseJSON(config.value); + }); + + this.block.configsRecord = CoreUtils.arrayToObject(this.block.configs, 'name'); } /** From 379156bfa7909528d428d4185a102bbda989f75a Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 31 Oct 2023 11:42:29 +0100 Subject: [PATCH 6/6] MOBILE-4368 analytics: Limit cases where setting is displayed Now the setting will only be displayed if there is an active handler --- .../settings/pages/general/general.html | 2 +- .../settings/pages/general/general.ts | 6 ++-- src/core/services/analytics.ts | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/core/features/settings/pages/general/general.html b/src/core/features/settings/pages/general/general.html index feb5e33a3..57fe64eee 100644 --- a/src/core/features/settings/pages/general/general.html +++ b/src/core/features/settings/pages/general/general.html @@ -75,7 +75,7 @@ - +

{{ 'core.settings.enableanalytics' | translate }}

{{ 'core.settings.enableanalyticsdescription' | translate }}

diff --git a/src/core/features/settings/pages/general/general.ts b/src/core/features/settings/pages/general/general.ts index de859cb2d..638b088ef 100644 --- a/src/core/features/settings/pages/general/general.ts +++ b/src/core/features/settings/pages/general/general.ts @@ -44,7 +44,7 @@ export class CoreSettingsGeneralPage { selectedZoomLevel = CoreZoomLevel.NONE; richTextEditor = true; debugDisplay = false; - analyticsSupported = false; + analyticsAvailable = false; analyticsEnabled = false; colorSchemes: CoreColorScheme[] = []; selectedScheme: CoreColorScheme = CoreColorScheme.LIGHT; @@ -101,8 +101,8 @@ export class CoreSettingsGeneralPage { this.debugDisplay = await CoreConfig.get(CoreConstants.SETTINGS_DEBUG_DISPLAY, false); - this.analyticsSupported = CoreAnalytics.hasHandlers(); - if (this.analyticsSupported) { + this.analyticsAvailable = await CoreAnalytics.isAnalyticsAvailable(); + if (this.analyticsAvailable) { this.analyticsEnabled = await CoreConfig.get(CoreConstants.SETTINGS_ANALYTICS_ENABLED, true); } diff --git a/src/core/services/analytics.ts b/src/core/services/analytics.ts index e442a6a89..71146ad89 100644 --- a/src/core/services/analytics.ts +++ b/src/core/services/analytics.ts @@ -57,6 +57,29 @@ export class CoreAnalyticsService extends CoreDelegate { } } + /** + * Check if analytics is available for the app/site. + * + * @returns True if available, false otherwise. + */ + async isAnalyticsAvailable(): Promise { + if (Object.keys(this.enabledHandlers).length > 0) { + // There is an enabled handler, analytics is available. + return true; + } + + // Check if there is a handler that is enabled at app level (enabled handlers are only set when logged in). + const enabledList = await Promise.all(Object.values(this.handlers).map(handler => { + if (!handler.appLevelEnabled) { + return false; + } + + return handler.isEnabled(); + })); + + return enabledList.includes(true); + } + /** * Log an event for the current site. * @@ -108,6 +131,11 @@ export const CoreAnalytics = makeSingleton(CoreAnalyticsService); */ export interface CoreAnalyticsHandler extends CoreDelegateHandler { + /** + * If true it means that the handler is enabled or not for the whole app, it doesn't depend on the site. + */ + appLevelEnabled?: boolean; + /** * Log an event. *