mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
transitive dependency error and metrics scrolling
This commit is contained in:
committed by
Aiden McClelland
parent
97997bff97
commit
ffa9cac362
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user