only reach for config if exists

This commit is contained in:
Matt Hill
2021-09-09 10:20:35 -06:00
committed by Aiden McClelland
parent 946d4c6c1d
commit 6747a87800
4 changed files with 76 additions and 68 deletions

View File

@@ -6,8 +6,8 @@
</ion-button>
</ion-buttons>
<ion-title>Config</ion-title>
<ion-buttons *ngIf="hasConfig" slot="end" class="ion-padding-end">
<ion-button fill="clear" [disabled]="loadingText" (click)="resetDefaults()">
<ion-buttons *ngIf="!loadingText && hasConfig" slot="end" class="ion-padding-end">
<ion-button fill="clear" (click)="resetDefaults()">
<ion-icon slot="start" name="refresh"></ion-icon>
Reset Defaults
</ion-button>
@@ -23,68 +23,66 @@
<!-- not loading -->
<ng-template #loaded>
<ng-container *ngIf="patch.data['package-data'][pkgId] as pkg">
<ion-item *ngIf="hasConfig && !pkg.installed.status.configured && !configForm.dirty">
<ion-item *ngIf="hasConfig && !pkg.installed?.status.configured && !configForm.dirty">
<ion-label>
<ion-text color="success">To use the default config for {{ pkg.manifest.title }}, click "Save" below.</ion-text>
</ion-label>
</ion-item>
<ng-container *ngIf="rec && showRec">
<ion-item class="rec-item">
<ion-label>
<ion-text color="success">To use the default config for {{ pkg.manifest.title }}, click "Save" below.</ion-text>
<h2 style="display: flex; align-items: center;">
<ion-icon size="small" style="margin: 4px" slot="start" color="primary" slot="start" name="ellipse"></ion-icon>
<ion-thumbnail style="width: 3vh; height: 3vh; margin: 0px 2px 0px 5px;" slot="start">
<img [src]="rec.dependentIcon" [alt]="rec.dependentTitle"/>
</ion-thumbnail>
<ion-text style="margin: 5px; font-family: 'Montserrat'; font-size: smaller;">{{ rec.dependentTitle }}</ion-text>
</h2>
<div style="margin: 7px 5px;">
<p style="font-size: small; color: var(--ion-color-medium)"> {{ pkg.manifest.title }} config has been modified to satisfy {{ rec.dependentTitle }}.
<ion-text color="dark">To accept the changes, click “Save” above.</ion-text>
</p>
<a style="font-size: small" *ngIf="!openRec" (click)="openRec = true">More Info</a>
<ng-container *ngIf="openRec">
<p style="margin-top: 10px; color: var(--ion-color-medium); font-size: small" [innerHTML]="rec.description"></p>
<a style="font-size: x-small; font-style: italic;" (click)="openRec = false">hide</a>
</ng-container>
<ion-button style="position: absolute; right: 0; top: 0" color="primary" fill="clear" (click)="dismissRec()">
<ion-icon name="close"></ion-icon>
</ion-button>
</div>
</ion-label>
</ion-item>
<ng-container *ngIf="rec && showRec">
<ion-item class="rec-item">
<ion-label>
<h2 style="display: flex; align-items: center;">
<ion-icon size="small" style="margin: 4px" slot="start" color="primary" slot="start" name="ellipse"></ion-icon>
<ion-thumbnail style="width: 3vh; height: 3vh; margin: 0px 2px 0px 5px;" slot="start">
<img [src]="rec.dependentIcon" [alt]="rec.dependentTitle"/>
</ion-thumbnail>
<ion-text style="margin: 5px; font-family: 'Montserrat'; font-size: smaller;">{{ rec.dependentTitle }}</ion-text>
</h2>
<div style="margin: 7px 5px;">
<p style="font-size: small; color: var(--ion-color-medium)"> {{ pkg.manifest.title }} config has been modified to satisfy {{ rec.dependentTitle }}.
<ion-text color="dark">To accept the changes, click “Save” above.</ion-text>
</p>
<a style="font-size: small" *ngIf="!openRec" (click)="openRec = true">More Info</a>
<ng-container *ngIf="openRec">
<p style="margin-top: 10px; color: var(--ion-color-medium); font-size: small" [innerHTML]="rec.description"></p>
<a style="font-size: x-small; font-style: italic;" (click)="openRec = false">hide</a>
</ng-container>
<ion-button style="position: absolute; right: 0; top: 0" color="primary" fill="clear" (click)="dismissRec()">
<ion-icon name="close"></ion-icon>
</ion-button>
</div>
</ion-label>
</ion-item>
<ion-item-divider></ion-item-divider>
</ng-container>
<!-- no config -->
<ion-item *ngIf="!hasConfig">
<ion-label>
<p>No config options for {{ pkg.manifest.title }} {{ pkg.manifest.version }}.</p>
</ion-label>
</ion-item>
<!-- has config -->
<form *ngIf="hasConfig" [formGroup]="configForm" (ngSubmit)="save(pkg)" novalidate>
<form-object
[objectSpec]="configSpec"
[formGroup]="configForm"
[current]="current"
[showEdited]="true"
></form-object>
</form>
<ion-item-divider></ion-item-divider>
</ng-container>
<!-- no config -->
<ion-item *ngIf="!hasConfig">
<ion-label>
<p>No config options for {{ pkg.manifest.title }} {{ pkg.manifest.version }}.</p>
</ion-label>
</ion-item>
<!-- has config -->
<form *ngIf="hasConfig" [formGroup]="configForm" novalidate>
<form-object
[objectSpec]="configSpec"
[formGroup]="configForm"
[current]="current"
[showEdited]="true"
></form-object>
</form>
</ng-template>
</ion-content>
<ion-footer>
<ion-toolbar *ngIf="patch.data['package-data'][pkgId] as pkg">
<ion-buttons slot="end" class="ion-padding-end">
<ion-button *ngIf="hasConfig" fill="outline" [disabled]="saving" (click)="save(pkg)" class="enter-click" [class.no-click]="saving">
<ion-toolbar>
<ion-buttons *ngIf="!loadingText" slot="end" class="ion-padding-end">
<ion-button *ngIf="hasConfig" fill="outline" [disabled]="saving" (click)="save()" class="enter-click" [class.no-click]="saving">
Save
</ion-button>
<ion-button *ngIf="!loadingText && !hasConfig" fill="outline" (click)="dismiss()" class="enter-click">
<ion-button *ngIf="!hasConfig" fill="outline" (click)="dismiss()" class="enter-click">
Close
</ion-button>
</ion-buttons>

View File

@@ -1,7 +1,7 @@
import { Component, Input, ViewChild } from '@angular/core'
import { AlertController, ModalController, IonContent, LoadingController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { isEmptyObject, Recommendation } from 'src/app/util/misc.util'
import { isEmptyObject, isObject, Recommendation } from 'src/app/util/misc.util'
import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component'
import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards'
import { ConfigSpec } from 'src/app/pkg-config/config-types'
@@ -18,6 +18,7 @@ import { FormService } from 'src/app/services/form.service'
})
export class AppConfigPage {
@Input() pkgId: string
pkg: PackageDataEntry
loadingText: string | undefined
configSpec: ConfigSpec
configForm: FormGroup
@@ -39,18 +40,24 @@ export class AppConfigPage {
private readonly alertCtrl: AlertController,
private readonly modalCtrl: ModalController,
private readonly formService: FormService,
public readonly patch: PatchDbService,
private readonly patch: PatchDbService,
) { }
async ngOnInit () {
const rec = history.state?.configRecommendation as Recommendation
this.pkg = this.patch.data['package-data'][this.pkgId]
this.hasConfig = !!this.pkg.manifest.config
if (!this.hasConfig) return
this.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}...`
depConfig = await this.embassyApi.dryConfigureDependency({ 'dependency-id': this.pkgId, 'dependent-id': rec.dependentId })
if (this.rec) {
this.loadingText = `Setting properties to accommodate ${this.rec.dependentTitle}`
depConfig = await this.embassyApi.dryConfigureDependency({ 'dependency-id': this.pkgId, 'dependent-id': this.rec.dependentId })
}
this.setConfig(spec, config, depConfig)
} catch (e) {
@@ -67,7 +74,6 @@ export class AppConfigPage {
setConfig (spec: ConfigSpec, config: object, depConfig?: object) {
this.configSpec = spec
this.current = config
this.hasConfig = !isEmptyObject(config)
this.configForm = this.formService.createForm(spec, { ...config, ...depConfig })
this.configForm.markAllAsTouched()
@@ -82,7 +88,7 @@ export class AppConfigPage {
if (!next) throw new Error('Dependency config not compatible with service version. Please contact support')
const newVal = config[key]
// check if val is an object
if (newVal && typeof newVal === 'object' && !Array.isArray(newVal)) {
if (isObject(newVal)) {
this.alterConfigRecursive(next as FormGroup, newVal)
} else {
let val1 = group.get(key).value
@@ -113,7 +119,7 @@ export class AppConfigPage {
}
}
async save (pkg: PackageDataEntry) {
async save () {
if (this.configForm.invalid) {
document.getElementsByClassName('validation-error')[0].parentElement.parentElement.scrollIntoView({ behavior: 'smooth' })
return
@@ -131,7 +137,7 @@ export class AppConfigPage {
try {
this.saving = true
const breakages = await this.embassyApi.drySetPackageConfig({
id: pkg.manifest.id,
id: this.pkg.manifest.id,
config,
})
@@ -139,7 +145,7 @@ export class AppConfigPage {
const { cancelled } = await wizardModal(
this.modalCtrl,
this.wizardBaker.configure({
pkg,
pkg: this.pkg,
breakages,
}),
)
@@ -147,7 +153,7 @@ export class AppConfigPage {
}
await this.embassyApi.setPackageConfig({
id: pkg.manifest.id,
id: this.pkg.manifest.id,
config,
})
this.modalCtrl.dismiss()

View File

@@ -52,7 +52,7 @@ export module Mock {
'shm-size': '',
},
'health-checks': { },
config: null,
config: { get: { } as any, set: { } as any },
volumes: { },
'min-os-version': '0.2.12',
interfaces: {
@@ -359,7 +359,7 @@ export module Mock {
'shm-size': '',
},
'health-checks': { },
config: null,
config: { get: { } as any, set: { } as any },
volumes: { },
'min-os-version': '0.2.12',
interfaces: {

View File

@@ -81,6 +81,10 @@ export async function doForAtLeast (promises: Promise<any>[], minTime: number):
return returned
}
export function isObject (val: any): boolean {
return val && typeof val === 'object' && !Array.isArray(val)
}
export function isEmptyObject (obj: object): boolean {
if (!obj) return true
return Object.keys(obj).length === 0 && obj.constructor === Object