transitive dependency error and metrics scrolling

This commit is contained in:
Matt Hill
2021-10-05 21:17:39 -06:00
committed by Aiden McClelland
parent 97997bff97
commit ffa9cac362
5 changed files with 63 additions and 37 deletions

View File

@@ -62,15 +62,15 @@
<ng-container *ngIf="!connectionFailure">
<ion-item *ngFor="let health of healthChecks | keyvalue : asIsOrder">
<ng-container *ngIf="$any(health.value).result as result">
<ion-spinner class="icon-spinner" color="primary" slot="start" *ngIf="['starting', 'loading'] | includes : result"></ion-spinner>
<ion-icon slot="start" *ngIf="result === 'success'" name="checkmark" color="success"></ion-icon>
<ion-icon slot="start" *ngIf="result === 'failure'" name="warning" color="warning"></ion-icon>
<ion-icon slot="start" *ngIf="result === 'disabled'" name="remove" color="dark"></ion-icon>
<ion-spinner class="icon-spinner" color="primary" slot="start" *ngIf="[HealthResult.Starting, HealthResult.Loading] | includes : result"></ion-spinner>
<ion-icon slot="start" *ngIf="result === HealthResult.Success" name="checkmark" color="success"></ion-icon>
<ion-icon slot="start" *ngIf="result === HealthResult.Failure" name="warning" color="warning"></ion-icon>
<ion-icon slot="start" *ngIf="result === HealthResult.Disabled" name="remove" color="dark"></ion-icon>
<ion-label>
<h2 style="font-weight: bold;">{{ health.key }}</h2>
<h2>Result: {{ result | titlecase }}</h2>
<p *ngIf="result === 'loading'"><ion-text color="primary">{{ $any(health.value).message }}</ion-text></p>
<p *ngIf="result === 'failure'"><ion-text color="warning">{{ $any(health.value).error }}</ion-text></p>
<p *ngIf="result === HealthResult.Loading"><ion-text color="primary">{{ $any(health.value).message }}</ion-text></p>
<p *ngIf="result === HealthResult.Failure"><ion-text color="warning">{{ $any(health.value).error }}</ion-text></p>
</ion-label>
</ng-container>
</ion-item>

View File

@@ -8,7 +8,7 @@ import { wizardModal } from 'src/app/components/install-wizard/install-wizard.co
import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards'
import { ConfigService } from 'src/app/services/config.service'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
import { DependencyErrorConfigUnsatisfied, DependencyErrorType, HealthCheckResult, PackageDataEntry, PackageMainStatus, PackageState } from 'src/app/services/patch-db/data-model'
import { DependencyErrorConfigUnsatisfied, DependencyErrorType, HealthCheckResult, HealthResult, PackageDataEntry, PackageMainStatus, PackageState } from 'src/app/services/patch-db/data-model'
import { DependencyStatus, HealthStatus, PrimaryRendering, PrimaryStatus, renderPkgStatus } from 'src/app/services/pkg-status-rendering.service'
import { ConnectionFailure, ConnectionService } from 'src/app/services/connection.service'
import { ErrorToastService } from 'src/app/services/error-toast.service'
@@ -24,6 +24,7 @@ export class AppShowPage {
PackageState = PackageState
DependencyErrorType = DependencyErrorType
Math = Math
HealthResult = HealthResult
PS = PrimaryStatus
DS = DependencyStatus
PR = PrimaryRendering
@@ -210,13 +211,13 @@ export class AppShowPage {
if (error) {
// health checks failed
if ([DependencyErrorType.InterfaceHealthChecksFailed, DependencyErrorType.HealthChecksFailed].includes(error.type)) {
errorText = 'Health Check Failed'
errorText = 'Health check failed'
// not fully installed (same as !localDep?.installed)
} else if (error.type === DependencyErrorType.NotInstalled) {
if (localDep) {
errorText = localDep.state // 'Installing' | 'Removing'
} else {
errorText = 'Not Installed'
errorText = 'Not installed'
actionText = 'Install'
action = () => this.fixDep('install', id)
}
@@ -225,19 +226,21 @@ export class AppShowPage {
if (localDep) {
errorText = localDep.state // 'Updating' | 'Removing'
} else {
errorText = 'Incorrect Version'
errorText = 'Incorrect version'
actionText = 'Update'
action = () => this.fixDep('update', id)
}
// not running
} else if (error.type === DependencyErrorType.NotRunning) {
errorText = 'Not Running'
errorText = 'Not running'
actionText = 'Start'
// config unsatisfied
} else if (error.type === DependencyErrorType.ConfigUnsatisfied) {
errorText = 'Config Not Satisfied'
errorText = 'Config not satisfied'
actionText = 'Auto Config'
action = () => this.fixDep('configure', id)
} else if (error.type === DependencyErrorType.Transitive) {
errorText = 'Dependency has a dependency issue'
}
if (localDep && localDep.state !== PackageState.Installed) {

View File

@@ -8,18 +8,20 @@
</ion-header>
<ion-content class="ion-padding">
<skeleton-list *ngIf="loading; else loaded" groups="2"></skeleton-list>
<skeleton-list *ngIf="loading" groups="2"></skeleton-list>
<ng-template #loaded>
<ion-item-group *ngFor="let metricGroup of metrics | keyvalue : asIsOrder">
<ion-item-divider>{{ metricGroup.key }}</ion-item-divider>
<ion-item *ngFor="let metric of metricGroup.value | keyvalue : asIsOrder">
<ion-label>{{ metric.key }}</ion-label>
<ion-note *ngIf="metric.value" slot="end" class="metric-note">
<ion-text style="color: white;">{{ metric.value.value }} {{ metric.value.unit }}</ion-text>
</ion-note>
</ion-item>
</ion-item-group>
</ng-template>
<div id="metricSection">
<ng-container *ngIf="!loading">
<ion-item-group *ngFor="let metricGroup of metrics | keyvalue : asIsOrder">
<ion-item-divider>{{ metricGroup.key }}</ion-item-divider>
<ion-item *ngFor="let metric of metricGroup.value | keyvalue : asIsOrder">
<ion-label>{{ metric.key }}</ion-label>
<ion-note *ngIf="metric.value" slot="end" class="metric-note">
<ion-text style="color: white;">{{ metric.value.value }} {{ metric.value.unit }}</ion-text>
</ion-note>
</ion-item>
</ion-item-group>
</ng-container>
</div>
</ion-content>

View File

@@ -14,26 +14,34 @@ export class ServerMetricsPage {
loading = true
going = false
metrics: Metrics = { }
@ViewChild(IonContent) content: IonContent
constructor (
private readonly errToast: ErrorToastService,
private readonly embassyApi: ApiService,
) { }
ngOnInit () {
async ngOnInit () {
await this.getMetrics()
let headersCount = 0
let rowsCount = 0
Object.values(this.metrics).forEach(groupVal => {
headersCount++
Object.keys(groupVal).forEach(_ => {
rowsCount++
})
})
const height = headersCount * 54 + rowsCount * 50 + 24 // extra 24 for room at the bottom
const elem = document.getElementById('metricSection')
elem.style.height = `${height}px`
this.startDaemon()
}
ngAfterViewInit () {
this.content.scrollToPoint(undefined, 1)
this.loading = false
}
ngOnDestroy () {
this.stopDaemon()
}
async startDaemon (): Promise<void> {
private async startDaemon (): Promise<void> {
this.going = true
while (this.going) {
await this.getMetrics()
@@ -41,11 +49,11 @@ export class ServerMetricsPage {
}
}
stopDaemon () {
private stopDaemon () {
this.going = false
}
async getMetrics (): Promise<void> {
private async getMetrics (): Promise<void> {
try {
const metrics = await this.embassyApi.getServerMetrics({ })
Object.entries(metrics).forEach(([groupKey, groupVal]) => {
@@ -59,8 +67,6 @@ export class ServerMetricsPage {
} catch (e) {
this.errToast.present(e)
this.stopDaemon()
} finally {
this.loading = false
}
}

View File

@@ -261,7 +261,11 @@ export enum PackageMainStatus {
Restoring = 'restoring',
}
export type HealthCheckResult = HealthCheckResultStarting | HealthCheckResultLoading | HealthCheckResultDisabled | HealthCheckResultSuccess | HealthCheckResultFailure
export type HealthCheckResult = HealthCheckResultStarting |
HealthCheckResultLoading |
HealthCheckResultDisabled |
HealthCheckResultSuccess |
HealthCheckResultFailure
export enum HealthResult {
Starting = 'starting',
@@ -293,7 +297,13 @@ export interface HealthCheckResultFailure {
error: string
}
export type DependencyError = DependencyErrorNotInstalled | DependencyErrorNotRunning | DependencyErrorIncorrectVersion | DependencyErrorConfigUnsatisfied | DependencyErrorHealthChecksFailed | DependencyErrorInterfaceHealthChecksFailed
export type DependencyError = DependencyErrorNotInstalled |
DependencyErrorNotRunning |
DependencyErrorIncorrectVersion |
DependencyErrorConfigUnsatisfied |
DependencyErrorHealthChecksFailed |
DependencyErrorInterfaceHealthChecksFailed |
DependencyErrorTransitive
export enum DependencyErrorType {
NotInstalled = 'not-installed',
@@ -302,6 +312,7 @@ export enum DependencyErrorType {
ConfigUnsatisfied = 'config-unsatisfied',
HealthChecksFailed = 'health-checks-failed',
InterfaceHealthChecksFailed = 'interface-health-checks-failed',
Transitive = 'transitive',
}
export interface DependencyErrorNotInstalled {
@@ -333,6 +344,10 @@ export interface DependencyErrorInterfaceHealthChecksFailed {
failures: { [id: string]: HealthCheckResult }
}
export interface DependencyErrorTransitive {
type: DependencyErrorType.Transitive
}
export interface DependencyInfo {
[id: string]: DependencyEntry
}