mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-02 05:23:14 +00:00
update disks type, bring back server name, and better gifs for loading and updating
This commit is contained in:
committed by
Aiden McClelland
parent
8c1a01b306
commit
b0c78ad1a0
@@ -1,14 +1,14 @@
|
||||
<ion-content *ngIf="patch.data['server-info'].status as status">
|
||||
<ion-content *ngIf="patch.data['server-info'].status as status" style="--background: black;">
|
||||
|
||||
<ion-grid style="height: 100%;">
|
||||
<ion-row class="ion-align-items-center ion-text-center" style="height: 100%;">
|
||||
<ion-col>
|
||||
<ng-container *ngIf="status === ServerStatus.Updating">
|
||||
<h1>Embassy Updating</h1>
|
||||
<img src="assets/img/gifs/cube.gif" />
|
||||
<h1>Embassy updating</h1>
|
||||
<img src="assets/img/gifs/updating.gif" />
|
||||
</ng-container>
|
||||
<ng-container *ngIf="status === ServerStatus.BackingUp">
|
||||
<h1>Backing Up</h1>
|
||||
<h1>Embassy backing up</h1>
|
||||
<img src="assets/img/gifs/backing-up.gif" />
|
||||
</ng-container>
|
||||
</ion-col>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
img {
|
||||
width: 20%;
|
||||
border-radius: 0;
|
||||
width: 50%;
|
||||
max-width: 500px;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { PreferencesPage } from './preferences.page'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: PreferencesPage,
|
||||
},
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
],
|
||||
declarations: [
|
||||
PreferencesPage,
|
||||
],
|
||||
})
|
||||
export class PreferencesPageModule { }
|
||||
@@ -0,0 +1,19 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<pwa-back-button></pwa-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Preferences</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding-top">
|
||||
|
||||
<ion-item-group>
|
||||
<ion-item button (click)="presentModalName()">
|
||||
<ion-label>{{ fields['name'].name }}</ion-label>
|
||||
<ion-note slot="end">{{ patch.data.ui.name }}</ion-note>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
|
||||
</ion-content>
|
||||
@@ -0,0 +1,75 @@
|
||||
import { Component, ViewChild } from '@angular/core'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import { IonContent, LoadingController, ModalController } from '@ionic/angular'
|
||||
import { GenericInputComponent } from 'src/app/modals/generic-input/generic-input.component'
|
||||
import { ConfigSpec } from 'src/app/pkg-config/config-types'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
|
||||
@Component({
|
||||
selector: 'preferences',
|
||||
templateUrl: './preferences.page.html',
|
||||
styleUrls: ['./preferences.page.scss'],
|
||||
})
|
||||
export class PreferencesPage {
|
||||
@ViewChild(IonContent) content: IonContent
|
||||
fields = fields
|
||||
|
||||
constructor (
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly loadingCtrl: LoadingController,
|
||||
private readonly errToast: ErrorToastService,
|
||||
private readonly api: ApiService,
|
||||
public readonly patch: PatchDbService,
|
||||
) { }
|
||||
|
||||
ngAfterViewInit () {
|
||||
this.content.scrollToPoint(undefined, 1)
|
||||
}
|
||||
|
||||
async presentModalName (): Promise<void> {
|
||||
const modal = await this.modalCtrl.create({
|
||||
componentProps: {
|
||||
title: 'Edit Device Name',
|
||||
message: 'This is for your reference only.',
|
||||
label: 'Device Name',
|
||||
useMask: false,
|
||||
value: this.patch.data.ui.name,
|
||||
buttonText: 'Save',
|
||||
submitFn: async (value: string) => await this.setDbValue('name', value),
|
||||
},
|
||||
cssClass: 'alertlike-modal',
|
||||
presentingElement: await this.modalCtrl.getTop(),
|
||||
component: GenericInputComponent,
|
||||
})
|
||||
|
||||
await modal.present()
|
||||
}
|
||||
|
||||
private async setDbValue (key: string, value: string): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Saving...',
|
||||
cssClass: 'loader',
|
||||
})
|
||||
await loader.present()
|
||||
|
||||
try {
|
||||
await this.api.setDbValue({ pointer: `/${key}`, value })
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
loader.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const fields: ConfigSpec = {
|
||||
'name': {
|
||||
name: 'Device Name',
|
||||
type: 'string',
|
||||
nullable: false,
|
||||
masked: false,
|
||||
copyable: false,
|
||||
},
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
<ion-item-group>
|
||||
<ion-item-divider>General</ion-item-divider>
|
||||
<ion-item button (click)="serverConfig.presentAlert('share-stats', server['share-stats'])">
|
||||
<ion-label>Share Anonymous Statistics</ion-label>
|
||||
<ion-label>Report Bugs</ion-label>
|
||||
<ion-note slot="end">{{ server['share-stats'] ? 'Enabled' : 'Disabled' }}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { AlertController, LoadingController, ModalController } from '@ionic/angu
|
||||
import { SSHKeys } from 'src/app/services/api/api.types'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { BackupConfirmationComponent } from 'src/app/modals/backup-confirmation/backup-confirmation.component'
|
||||
import { GenericInputComponent } from 'src/app/modals/generic-input/generic-input.component'
|
||||
|
||||
@Component({
|
||||
selector: 'ssh-keys',
|
||||
@@ -41,7 +41,7 @@ export class SSHKeysPage {
|
||||
const { name, description } = sshSpec
|
||||
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: BackupConfirmationComponent,
|
||||
component: GenericInputComponent,
|
||||
componentProps: {
|
||||
title: name,
|
||||
message: description,
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { BehaviorSubject } from 'rxjs'
|
||||
import { SSHKeys } from 'src/app/services/api/api.types'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class SSHService {
|
||||
private readonly keys$ = new BehaviorSubject<SSHKeys>({ })
|
||||
|
||||
constructor (
|
||||
private readonly embassyApi: ApiService,
|
||||
) { }
|
||||
|
||||
watch$ () {
|
||||
return this.keys$.asObservable()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -3,7 +3,6 @@ import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { ServerBackupPage } from './server-backup.page'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { BackupConfirmationComponentModule } from 'src/app/modals/backup-confirmation/backup-confirmation.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -18,7 +17,6 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
BackupConfirmationComponentModule,
|
||||
SharingModule,
|
||||
],
|
||||
declarations: [
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<ion-item class="ion-margin-bottom">
|
||||
<ion-label>
|
||||
<h2>
|
||||
Select the drive where you want to create a backup of your Embassy, including all your installed services.
|
||||
Select the drive where you want to create a backup of your Embassy.
|
||||
</h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
@@ -38,22 +38,14 @@
|
||||
<!-- loaded -->
|
||||
<ng-container *ngIf="!loading">
|
||||
|
||||
<ion-item *ngIf="allPartitionsMounted">
|
||||
<ion-text class="ion-text-wrap" color="warning">No partitions available. To begin a backup, insert a storage device into your Embassy.</ion-text>
|
||||
</ion-item>
|
||||
|
||||
<ion-item-group>
|
||||
<div *ngFor="let disk of disks | keyvalue">
|
||||
<ion-item-divider>{{ disk.key }} - {{ disk.value.size }}</ion-item-divider>
|
||||
<ion-item button *ngFor="let partition of disk.value.partitions | keyvalue" [disabled]="partition.value['is-mounted']" (click)="presentModal(partition.key)">
|
||||
<div *ngFor="let disk of disks">
|
||||
<ion-item-divider>{{ disk.logicalname }} - {{ disk.capacity | convertBytes }}</ion-item-divider>
|
||||
<ion-item button *ngFor="let partition of disk.partitions" (click)="presentModal(partition.logicalname)">
|
||||
<ion-icon slot="start" name="save-outline" size="large"></ion-icon>
|
||||
<ion-label>
|
||||
<h1>{{ partition.value.label || partition.key }}</h1>
|
||||
<h2>{{ partition.value.size || 'unknown size' }}</h2>
|
||||
<p *ngIf="!partition.value['is-mounted']; else unavailable"><ion-text color="success">Available</ion-text></p>
|
||||
<ng-template #unavailable>
|
||||
<p><ion-text color="danger">Unavailable</ion-text></p>
|
||||
</ng-template>
|
||||
<h1>{{ partition.label || partition.logicalname }}</h1>
|
||||
<h2>{{ partition.capacity | convertBytes }}</h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ModalController } from '@ionic/angular'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { BackupConfirmationComponent } from 'src/app/modals/backup-confirmation/backup-confirmation.component'
|
||||
import { GenericInputComponent } from 'src/app/modals/generic-input/generic-input.component'
|
||||
import { DiskInfo } from 'src/app/services/api/api.types'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
styleUrls: ['./server-backup.page.scss'],
|
||||
})
|
||||
export class ServerBackupPage {
|
||||
disks: DiskInfo
|
||||
disks: DiskInfo[]
|
||||
loading = true
|
||||
allPartitionsMounted: boolean
|
||||
|
||||
@@ -33,7 +33,6 @@ export class ServerBackupPage {
|
||||
async getExternalDisks (): Promise<void> {
|
||||
try {
|
||||
this.disks = await this.embassyApi.getDisks({ })
|
||||
this.allPartitionsMounted = Object.values(this.disks).every(d => Object.values(d.partitions).every(p => p['is-mounted']))
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
@@ -52,7 +51,7 @@ export class ServerBackupPage {
|
||||
submitFn: async (value: string) => await this.create(logicalname, value),
|
||||
},
|
||||
cssClass: 'alertlike-modal',
|
||||
component: BackupConfirmationComponent,
|
||||
component: GenericInputComponent,
|
||||
})
|
||||
|
||||
return await m.present()
|
||||
|
||||
@@ -34,6 +34,10 @@ const routes: Routes = [
|
||||
path: 'security',
|
||||
loadChildren: () => import('./security-routes/security-routing.module').then( m => m.SecurityRoutingModule),
|
||||
},
|
||||
{
|
||||
path: 'preferences',
|
||||
loadChildren: () => import('./preferences/preferences.module').then( m => m.PreferencesPageModule),
|
||||
},
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Embassy</ion-title>
|
||||
<ion-title>{{ patch.data.ui.name || patch.data['server-info'].id }}</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<badge-menu-button></badge-menu-button>
|
||||
</ion-buttons>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { AlertController, LoadingController, NavController } from '@ionic/angula
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
|
||||
@Component({
|
||||
selector: 'server-show',
|
||||
@@ -19,6 +20,7 @@ export class ServerShowPage {
|
||||
private readonly embassyApi: ApiService,
|
||||
private readonly navCtrl: NavController,
|
||||
private readonly route: ActivatedRoute,
|
||||
public readonly patch: PatchDbService,
|
||||
) { }
|
||||
|
||||
ngOnInit () {
|
||||
@@ -48,8 +50,8 @@ export class ServerShowPage {
|
||||
|
||||
async presentAlertShutdown () {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: 'Confirm',
|
||||
message: `Are you sure you want to shut down your Embassy? To turn it back on, you will need to physically unplug the device and plug it back in.`,
|
||||
header: 'Warning',
|
||||
message: `Embassy will remain off. To power back on, you will need to unplug the device and plug it back in.`,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
@@ -103,7 +105,21 @@ export class ServerShowPage {
|
||||
|
||||
private setButtons (): void {
|
||||
this.settings = {
|
||||
'Backups': [
|
||||
{
|
||||
title: 'Create Backup',
|
||||
icon: 'save-outline',
|
||||
action: () => this.navCtrl.navigateForward(['backup'], { relativeTo: this.route }),
|
||||
detail: true,
|
||||
},
|
||||
],
|
||||
'Settings': [
|
||||
{
|
||||
title: 'Preferences',
|
||||
icon: 'options-outline',
|
||||
action: () => this.navCtrl.navigateForward(['preferences'], { relativeTo: this.route }),
|
||||
detail: true,
|
||||
},
|
||||
{
|
||||
title: 'Privacy and Security',
|
||||
icon: 'shield-checkmark-outline',
|
||||
@@ -143,14 +159,6 @@ export class ServerShowPage {
|
||||
detail: true,
|
||||
},
|
||||
],
|
||||
'Backups': [
|
||||
{
|
||||
title: 'Create Backup',
|
||||
icon: 'save-outline',
|
||||
action: () => this.navCtrl.navigateForward(['backup'], { relativeTo: this.route }),
|
||||
detail: true,
|
||||
},
|
||||
],
|
||||
'Power': [
|
||||
{
|
||||
title: 'Restart',
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<ion-item-divider>Country</ion-item-divider>
|
||||
|
||||
<!-- loading -->
|
||||
<ng-container *ngIf="loading">
|
||||
<!-- <ng-container *ngIf="loading">
|
||||
<ion-item class="skeleton-parts">
|
||||
<ion-button slot="start" fill="clear">
|
||||
<ion-skeleton-text animated style="width: 30px; height: 30px; border-radius: 0;"></ion-skeleton-text>
|
||||
@@ -32,16 +32,14 @@
|
||||
<ion-skeleton-text animated style="width: 150px;"></ion-skeleton-text>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ng-container> -->
|
||||
|
||||
<!-- not loading -->
|
||||
<ng-container *ngIf="!loading">
|
||||
<ion-item button detail="false" (click)="presentAlertCountry()">
|
||||
<ion-icon slot="start" name="earth-outline" size="large"></ion-icon>
|
||||
<ion-label *ngIf="wifi.country">{{ wifi.country }} - {{ this.countries[wifi.country] }}</ion-label>
|
||||
<ion-label *ngIf="!wifi.country">Select Country</ion-label>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
<ion-item button detail="false" (click)="presentAlertCountry()" [disabled]="loading">
|
||||
<ion-icon slot="start" name="earth-outline" size="large"></ion-icon>
|
||||
<ion-label *ngIf="wifi.country">{{ wifi.country }} - {{ this.countries[wifi.country] }}</ion-label>
|
||||
<ion-label *ngIf="!wifi.country">Select Country</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<!-- loading -->
|
||||
<ng-container *ngIf="loading">
|
||||
|
||||
Reference in New Issue
Block a user