File
Implements
Index
Properties
|
|
|
Methods
|
|
|
Inputs
|
|
|
Accessors
|
|
|
Constructor
constructor(environment: Environment)
|
|
|
Parameters :
| Name |
Type |
Optional |
| environment |
Environment
|
No
|
|
|
error
|
Type : | null | Observable<>
|
|
|
|
loading
|
Type : Observable<boolean> | boolean
|
|
|
Methods
|
triggerReset
|
triggerReset()
|
|
|
|
|
|
triggerRetry
|
triggerRetry()
|
|
|
|
|
|
Public
errorMessage
|
Default value : signal('Unknown Error')
|
|
|
|
Public
isNotRelease
|
Default value : false
|
|
|
|
Public
resetInProgress
|
Default value : signal(false)
|
|
|
|
Public
retryInProgress
|
Default value : signal(false)
|
|
|
import {
JsonPipe,
NgIf,
} from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
Inject,
Input,
OnChanges,
OnDestroy,
OnInit,
signal,
SimpleChanges,
} from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import {
Environment,
IsNotReleaseVersion,
RXAP_ENVIRONMENT,
} from '@rxap/environment';
import {
Observable,
Subscription,
} from 'rxjs';
export interface DataSourceLikeForErrorHandling {
refresh?: () => void;
retry?: () => void;
reset?: () => void;
loading?: Observable<boolean> | boolean;
loading$?: Observable<boolean>;
error$?: Observable<unknown>;
error?: Observable<unknown> | unknown | null;
}
@Component({
selector: 'rxap-data-source-error',
templateUrl: './data-source-error.component.html',
styleUrls: ['./data-source-error.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
MatButtonModule,
NgIf,
MatProgressSpinnerModule,
JsonPipe,
]
})
export class DataSourceErrorComponent implements OnChanges, OnInit, OnDestroy {
@Input()
public error?: unknown | null | Observable<unknown>;
@Input()
public refresh?: () => void;
@Input()
public retry?: () => void;
@Input()
public reset?: () => void;
@Input()
public set dataSourceLike(value: DataSourceLikeForErrorHandling) {
this.refresh ??= value.refresh;
this.retry ??= value.retry;
this.reset ??= value.reset;
this.loading ??= value.loading ?? value.loading$;
this.error ??= value.error ?? value.error$;
}
@Input()
public loading?: Observable<boolean> | boolean;
public isNotRelease = false;
public errorMessage = signal('Unknown Error');
public retryInProgress = signal(false);
public resetInProgress = signal(false);
private _subscription?: Subscription;
constructor(
@Inject(RXAP_ENVIRONMENT)
private readonly environment: Environment,
) {
this.isNotRelease = IsNotReleaseVersion(environment);
}
ngOnChanges(changes: SimpleChanges) {
if (changes['error']) {
this.retryInProgress.set(false);
this.resetInProgress.set(false);
}
if (changes['loading']) {
if (!changes['loading'].currentValue && typeof changes['loading'].currentValue === 'boolean') {
this.retryInProgress.set(false);
this.resetInProgress.set(false);
}
}
}
ngOnDestroy() {
this._subscription?.unsubscribe();
}
ngOnInit() {
this._subscription = new Subscription();
if (this.loading instanceof Observable) {
this._subscription.add(this.loading.subscribe((loading) => {
if (!loading) {
if (this.retryInProgress()) {
this.retryInProgress.set(false);
}
if (this.resetInProgress()) {
this.resetInProgress.set(false);
}
}
}));
}
if (this.error instanceof Observable) {
this._subscription.add(this.error.subscribe((error) => {
if (error) {
this.errorMessage.set(error.message);
}
}));
}
}
triggerRetry() {
if (this.retry) {
this.retryInProgress.set(true);
this.retry();
} else if (this.refresh) {
this.retryInProgress.set(true);
this.refresh();
}
}
triggerReset() {
if (this.reset) {
this.resetInProgress.set(true);
this.reset();
}
}
}
<div class="p-10 w-full">
<div class="flex flex-col justify-center items-center gap-8">
<span i18n>Something has gone wrong!</span>
<div class="flex flex-row justify-center items-center gap-4">
<button *ngIf="refresh || retry" type="button" (click)="triggerRetry()" [disabled]="retryInProgress() || resetInProgress()" mat-stroked-button>
<span class="flex flex-row items-center gap-4">
<span i18n>Retry</span>
<mat-spinner *ngIf="retryInProgress()" [diameter]="15"></mat-spinner>
</span>
</button>
<button *ngIf="reset" type="button" (click)="triggerReset()" [disabled]="resetInProgress() || retryInProgress()" mat-stroked-button>
<span class="flex flex-row items-center gap-4">
<span i18n>Reset</span>
<mat-spinner *ngIf="resetInProgress()" [diameter]="15"></mat-spinner>
</span>
</button>
</div>
<span *ngIf="isNotRelease" class="text-red-700">{{errorMessage()}}</span>
</div>
</div>
.container {
padding: 64px;
width: 100%;
}
Legend
Html element with directive