Skip to content

Commit edaf963

Browse files
author
Andrea Barbasso
committed
[DSC-1652] add warning and error messages to loader component
1 parent 361f6ef commit edaf963

9 files changed

Lines changed: 143 additions & 29 deletions

File tree

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
1-
<div *ngIf="!spinner">
2-
<label *ngIf="showMessage && message">{{ message }}</label>
3-
<div class="loader">
4-
<span class="l-1"></span>
5-
<span class="l-2"></span>
6-
<span class="l-3"></span>
7-
<span class="l-4"></span>
8-
<span class="l-5"></span>
9-
<span class="l-6"></span>
10-
<span class="l-7"></span>
11-
<span class="l-8"></span>
12-
<span class="l-9"></span>
13-
<span class="l-10"></span>
14-
</div>
15-
</div>
16-
<div *ngIf='spinner' class="spinner spinner-border" role="status">
17-
<span class="sr-only">{{ message }}</span>
1+
<div [ngSwitch]="messageToShow">
2+
<ng-container *ngSwitchCase="MessageType.LOADING">
3+
<label *ngIf="message">{{ message }}</label>
4+
</ng-container>
5+
<ng-container *ngSwitchCase="MessageType.WARNING">
6+
<label *ngIf="warningMessage">{{ warningMessage }}</label>
7+
</ng-container>
8+
<ng-container *ngSwitchCase="MessageType.ERROR">
9+
<ds-alert *ngIf="errorMessage" [type]="AlertTypeEnum.Error" [content]="errorMessage"></ds-alert>
10+
</ng-container>
11+
<ng-container *ngIf="!spinner && messageToShow !== MessageType.ERROR">
12+
<div class="loader">
13+
<span class="l-1"></span>
14+
<span class="l-2"></span>
15+
<span class="l-3"></span>
16+
<span class="l-4"></span>
17+
<span class="l-5"></span>
18+
<span class="l-6"></span>
19+
<span class="l-7"></span>
20+
<span class="l-8"></span>
21+
<span class="l-9"></span>
22+
<span class="l-10"></span>
23+
</div>
24+
</ng-container>
25+
<ng-container *ngIf="spinner && messageToShow !== MessageType.ERROR" class="spinner spinner-border" role="status">
26+
<span class="sr-only">{{ message }}</span>
27+
</ng-container>
1828
</div>

src/app/shared/loading/loading.component.spec.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ describe('LoadingComponent (inline template)', () => {
3535

3636
comp = fixture.componentInstance; // LoadingComponent test instance
3737
comp.message = 'test message';
38+
comp.warningMessage = 'test warning message';
39+
comp.errorMessage = 'test error message';
40+
3841
fixture.detectChanges();
39-
// query for the message <label> by CSS element selector
40-
de = fixture.debugElement.query(By.css('label'));
41-
el = de.nativeElement;
4242
});
4343

4444
it('should create', () => {
@@ -47,13 +47,32 @@ describe('LoadingComponent (inline template)', () => {
4747

4848
it('should display default message', () => {
4949
fixture.detectChanges();
50+
de = fixture.debugElement.query(By.css('label'));
51+
el = de.nativeElement;
5052
expect(el.textContent).toContain(comp.message);
5153
});
5254

5355
it('should display input message', () => {
5456
comp.message = 'Test Message';
5557
fixture.detectChanges();
58+
de = fixture.debugElement.query(By.css('label'));
59+
el = de.nativeElement;
5660
expect(el.textContent).toContain('Test Message');
5761
});
5862

63+
it('should display warning message when MessageType WARNING is set as messageToShow', () => {
64+
comp.messageToShow = comp.MessageType.WARNING;
65+
fixture.detectChanges();
66+
de = fixture.debugElement.query(By.css('label'));
67+
el = de.nativeElement;
68+
expect(el.textContent).toContain(comp.warningMessage);
69+
});
70+
71+
it('should display ds-alert when MessageType ERROR is set as messageToShow', () => {
72+
comp.messageToShow = comp.MessageType.ERROR;
73+
fixture.detectChanges();
74+
de = fixture.debugElement.query(By.css('ds-alert'));
75+
expect(de).toBeTruthy();
76+
});
77+
5978
});
Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1-
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
1+
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
22

33
import { TranslateService } from '@ngx-translate/core';
44

55
import { Subscription } from 'rxjs';
66
import { hasValue } from '../empty.util';
7+
import { environment } from '../../../environments/environment';
8+
import { AlertType } from '../alert/alert-type';
9+
10+
enum MessageType {
11+
LOADING = 'loading',
12+
WARNING = 'warning',
13+
ERROR = 'error'
14+
}
715

816
@Component({
917
selector: 'ds-loading',
@@ -15,29 +23,74 @@ export class LoadingComponent implements OnDestroy, OnInit {
1523
@Input() message: string;
1624
@Input() showMessage = true;
1725

26+
@Input() enableFallbackMessages = environment.loader.enableFallbackMessagesByDefault;
27+
@Input() warningMessage: string;
28+
@Input() warningMessageDelay = environment.loader.warningMessageDelay;
29+
@Input() errorMessage: string;
30+
@Input() errorMessageDelay = environment.loader.errorMessageDelay;
31+
1832
/**
1933
* Show a more compact spinner animation instead of the default one
2034
*/
2135
@Input() spinner = false;
2236

23-
private subscription: Subscription;
37+
readonly MessageType = MessageType;
38+
messageToShow: MessageType = this.showMessage ? MessageType.LOADING : undefined;
39+
40+
private subscriptions: Subscription[] = [];
41+
42+
warningTimeout: any;
43+
errorTimeout: any;
44+
45+
readonly AlertTypeEnum = AlertType;
2446

25-
constructor(private translate: TranslateService) {
47+
constructor(private translate: TranslateService, private changeDetectorRef: ChangeDetectorRef) {
2648

2749
}
2850

2951
ngOnInit() {
30-
if (this.message === undefined) {
31-
this.subscription = this.translate.get('loading.default').subscribe((message: string) => {
52+
if (this.showMessage && this.message === undefined) {
53+
this.subscriptions.push(this.translate.get('loading.default').subscribe((message: string) => {
3254
this.message = message;
33-
});
55+
}));
56+
}
57+
if (this.enableFallbackMessages) {
58+
if (!this.warningMessage) {
59+
this.subscriptions.push(this.translate.get('loading.warning').subscribe((warningMessage: string) => {
60+
this.warningMessage = warningMessage;
61+
}));
62+
}
63+
if (!this.errorMessage) {
64+
this.subscriptions.push(this.translate.get('loading.error').subscribe((errorMessage: string) => {
65+
this.errorMessage = errorMessage;
66+
}));
67+
}
68+
if (this.warningMessageDelay > 0) {
69+
this.warningTimeout = setTimeout(() => {
70+
this.messageToShow = MessageType.WARNING;
71+
this.changeDetectorRef.detectChanges();
72+
}, this.warningMessageDelay);
73+
}
74+
if (this.errorMessageDelay > 0) {
75+
this.errorTimeout = setTimeout(() => {
76+
this.messageToShow = MessageType.ERROR;
77+
this.changeDetectorRef.detectChanges();
78+
}, this.errorMessageDelay);
79+
}
3480
}
3581
}
3682

3783
ngOnDestroy() {
38-
if (hasValue(this.subscription)) {
39-
this.subscription.unsubscribe();
84+
if (this.subscriptions.length > 0) {
85+
this.subscriptions.forEach((sub) => {
86+
sub.unsubscribe();
87+
});
88+
}
89+
if (hasValue(this.warningTimeout)) {
90+
clearTimeout(this.warningTimeout);
91+
}
92+
if (hasValue(this.errorTimeout)) {
93+
clearTimeout(this.errorTimeout);
4094
}
4195
}
42-
4396
}

src/assets/i18n/en.json5

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3677,6 +3677,10 @@
36773677

36783678
"loading.default": "Loading...",
36793679

3680+
"loading.warning": "This is taking longer than expected. Please be patient.",
3681+
3682+
"loading.error": "An error occurred while loading the page. Please refresh the page and try again.",
3683+
36803684
"loading.item": "Loading item...",
36813685

36823686
"loading.items": "Loading items...",

src/assets/i18n/it.json5

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5372,6 +5372,12 @@
53725372
// "loading.default": "Loading...",
53735373
"loading.default": "Caricamento...",
53745374

5375+
// "loading.warning": "This is taking longer than expected. Please be patient.",
5376+
"loading.warning": "Il caricamento sta richiedendo più tempo del previsto. Si prega di attendere.",
5377+
5378+
// "loading.error": "An error occurred while loading the page. Please refresh the page and try again.",
5379+
"loading.error": "Si è verificato un errore durante il caricamento della pagina. Si prega di aggiornare la pagina e riprovare.",
5380+
53755381
// "loading.item": "Loading item...",
53765382
"loading.item": "Caricamento articolo...",
53775383

src/config/app-config.interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { AdvancedAttachmentRenderingConfig } from './advanced-attachment-renderi
3232
import { AttachmentRenderingConfig } from './attachment-rendering.config';
3333
import { SearchResultConfig } from './search-result-config.interface';
3434
import { MiradorConfig } from './mirador-config.interfaces';
35+
import { LoaderConfig } from './loader-config.interfaces';
3536

3637
interface AppConfig extends Config {
3738
ui: UIServerConfig;
@@ -70,6 +71,7 @@ interface AppConfig extends Config {
7071
advancedAttachmentRendering: AdvancedAttachmentRenderingConfig;
7172
searchResult: SearchResultConfig;
7273
mirador: MiradorConfig;
74+
loader: LoaderConfig;
7375
}
7476

7577
/**

src/config/default-app-config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
import { AttachmentRenderingConfig } from './attachment-rendering.config';
3636
import { SearchResultConfig } from './search-result-config.interface';
3737
import { MiradorConfig } from './mirador-config.interfaces';
38+
import { LoaderConfig } from './loader-config.interfaces';
3839

3940
export class DefaultAppConfig implements AppConfig {
4041
production = false;
@@ -760,4 +761,10 @@ export class DefaultAppConfig implements AppConfig {
760761
mirador: MiradorConfig = {
761762
enableDownloadPlugin: true,
762763
};
764+
765+
loader: LoaderConfig = {
766+
enableFallbackMessagesByDefault: false,
767+
warningMessageDelay: 10000, // 10 seconds
768+
errorMessageDelay: 30000, // 30 seconds
769+
};
763770
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Config } from './config.interface';
2+
3+
export interface LoaderConfig extends Config {
4+
enableFallbackMessagesByDefault: boolean;
5+
warningMessageDelay: number;
6+
errorMessageDelay: number;
7+
}

src/environments/environment.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,4 +577,10 @@ export const environment: BuildConfig = {
577577
mirador: {
578578
enableDownloadPlugin: true,
579579
},
580+
581+
loader: {
582+
enableFallbackMessagesByDefault: true,
583+
warningMessageDelay: 1000,
584+
errorMessageDelay: 2000,
585+
},
580586
};

0 commit comments

Comments
 (0)