Initial UI config for add-ons (#8271)

This commit is contained in:
Joakim Sørensen 2021-01-29 18:06:38 +01:00 committed by GitHub
parent b798523d53
commit 86847263b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 27 deletions

View File

@ -1,4 +1,7 @@
import "@material/mwc-button";
import { ActionDetail } from "@material/mwc-list";
import "@material/mwc-list/mwc-list-item";
import { mdiDotsVertical } from "@mdi/js";
import "@polymer/iron-autogrow-textarea/iron-autogrow-textarea";
import {
css,
@ -14,7 +17,9 @@ import {
} from "lit-element";
import { fireEvent } from "../../../../src/common/dom/fire_event";
import "../../../../src/components/buttons/ha-progress-button";
import "../../../../src/components/ha-button-menu";
import "../../../../src/components/ha-card";
import "../../../../src/components/ha-form/ha-form";
import "../../../../src/components/ha-yaml-editor";
import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor";
import {
@ -29,35 +34,67 @@ import type { HomeAssistant } from "../../../../src/types";
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
import { hassioStyle } from "../../resources/hassio-style";
const SUPPORTED_UI_TYPES = ["string", "select", "boolean", "integer", "float"];
@customElement("hassio-addon-config")
class HassioAddonConfig extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ type: Boolean }) private _configHasChanged = false;
@property({ type: Boolean }) private _valid = true;
@query("ha-yaml-editor", true) private _editor!: HaYamlEditor;
@internalProperty() private _canShowSchema = false;
@internalProperty() private _error?: string;
@internalProperty() private _options?: Record<string, unknown>;
@internalProperty() private _yamlMode = false;
@query("ha-yaml-editor") private _editor?: HaYamlEditor;
protected render(): TemplateResult {
return html`
<h1>${this.addon.name}</h1>
<ha-card header="Configuration">
<ha-card>
<div class="header">
<h2>Configuration</h2>
<div class="card-menu">
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
<mwc-icon-button slot="trigger">
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item .disabled=${!this._canShowSchema}>
${this._yamlMode ? "Edit in UI" : "Edit in YAML"}
</mwc-list-item>
<mwc-list-item class="warning">
Reset to defaults
</mwc-list-item>
</ha-button-menu>
</div>
</div>
<div class="card-content">
<ha-yaml-editor
@value-changed=${this._configChanged}
></ha-yaml-editor>
${!this._yamlMode && this._canShowSchema && this.addon.schema
? html`<ha-form
.data=${this._options!}
@value-changed=${this._configChanged}
.schema=${this.addon.schema}
></ha-form>`
: html` <ha-yaml-editor
@value-changed=${this._configChanged}
></ha-yaml-editor>`}
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
${this._valid ? "" : html` <div class="errors">Invalid YAML</div> `}
${!this._yamlMode ||
(this._canShowSchema && this.addon.schema) ||
this._valid
? ""
: html` <div class="errors">Invalid YAML</div> `}
</div>
<div class="card-actions">
<ha-progress-button class="warning" @click=${this._resetTapped}>
Reset to defaults
</ha-progress-button>
<ha-progress-button
@click=${this._saveTapped}
.disabled=${!this._configHasChanged || !this._valid}
@ -69,16 +106,54 @@ class HassioAddonConfig extends LitElement {
`;
}
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
this._canShowSchema = !this.addon.schema.find(
(entry) => !SUPPORTED_UI_TYPES.includes(entry.type)
);
this._yamlMode = !this._canShowSchema;
}
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (changedProperties.has("addon")) {
this._editor.setValue(this.addon.options);
this._options = { ...this.addon.options };
}
super.updated(changedProperties);
if (
changedProperties.has("_yamlMode") ||
changedProperties.has("_options")
) {
if (this._yamlMode) {
const editor = this._editor;
if (editor) {
editor.setValue(this._options!);
}
}
}
}
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._yamlMode = !this._yamlMode;
break;
case 1:
this._resetTapped(ev);
break;
}
}
private _configChanged(ev): void {
this._configHasChanged = true;
this._valid = ev.detail.isValid;
if (this.addon.schema && this._canShowSchema && !this._yamlMode) {
this._valid = true;
this._configHasChanged = true;
} else {
this._configHasChanged = true;
this._valid = ev.detail.isValid;
}
if (this._valid) {
this._options! = ev.detail.value;
}
}
private async _resetTapped(ev: CustomEvent): Promise<void> {
@ -122,18 +197,12 @@ class HassioAddonConfig extends LitElement {
const button = ev.currentTarget as any;
button.progress = true;
let data: HassioAddonSetOptionParams;
this._error = undefined;
try {
data = {
options: this._editor.value,
};
} catch (err) {
this._error = err;
return;
}
try {
await setHassioAddonOption(this.hass, this.addon.slug, data);
await setHassioAddonOption(this.hass, this.addon.slug, {
options: this._options!,
});
this._configHasChanged = false;
const eventdata = {
success: true,
@ -178,6 +247,29 @@ class HassioAddonConfig extends LitElement {
.syntaxerror {
color: var(--error-color);
}
.card-menu {
float: right;
z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color);
}
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
}
.header {
display: flex;
justify-content: space-between;
}
.header h2 {
color: var(--ha-card-header-color, --primary-text-color);
font-family: var(--ha-card-header-font-family, inherit);
font-size: var(--ha-card-header-font-size, 24px);
letter-spacing: -0.012em;
line-height: 48px;
padding: 12px 16px 16px;
display: block;
margin-block: 0px;
font-weight: normal;
}
`,
];
}

View File

@ -1,3 +1,4 @@
import { HaFormSchema } from "../../components/ha-form/ha-form";
import { HomeAssistant } from "../../types";
import { hassioApiResultExtractor, HassioResponse } from "./common";
@ -62,7 +63,7 @@ export interface HassioAddonDetails extends HassioAddonInfo {
privileged: any;
protected: boolean;
rating: "1-6";
schema: Record<string, any>;
schema: HaFormSchema[];
services_role: string[];
slug: string;
startup: "initialize" | "system" | "services" | "application" | "once";