mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
ui: beautiful checkbox for marking to eject drive after backup. broken
This commit is contained in:
committed by
Aiden McClelland
parent
0cd2a32b24
commit
a896f4c7a1
@@ -34,7 +34,7 @@
|
|||||||
<ion-item-group *ngFor="let d of disks">
|
<ion-item-group *ngFor="let d of disks">
|
||||||
<ion-item-divider>{{ d.logicalname }} ({{ d.size }})</ion-item-divider>
|
<ion-item-divider>{{ d.logicalname }} ({{ d.size }})</ion-item-divider>
|
||||||
<ion-item-group>
|
<ion-item-group>
|
||||||
<ion-item button [disabled]="p.isMounted" *ngFor="let p of d.partitions" (click)="presentAlert(p)">
|
<ion-item button [disabled]="p.isMounted" *ngFor="let p of d.partitions" (click)="presentAlert(d, p)">
|
||||||
<ion-icon slot="start" name="save-outline"></ion-icon>
|
<ion-icon slot="start" name="save-outline"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ p.label || p.logicalname }}</h2>
|
<h2>{{ p.label || p.logicalname }}</h2>
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
import { Component, Input } from '@angular/core'
|
||||||
import { ModalController, AlertController, LoadingController, IonicSafeString } from '@ionic/angular'
|
import { ModalController, AlertController, LoadingController, IonicSafeString, ToastController } from '@ionic/angular'
|
||||||
import { AppModel, AppStatus } from 'src/app/models/app-model'
|
import { AppModel, AppStatus } from 'src/app/models/app-model'
|
||||||
import { AppInstalledFull } from 'src/app/models/app-types'
|
import { AppInstalledFull } from 'src/app/models/app-types'
|
||||||
import { ApiService } from 'src/app/services/api/api.service'
|
import { ApiService } from 'src/app/services/api/api.service'
|
||||||
import { DiskInfo, DiskPartition } from 'src/app/models/server-model'
|
import { DiskInfo, DiskPartition } from 'src/app/models/server-model'
|
||||||
import { pauseFor } from 'src/app/util/misc.util'
|
import { pauseFor } from 'src/app/util/misc.util'
|
||||||
|
import { concatMap } from 'rxjs/operators'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-backup',
|
selector: 'app-backup',
|
||||||
@@ -25,6 +26,7 @@ export class AppBackupPage {
|
|||||||
private readonly loadingCtrl: LoadingController,
|
private readonly loadingCtrl: LoadingController,
|
||||||
private readonly apiService: ApiService,
|
private readonly apiService: ApiService,
|
||||||
private readonly appModel: AppModel,
|
private readonly appModel: AppModel,
|
||||||
|
private readonly toastCtrl: ToastController,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
@@ -73,18 +75,18 @@ export class AppBackupPage {
|
|||||||
await alert.present()
|
await alert.present()
|
||||||
}
|
}
|
||||||
|
|
||||||
async presentAlert (partition: DiskPartition): Promise<void> {
|
async presentAlert (disk: DiskInfo, partition: DiskPartition): Promise<void> {
|
||||||
if (this.type === 'create') {
|
if (this.type === 'create') {
|
||||||
this.presentAlertCreateEncrypted(partition)
|
this.presentAlertCreateEncrypted(disk, partition)
|
||||||
} else {
|
} else {
|
||||||
this.presentAlertWarn(partition)
|
this.presentAlertWarn(partition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async presentAlertCreateEncrypted (partition: DiskPartition): Promise<void> {
|
private async presentAlertCreateEncrypted (disk: DiskInfo, partition: DiskPartition): Promise<void> {
|
||||||
const alert = await this.alertCtrl.create({
|
const alert = await this.alertCtrl.create({
|
||||||
backdropDismiss: false,
|
backdropDismiss: false,
|
||||||
header: `Encrypt Backup`,
|
header: `Ready to Backup`,
|
||||||
message: `Enter your master password to create an encrypted backup of ${this.app.title} to "${partition.label || partition.logicalname}".`,
|
message: `Enter your master password to create an encrypted backup of ${this.app.title} to "${partition.label || partition.logicalname}".`,
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
@@ -93,6 +95,12 @@ export class AppBackupPage {
|
|||||||
type: 'password',
|
type: 'password',
|
||||||
placeholder: 'Master Password',
|
placeholder: 'Master Password',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'eject',
|
||||||
|
label: 'Eject drive when finished',
|
||||||
|
placeholder: 'Eject drive when finished',
|
||||||
|
type: 'checkbox',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
@@ -101,12 +109,12 @@ export class AppBackupPage {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Create Backup',
|
text: 'Create Backup',
|
||||||
handler: (data) => {
|
handler: async (data) => {
|
||||||
if (!data.password || data.password.length < 12) {
|
if (!data.password || data.password.length < 12) {
|
||||||
alert.message = new IonicSafeString(alert.message + '<br /><br /><ion-text color="danger">Password must be at least 12 characters in length.</ion-text>')
|
alert.message = new IonicSafeString(alert.message + '<br /><br /><ion-text color="danger">Password must be at least 12 characters in length.</ion-text>')
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
this.create(partition, data.password)
|
return this.create(disk, partition, data.password, data.eject)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -183,7 +191,7 @@ export class AppBackupPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async create (partition: DiskPartition, password?: string): Promise<void> {
|
private async create (disk: DiskInfo, partition: DiskPartition, password: string, eject: boolean): Promise<void> {
|
||||||
this.error = ''
|
this.error = ''
|
||||||
|
|
||||||
const loader = await this.loadingCtrl.create({
|
const loader = await this.loadingCtrl.create({
|
||||||
@@ -195,6 +203,14 @@ export class AppBackupPage {
|
|||||||
try {
|
try {
|
||||||
await this.apiService.createAppBackup(this.app.id, partition.logicalname, password)
|
await this.apiService.createAppBackup(this.app.id, partition.logicalname, password)
|
||||||
this.appModel.update({ id: this.app.id, status: AppStatus.CREATING_BACKUP })
|
this.appModel.update({ id: this.app.id, status: AppStatus.CREATING_BACKUP })
|
||||||
|
if (eject) {
|
||||||
|
this.appModel.watchForBackup(this.app.id).pipe(concatMap(
|
||||||
|
() => this.apiService.ejectExternalDisk(disk.logicalname),
|
||||||
|
)).subscribe({
|
||||||
|
next: () => this.toastEjection(true),
|
||||||
|
error: () => this.toastEjection(false),
|
||||||
|
})
|
||||||
|
}
|
||||||
await this.dismiss()
|
await this.dismiss()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
@@ -203,4 +219,26 @@ export class AppBackupPage {
|
|||||||
await loader.dismiss()
|
await loader.dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async toastEjection (success: boolean) {
|
||||||
|
const { header, message, cssClass } = success ? {
|
||||||
|
header: 'Success',
|
||||||
|
message: 'Drive ejected successfully',
|
||||||
|
cssClass: '',
|
||||||
|
} : {
|
||||||
|
header: 'Error',
|
||||||
|
message: 'Drive did not eject successfully',
|
||||||
|
cssClass: 'alert-error-message',
|
||||||
|
}
|
||||||
|
const t = await this.toastCtrl.create({
|
||||||
|
header,
|
||||||
|
message,
|
||||||
|
cssClass,
|
||||||
|
buttons: [{
|
||||||
|
icon: 'close-outline',
|
||||||
|
role: 'cancel',
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
await t.present()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,19 @@ export class AppModel extends MapSubject<AppInstalledFull> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// when an app is installing
|
||||||
|
watchForBackup (appId: string): Observable<string | undefined> {
|
||||||
|
const toWatch = super.watch(appId)
|
||||||
|
if (!toWatch) return of(undefined)
|
||||||
|
|
||||||
|
return toWatch.status.pipe(
|
||||||
|
pairwise(),
|
||||||
|
filter( ([old, _]) => old === AppStatus.CREATING_BACKUP),
|
||||||
|
take(1),
|
||||||
|
mapTo(appId),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
watchForInstallations (appIds: { id: string }[]): Observable<string> {
|
watchForInstallations (appIds: { id: string }[]): Observable<string> {
|
||||||
return merge(...appIds.map(({ id }) => this.watchForInstallation(id))).pipe(
|
return merge(...appIds.map(({ id }) => this.watchForInstallation(id))).pipe(
|
||||||
filter(t => !!t),
|
filter(t => !!t),
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { ServerModel, S9Notification } from 'src/app/models/server-model'
|
|||||||
import { ApiService } from 'src/app/services/api/api.service'
|
import { ApiService } from 'src/app/services/api/api.service'
|
||||||
import { pauseFor } from 'src/app/util/misc.util'
|
import { pauseFor } from 'src/app/util/misc.util'
|
||||||
import { LoaderService } from 'src/app/services/loader.service'
|
import { LoaderService } from 'src/app/services/loader.service'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'notifications',
|
selector: 'notifications',
|
||||||
templateUrl: 'notifications.page.html',
|
templateUrl: 'notifications.page.html',
|
||||||
|
|||||||
Reference in New Issue
Block a user