mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
ui up to date w old master
This commit is contained in:
@@ -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/
|
||||||
|
|||||||
@@ -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
2
ui/release.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
- Update app version in package.json
|
||||||
|
- Update app version in manifest.yaml
|
||||||
@@ -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-->
|
||||||
|
|||||||
@@ -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 })
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
Reference in New Issue
Block a user