mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 19:26:36 +00:00
Initial UI config for add-ons (#8271)
This commit is contained in:
parent
b798523d53
commit
86847263b8
@ -1,4 +1,7 @@
|
|||||||
import "@material/mwc-button";
|
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 "@polymer/iron-autogrow-textarea/iron-autogrow-textarea";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
@ -14,7 +17,9 @@ import {
|
|||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
import "../../../../src/components/buttons/ha-progress-button";
|
import "../../../../src/components/buttons/ha-progress-button";
|
||||||
|
import "../../../../src/components/ha-button-menu";
|
||||||
import "../../../../src/components/ha-card";
|
import "../../../../src/components/ha-card";
|
||||||
|
import "../../../../src/components/ha-form/ha-form";
|
||||||
import "../../../../src/components/ha-yaml-editor";
|
import "../../../../src/components/ha-yaml-editor";
|
||||||
import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor";
|
import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor";
|
||||||
import {
|
import {
|
||||||
@ -29,35 +34,67 @@ import type { HomeAssistant } from "../../../../src/types";
|
|||||||
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
|
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
|
||||||
import { hassioStyle } from "../../resources/hassio-style";
|
import { hassioStyle } from "../../resources/hassio-style";
|
||||||
|
|
||||||
|
const SUPPORTED_UI_TYPES = ["string", "select", "boolean", "integer", "float"];
|
||||||
|
|
||||||
@customElement("hassio-addon-config")
|
@customElement("hassio-addon-config")
|
||||||
class HassioAddonConfig extends LitElement {
|
class HassioAddonConfig extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
|
||||||
|
|
||||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
@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 _configHasChanged = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) private _valid = true;
|
@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 {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<h1>${this.addon.name}</h1>
|
<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">
|
<div class="card-content">
|
||||||
<ha-yaml-editor
|
${!this._yamlMode && this._canShowSchema && this.addon.schema
|
||||||
@value-changed=${this._configChanged}
|
? html`<ha-form
|
||||||
></ha-yaml-editor>
|
.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._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>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<ha-progress-button class="warning" @click=${this._resetTapped}>
|
|
||||||
Reset to defaults
|
|
||||||
</ha-progress-button>
|
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
@click=${this._saveTapped}
|
@click=${this._saveTapped}
|
||||||
.disabled=${!this._configHasChanged || !this._valid}
|
.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 {
|
protected updated(changedProperties: PropertyValues): void {
|
||||||
super.updated(changedProperties);
|
|
||||||
if (changedProperties.has("addon")) {
|
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 {
|
private _configChanged(ev): void {
|
||||||
this._configHasChanged = true;
|
if (this.addon.schema && this._canShowSchema && !this._yamlMode) {
|
||||||
this._valid = ev.detail.isValid;
|
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> {
|
private async _resetTapped(ev: CustomEvent): Promise<void> {
|
||||||
@ -122,18 +197,12 @@ class HassioAddonConfig extends LitElement {
|
|||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
button.progress = true;
|
button.progress = true;
|
||||||
|
|
||||||
let data: HassioAddonSetOptionParams;
|
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
data = {
|
await setHassioAddonOption(this.hass, this.addon.slug, {
|
||||||
options: this._editor.value,
|
options: this._options!,
|
||||||
};
|
});
|
||||||
} catch (err) {
|
|
||||||
this._error = err;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await setHassioAddonOption(this.hass, this.addon.slug, data);
|
|
||||||
this._configHasChanged = false;
|
this._configHasChanged = false;
|
||||||
const eventdata = {
|
const eventdata = {
|
||||||
success: true,
|
success: true,
|
||||||
@ -178,6 +247,29 @@ class HassioAddonConfig extends LitElement {
|
|||||||
.syntaxerror {
|
.syntaxerror {
|
||||||
color: var(--error-color);
|
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;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { HaFormSchema } from "../../components/ha-form/ha-form";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ export interface HassioAddonDetails extends HassioAddonInfo {
|
|||||||
privileged: any;
|
privileged: any;
|
||||||
protected: boolean;
|
protected: boolean;
|
||||||
rating: "1-6";
|
rating: "1-6";
|
||||||
schema: Record<string, any>;
|
schema: HaFormSchema[];
|
||||||
services_role: string[];
|
services_role: string[];
|
||||||
slug: string;
|
slug: string;
|
||||||
startup: "initialize" | "system" | "services" | "application" | "once";
|
startup: "initialize" | "system" | "services" | "application" | "once";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user