mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
ui: eject disks todo
This commit is contained in:
committed by
Aiden McClelland
parent
8c79984e80
commit
5a4e980d31
@@ -76,7 +76,9 @@ export class AppComponent {
|
||||
this.init()
|
||||
}
|
||||
|
||||
ionViewDidEnter(){
|
||||
ionViewDidEnter () {
|
||||
// weird bug where a browser grabbed the value 'getdots' from the app.component.html preload input field.
|
||||
// this removes that field after prleloading occurs.
|
||||
pauseFor(500).then(() => this.untilLoaded = false)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!-- TODO: EJECT-DISKS, add a check box to allow a user to eject a disk on backup completion. -->
|
||||
<ion-content>
|
||||
<div style="height: 85%; margin: 20px; display: flex; flex-direction: column; justify-content: space-between;">
|
||||
<div>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
.error-message {
|
||||
--background: var(--ion-color-danger);
|
||||
margin: 12px;
|
||||
border-radius: 3px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.legacy-error-message {
|
||||
margin: 5px;
|
||||
}
|
||||
@@ -14,7 +14,7 @@ export class AppBackupConfirmationComponent implements OnInit {
|
||||
password: string
|
||||
$error$: BehaviorSubject<string> = new BehaviorSubject('')
|
||||
|
||||
// pass this through the modalCtrl once ejecting disks is an option in the UI.
|
||||
// TODO: EJECT-DISKS pass this through the modalCtrl once ejecting disks is an option in the UI.
|
||||
eject = true
|
||||
message: string
|
||||
|
||||
|
||||
@@ -173,4 +173,4 @@ function validate<T> (t: T, test: (t: T) => Boolean, desc: string) {
|
||||
}
|
||||
|
||||
|
||||
const defaultUninstallationWarning = serviceName => `Uninstalling ${ serviceName } will result in the deletion of its data.`
|
||||
const defaultUninstallationWarning = serviceName => `Uninstalling ${ serviceName } will result in the deletion of its data.`
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
<ion-label>
|
||||
New EmbassyOS Version {{version | displayEmver}} Available!
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-item>
|
||||
|
||||
@@ -8,4 +8,4 @@ ion-item {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ export class AppBackupPage {
|
||||
m.onWillDismiss().then(res => {
|
||||
const data = res.data
|
||||
if (data.cancel) return
|
||||
// we hard code the 'eject' last argument to be false, until ejection is an option in the UI.
|
||||
// TODO: EJECT-DISKS we hard code the 'eject' last argument to be false, until ejection is an option in the UI. When it is, add it to the data object above ^
|
||||
return this.create(disk, partition, data.password, false)
|
||||
})
|
||||
|
||||
|
||||
@@ -39,4 +39,4 @@
|
||||
</ion-button>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-content>
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
min-height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export class OSWelcomePage {
|
||||
.then(() => this.apiService.acknowledgeOSWelcome(this.config.version))
|
||||
.catch(console.error)
|
||||
|
||||
// return false to skip subsequent alert modals
|
||||
// return false to skip subsequent alert modals (e.g. check for updates modals)
|
||||
// return true to show subsequent alert modals
|
||||
return this.modalCtrl.dismiss(this.autoCheckUpdates)
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ export class AppModel extends MapSubject<AppInstalledFull> {
|
||||
)
|
||||
}
|
||||
|
||||
// when an app is backing up
|
||||
// TODO: EJECT-DISKS: we can use this to watch for an app completing its backup process.
|
||||
watchForBackup (appId: string): Observable<string | undefined> {
|
||||
const toWatch = super.watch(appId)
|
||||
if (!toWatch) return of(undefined)
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface BaseApp {
|
||||
export interface AppAvailablePreview extends BaseApp {
|
||||
versionLatest: string
|
||||
descriptionShort: string
|
||||
latestVersionTimestamp: Date
|
||||
latestVersionTimestamp: Date //used for sorting AAL
|
||||
}
|
||||
|
||||
export type AppAvailableFull =
|
||||
|
||||
@@ -88,4 +88,4 @@
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,4 +58,4 @@
|
||||
z-index: 1;
|
||||
right: -2px;
|
||||
--border-radius: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<ion-header *ngIf="{appLoading: $appLoading$ | async} as vars">
|
||||
<ion-toolbar>
|
||||
<ion-buttons style="margin: 0px 15px" slot="start">
|
||||
<img class="bulb" *ngIf="status$ | async | displayBulb: 'green'" src="assets/img/green-bulb.png"/>
|
||||
<img class="bulb" *ngIf="status$ | async | displayBulb: 'red'" src="assets/img/red-bulb.png"/>
|
||||
<img class="bulb" *ngIf="status$ | async | displayBulb: 'yellow'" src="assets/img/yellow-bulb.png"/>
|
||||
<img class="bulb" *ngIf="status$ | async | displayBulb: 'off'" src="assets/img/black-bulb.png"/>
|
||||
</ion-buttons>
|
||||
<ion-title>{{$app$.title | async}}</ion-title>
|
||||
<ion-buttons slot="end" *ngIf="">
|
||||
<ion-spinner *ngIf="vars.appLoading" name="dots" color="medium"></ion-spinner>
|
||||
<ion-button *ngIf="!vars.appLoading" (click)=presentPopoverMenu($event)>
|
||||
<ion-icon name="ellipsis-vertical"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content style="--overflow: hidden;" *ngIf="{isRunning: isRunning$ | async, status: status$ | async, appLoading: $appLoading$ | async, iframeLoading: $iframeLoading$ | async } as vars">
|
||||
<ion-spinner *ngIf="vars.appLoading || vars.iframeLoading" style="position: absolute; width: 4vh; left: calc(50% - 2vh); height: 100%;" name="lines" color="warning"></ion-spinner>
|
||||
<iframe (load)="iframeLoaded()" *ngIf="!vars.appLoading && vars.isRunning" [id]="appId + '-ui'" src="http://localhost:8100" width="100%" height="100%" style="border:1px solid black;"></iframe>
|
||||
<div *ngIf="!vars.appLoading && !vars.isRunning" class="flex-center" style="border:1px solid black; color: white">
|
||||
<ion-label style="margin:10px">{{$app$.title | async}} is not running.</ion-label>
|
||||
<ion-button fill="outline" (click)="toServiceShow()">View</ion-button>
|
||||
</div>
|
||||
</ion-content>
|
||||
@@ -7,6 +7,7 @@ import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { PwaBackComponentModule } from 'src/app/components/pwa-back-button/pwa-back.component.module'
|
||||
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
|
||||
import { ObjectConfigComponentModule } from 'src/app/components/object-config/object-config.component.module'
|
||||
// TODO: EJECT-DISKS
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!-- TODO: EJECT-DISKS -->
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
@@ -16,16 +17,14 @@
|
||||
</ion-refresher>
|
||||
|
||||
<ion-item-group>
|
||||
<!-- <ion-list> -->
|
||||
<ion-item *ngFor="let d of disks; let i = index">
|
||||
<ion-icon slot="start" name="save-outline"></ion-icon>
|
||||
<ion-label>{{d.logicalname}} ({{ d.size }})</ion-label>
|
||||
<ion-button *ngIf="!(d.$ejecting$ | async)" slot="end" fill="clear" color="medium" (click)="ejectDisk(i)">
|
||||
<ion-icon color="primary" class="icon" src="/assets/icon/eject.svg"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-spinner *ngIf="d.$ejecting$ | async" name="lines" color="medium"></ion-spinner>
|
||||
</ion-item>
|
||||
<!-- </ion-list> -->
|
||||
<ion-item *ngFor="let d of disks; let i = index">
|
||||
<ion-icon slot="start" name="save-outline"></ion-icon>
|
||||
<ion-label>{{d.logicalname}} ({{ d.size }})</ion-label>
|
||||
<ion-button *ngIf="!(d.$ejecting$ | async)" slot="end" fill="clear" color="medium" (click)="ejectDisk(i)">
|
||||
<ion-icon color="primary" class="icon" src="/assets/icon/eject.svg"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-spinner *ngIf="d.$ejecting$ | async" name="lines" color="medium"></ion-spinner>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
</ion-content>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { DiskInfo } from 'src/app/models/server-model'
|
||||
import { markAsLoadingDuringP } from 'src/app/services/loader.service'
|
||||
import { BehaviorSubject } from 'rxjs'
|
||||
import { AlertController } from '@ionic/angular'
|
||||
// TODO: EJECT-DISKS
|
||||
|
||||
type Ejectable<T> = T & { $ejecting$: BehaviorSubject<boolean> }
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ export class LiveApiService extends ApiService {
|
||||
return this.authRequest<ReqRes.GetExternalDisksRes>({ method: Method.GET, url: `/disks` })
|
||||
}
|
||||
|
||||
// TODO: EJECT-DISKS
|
||||
async ejectExternalDisk (logicalName: string): Promise<Unit> {
|
||||
return this.authRequest({ method: Method.POST, url: `/disks/eject`, data: { logicalName } })
|
||||
}
|
||||
|
||||
@@ -22,13 +22,15 @@ export class StartupAlertsNotifier {
|
||||
private readonly osUpdateService: OsUpdateService,
|
||||
) { }
|
||||
|
||||
// So. This takes our three checks and filters down to those that should run.
|
||||
// Then, the reduce fires, quickly iterating through yielding a promise (acc) to the next element
|
||||
// This takes our three checks and filters down to those that should run.
|
||||
// Then, the reduce fires, quickly iterating through yielding a promise (previousDisplay) to the next element
|
||||
// Each promise fires more or less concurrently, so each c.check(server) is run concurrently
|
||||
// Then, since we await acc before c.display(res), each promise executing gets hung awaiting the display of the previous run
|
||||
// Then, since we await previoudDisplay before c.display(res), each promise executing gets hung awaiting the display of the previous run
|
||||
async runChecks (server: Readonly<S9Server>): Promise<void> {
|
||||
await this.checks
|
||||
.filter(c => !c.hasRun && c.shouldRun(server))
|
||||
// returning true in the below block means to continue to next modal
|
||||
// returning false means to skip all subsequent modals
|
||||
.reduce(async (previousDisplay, c) => {
|
||||
let checkRes: any
|
||||
try {
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { ConfigService } from 'src/app/services/config.service'
|
||||
import { ToastController, NavController, ModalController, AlertController } from '@ionic/angular'
|
||||
import { ToastController, NavController } from '@ionic/angular'
|
||||
import { ServerModel, S9Server } from '../models/server-model'
|
||||
import { OSWelcomePage } from '../modals/os-welcome/os-welcome.page'
|
||||
import { ApiService } from './api/api.service'
|
||||
import { Emver } from './emver.service'
|
||||
import { LoaderService } from './loader.service'
|
||||
import { OsUpdateService } from './os-update.service'
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
@@ -15,16 +9,9 @@ export class SyncNotifier {
|
||||
checkedForUpdates = false
|
||||
|
||||
constructor (
|
||||
private readonly config: ConfigService,
|
||||
private readonly toastCtrl: ToastController,
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly alertCtrl: AlertController,
|
||||
private readonly navCtrl: NavController,
|
||||
private readonly serverModel: ServerModel,
|
||||
private readonly apiService: ApiService,
|
||||
private readonly loader: LoaderService,
|
||||
private readonly emver: Emver,
|
||||
private readonly osUpdateService: OsUpdateService,
|
||||
) { }
|
||||
|
||||
async handleSpecial (server: Readonly<S9Server>): Promise<void> {
|
||||
@@ -67,41 +54,3 @@ export class SyncNotifier {
|
||||
this.serverModel.update(updates)
|
||||
}
|
||||
}
|
||||
|
||||
// return new Promise(async resolve => {
|
||||
// const confirm = await this.alertController.create({
|
||||
// cssClass: 'alert-demo',
|
||||
// header: 'Warning',
|
||||
// message: `<h6>This is a <i>hosted</i> instance of Burn After Reading.</h6>
|
||||
// <p>Since you are not the server operator, you can never be 100% certain that your data are private or secure.</p>
|
||||
// <p>You can run your own, private instance with the click of a button using the Start9 Embassy.</p>`,
|
||||
// buttons: [
|
||||
// {
|
||||
// text: 'Run my Own',
|
||||
// handler: () => {
|
||||
// const a = document.createElement('a')
|
||||
// const site = (this.config.isConsulate || !this.config.isTor) ? 'https://start9labs.com' : 'http://privacy34kn4ez3y3nijweec6w4g54i3g54sdv7r5mr6soma3w4begyd.onion/'
|
||||
// a.href = site
|
||||
// a.target = '_blank'
|
||||
// pauseFor(500).then(() => a.click())
|
||||
// return resolve()
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// text: 'Use Demo',
|
||||
// role: 'cancel',
|
||||
// handler: () => resolve(),
|
||||
// },
|
||||
// ],
|
||||
// })
|
||||
|
||||
// await confirm.present()
|
||||
|
||||
// const alert = document.getElementsByClassName('alert-demo').item(0)
|
||||
// this.cleanup(
|
||||
// fromEvent(alert, 'keyup')
|
||||
// .pipe(filter((k: KeyboardEvent) => isEnter(k)))
|
||||
// .subscribe(() => confirm.dismiss()),
|
||||
// )
|
||||
// })
|
||||
// }
|
||||
@@ -160,4 +160,4 @@ export function capitalizeFirstLetter (string: string): string {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||
}
|
||||
|
||||
export const exists = t => !!t
|
||||
export const exists = t => !!t
|
||||
|
||||
Reference in New Issue
Block a user