feat: add not found screen

This commit is contained in:
Wieland Schöbl
2021-01-19 15:17:47 +01:00
parent 0641ab12c8
commit e3d9ef40cc
11 changed files with 23964 additions and 59 deletions

View File

@@ -12,43 +12,53 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component} from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {Network} from '@ionic-native/network/ngx';
import {IonRefresher} from '@ionic/angular';
import {LangChangeEvent, TranslateService} from '@ngx-translate/core';
import {SCLanguageCode, SCThing, SCUuid} from '@openstapps/core';
import {SCLanguageCode, SCSaveableThing, SCThings, SCUuid} from '@openstapps/core';
import {DataProvider, DataScope} from '../data.provider';
/**
* TODO
* A Component to display an SCThing detailed
*/
@Component({
selector: 'stapps-data-detail',
styleUrls: ['data-detail.scss'],
templateUrl: 'data-detail.html',
})
export class DataDetailComponent {
export class DataDetailComponent implements OnInit {
/**
* TODO
* The associated item
*
* undefined if not loaded, null when unavailable
*/
dataProvider: DataProvider;
item?: SCThings | null = undefined;
/**
* TODO
*/
item: SCThing;
/**
* TODO
* The language of the item
*/
language: SCLanguageCode;
/**
*
* @param route TODO
* @param dataProvider TODO
* @param translateService TODO
* Type guard for SCSavableThing
*/
constructor(private readonly route: ActivatedRoute, dataProvider: DataProvider, translateService: TranslateService) {
this.dataProvider = dataProvider;
static isSCSavableThing(thing: SCThings | SCSaveableThing<SCThings>): thing is SCSaveableThing<SCThings> {
return typeof (thing as SCSaveableThing<SCThings>).data !== 'undefined';
}
/**
*
* @param route the route the page was accessed from
* @param dataProvider the data provider
* @param network the network provider
* @param translateService the translation service
*/
constructor(private readonly route: ActivatedRoute,
private readonly dataProvider: DataProvider,
private readonly network: Network,
translateService: TranslateService) {
this.language = translateService.currentLang as SCLanguageCode;
translateService.onLangChange.subscribe((event: LangChangeEvent) => {
this.language = event.lang as SCLanguageCode;
@@ -60,19 +70,27 @@ export class DataDetailComponent {
*
* @param uid Unique identifier of a thing
*/
async getItem(uid: SCUuid): Promise<void> {
await this.dataProvider.get(uid, DataScope.Remote)
.then((data) => {
this.item = data;
});
async getItem(uid: SCUuid) {
try {
const item = await this.dataProvider.get(uid, DataScope.Remote);
this.item = DataDetailComponent.isSCSavableThing(item) ? item.data : item;
} catch (_) {
this.item = null;
}
}
/**
* TODO
* Check if we have internet
*/
isDisconnected(): boolean {
return this.network.type === this.network.Connection.NONE;
}
/**
* Initialize
*/
// tslint:disable-next-line:prefer-function-over-method
ngOnInit() {
this.getItem(this.route.snapshot.paramMap.get('uid') || '');
void this.getItem(this.route.snapshot.paramMap.get('uid') ?? '');
}
/**
@@ -81,7 +99,7 @@ export class DataDetailComponent {
* @param refresher Refresher component that triggers the update
*/
async refresh(refresher: IonRefresher) {
await this.getItem(this.item.uid);
refresher.complete();
await this.getItem(this.item?.uid ?? this.route.snapshot.paramMap.get('uid') ?? '');
await refresher.complete();
}
}

View File

@@ -13,12 +13,32 @@
refreshingText="{{'data.REFRESHING' | translate}}">
</ion-refresher-content>
</ion-refresher>
<ng-container *ngIf="!item">
<stapps-skeleton-list-item></stapps-skeleton-list-item>
<stapps-skeleton-simple-card></stapps-skeleton-simple-card>
</ng-container>
<ng-container *ngIf="item">
<stapps-data-list-item [item]="item"></stapps-data-list-item>
<stapps-data-detail-content [item]="item"></stapps-data-detail-content>
</ng-container>
<div [ngSwitch]="true">
<ng-container *ngSwitchCase='!item && isDisconnected()'>
<div class='notFoundContainer'>
<ion-icon name='no-connection'>
</ion-icon>
<ion-label>
{{ 'data.detail.COULD_NOT_CONNECT' | translate }}
</ion-label>
</div>
</ng-container>
<ng-container *ngSwitchCase="item === null">
<div class="notFoundContainer">
<ion-icon name="broken-link">
</ion-icon>
<ion-label>
{{ 'data.detail.NOT_FOUND' | translate }}
</ion-label>
</div>
</ng-container>
<ng-container *ngSwitchCase="!item && item !== null">
<stapps-skeleton-list-item></stapps-skeleton-list-item>
<stapps-skeleton-simple-card></stapps-skeleton-simple-card>
</ng-container>
<ng-container *ngSwitchDefault>
<stapps-data-list-item [item]="item"></stapps-data-list-item>
<stapps-data-detail-content [item]="item"></stapps-data-detail-content>
</ng-container>
</div>
</ion-content>

View File

@@ -11,3 +11,20 @@
}
}
}
.notFoundContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
min-height: 50vh;
ion-icon {
font-size: 64px;
}
ion-label {
font-size: x-large;
}
}