Browse Source

Merge pull request #19421 from abpframework/issue-19416

Adding constants to theme-shared module for error messages by status code
pull/19449/head
Masum ULU 3 years ago
committed by GitHub
parent
commit
450824898a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      npm/ng-packs/apps/dev-app/src/app/app-routing.module.ts
  2. 44
      npm/ng-packs/packages/theme-shared/src/lib/components/http-error-wrapper/http-error-wrapper.component.html
  3. 51
      npm/ng-packs/packages/theme-shared/src/lib/components/http-error-wrapper/http-error-wrapper.component.ts
  4. 14
      npm/ng-packs/packages/theme-shared/src/lib/constants/default-errors.ts
  5. 4
      npm/ng-packs/packages/theme-shared/src/lib/constants/index.ts
  6. 15
      npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts
  7. 5
      npm/ng-packs/packages/theme-shared/src/public-api.ts

2
npm/ng-packs/apps/dev-app/src/app/app-routing.module.ts

@ -31,4 +31,4 @@ const routes: Routes = [
imports: [RouterModule.forRoot(routes, {})], imports: [RouterModule.forRoot(routes, {})],
exports: [RouterModule], exports: [RouterModule],
}) })
export class AppRoutingModule { } export class AppRoutingModule {}

44
npm/ng-packs/packages/theme-shared/src/lib/components/http-error-wrapper/http-error-wrapper.component.html

@ -4,32 +4,28 @@
class="error" class="error"
[style.backgroundColor]="backgroundColor" [style.backgroundColor]="backgroundColor"
> >
<button @if (!hideCloseIcon) {
*ngIf="!hideCloseIcon" <button id="abp-close-button" type="button" class="btn-close me-2" (click)="destroy()"></button>
id="abp-close-button" }
type="button"
class="btn-close me-2"
(click)="destroy()"
></button>
<div *ngIf="!customComponent" class="row centered"> @if (!customComponent) {
<div class="col-md-12"> <div class="row centered">
<div class="error-template"> <div class="col-md-12">
<h1>{{ statusText }} {{ title | abpLocalization }}</h1> <div class="error-template">
<div class="error-details"> <h1>{{ statusText }} {{ title | abpLocalization }}</h1>
{{ details | abpLocalization }} <div class="error-details">
</div> {{ details | abpLocalization }}
<div class="error-actions"> </div>
<a <div class="error-actions">
*ngIf="isHomeShow" @if (isHomeShow) {
(click)="destroy()" <a (click)="goHome()" class="btn btn-primary btn-md mt-2"
routerLink="/" ><span class="glyphicon glyphicon-home"></span>
class="btn btn-primary btn-md mt-2" {{ { key: '::Menu:Home', defaultValue: 'Home' } | abpLocalization }}
><span class="glyphicon glyphicon-home"></span> </a>
{{ { key: '::Menu:Home', defaultValue: 'Home' } | abpLocalization }} }
</a> </div>
</div> </div>
</div> </div>
</div> </div>
</div> }
</div> </div>

51
npm/ng-packs/packages/theme-shared/src/lib/components/http-error-wrapper/http-error-wrapper.component.ts

@ -1,38 +1,40 @@
import { import {
ApplicationRef, ApplicationRef,
Component, Component,
Injector,
inject, inject,
OnInit, OnInit,
ComponentFactoryResolver,
ElementRef, ElementRef,
EmbeddedViewRef, EmbeddedViewRef,
Type, Type,
ViewChild, ViewChild,
AfterViewInit, AfterViewInit,
OnDestroy, OnDestroy,
createComponent,
EnvironmentInjector,
DestroyRef,
} from '@angular/core'; } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { DOCUMENT } from '@angular/common'; import { DOCUMENT } from '@angular/common';
import { Router } from '@angular/router';
import { fromEvent, Subject } from 'rxjs'; import { fromEvent, Subject } from 'rxjs';
import { debounceTime, filter } from 'rxjs/operators'; import { debounceTime, filter } from 'rxjs/operators';
import { LocalizationParam, SubscriptionService } from '@abp/ng.core'; import { LocalizationParam } from '@abp/ng.core';
import { ErrorScreenErrorCodes } from '../../models'; import { ErrorScreenErrorCodes } from '../../models';
@Component({ @Component({
selector: 'abp-http-error-wrapper', selector: 'abp-http-error-wrapper',
templateUrl: './http-error-wrapper.component.html', templateUrl: './http-error-wrapper.component.html',
styleUrls: ['http-error-wrapper.component.scss'], styleUrls: ['http-error-wrapper.component.scss'],
providers: [SubscriptionService],
}) })
export class HttpErrorWrapperComponent implements OnInit, AfterViewInit, OnDestroy { export class HttpErrorWrapperComponent implements OnInit, AfterViewInit, OnDestroy {
protected readonly destroyRef = inject(DestroyRef);
protected readonly document = inject(DOCUMENT); protected readonly document = inject(DOCUMENT);
protected readonly window = this.document.defaultView; protected readonly window = this.document.defaultView;
protected readonly router = inject(Router);
appRef!: ApplicationRef; appRef!: ApplicationRef;
cfRes!: ComponentFactoryResolver; environmentInjector!: EnvironmentInjector;
injector!: Injector;
status: ErrorScreenErrorCodes = 0; status: ErrorScreenErrorCodes = 0;
@ -57,21 +59,23 @@ export class HttpErrorWrapperComponent implements OnInit, AfterViewInit, OnDestr
return this.status ? `[${this.status}]` : ''; return this.status ? `[${this.status}]` : '';
} }
constructor(private subscription: SubscriptionService) {}
ngOnInit(): void { ngOnInit(): void {
this.backgroundColor = const computedStyle = this.window.getComputedStyle(this.document.body);
this.window.getComputedStyle(this.document.body)?.getPropertyValue('background-color') || '#fff'; const backgroundColor = computedStyle?.getPropertyValue('background-color');
this.backgroundColor = backgroundColor || '#fff';
} }
ngAfterViewInit(): void { ngAfterViewInit(): void {
if (this.customComponent) { if (this.customComponent) {
const customComponentRef = this.cfRes const customComponentRef = createComponent(this.customComponent, {
.resolveComponentFactory(this.customComponent) environmentInjector: this.environmentInjector,
.create(this.injector); });
customComponentRef.instance.errorStatus = this.status; customComponentRef.instance.errorStatus = this.status;
customComponentRef.instance.destroy$ = this.destroy$; customComponentRef.instance.destroy$ = this.destroy$;
this.appRef.attachView(customComponentRef.hostView); this.appRef.attachView(customComponentRef.hostView);
if (this.containerRef) { if (this.containerRef) {
this.containerRef.nativeElement.appendChild( this.containerRef.nativeElement.appendChild(
(customComponentRef.hostView as EmbeddedViewRef<any>).rootNodes[0], (customComponentRef.hostView as EmbeddedViewRef<any>).rootNodes[0],
@ -80,14 +84,17 @@ export class HttpErrorWrapperComponent implements OnInit, AfterViewInit, OnDestr
customComponentRef.changeDetectorRef.detectChanges(); customComponentRef.changeDetectorRef.detectChanges();
} }
const keyup$ = fromEvent<KeyboardEvent>(this.document, 'keyup').pipe( fromEvent<KeyboardEvent>(this.document, 'keyup')
debounceTime(150), .pipe(
filter((key: KeyboardEvent) => key && key.key === 'Escape'), debounceTime(150),
); filter((key: KeyboardEvent) => key && key.key === 'Escape'),
this.subscription.addOne(keyup$, () => this.destroy()); takeUntilDestroyed(this.destroyRef),
)
.subscribe(() => this.destroy());
} }
ngOnDestroy(): void { goHome(): void {
this.router.navigateByUrl('/', { onSameUrlNavigation: 'reload' });
this.destroy(); this.destroy();
} }
@ -95,4 +102,8 @@ export class HttpErrorWrapperComponent implements OnInit, AfterViewInit, OnDestr
this.destroy$.next(); this.destroy$.next();
this.destroy$.complete(); this.destroy$.complete();
} }
ngOnDestroy(): void {
this.destroy();
}
} }

14
npm/ng-packs/packages/theme-shared/src/lib/constants/default-errors.ts

@ -51,3 +51,17 @@ export const CUSTOM_HTTP_ERROR_HANDLER_PRIORITY = Object.freeze({
high: 9, high: 9,
veryHigh: 99, veryHigh: 99,
}); });
export const HTTP_ERROR_STATUS = {
'401': 'AbpUi::401Message',
'403': 'AbpUi::403Message',
'404': 'AbpUi::404Message',
'500': 'AbpUi::500Message',
};
export const HTTP_ERROR_DETAIL = {
'401': 'AbpUi::DefaultErrorMessage401Detail',
'403': 'AbpUi::DefaultErrorMessage403Detail',
'404': 'AbpUi::DefaultErrorMessage404Detail',
'500': 'AbpUi::DefaultErrorMessage',
};

4
npm/ng-packs/packages/theme-shared/src/lib/constants/index.ts

@ -0,0 +1,4 @@
export * from './validation';
export * from './default-errors';
export * from './styles';
export * from './scripts';

15
npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts

@ -1,8 +1,9 @@
import { import {
ApplicationRef, ApplicationRef,
ComponentFactoryResolver,
ComponentRef, ComponentRef,
createComponent,
EmbeddedViewRef, EmbeddedViewRef,
EnvironmentInjector,
inject, inject,
Injectable, Injectable,
Injector, Injector,
@ -21,9 +22,9 @@ import { ErrorScreenErrorCodes } from '../models/common';
export class CreateErrorComponentService { export class CreateErrorComponentService {
protected readonly document = inject(DOCUMENT); protected readonly document = inject(DOCUMENT);
protected readonly rendererFactory = inject(RendererFactory2); protected readonly rendererFactory = inject(RendererFactory2);
protected readonly cfRes = inject(ComponentFactoryResolver);
protected readonly routerEvents = inject(RouterEvents); protected readonly routerEvents = inject(RouterEvents);
protected readonly injector = inject(Injector); protected readonly injector = inject(Injector);
protected readonly envInjector = inject(EnvironmentInjector);
protected readonly httpErrorConfig = inject(HTTP_ERROR_CONFIG); protected readonly httpErrorConfig = inject(HTTP_ERROR_CONFIG);
componentRef: ComponentRef<HttpErrorWrapperComponent> | null = null; componentRef: ComponentRef<HttpErrorWrapperComponent> | null = null;
@ -65,9 +66,9 @@ export class CreateErrorComponentService {
const hostElement = this.getErrorHostElement(); const hostElement = this.getErrorHostElement();
const host = renderer.selectRootElement(hostElement, true); const host = renderer.selectRootElement(hostElement, true);
this.componentRef = this.cfRes this.componentRef = createComponent(HttpErrorWrapperComponent, {
.resolveComponentFactory(HttpErrorWrapperComponent) environmentInjector: this.envInjector,
.create(this.injector); });
for (const key in instance) { for (const key in instance) {
/* istanbul ignore else */ /* istanbul ignore else */
@ -80,9 +81,8 @@ export class CreateErrorComponentService {
const appRef = this.injector.get(ApplicationRef); const appRef = this.injector.get(ApplicationRef);
if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) { if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) {
this.componentRef.instance.cfRes = this.cfRes;
this.componentRef.instance.appRef = appRef; this.componentRef.instance.appRef = appRef;
this.componentRef.instance.injector = this.injector; this.componentRef.instance.environmentInjector = this.envInjector;
this.componentRef.instance.customComponent = this.httpErrorConfig.errorScreen?.component; this.componentRef.instance.customComponent = this.httpErrorConfig.errorScreen?.component;
} }
@ -91,6 +91,7 @@ export class CreateErrorComponentService {
const destroy$ = new Subject<void>(); const destroy$ = new Subject<void>();
this.componentRef.instance.destroy$ = destroy$; this.componentRef.instance.destroy$ = destroy$;
destroy$.subscribe(() => { destroy$.subscribe(() => {
this.componentRef?.destroy(); this.componentRef?.destroy();
this.componentRef = null; this.componentRef = null;

5
npm/ng-packs/packages/theme-shared/src/public-api.ts

@ -2,11 +2,9 @@
* Public API Surface of theme-shared * Public API Surface of theme-shared
*/ */
export * from './lib/adapters' export * from './lib/adapters';
export * from './lib/animations'; export * from './lib/animations';
export * from './lib/components'; export * from './lib/components';
export * from './lib/constants/validation';
export * from './lib/constants/default-errors';
export * from './lib/directives'; export * from './lib/directives';
export * from './lib/enums'; export * from './lib/enums';
export * from './lib/handlers'; export * from './lib/handlers';
@ -16,3 +14,4 @@ export * from './lib/services';
export * from './lib/theme-shared.module'; export * from './lib/theme-shared.module';
export * from './lib/tokens'; export * from './lib/tokens';
export * from './lib/utils'; export * from './lib/utils';
export * from './lib/constants';

Loading…
Cancel
Save