MOBILE-4059 login: Contact support from errors

Allow users to contact site support in errors where the site is not configured properly
main
Noel De Martin 2022-10-03 17:07:48 +02:00
parent 4eb01a063c
commit 1a7d64a0d4
5 changed files with 68 additions and 13 deletions

View File

@ -1520,6 +1520,7 @@
"core.confirmloss": "local_moodlemobileapp", "core.confirmloss": "local_moodlemobileapp",
"core.confirmopeninbrowser": "local_moodlemobileapp", "core.confirmopeninbrowser": "local_moodlemobileapp",
"core.considereddigitalminor": "moodle", "core.considereddigitalminor": "moodle",
"core.contactsupport": "local_moodlemobileapp",
"core.content": "moodle", "core.content": "moodle",
"core.contenteditingsynced": "local_moodlemobileapp", "core.contenteditingsynced": "local_moodlemobileapp",
"core.contentlinks.chooseaccount": "local_moodlemobileapp", "core.contentlinks.chooseaccount": "local_moodlemobileapp",

View File

@ -13,6 +13,8 @@
// limitations under the License. // limitations under the License.
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { CoreSitePublicConfigResponse } from '@classes/site';
import { CoreUserSupport } from '@features/user/services/support';
/** /**
* Error returned when performing operations regarding a site (check if it exists, authenticate user, etc.). * Error returned when performing operations regarding a site (check if it exists, authenticate user, etc.).
@ -22,20 +24,52 @@ export class CoreSiteError extends CoreError {
errorcode?: string; errorcode?: string;
critical?: boolean; critical?: boolean;
loggedOut?: boolean; loggedOut?: boolean;
contactSupport?: boolean;
siteConfig?: CoreSitePublicConfigResponse;
constructor(protected error: SiteError) { constructor(options: CoreSiteErrorOptions) {
super(error.message); super(options.message);
this.errorcode = error.errorcode; this.errorcode = options.errorcode;
this.critical = error.critical; this.critical = options.critical;
this.loggedOut = error.loggedOut; this.loggedOut = options.loggedOut;
this.contactSupport = options.contactSupport;
this.siteConfig = options.siteConfig;
}
/**
* Get a url to contact site support.
*
* @returns Support page url.
*/
getSupportPageUrl(): string {
if (!this.siteConfig) {
throw new CoreError('Can\'t get support page url');
}
return CoreUserSupport.getSupportPageUrl(this.siteConfig);
}
/**
* Check whether the handling of this error allows users to contact support or not.
*
* @returns Whether to contact support or not.
*/
canContactSupport(): boolean {
if (!this.contactSupport || !this.siteConfig) {
return false;
}
return CoreUserSupport.canContactSupport(this.siteConfig);
} }
} }
export type SiteError = { export type CoreSiteErrorOptions = {
message: string; message: string;
errorcode?: string; errorcode?: string;
critical?: boolean; // Whether the error is important enough to abort the operation. critical?: boolean; // Whether the error is important enough to abort the operation.
loggedOut?: boolean; // Whether site has been marked as logged out. loggedOut?: boolean; // Whether site has been marked as logged out.
contactSupport?: boolean;
siteConfig?: CoreSitePublicConfigResponse;
}; };

View File

@ -40,6 +40,8 @@ import { CoreCustomURLSchemes, CoreCustomURLSchemesHandleError } from '@services
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreForms } from '@singletons/form'; import { CoreForms } from '@singletons/form';
import { AlertButton } from '@ionic/core'; import { AlertButton } from '@ionic/core';
import { CoreSiteError } from '@classes/errors/siteerror';
import { CoreUserSupport } from '@features/user/services/support';
/** /**
* Site (url) chooser when adding a new site. * Site (url) chooser when adding a new site.
@ -382,6 +384,13 @@ export class CoreLoginSitePage implements OnInit {
*/ */
protected showLoginIssue(url: string | null, error: CoreError): void { protected showLoginIssue(url: string | null, error: CoreError): void {
let errorMessage = CoreDomUtils.getErrorMessage(error); let errorMessage = CoreDomUtils.getErrorMessage(error);
let siteExists = false;
let supportPageUrl: string | null = null;
if (error instanceof CoreSiteError) {
siteExists = !!error.siteConfig;
supportPageUrl = error.canContactSupport() ? error.getSupportPageUrl() : null;
}
if (errorMessage == Translate.instant('core.cannotconnecttrouble')) { if (errorMessage == Translate.instant('core.cannotconnecttrouble')) {
const found = this.sites.find((site) => site.url == url); const found = this.sites.find((site) => site.url == url);
@ -392,19 +401,25 @@ export class CoreLoginSitePage implements OnInit {
} }
let message = '<p>' + errorMessage + '</p>'; let message = '<p>' + errorMessage + '</p>';
if (url) { if (!siteExists && url) {
const fullUrl = CoreUrlUtils.isAbsoluteURL(url) ? url : 'https://' + url; const fullUrl = CoreUrlUtils.isAbsoluteURL(url) ? url : 'https://' + url;
message += '<p padding><a href="' + fullUrl + '" core-link>' + url + '</a></p>'; message += '<p padding><a href="' + fullUrl + '" core-link>' + url + '</a></p>';
} }
const buttons: AlertButton[] = [ const buttons: AlertButton[] = [
{ supportPageUrl
text: Translate.instant('core.needhelp'), ? {
cssClass: 'core-login-need-help', text: Translate.instant('core.contactsupport'),
handler: (): void => { handler: () => CoreUserSupport.contact({
this.showHelp(); supportPageUrl,
subject: Translate.instant('core.cannotconnect', { $a: CoreSite.MINIMUM_MOODLE_VERSION }),
}),
}
: {
text: Translate.instant('core.needhelp'),
cssClass: 'core-login-need-help',
handler: () => this.showHelp(),
}, },
},
{ {
text: Translate.instant('core.tryagain'), text: Translate.instant('core.tryagain'),
role: 'cancel', role: 'cancel',

View File

@ -54,6 +54,7 @@
"confirmloss": "Are you sure? All changes will be lost.", "confirmloss": "Are you sure? All changes will be lost.",
"confirmopeninbrowser": "Do you want to open it in a web browser?", "confirmopeninbrowser": "Do you want to open it in a web browser?",
"considereddigitalminor": "You are too young to create an account on this site.", "considereddigitalminor": "You are too young to create an account on this site.",
"contactsupport": "Contact support",
"content": "Content", "content": "Content",
"contenteditingsynced": "The content you are editing has been synced.", "contenteditingsynced": "The content you are editing has been synced.",
"continue": "Continue", "continue": "Continue",

View File

@ -299,11 +299,15 @@ export class CoreSitesProvider {
throw new CoreSiteError({ throw new CoreSiteError({
message: Translate.instant('core.login.webservicesnotenabled'), message: Translate.instant('core.login.webservicesnotenabled'),
critical: true, critical: true,
contactSupport: true,
siteConfig: config,
}); });
} else if (!config.enablemobilewebservice) { } else if (!config.enablemobilewebservice) {
throw new CoreSiteError({ throw new CoreSiteError({
message: Translate.instant('core.login.mobileservicesnotenabled'), message: Translate.instant('core.login.mobileservicesnotenabled'),
critical: true, critical: true,
contactSupport: true,
siteConfig: config,
}); });
} else if (config.maintenanceenabled) { } else if (config.maintenanceenabled) {
let message = Translate.instant('core.sitemaintenance'); let message = Translate.instant('core.sitemaintenance');