misc changes

This commit is contained in:
Drew Ansbacher
2021-08-30 14:04:01 -06:00
committed by Aiden McClelland
parent 9d52149a0d
commit 7ec2d26fe7
11 changed files with 172 additions and 152 deletions

View File

@@ -13,7 +13,7 @@ import { WizardAction } from '../wizard-types'
export class CompleteComponent implements OnInit, Loadable {
@Input() params: {
action: WizardAction
verb: string //loader verb: '*stopping* ...'
verb: string // loader verb: '*stopping* ...'
title: string
executeAction: () => Promise<any>
skipCompletionDialogue?: boolean
@@ -26,7 +26,6 @@ export class CompleteComponent implements OnInit, Loadable {
error: (e: Error) => void
}
loading$ = new BehaviorSubject(false)
color$ = new BehaviorSubject('medium')
cancel$ = new Subject<void>()

View File

@@ -43,11 +43,9 @@ export class AppConfigPage {
async ngOnInit () {
const rec = history.state?.configRecommendation as Recommendation
try {
this.loadingText = 'Loading Config'
const { spec, config } = await this.embassyApi.getPackageConfig({ id: this.pkgId })
let depConfig: object
if (rec) {
this.loadingText = `Setting properties to accommodate ${rec.dependentTitle}...`

View File

@@ -1,6 +1,7 @@
import { Component, Input } from '@angular/core'
import { IonicSafeString, LoadingController, ModalController } from '@ionic/angular'
import { getErrorMessage } from 'src/app/services/error-toast.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ErrorToastService, getErrorMessage } from 'src/app/services/error-toast.service'
@Component({
selector: 'backup-confirmation',

View File

@@ -25,7 +25,7 @@
<ion-col *ngFor="let pkg of pkgs | keyvalue : asIsOrder" sizeXs="4" sizeSm="3" sizeLg="3" sizeXl="2">
<ion-card class="installed-card" [routerLink]="['/services', pkg.value.entry.manifest.id]">
<div class="launch-container" *ngIf="pkg.value.entry.manifest.interfaces | hasUi">
<div class="launch-button-triangle" (click)="launchUi(pkg.value.entry, $event)" [class.launch-disabled]="!(pkg.value.entry.state | isLaunchable : pkg.value.entry.installed.status.main.status : pkg.value.entry.manifest.interfaces)">
<div class="launch-button-triangle" (click)="launchUi(pkg.value.entry, $event)" [class.launch-disabled]="!(pkg.value.entry.state | isLaunchable : pkg.value.entry.installed?.status.main.status : pkg.value.entry.manifest.interfaces)">
<ion-icon name="open-outline"></ion-icon>
</div>
</div>

View File

@@ -122,6 +122,7 @@ export class AppPropertiesPage {
this.properties = await this.embassyApi.getPackageProperties({ id: this.pkgId })
this.node = JsonPointer.get(this.properties, this.pointer || '')
} catch (e) {
console.log('catching')
this.errToast.present(e)
} finally {
this.loading = false

View File

@@ -1,156 +1,158 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-item lines="none">
<ion-avatar slot="start">
<img [src]="pkg['static-files'].icon" />
</ion-avatar>
<ion-label style="text-overflow: ellipsis;">
<h1 style="font-family: 'Montserrat';" [class.less-large]="pkg.manifest.title.length > 20">
{{ pkg.manifest.title }}
</h1>
<h2>{{ pkg.manifest.version | displayEmver }}</h2>
</ion-label>
</ion-item>
</ion-toolbar>
</ion-header>
<ng-container *ngIf="!!pkg">
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-item lines="none">
<ion-avatar slot="start">
<img [src]="pkg['static-files'].icon" />
</ion-avatar>
<ion-label style="text-overflow: ellipsis;">
<h1 style="font-family: 'Montserrat';" [class.less-large]="pkg.manifest.title.length > 20">
{{ pkg.manifest.title }}
</h1>
<h2>{{ pkg.manifest.version | displayEmver }}</h2>
</ion-label>
</ion-item>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-item-group>
<!-- ** always ** -->
<ion-item-divider>Status</ion-item-divider>
<ion-item>
<ion-label style="overflow: visible;">
<status [disconnected]="connectionFailure" size="x-large" weight="500" [rendering]="rendering"></status>
</ion-label>
<ion-button slot="end" class="action-button" *ngIf="pkg.state === PackageState.Installed && (pkg.manifest.interfaces | hasUi)" [disabled]="!(pkg.state | isLaunchable : pkg.installed.status.main.status : pkg.manifest.interfaces)" (click)="launchUiTab()">
<ion-icon slot="start" name="open-outline"></ion-icon>
Open UI
</ion-button>
<ng-container *ngIf="!connectionFailure">
<ion-button slot="end" class="action-button" *ngIf="rendering.feStatus === FeStatus.NeedsConfig" [routerLink]="['config']">
Configure
<ion-content>
<ion-item-group>
<!-- ** always ** -->
<ion-item-divider>Status</ion-item-divider>
<ion-item>
<ion-label style="overflow: visible;">
<status [disconnected]="connectionFailure" size="x-large" weight="500" [rendering]="rendering"></status>
</ion-label>
<ion-button slot="end" class="action-button" *ngIf="pkg.state === PackageState.Installed && (pkg.manifest.interfaces | hasUi)" [disabled]="!(pkg.state | isLaunchable : pkg.installed.status.main.status : pkg.manifest.interfaces)" (click)="launchUiTab()">
<ion-icon slot="start" name="open-outline"></ion-icon>
Open UI
</ion-button>
<ion-button slot="end" class="action-button" *ngIf="[FeStatus.Running, FeStatus.StartingUp, FeStatus.NeedsAttention] | includes : rendering.feStatus" color="danger" (click)="stop()">
Stop
</ion-button>
<ion-button slot="end" class="action-button" *ngIf="rendering.feStatus === FeStatus.DependencyIssue" (click)="scrollToRequirements()">
Fix
</ion-button>
<ion-button slot="end" class="action-button" *ngIf="rendering.feStatus === FeStatus.Stopped" color="success" (click)="tryStart()">
Start
</ion-button>
</ng-container>
</ion-item>
<!-- ** installed ** -->
<ng-container *ngIf="pkg.state === PackageState.Installed">
<!-- ** !restoring/backing-up ** -->
<ng-container *ngIf="!([PackageMainStatus.BackingUp, PackageMainStatus.Restoring] | includes : mainStatus.status); else maintenance">
<!-- ** health checks ** -->
<ng-container *ngIf="!(mainStatus.health | empty)">
<ion-item-divider>Health Checks</ion-item-divider>
<ng-container *ngIf="connectionFailure">
<ion-item *ngFor="let health of mainStatus.health | keyvalue">
<ion-avatar slot="start">
<ion-skeleton-text style="width: 20px; height: 20px; border-radius: 0;"></ion-skeleton-text>
</ion-avatar>
<ion-label>
<ion-skeleton-text style="width: 100px; margin-bottom: 10px;"></ion-skeleton-text>
<ion-skeleton-text style="width: 150px; margin-bottom: 10px;"></ion-skeleton-text>
</ion-label>
</ion-item>
</ng-container>
<ng-container *ngIf="!connectionFailure">
<ion-item *ngFor="let health of mainStatus.health | keyvalue : asIsOrder">
<ion-spinner class="icon-spinner" color="warning" slot="start" *ngIf="['starting', 'loading'] | includes : health.value.result"></ion-spinner>
<ion-icon slot="start" *ngIf="health.value.result === 'success'" name="checkmark-outline" color="success"></ion-icon>
<ion-icon slot="start" *ngIf="health.value.result === 'failure'" name="close" color="danger"></ion-icon>
<ion-icon slot="start" *ngIf="health.value.result === 'disabled'" name="remove-outline" color="dark"></ion-icon>
<ion-label>
<p>{{ health.key }}</p>
<h2>{{ health.value.result }}</h2>
<p *ngIf="health.value.result === 'failure'"><ion-text color="danger">{{ health.value.error }}</ion-text></p>
</ion-label>
</ion-item>
</ng-container>
<ng-container *ngIf="!connectionFailure">
<ion-button slot="end" class="action-button" *ngIf="rendering.feStatus === FeStatus.NeedsConfig" (click)="presentModalConfig()">
Configure
</ion-button>
<ion-button slot="end" class="action-button" *ngIf="[FeStatus.Running, FeStatus.StartingUp, FeStatus.NeedsAttention] | includes : rendering.feStatus" color="danger" (click)="stop()">
Stop
</ion-button>
<ion-button slot="end" class="action-button" *ngIf="rendering.feStatus === FeStatus.DependencyIssue" (click)="scrollToRequirements()">
Fix
</ion-button>
<ion-button slot="end" class="action-button" *ngIf="rendering.feStatus === FeStatus.Stopped" color="success" (click)="tryStart()">
Start
</ion-button>
</ng-container>
</ion-item>
<!-- ** menu ** -->
<ion-item-divider>Menu</ion-item-divider>
<ion-item button detail *ngFor="let button of buttons" (click)="button.action()">
<ion-icon slot="start" [name]="button.icon"></ion-icon>
<ion-label>{{ button.title }}</ion-label>
</ion-item>
<!-- ** installed ** -->
<ng-container *ngIf="pkg.state === PackageState.Installed">
<!-- ** !restoring/backing-up ** -->
<ng-container *ngIf="!([PackageMainStatus.BackingUp, PackageMainStatus.Restoring] | includes : mainStatus.status); else maintenance">
<!-- ** health checks ** -->
<ng-container *ngIf="!(mainStatus.health | empty)">
<ion-item-divider>Health Checks</ion-item-divider>
<ng-container *ngIf="connectionFailure">
<ion-item *ngFor="let health of mainStatus.health | keyvalue">
<ion-avatar slot="start">
<ion-skeleton-text style="width: 20px; height: 20px; border-radius: 0;"></ion-skeleton-text>
</ion-avatar>
<ion-label>
<ion-skeleton-text style="width: 100px; margin-bottom: 10px;"></ion-skeleton-text>
<ion-skeleton-text style="width: 150px; margin-bottom: 10px;"></ion-skeleton-text>
</ion-label>
</ion-item>
</ng-container>
<ng-container *ngIf="!connectionFailure">
<ion-item *ngFor="let health of mainStatus.health | keyvalue : asIsOrder">
<ion-spinner class="icon-spinner" color="warning" slot="start" *ngIf="['starting', 'loading'] | includes : health.value.result"></ion-spinner>
<ion-icon slot="start" *ngIf="health.value.result === 'success'" name="checkmark-outline" color="success"></ion-icon>
<ion-icon slot="start" *ngIf="health.value.result === 'failure'" name="close" color="danger"></ion-icon>
<ion-icon slot="start" *ngIf="health.value.result === 'disabled'" name="remove-outline" color="dark"></ion-icon>
<ion-label>
<p>{{ health.key }}</p>
<h2>{{ health.value.result }}</h2>
<p *ngIf="health.value.result === 'failure'"><ion-text color="danger">{{ health.value.error }}</ion-text></p>
</ion-label>
</ion-item>
</ng-container>
</ng-container>
<!-- ** dependencies ** -->
<ng-container *ngIf="!(pkg.installed['current-dependencies'] | empty)">
<ion-item-divider id="dependencies">Dependencies</ion-item-divider>
<!-- A current-dependency is a subset of the pkg.manifest.dependencies that is currently required as determined by the service config. -->
<ion-item *ngFor="let dep of pkg.installed['current-dependencies'] | keyvalue">
<ion-thumbnail slot="start">
<img [src]="pkg.installed['dependency-info'][dep.key].icon" />
</ion-thumbnail>
<ion-label>
<h2 style="font-family: 'Montserrat'">{{ pkg.installed['dependency-info'][dep.key].manifest.title }}</h2>
<p>{{ pkg.manifest.dependencies[dep.key].version | displayEmver }}</p>
<p><ion-text [color]="pkg.installed.status['dependency-errors'][dep.key] ? 'warning' : 'success'">{{ pkg.installed.status['dependency-errors'][dep.key] ? pkg.installed.status['dependency-errors'][dep.key].type : 'satisfied' }}</ion-text></p>
</ion-label>
<!-- ** menu ** -->
<ion-item-divider>Menu</ion-item-divider>
<ion-item button detail *ngFor="let button of buttons" (click)="button.action()">
<ion-icon slot="start" [name]="button.icon"></ion-icon>
<ion-label>{{ button.title }}</ion-label>
</ion-item>
<ion-button *ngIf="!pkg.installed.status['dependency-errors'][dep.key] || (pkg.installed.status['dependency-errors'][dep.key] && [DependencyErrorType.InterfaceHealthChecksFailed, DependencyErrorType.HealthChecksFailed] | includes : pkg.installed.status['dependency-errors'][dep.key].type)" slot="end" size="small" [routerLink]="['/services', dep.key]">
View
</ion-button>
<!-- ** dependencies ** -->
<ng-container *ngIf="!(pkg.installed['current-dependencies'] | empty)">
<ion-item-divider id="dependencies">Dependencies</ion-item-divider>
<!-- A current-dependency is a subset of the pkg.manifest.dependencies that is currently required as determined by the service config. -->
<ion-item *ngFor="let dep of pkg.installed['current-dependencies'] | keyvalue">
<ion-thumbnail slot="start">
<img [src]="pkg.installed['dependency-info'][dep.key].icon" />
</ion-thumbnail>
<ion-label>
<h2 style="font-family: 'Montserrat'">{{ pkg.installed['dependency-info'][dep.key].manifest.title }}</h2>
<p>{{ pkg.manifest.dependencies[dep.key].version | displayEmver }}</p>
<p><ion-text [color]="pkg.installed.status['dependency-errors'][dep.key] ? 'warning' : 'success'">{{ pkg.installed.status['dependency-errors'][dep.key] ? pkg.installed.status['dependency-errors'][dep.key].type : 'satisfied' }}</ion-text></p>
</ion-label>
<ng-container *ngIf="pkg.installed.status['dependency-errors'][dep.key]">
<ion-button *ngIf="!patch.data['package-data'][dep.key]" slot="end" size="small" (click)="fixDep('install', dep.key)">
Install
<ion-button *ngIf="!pkg.installed.status['dependency-errors'][dep.key] || (pkg.installed.status['dependency-errors'][dep.key] && [DependencyErrorType.InterfaceHealthChecksFailed, DependencyErrorType.HealthChecksFailed] | includes : pkg.installed.status['dependency-errors'][dep.key].type)" slot="end" size="small" [routerLink]="['/services', dep.key]">
View
</ion-button>
<ng-container *ngIf="patch.data['package-data'][dep.key] && patch.data['package-data'][dep.key].state === PackageState.Installed">
<ion-button *ngIf="pkg.installed.status['dependency-errors'][dep.key].type === DependencyErrorType.NotRunning" slot="end" size="small" [routerLink]="['/services', dep.key]">
Start
<ng-container *ngIf="pkg.installed.status['dependency-errors'][dep.key]">
<ion-button *ngIf="!patch.data['package-data'][dep.key]" slot="end" size="small" (click)="fixDep('install', dep.key)">
Install
</ion-button>
<ion-button *ngIf="pkg.installed.status['dependency-errors'][dep.key].type === DependencyErrorType.IncorrectVersion" slot="end" size="small" (click)="fixDep('update', dep.key)">
Update
</ion-button>
<ion-button *ngIf="pkg.installed.status['dependency-errors'][dep.key].type === DependencyErrorType.ConfigUnsatisfied" slot="end" size="small" (click)="fixDep('configure', dep.key)">
Configure
</ion-button>
</ng-container>
<div *ngIf="patch.data['package-data'][dep.key] && patch.data['package-data'][dep.key].state !== PackageState.Installed" slot="end">
<ion-spinner [color]="patch.data['package-data'][dep.key].state === PackageState.Removing ? 'danger' : 'primary'" style="height: 3vh; width: 3vh" name="dots"></ion-spinner>
</div>
</ng-container>
</ion-item>
</ng-container>
<ng-container *ngIf="patch.data['package-data'][dep.key] && patch.data['package-data'][dep.key].state === PackageState.Installed">
<ion-button *ngIf="pkg.installed.status['dependency-errors'][dep.key].type === DependencyErrorType.NotRunning" slot="end" size="small" [routerLink]="['/services', dep.key]">
Start
</ion-button>
<ion-button *ngIf="pkg.installed.status['dependency-errors'][dep.key].type === DependencyErrorType.IncorrectVersion" slot="end" size="small" (click)="fixDep('update', dep.key)">
Update
</ion-button>
<ion-button *ngIf="pkg.installed.status['dependency-errors'][dep.key].type === DependencyErrorType.ConfigUnsatisfied" slot="end" size="small" (click)="fixDep('configure', dep.key)">
Configure
</ion-button>
</ng-container>
<div *ngIf="patch.data['package-data'][dep.key] && patch.data['package-data'][dep.key].state !== PackageState.Installed" slot="end">
<ion-spinner [color]="patch.data['package-data'][dep.key].state === PackageState.Removing ? 'danger' : 'primary'" style="height: 3vh; width: 3vh" name="dots"></ion-spinner>
</div>
</ng-container>
</ion-item>
</ng-container>
</ng-container>
<ng-template #maintenance>
App is undergoing maintenance.
</ng-template>
</ng-container>
<ng-template #maintenance>
App is undergoing maintenance.
</ng-template>
</ng-container>
</ion-item-group>
</ion-item-group>
<!-- ** installing or updating ** -->
<div *ngIf="[PackageState.Installing, PackageState.Updating] | includes : pkg.state" style="padding: 16px;">
<p>Downloading: {{ (pkg['install-progress'] | installState).downloadProgress }}%</p>
<ion-progress-bar
[color]="pkg['install-progress']['download-complete'] ? 'success' : 'secondary'"
[value]="(pkg['install-progress'] | installState).downloadProgress / 100"
></ion-progress-bar>
<!-- ** installing or updating ** -->
<div *ngIf="[PackageState.Installing, PackageState.Updating] | includes : pkg.state" style="padding: 16px;">
<p>Downloading: {{ (pkg['install-progress'] | installState).downloadProgress }}%</p>
<ion-progress-bar
[color]="pkg['install-progress']['download-complete'] ? 'success' : 'secondary'"
[value]="(pkg['install-progress'] | installState).downloadProgress / 100"
></ion-progress-bar>
<p>Validating: {{ (pkg['install-progress'] | installState).validateProgress }}%</p>
<ion-progress-bar
[color]="pkg['install-progress']['validation-complete'] ? 'success' : 'secondary'"
[value]="(pkg['install-progress'] | installState).validateProgress / 100"
></ion-progress-bar>
<p>Validating: {{ (pkg['install-progress'] | installState).validateProgress }}%</p>
<ion-progress-bar
[color]="pkg['install-progress']['validation-complete'] ? 'success' : 'secondary'"
[value]="(pkg['install-progress'] | installState).validateProgress / 100"
></ion-progress-bar>
<p>Installing: {{ (pkg['install-progress'] | installState).unpackProgress }}%</p>
<ion-progress-bar
[color]="pkg['install-progress']['unpack-complete'] ? 'success' : 'secondary'"
[value]="(pkg['install-progress'] | installState).unpackProgress / 100"
></ion-progress-bar>
</div>
</ion-content>
<p>Installing: {{ (pkg['install-progress'] | installState).unpackProgress }}%</p>
<ion-progress-bar
[color]="pkg['install-progress']['unpack-complete'] ? 'success' : 'secondary'"
[value]="(pkg['install-progress'] | installState).unpackProgress / 100"
></ion-progress-bar>
</div>
</ion-content>
</ng-container>

View File

@@ -32,6 +32,7 @@ export class AppShowPage {
mainStatus: MainStatus
PackageMainStatus = PackageMainStatus
connectionFailure: boolean
loading = true
@ViewChild(IonContent) content: IonContent
subs: Subscription[] = []

View File

@@ -8,7 +8,7 @@
</ion-header>
<ion-content>
<text-spinner *ngIf="!marketplaceService.releaseNotes[pkgId]; else loaded" text="Loading Release Notes"></text-spinner>
<text-spinner *ngIf="loading; else loaded" text="Loading Release Notes"></text-spinner>
<ng-template #loaded>
<div style="margin: 0px;" *ngFor="let note of marketplaceService.releaseNotes[pkgId] | keyvalue : asIsOrder">

View File

@@ -1,6 +1,7 @@
import { Component, ViewChild } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { IonContent } from '@ionic/angular'
import { ErrorToastService } from 'src/app/services/error-toast.service'
import { MarketplaceService } from '../marketplace.service'
@Component({
@@ -12,17 +13,26 @@ export class AppReleaseNotes {
@ViewChild(IonContent) content: IonContent
selected: string
pkgId: string
loading = true
constructor (
private readonly route: ActivatedRoute,
public marketplaceService: MarketplaceService,
public errToast: ErrorToastService,
) { }
ngOnInit () {
async ngOnInit () {
this.pkgId = this.route.snapshot.paramMap.get('pkgId')
if (!this.marketplaceService.releaseNotes[this.pkgId]) {
this.marketplaceService.getReleaseNotes(this.pkgId)
try {
if (!this.marketplaceService.releaseNotes[this.pkgId]) {
await this.marketplaceService.getReleaseNotes(this.pkgId)
}
} catch (e) {
this.errToast.present(e)
} finally {
this.loading = false
}
}
ngAfterViewInit () {

View File

@@ -46,7 +46,7 @@ export class SSHKeysPage {
title: name,
message: description,
label: name,
submitFn: this.add,
submitFn: async (pk: string) => await this.add(pk),
},
cssClass: 'alertlike-modal',
})

View File

@@ -50,6 +50,14 @@ export class ConfigService {
}
isLaunchable (state: PackageState, status: PackageMainStatus, interfaces: { [id: string]: InterfaceDef }): boolean {
console.log('is launchable', this.isLaunchable)
console.log('state', state)
console.log('status', status)
console.log('ret val', status === PackageMainStatus.Running &&
(
(hasTorUi(interfaces) && this.isTor()) ||
(hasLanUi(interfaces) && !this.isTor())
))
if (this.isConsulate || state !== PackageState.Installed) {
return false
}