[ADF-4867] adf-error-component refactor (#5056)

* Refactor the adf-error-component
Move the custom buttons on demoshell
Fix unit test
Remove usefull e2e

* Add basic example
This commit is contained in:
Maurizio Vitale
2019-09-07 10:29:19 +01:00
committed by Eugenio Romano
parent 4d7c07ef93
commit 4de00fd6ca
12 changed files with 98 additions and 97 deletions

View File

@@ -83,6 +83,8 @@ import { ConfirmDialogExampleComponent } from './components/confirm-dialog/confi
import { FormCloudDemoComponent } from './components/app-layout/cloud/form-demo/cloud-form-demo.component';
import { environment } from '../environments/environment';
import { AppCloudSharedModule } from './components/cloud/shared/cloud.shared.module';
import { DemoErrorComponent } from './components/error/demo-error.component';
import {
UserPreferenceCloudService,
PROCESS_FILTERS_SERVICE_TOKEN,
@@ -171,6 +173,7 @@ registerLocaleData(localeSv);
SharedLinkViewComponent,
FormLoadingComponent,
DemoPermissionComponent,
DemoErrorComponent,
FormLoadingComponent,
ReportIssueComponent,
TreeViewSampleComponent,

View File

@@ -57,6 +57,7 @@ import { ProcessDetailsCloudDemoComponent } from './components/cloud/process-det
import { TemplateDemoComponent } from './components/template-list/template-demo.component';
import { FormCloudDemoComponent } from './components/app-layout/cloud/form-demo/cloud-form-demo.component';
import { ConfirmDialogExampleComponent } from './components/confirm-dialog/confirm-dialog-example.component';
import { DemoErrorComponent } from './components/error/demo-error.component';
export const appRoutes: Routes = [
{ path: 'login', loadChildren: 'app/components/login/login.module#AppLoginModule' },
{ path: 'logout', component: LogoutComponent },
@@ -414,7 +415,7 @@ export const appRoutes: Routes = [
},
{
path: 'error/:id',
component: ErrorContentComponent
component: DemoErrorComponent
},
{
path: 'error/no-authorization',

View File

@@ -0,0 +1,15 @@
<div fxLayout="column" fxLayoutAlign="center center">
<adf-error-content [errorCode]="errorCode">
<div adf-error-content-actions class="adf-error-content-buttons">
<a a id="adf-secondary-button" mat-raised-button color="primary"
(click)="onReportIssue()"
class="adf-error-content-description-link">
{{ 'ERROR_CONTENT.' + errorCode + '.SECONDARY_BUTTON.TEXT' | translate | uppercase }}
</a>
<a id="adf-return-button" mat-raised-button color="primary" (click)="onReturnButton()">
{{ 'ERROR_CONTENT.' + errorCode + '.RETURN_BUTTON.TEXT' | translate | uppercase }}
</a>
</div>
</adf-error-content>
</div>

View File

@@ -0,0 +1,9 @@
.adf-error-content {
&-buttons {
display: flex;
width: 100%;
justify-content: space-evenly;
}
}

View File

@@ -0,0 +1,51 @@
/*!
* @license
* Copyright 2019 Alfresco Software, 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, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
@Component({
selector: 'app-demo-error',
styleUrls: ['./demo-error.component.scss'],
templateUrl: './demo-error.component.html'
})
export class DemoErrorComponent implements OnInit {
errorCode: string = '';
constructor(private route: ActivatedRoute, private router: Router) {
}
ngOnInit() {
if (this.route) {
this.route.params.forEach((params: Params) => {
if (params['id']) {
this.errorCode = params['id'];
}
});
}
}
onReportIssue() {
this.router.navigate(['/report-issue']);
}
onReturnButton() {
this.router.navigate(['/']);
}
}

View File

@@ -24,8 +24,6 @@ this.router.navigate(['/error', errorCode]);
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| errorCode | `string` | | Error code associated with this error. |
| returnButtonUrl | `string` | "/" | Target URL for the return button. |
| secondaryButtonUrl | `string` | "report-issue" | Target URL for the secondary button. |
## Details
@@ -49,6 +47,20 @@ You can customize your error messages by adding them to the translate files insi
}
```
## How to customise the action button.
The errorContentComponent allows you to customise the actions section using the selector `adf-error-content-actions`.
For example you can have a custom action button with the following code
```html
<adf-error-content [errorCode]="errorCode">
<div adf-error-content-actions>
<button type="button">MyAction</button>
</div>
</adf-error-content>
```
## See also
- [Empty Content component](empty-content.component.md)

View File

@@ -51,22 +51,6 @@ describe('Error Component', () => {
await expect(await errorPage.getErrorDescription()).toBe('You\'re not allowed access to this resource on the server.');
});
it('[C280563] Should back home button navigate to the home page', async () => {
await BrowserActions.getUrl(browser.params.testConfig.adf.url + '/error/404');
await errorPage.clickBackButton();
await expect(await browser.getCurrentUrl()).toBe(browser.params.testConfig.adf.url + '/');
});
it('[C280564] Should secondary button by default redirect to report-issue URL', async () => {
await BrowserActions.getUrl(browser.params.testConfig.adf.url + '/error/403');
await errorPage.clickSecondButton();
await expect(await browser.getCurrentUrl()).toBe(browser.params.testConfig.adf.url + '/report-issue');
});
it('[C277304] Should display the error 404 when access to not found page', async () => {
await BrowserActions.getUrl(browser.params.testConfig.adf.url + '/error/404');
await expect(await errorPage.getErrorCode()).toBe('404');

View File

@@ -9,14 +9,5 @@
<p class="adf-error-content-description">
{{ 'ERROR_CONTENT.' + errorCode + '.DESCRIPTION' | translate }}
</p>
<div class="adf-error-content-buttons">
<a a id="adf-secondary-button" mat-raised-button color="primary"
*ngIf="hasSecondButton" (click)="onSecondButton()"
class="adf-error-content-description-link">
{{ 'ERROR_CONTENT.' + errorCode + '.SECONDARY_BUTTON.TEXT' | translate | uppercase }}
</a>
<a id="adf-return-button" mat-raised-button color="primary" (click)="onReturnButton()">
{{ 'ERROR_CONTENT.' + this.errorCode + '.RETURN_BUTTON.TEXT' | translate | uppercase }}
</a>
</div>
<ng-content select="[adf-error-content-actions]"></ng-content>
</div>

View File

@@ -40,12 +40,6 @@
margin-bottom: 60px;
line-height: 30px;
}
&-buttons {
display: flex;
width: 100%;
justify-content: space-evenly;
}
}
@media screen and ($mat-small) {

View File

@@ -99,27 +99,6 @@ describe('ErrorContentComponent', () => {
});
}));
it('should render secondary button with its value from the translate file', async(() => {
spyOn(translateService, 'instant').and.callFake(() => {
return 'Secondary Button';
});
fixture.detectChanges();
fixture.whenStable().then(() => {
const errorContentElement = element.querySelector('#adf-secondary-button');
expect(errorContentElement).not.toBeNull();
expect(errorContentElement).toBeDefined();
expect(errorContentElement.textContent).toContain('ERROR_CONTENT.UNKNOWN.SECONDARY_BUTTON.TEXT');
});
}));
it('should the default value of return button be /', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(errorContentComponent.returnButtonUrl).toBe('/');
});
}));
it('should navigate to the default error UNKNOWN if it does not find the error', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {

View File

@@ -20,10 +20,9 @@ import {
ChangeDetectionStrategy,
Input,
ViewEncapsulation,
OnInit,
AfterContentChecked
OnInit
} from '@angular/core';
import { Params, ActivatedRoute, Router } from '@angular/router';
import { Params, ActivatedRoute } from '@angular/router';
import { TranslationService } from '../../services/translation.service';
@Component({
@@ -34,26 +33,15 @@ import { TranslationService } from '../../services/translation.service';
encapsulation: ViewEncapsulation.None,
host: { class: 'adf-error-content' }
})
export class ErrorContentComponent implements OnInit, AfterContentChecked {
export class ErrorContentComponent implements OnInit {
static UNKNOWN_ERROR = 'UNKNOWN';
/** Target URL for the secondary button. */
@Input()
secondaryButtonUrl: string = 'report-issue';
/** Target URL for the return button. */
@Input()
returnButtonUrl: string = '/';
/** Error code associated with this error. */
@Input()
errorCode: string = ErrorContentComponent.UNKNOWN_ERROR;
hasSecondButton: boolean;
constructor(private route: ActivatedRoute,
private router: Router,
private translateService: TranslationService) {
}
@@ -72,20 +60,4 @@ export class ErrorContentComponent implements OnInit, AfterContentChecked {
return errorMessage !== ('ERROR_CONTENT.' + errorCode);
}
getTranslations() {
this.hasSecondButton = this.translateService.instant(
'ERROR_CONTENT.' + this.errorCode + '.SECONDARY_BUTTON.TEXT') ? true : false;
}
ngAfterContentChecked() {
this.getTranslations();
}
onSecondButton() {
this.router.navigate(['/' + this.secondaryButtonUrl]);
}
onReturnButton() {
this.router.navigate(['/' + this.returnButtonUrl]);
}
}

View File

@@ -25,16 +25,6 @@ export class ErrorPage {
errorPageCode: ElementFinder = element(by.css('adf-error-content .adf-error-content-code'));
errorPageTitle: ElementFinder = element(by.css('adf-error-content .adf-error-content-title'));
errorPageDescription: ElementFinder = element(by.css('adf-error-content .adf-error-content-description'));
backButton: ElementFinder = element(by.id('adf-return-button'));
secondButton: ElementFinder = element(by.id('adf-secondary-button'));
async clickBackButton(): Promise<void> {
await BrowserActions.click(this.backButton);
}
async clickSecondButton(): Promise<void> {
await BrowserActions.click(this.secondButton);
}
async checkErrorCode(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.errorPageCode);