MOBILE-4268 core: Refactor error accordion into service

main
Noel De Martin 2024-03-19 10:57:46 +01:00
parent 6b461b035e
commit dcf9439eb7
6 changed files with 26 additions and 56 deletions

View File

@ -1,6 +0,0 @@
<!--
The markup for this component is rendered dynamically using the static render() method
instead of using Angular's engine. The reason for using this approach is that this
allows injecting this component into HTML directly, rather than requiring Angular
to control its lifecycle. This is necessary, for example, to render within alerts.
-->

View File

@ -40,7 +40,7 @@ import { CoreForms } from '@singletons/form';
import { AlertButton } from '@ionic/core';
import { CoreSiteError, CoreSiteErrorDebug } from '@classes/errors/siteerror';
import { CoreUserSupport } from '@features/user/services/support';
import { CoreErrorAccordionComponent } from '@components/error-accordion/error-accordion';
import { CoreErrorAccordion } from '@services/error-accordion';
import { CoreUserSupportConfig } from '@features/user/classes/support/support-config';
import { CoreUserGuestSupportConfig } from '@features/user/classes/support/guest-support-config';
import { CoreLoginError } from '@classes/errors/loginerror';
@ -460,7 +460,7 @@ export class CoreLoginSitePage implements OnInit {
const containerElement = alertElement.querySelector('.core-error-accordion-container');
if (containerElement) {
await CoreErrorAccordionComponent.render(containerElement, debug.code, debug.details);
await CoreErrorAccordion.render(containerElement, debug.code, debug.details);
}
}
}

View File

@ -12,27 +12,27 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, ElementRef, Input, OnChanges, OnInit } from '@angular/core';
import { Translate } from '@singletons';
import { Injectable } from '@angular/core';
import { Translate, makeSingleton } from '@singletons';
import { CoreUtils } from '@services/utils/utils';
import { CoreDom } from '@singletons/dom';
import { CoreForms } from '@singletons/form';
import { CoreLogger } from '@singletons/logger';
const logger = CoreLogger.getInstance('CoreErrorAccordionComponent');
/**
* Component to show error details.
* Service used to render an Error Accordion component.
*
* Given that this component has to be injected dynamically in some situations (for example, error alerts),
* it can be rendered using the static render() method to get the raw HTML.
* This is declared as a service instead of an Angular Component because the HTML
* has to be injected dynamically in alerts (only HTML and Ionic components work).
*/
@Component({
selector: 'core-error-accordion',
templateUrl: 'core-error-accordion.html',
styleUrls: ['error-accordion.scss'],
})
export class CoreErrorAccordionComponent implements OnInit, OnChanges {
@Injectable({ providedIn: 'root' })
export class CoreErrorAccordionService {
private logger: CoreLogger;
constructor() {
this.logger = CoreLogger.getInstance('CoreErrorAccordion');
}
/**
* Render an instance of the component into an HTML string.
@ -41,7 +41,7 @@ export class CoreErrorAccordionComponent implements OnInit, OnChanges {
* @param errorCode Error code.
* @param errorDetails Error details.
*/
static async render(element: Element, errorCode: string, errorDetails: string): Promise<void> {
async render(element: Element, errorCode: string, errorDetails: string): Promise<void> {
const html = this.html(errorCode, errorDetails);
element.innerHTML = html;
@ -56,7 +56,7 @@ export class CoreErrorAccordionComponent implements OnInit, OnChanges {
* @param errorDetails Error details.
* @returns HTML.
*/
static html(errorCode: string, errorDetails: string): string {
private html(errorCode: string, errorDetails: string): string {
const contentId = CoreForms.uniqueId('error-accordion-content');
const errorCodeLabel = Translate.instant('core.errorcode', { errorCode });
const hideDetailsLabel = Translate.instant('core.errordetailshide');
@ -88,14 +88,14 @@ export class CoreErrorAccordionComponent implements OnInit, OnChanges {
*
* @param element Root element.
*/
static async hydrate(element: Element): Promise<void> {
private async hydrate(element: Element): Promise<void> {
const wrapper = element.querySelector<HTMLDivElement>('.core-error-accordion');
const description = element.querySelector<HTMLParagraphElement>('.core-error-accordion--details');
const button = element.querySelector<HTMLButtonElement>('.core-error-accordion--toggle');
const hideText = element.querySelector<HTMLSpanElement>('.core-error-accordion--hide-details');
if (!wrapper || !description || !button || !hideText) {
logger.error('Couldn\'t render error-accordion, one of the child elements is missing');
this.logger.error('Couldn\'t render error-accordion, one of the child elements is missing');
return;
}
@ -118,30 +118,6 @@ export class CoreErrorAccordionComponent implements OnInit, OnChanges {
hideText.style.display = 'revert';
}
@Input() errorCode!: string;
@Input() errorDetails!: string;
constructor(private element: ElementRef<HTMLElement>) {}
/**
* @inheritdoc
*/
ngOnInit(): void {
this.render();
}
/**
* @inheritdoc
*/
ngOnChanges(): void {
this.render();
}
/**
* Render component html in the element created by Angular.
*/
private async render(): Promise<void> {
await CoreErrorAccordionComponent.render(this.element.nativeElement, this.errorCode, this.errorDetails);
}
}
export const CoreErrorAccordion = makeSingleton(CoreErrorAccordionService);

View File

@ -52,7 +52,7 @@ import { Subscription } from 'rxjs';
import { CoreNetwork } from '@services/network';
import { CoreSiteError } from '@classes/errors/siteerror';
import { CoreUserSupport } from '@features/user/services/support';
import { CoreErrorAccordionComponent } from '@components/error-accordion/error-accordion';
import { CoreErrorAccordion } from '@services/error-accordion';
import { CorePlatform } from '@services/platform';
import { CoreCancellablePromise } from '@classes/cancellable-promise';
import { CoreLang } from '@services/lang';
@ -1065,7 +1065,7 @@ export class CoreDomUtilsProvider {
const containerElement = alertElement.querySelector('.core-error-accordion-container');
if (containerElement) {
await CoreErrorAccordionComponent.render(containerElement, error.debug.code, error.debug.details);
await CoreErrorAccordion.render(containerElement, error.debug.code, error.debug.details);
}
}

View File

@ -22,12 +22,12 @@
/* Components */
@import "components/collapsible-header.scss";
@import "components/collapsible-item.scss";
@import "components/error-accordion.scss";
@import "components/format-text.scss";
@import "components/rubrics.scss";
@import "components/mod-label.scss";
@import "components/ion-icon.scss";
@import "components/mod-label.scss";
@import "components/rubrics.scss";
@import "components/videojs.scss";
@import "../core/components/error-accordion/error-accordion.scss";
/* Some styles from 3rd party libraries. */
@import "bootstrap.scss";