ui up to date w old master

This commit is contained in:
Aaron Greenspan
2020-11-23 16:51:42 -07:00
parent 20a8b991b5
commit c9d86ba94b
10 changed files with 32 additions and 32 deletions

View File

@@ -1,6 +1,6 @@
manifest-version: 0 manifest-version: 0
app-id: start9-ambassador app-id: start9-ambassador
app-version: 0.2.5 app-version: 0.2.6
uri-rewrites: uri-rewrites:
- =/api -> http://{{start9-ambassador}}:5959/authenticate - =/api -> http://{{start9-ambassador}}:5959/authenticate
- /api/ -> http://{{start9-ambassador}}:5959/ - /api/ -> http://{{start9-ambassador}}:5959/

View File

@@ -1,6 +1,6 @@
{ {
"name": "embassy-ui", "name": "embassy-ui",
"version": "0.2.5", "version": "0.2.6",
"description": "GUI for EmbassyOS", "description": "GUI for EmbassyOS",
"author": "Start9 Labs", "author": "Start9 Labs",
"homepage": "https://github.com/Start9Labs/embassy-ui", "homepage": "https://github.com/Start9Labs/embassy-ui",

2
ui/release.md Normal file
View File

@@ -0,0 +1,2 @@
- Update app version in package.json
- Update app version in manifest.yaml

View File

@@ -65,6 +65,7 @@
<!-- Ionicons --> <!-- Ionicons -->
<ion-icon name="add"></ion-icon> <!--0.2.5--> <ion-icon name="add"></ion-icon> <!--0.2.5-->
<ion-icon name="alert-outline"></ion-icon> <!--0.2.5--> <ion-icon name="alert-outline"></ion-icon> <!--0.2.5-->
<ion-icon name="alert-circle-outline"></ion-icon> <!--0.2.5-->
<ion-icon name="arrow-back"></ion-icon> <!--0.2.5--> <ion-icon name="arrow-back"></ion-icon> <!--0.2.5-->
<ion-icon name="arrow-forward"></ion-icon> <!--0.2.5--> <ion-icon name="arrow-forward"></ion-icon> <!--0.2.5-->
<ion-icon name="arrow-up"></ion-icon> <!--0.2.5--> <ion-icon name="arrow-up"></ion-icon> <!--0.2.5-->

View File

@@ -1,10 +1,10 @@
import { Component } from '@angular/core' import { Component } from '@angular/core'
import { NavController, AlertController, ModalController, PopoverController } from '@ionic/angular' import { NavController, AlertController, ModalController, PopoverController } from '@ionic/angular'
import { ActivatedRoute } from '@angular/router' import { ActivatedRoute } from '@angular/router'
import { 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 { pauseFor, isEmptyObject } from 'src/app/util/misc.util' import { pauseFor, isEmptyObject, modulateTime } from 'src/app/util/misc.util'
import { PropertySubject, peekProperties } from 'src/app/util/property-subject.util' import { PropertySubject, peekProperties } from 'src/app/util/property-subject.util'
import { LoaderService, markAsLoadingDuring$ } from 'src/app/services/loader.service' import { LoaderService, markAsLoadingDuring$ } from 'src/app/services/loader.service'
import { TrackingModalController } from 'src/app/services/tracking-modal-controller.service' import { TrackingModalController } from 'src/app/services/tracking-modal-controller.service'
@@ -60,6 +60,7 @@ export class AppConfigPage extends Cleanup {
private readonly modalController: ModalController, private readonly modalController: ModalController,
private readonly trackingModalCtrl: TrackingModalController, private readonly trackingModalCtrl: TrackingModalController,
private readonly popoverController: PopoverController, private readonly popoverController: PopoverController,
private readonly appModel: AppModel,
) { super() } ) { super() }
backButtonDefense = false backButtonDefense = false
@@ -182,6 +183,7 @@ export class AppConfigPage extends Cleanup {
async save () { async save () {
const app = peekProperties(this.app) const app = peekProperties(this.app)
const ogAppStatus = app.status
return this.loader.of({ return this.loader.of({
message: `Saving config...`, message: `Saving config...`,
@@ -208,6 +210,9 @@ export class AppConfigPage extends Cleanup {
}) })
.then(({ skip }) => { .then(({ skip }) => {
if (skip) return if (skip) return
if (ogAppStatus === AppStatus.RUNNING) {
this.appModel.update({ id: this.appId, status: AppStatus.RESTARTING }, modulateTime(new Date(), 3, 'seconds'))
}
this.navCtrl.back() this.navCtrl.back()
}) })
.catch(e => this.error = { text: e.message }) .catch(e => this.error = { text: e.message })

View File

@@ -81,8 +81,8 @@
<ion-item-group class="ion-padding-bottom"> <ion-item-group class="ion-padding-bottom">
<ion-item-divider>Tor Address</ion-item-divider> <ion-item-divider>Tor Address</ion-item-divider>
<ion-item lines="none"> <ion-item lines="none">
<ion-label style="display: flex; justify-content: space-between; align-items: center;"> <ion-label style="display: flex; justify-content: space-between; align-items: center;" class="ion-text-wrap">
<p style="color: var(--ion-color-dark)">{{ vars.torAddress | truncateCenter:18:18:true }}</p> <p style="color: var(--ion-color-dark)">{{ vars.torAddress }}</p>
<ion-button slot="end" fill="clear" (click)="copyTor()"> <ion-button slot="end" fill="clear" (click)="copyTor()">
<ion-icon slot="icon-only" name="copy-outline" color="primary"></ion-icon> <ion-icon slot="icon-only" name="copy-outline" color="primary"></ion-icon>
</ion-button> </ion-button>

View File

@@ -17,6 +17,7 @@ import { catchError, concatMap, filter, switchMap, tap } from 'rxjs/operators'
import { Cleanup } from 'src/app/util/cleanup' import { Cleanup } from 'src/app/util/cleanup'
import { InformationPopoverComponent } from 'src/app/components/information-popover/information-popover.component' import { InformationPopoverComponent } from 'src/app/components/information-popover/information-popover.component'
import { Emver } from 'src/app/services/emver.service' import { Emver } from 'src/app/services/emver.service'
import { displayEmver } from 'src/app/pipes/emver.pipe'
@Component({ @Component({
selector: 'app-installed-show', selector: 'app-installed-show',
@@ -115,7 +116,7 @@ export class AppInstalledShowPage extends Cleanup {
const alert = await this.alertCtrl.create({ const alert = await this.alertCtrl.create({
backdropDismiss: false, backdropDismiss: false,
header: 'Update Available', header: 'Update Available',
message: `New version ${versionLatest} found for ${app.title}.`, message: `New version ${displayEmver(versionLatest)} found for ${app.title}.`,
buttons: [ buttons: [
{ {
text: 'Cancel', text: 'Cancel',

View File

@@ -20,13 +20,3 @@ export class TruncateEndPipe implements PipeTransform {
return val.slice(0, length) + '...' return val.slice(0, length) + '...'
} }
} }
// 4 and 4
// 12345678 => 12345678
// 123456789 => 123456789
// 1234567890 => 1234567890
// 12345678901 => 12345678901
// 1234...9012 => 1234...9012
// 1234...0123 => 1234...0123

View File

@@ -47,7 +47,7 @@ export abstract class ApiService {
abstract restoreAppBackup (appId: string, logicalname: string, password?: string): Promise<Unit> abstract restoreAppBackup (appId: string, logicalname: string, password?: string): Promise<Unit>
abstract stopAppBackup (appId: string): Promise<Unit> abstract stopAppBackup (appId: string): Promise<Unit>
abstract patchAppConfig (app: AppInstalledPreview, config: object, dryRun?: boolean): Promise<{ breakages: DependentBreakage[] }> abstract patchAppConfig (app: AppInstalledPreview, config: object, dryRun?: boolean): Promise<{ breakages: DependentBreakage[] }>
abstract postConfigureDependency(dependencyId: string, dependentId: string, dryRun?: boolean): Promise<{config: object, breakages: DependentBreakage[] }> abstract postConfigureDependency (dependencyId: string, dependentId: string, dryRun?: boolean): Promise< {config: object, breakages: DependentBreakage[] }>
abstract patchServerConfig (attr: string, value: any): Promise<Unit> abstract patchServerConfig (attr: string, value: any): Promise<Unit>
abstract wipeAppData (app: AppInstalledPreview): Promise<Unit> abstract wipeAppData (app: AppInstalledPreview): Promise<Unit>
abstract addSSHKey (sshKey: string): Promise<Unit> abstract addSSHKey (sshKey: string): Promise<Unit>

View File

@@ -9,6 +9,7 @@ import { HttpErrorResponse } from '@angular/common/http'
import { isUnauthorized } from 'src/app/util/web.util' import { isUnauthorized } from 'src/app/util/web.util'
import { Replace } from 'src/app/util/types.util' import { Replace } from 'src/app/util/types.util'
import { AppMetrics, parseMetricsPermissive } from 'src/app/util/metrics.util' import { AppMetrics, parseMetricsPermissive } from 'src/app/util/metrics.util'
import { modulateTime } from 'src/app/util/misc.util'
@Injectable() @Injectable()
export class LiveApiService extends ApiService { export class LiveApiService extends ApiService {
@@ -122,23 +123,23 @@ export class LiveApiService extends ApiService {
} }
async uninstallApp (appId: string, dryRun: boolean = false): Promise<{ breakages: DependentBreakage[] }> { async uninstallApp (appId: string, dryRun: boolean = false): Promise<{ breakages: DependentBreakage[] }> {
return this.authRequest({ method: Method.POST, url: `/apps/${appId}/uninstall${dryRunParam(dryRun, true)}`, readTimeout: 30000 }) return this.authRequest({ method: Method.POST, url: `/apps/${appId}/uninstall${dryRunParam(dryRun, true)}`, readTimeout: 60000 })
} }
async startApp (appId: string): Promise<Unit> { async startApp (appId: string): Promise<Unit> {
return this.authRequest({ method: Method.POST, url: `/apps/${appId}/start`, readTimeout: 30000 }) return this.authRequest({ method: Method.POST, url: `/apps/${appId}/start`, readTimeout: 60000 })
.then(() => this.appModel.update({ id: appId, status: AppStatus.RUNNING })) .then(() => this.appModel.update({ id: appId, status: AppStatus.RUNNING }))
.then(() => ({ })) .then(() => ({ }))
} }
async stopApp (appId: string, dryRun: boolean = false): Promise<{ breakages: DependentBreakage[] }> { async stopApp (appId: string, dryRun: boolean = false): Promise<{ breakages: DependentBreakage[] }> {
const res = await this.authRequest<{ breakages: DependentBreakage[] }>({ method: Method.POST, url: `/apps/${appId}/stop${dryRunParam(dryRun, true)}`, readTimeout: 30000 }) const res = await this.authRequest<{ breakages: DependentBreakage[] }>({ method: Method.POST, url: `/apps/${appId}/stop${dryRunParam(dryRun, true)}`, readTimeout: 60000 })
if (!dryRun) this.appModel.update({ id: appId, status: AppStatus.STOPPING }) if (!dryRun) this.appModel.update({ id: appId, status: AppStatus.STOPPING }, modulateTime(new Date(), 5, 'seconds'))
return res return res
} }
async restartApp (appId: string): Promise<Unit> { async restartApp (appId: string): Promise<Unit> {
return this.authRequest({ method: Method.POST, url: `/apps/${appId}/restart`, readTimeout: 30000 }) return this.authRequest({ method: Method.POST, url: `/apps/${appId}/restart`, readTimeout: 60000 })
.then(() => ({ } as any)) .then(() => ({ } as any))
} }
@@ -147,13 +148,13 @@ export class LiveApiService extends ApiService {
password: password || undefined, password: password || undefined,
logicalname, logicalname,
} }
return this.authRequest<ReqRes.PostAppBackupCreateRes>({ method: Method.POST, url: `/apps/${appId}/backup`, data, readTimeout: 30000 }) return this.authRequest<ReqRes.PostAppBackupCreateRes>({ method: Method.POST, url: `/apps/${appId}/backup`, data, readTimeout: 60000 })
.then(() => this.appModel.update({ id: appId, status: AppStatus.CREATING_BACKUP })) .then(() => this.appModel.update({ id: appId, status: AppStatus.CREATING_BACKUP }))
.then(() => ({ })) .then(() => ({ }))
} }
async stopAppBackup (appId: string): Promise<Unit> { async stopAppBackup (appId: string): Promise<Unit> {
return this.authRequest<ReqRes.PostAppBackupStopRes>({ method: Method.POST, url: `/apps/${appId}/backup/stop`, readTimeout: 30000 }) return this.authRequest<ReqRes.PostAppBackupStopRes>({ method: Method.POST, url: `/apps/${appId}/backup/stop`, readTimeout: 60000 })
.then(() => this.appModel.update({ id: appId, status: AppStatus.STOPPED })) .then(() => this.appModel.update({ id: appId, status: AppStatus.STOPPED }))
.then(() => ({ })) .then(() => ({ }))
} }
@@ -163,7 +164,7 @@ export class LiveApiService extends ApiService {
password: password || undefined, password: password || undefined,
logicalname, logicalname,
} }
return this.authRequest<ReqRes.PostAppBackupRestoreRes>({ method: Method.POST, url: `/apps/${appId}/backup/restore`, data, readTimeout: 30000 }) return this.authRequest<ReqRes.PostAppBackupRestoreRes>({ method: Method.POST, url: `/apps/${appId}/backup/restore`, data, readTimeout: 60000 })
.then(() => this.appModel.update({ id: appId, status: AppStatus.RESTORING_BACKUP })) .then(() => this.appModel.update({ id: appId, status: AppStatus.RESTORING_BACKUP }))
.then(() => ({ })) .then(() => ({ }))
} }
@@ -172,24 +173,24 @@ export class LiveApiService extends ApiService {
const data: ReqRes.PatchAppConfigReq = { const data: ReqRes.PatchAppConfigReq = {
config, config,
} }
return this.authRequest({ method: Method.PATCH, url: `/apps/${app.id}/config${dryRunParam(dryRun, true)}`, data, readTimeout: 30000 }) return this.authRequest({ method: Method.PATCH, url: `/apps/${app.id}/config${dryRunParam(dryRun, true)}`, data, readTimeout: 60000 })
} }
async postConfigureDependency (dependencyId: string, dependentId: string, dryRun?: boolean): Promise<{ config: object, breakages: DependentBreakage[] }> { async postConfigureDependency (dependencyId: string, dependentId: string, dryRun?: boolean): Promise<{ config: object, breakages: DependentBreakage[] }> {
return this.authRequest({ method: Method.POST, url: `/apps/${dependencyId}/autoconfig/${dependentId}${dryRunParam(dryRun, true)}`, readTimeout: 30000 }) return this.authRequest({ method: Method.POST, url: `/apps/${dependencyId}/autoconfig/${dependentId}${dryRunParam(dryRun, true)}`, readTimeout: 60000 })
} }
async patchServerConfig (attr: string, value: any): Promise<Unit> { async patchServerConfig (attr: string, value: any): Promise<Unit> {
const data: ReqRes.PatchServerConfigReq = { const data: ReqRes.PatchServerConfigReq = {
value, value,
} }
return this.authRequest({ method: Method.PATCH, url: `/${attr}`, data, readTimeout: 30000 }) return this.authRequest({ method: Method.PATCH, url: `/${attr}`, data, readTimeout: 60000 })
.then(() => this.serverModel.update({ [attr]: value })) .then(() => this.serverModel.update({ [attr]: value }))
.then(() => ({ })) .then(() => ({ }))
} }
async wipeAppData (app: AppInstalledPreview): Promise<Unit> { async wipeAppData (app: AppInstalledPreview): Promise<Unit> {
return this.authRequest({ method: Method.POST, url: `/apps/${app.id}/wipe`, readTimeout: 30000 }).then((res) => { return this.authRequest({ method: Method.POST, url: `/apps/${app.id}/wipe`, readTimeout: 60000 }).then((res) => {
this.appModel.update({ id: app.id, status: AppStatus.NEEDS_CONFIG }) this.appModel.update({ id: app.id, status: AppStatus.NEEDS_CONFIG })
return res return res
}) })
@@ -230,11 +231,11 @@ export class LiveApiService extends ApiService {
} }
async restartServer (): Promise<Unit> { async restartServer (): Promise<Unit> {
return this.authRequest({ method: Method.POST, url: '/restart', readTimeout: 30000 }) return this.authRequest({ method: Method.POST, url: '/restart', readTimeout: 60000 })
} }
async shutdownServer (): Promise<Unit> { async shutdownServer (): Promise<Unit> {
return this.authRequest({ method: Method.POST, url: '/shutdown', readTimeout: 30000 }) return this.authRequest({ method: Method.POST, url: '/shutdown', readTimeout: 60000 })
} }
private async authRequest<T> (opts: HttpOptions, overrides: Partial<{ version: string }> = { }): Promise<T> { private async authRequest<T> (opts: HttpOptions, overrides: Partial<{ version: string }> = { }): Promise<T> {