mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 03:06:41 +00:00
Add system-managed addon info (#25132)
* Add system managed addon info dialog * Add system managed alert * Fix translation * Update hassio/src/addon-view/info/hassio-addon-info.ts Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com> --------- Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
This commit is contained in:
parent
71b2e5f827
commit
dcbaa31c96
@ -1,12 +1,11 @@
|
|||||||
import "@material/mwc-button";
|
|
||||||
import "@material/mwc-list/mwc-list-item";
|
|
||||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { stopPropagation } from "../../../../src/common/dom/stop_propagation";
|
import { stopPropagation } from "../../../../src/common/dom/stop_propagation";
|
||||||
import "../../../../src/components/buttons/ha-progress-button";
|
import "../../../../src/components/buttons/ha-progress-button";
|
||||||
import "../../../../src/components/ha-alert";
|
import "../../../../src/components/ha-alert";
|
||||||
import "../../../../src/components/ha-card";
|
import "../../../../src/components/ha-card";
|
||||||
|
import "../../../../src/components/ha-list-item";
|
||||||
import "../../../../src/components/ha-select";
|
import "../../../../src/components/ha-select";
|
||||||
import type {
|
import type {
|
||||||
HassioAddonDetails,
|
HassioAddonDetails,
|
||||||
@ -29,6 +28,8 @@ class HassioAddonAudio extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
@state() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
@state() private _inputDevices?: HassioHardwareAudioDevice[];
|
@state() private _inputDevices?: HassioHardwareAudioDevice[];
|
||||||
@ -48,7 +49,7 @@ class HassioAddonAudio extends LitElement {
|
|||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
${this._error
|
${this._error
|
||||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||||
: ""}
|
: nothing}
|
||||||
${this._inputDevices &&
|
${this._inputDevices &&
|
||||||
html`<ha-select
|
html`<ha-select
|
||||||
.label=${this.supervisor.localize(
|
.label=${this.supervisor.localize(
|
||||||
@ -59,12 +60,13 @@ class HassioAddonAudio extends LitElement {
|
|||||||
fixedMenuPosition
|
fixedMenuPosition
|
||||||
naturalMenuWidth
|
naturalMenuWidth
|
||||||
.value=${this._selectedInput!}
|
.value=${this._selectedInput!}
|
||||||
|
.disabled=${this.disabled}
|
||||||
>
|
>
|
||||||
${this._inputDevices.map(
|
${this._inputDevices.map(
|
||||||
(item) => html`
|
(item) => html`
|
||||||
<mwc-list-item .value=${item.device || ""}>
|
<ha-list-item .value=${item.device || ""}>
|
||||||
${item.name}
|
${item.name}
|
||||||
</mwc-list-item>
|
</ha-list-item>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
</ha-select>`}
|
</ha-select>`}
|
||||||
@ -78,18 +80,22 @@ class HassioAddonAudio extends LitElement {
|
|||||||
fixedMenuPosition
|
fixedMenuPosition
|
||||||
naturalMenuWidth
|
naturalMenuWidth
|
||||||
.value=${this._selectedOutput!}
|
.value=${this._selectedOutput!}
|
||||||
|
.disabled=${this.disabled}
|
||||||
>
|
>
|
||||||
${this._outputDevices.map(
|
${this._outputDevices.map(
|
||||||
(item) => html`
|
(item) => html`
|
||||||
<mwc-list-item .value=${item.device || ""}
|
<ha-list-item .value=${item.device || ""}
|
||||||
>${item.name}</mwc-list-item
|
>${item.name}</ha-list-item
|
||||||
>
|
>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
</ha-select>`}
|
</ha-select>`}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<ha-progress-button @click=${this._saveSettings}>
|
<ha-progress-button
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
@click=${this._saveSettings}
|
||||||
|
>
|
||||||
${this.supervisor.localize("common.save")}
|
${this.supervisor.localize("common.save")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
</div>
|
</div>
|
||||||
@ -171,6 +177,10 @@ class HassioAddonAudio extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _saveSettings(ev: CustomEvent): Promise<void> {
|
private async _saveSettings(ev: CustomEvent): Promise<void> {
|
||||||
|
if (this.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
button.progress = true;
|
button.progress = true;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import "../../../../src/components/ha-spinner";
|
import "../../../../src/components/ha-spinner";
|
||||||
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
@ -7,6 +7,7 @@ import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
|||||||
import { haStyle } from "../../../../src/resources/styles";
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
import type { HomeAssistant } from "../../../../src/types";
|
import type { HomeAssistant } from "../../../../src/types";
|
||||||
import { hassioStyle } from "../../resources/hassio-style";
|
import { hassioStyle } from "../../resources/hassio-style";
|
||||||
|
import "../info/hassio-addon-system-managed";
|
||||||
import "./hassio-addon-audio";
|
import "./hassio-addon-audio";
|
||||||
import "./hassio-addon-config";
|
import "./hassio-addon-config";
|
||||||
import "./hassio-addon-network";
|
import "./hassio-addon-network";
|
||||||
@ -19,6 +20,11 @@ class HassioAddonConfigDashboard extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean, attribute: "control-enabled" })
|
||||||
|
public controlEnabled = false;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.addon) {
|
if (!this.addon) {
|
||||||
return html`<ha-spinner></ha-spinner>`;
|
return html`<ha-spinner></ha-spinner>`;
|
||||||
@ -29,6 +35,16 @@ class HassioAddonConfigDashboard extends LitElement {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
${this.addon.system_managed &&
|
||||||
|
(hasConfiguration || this.addon.network || this.addon.audio)
|
||||||
|
? html`
|
||||||
|
<hassio-addon-system-managed
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.hideButton=${this.controlEnabled}
|
||||||
|
></hassio-addon-system-managed>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
${hasConfiguration || this.addon.network || this.addon.audio
|
${hasConfiguration || this.addon.network || this.addon.audio
|
||||||
? html`
|
? html`
|
||||||
${hasConfiguration
|
${hasConfiguration
|
||||||
@ -37,27 +53,33 @@ class HassioAddonConfigDashboard extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.addon=${this.addon}
|
.addon=${this.addon}
|
||||||
.supervisor=${this.supervisor}
|
.supervisor=${this.supervisor}
|
||||||
|
.disabled=${this.addon.system_managed &&
|
||||||
|
!this.controlEnabled}
|
||||||
></hassio-addon-config>
|
></hassio-addon-config>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.network
|
${this.addon.network
|
||||||
? html`
|
? html`
|
||||||
<hassio-addon-network
|
<hassio-addon-network
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.addon=${this.addon}
|
.addon=${this.addon}
|
||||||
.supervisor=${this.supervisor}
|
.supervisor=${this.supervisor}
|
||||||
|
.disabled=${this.addon.system_managed &&
|
||||||
|
!this.controlEnabled}
|
||||||
></hassio-addon-network>
|
></hassio-addon-network>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.audio
|
${this.addon.audio
|
||||||
? html`
|
? html`
|
||||||
<hassio-addon-audio
|
<hassio-addon-audio
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.addon=${this.addon}
|
.addon=${this.addon}
|
||||||
.supervisor=${this.supervisor}
|
.supervisor=${this.supervisor}
|
||||||
|
.disabled=${this.addon.system_managed &&
|
||||||
|
!this.controlEnabled}
|
||||||
></hassio-addon-audio>
|
></hassio-addon-audio>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
`
|
`
|
||||||
: this.supervisor.localize("addon.configuration.no_configuration")}
|
: this.supervisor.localize("addon.configuration.no_configuration")}
|
||||||
</div>
|
</div>
|
||||||
|
@ -61,6 +61,8 @@ class HassioAddonConfig extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
@state() private _configHasChanged = false;
|
@state() private _configHasChanged = false;
|
||||||
|
|
||||||
@state() private _valid = true;
|
@state() private _valid = true;
|
||||||
@ -176,7 +178,7 @@ class HassioAddonConfig extends LitElement {
|
|||||||
.path=${mdiDotsVertical}
|
.path=${mdiDotsVertical}
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
<mwc-list-item .disabled=${!this._canShowSchema}>
|
<mwc-list-item .disabled=${!this._canShowSchema || this.disabled}>
|
||||||
${this._yamlMode
|
${this._yamlMode
|
||||||
? this.supervisor.localize(
|
? this.supervisor.localize(
|
||||||
"addon.configuration.options.edit_in_ui"
|
"addon.configuration.options.edit_in_ui"
|
||||||
@ -185,7 +187,10 @@ class HassioAddonConfig extends LitElement {
|
|||||||
"addon.configuration.options.edit_in_yaml"
|
"addon.configuration.options.edit_in_yaml"
|
||||||
)}
|
)}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
<mwc-list-item class="warning">
|
<mwc-list-item
|
||||||
|
class=${!this.disabled ? "warning" : ""}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
>
|
||||||
${this.supervisor.localize("common.reset_defaults")}
|
${this.supervisor.localize("common.reset_defaults")}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
</ha-button-menu>
|
</ha-button-menu>
|
||||||
@ -195,6 +200,7 @@ class HassioAddonConfig extends LitElement {
|
|||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
${showForm
|
${showForm
|
||||||
? html`<ha-form
|
? html`<ha-form
|
||||||
|
.disabled=${this.disabled}
|
||||||
.data=${this._options!}
|
.data=${this._options!}
|
||||||
@value-changed=${this._configChanged}
|
@value-changed=${this._configChanged}
|
||||||
.computeLabel=${this.computeLabel}
|
.computeLabel=${this.computeLabel}
|
||||||
@ -208,7 +214,7 @@ class HassioAddonConfig extends LitElement {
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
></ha-form>`
|
></ha-form>`
|
||||||
: html` <ha-yaml-editor
|
: html`<ha-yaml-editor
|
||||||
@value-changed=${this._configChanged}
|
@value-changed=${this._configChanged}
|
||||||
.yamlSchema=${ADDON_YAML_SCHEMA}
|
.yamlSchema=${ADDON_YAML_SCHEMA}
|
||||||
></ha-yaml-editor>`}
|
></ha-yaml-editor>`}
|
||||||
@ -244,7 +250,9 @@ class HassioAddonConfig extends LitElement {
|
|||||||
<div class="card-actions right">
|
<div class="card-actions right">
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
@click=${this._saveTapped}
|
@click=${this._saveTapped}
|
||||||
.disabled=${!this._configHasChanged || !this._valid}
|
.disabled=${this.disabled ||
|
||||||
|
!this._configHasChanged ||
|
||||||
|
!this._valid}
|
||||||
>
|
>
|
||||||
${this.supervisor.localize("common.save")}
|
${this.supervisor.localize("common.save")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
@ -346,6 +354,10 @@ class HassioAddonConfig extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _saveTapped(ev: CustomEvent): Promise<void> {
|
private async _saveTapped(ev: CustomEvent): Promise<void> {
|
||||||
|
if (this.disabled || !this._configHasChanged || !this._valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
const options: Record<string, unknown> = this._yamlMode
|
const options: Record<string, unknown> = this._yamlMode
|
||||||
? this._editor?.value
|
? this._editor?.value
|
||||||
|
@ -28,6 +28,8 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
@state() private _showOptional = false;
|
@state() private _showOptional = false;
|
||||||
|
|
||||||
@state() private _configHasChanged = false;
|
@state() private _configHasChanged = false;
|
||||||
@ -65,9 +67,10 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
</p>
|
</p>
|
||||||
${this._error
|
${this._error
|
||||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||||
: ""}
|
: nothing}
|
||||||
|
|
||||||
<ha-form
|
<ha-form
|
||||||
|
.disabled=${this.disabled}
|
||||||
.data=${this._config}
|
.data=${this._config}
|
||||||
@value-changed=${this._configChanged}
|
@value-changed=${this._configChanged}
|
||||||
.computeLabel=${this._computeLabel}
|
.computeLabel=${this._computeLabel}
|
||||||
@ -92,14 +95,18 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
>
|
>
|
||||||
</ha-switch>
|
</ha-switch>
|
||||||
</ha-formfield>`
|
</ha-formfield>`
|
||||||
: ""}
|
: nothing}
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<ha-progress-button class="warning" @click=${this._resetTapped}>
|
<ha-progress-button
|
||||||
|
class="warning"
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
@click=${this._resetTapped}
|
||||||
|
>
|
||||||
${this.supervisor.localize("common.reset_defaults")}
|
${this.supervisor.localize("common.reset_defaults")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
@click=${this._saveTapped}
|
@click=${this._saveTapped}
|
||||||
.disabled=${!this._configHasChanged}
|
.disabled=${!this._configHasChanged || this.disabled}
|
||||||
>
|
>
|
||||||
${this.supervisor.localize("common.save")}
|
${this.supervisor.localize("common.save")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
@ -155,6 +162,10 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _resetTapped(ev: CustomEvent): Promise<void> {
|
private async _resetTapped(ev: CustomEvent): Promise<void> {
|
||||||
|
if (this.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
const data: HassioAddonSetOptionParams = {
|
const data: HassioAddonSetOptionParams = {
|
||||||
network: null,
|
network: null,
|
||||||
@ -186,6 +197,10 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _saveTapped(ev: CustomEvent): Promise<void> {
|
private async _saveTapped(ev: CustomEvent): Promise<void> {
|
||||||
|
if (!this._configHasChanged || this.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
|
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
|
@ -52,6 +52,9 @@ class HassioAddonDashboard extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public narrow = false;
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
|
@state()
|
||||||
|
private _controlEnabled = false;
|
||||||
|
|
||||||
@state() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
private _backPath = new URLSearchParams(window.parent.location.search).get(
|
private _backPath = new URLSearchParams(window.parent.location.search).get(
|
||||||
@ -134,11 +137,17 @@ class HassioAddonDashboard extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.supervisor=${this.supervisor}
|
.supervisor=${this.supervisor}
|
||||||
.addon=${this.addon}
|
.addon=${this.addon}
|
||||||
|
.controlEnabled=${this._controlEnabled}
|
||||||
|
@system-managed-take-control=${this._enableControl}
|
||||||
></hassio-addon-router>
|
></hassio-addon-router>
|
||||||
</hass-tabs-subpage>
|
</hass-tabs-subpage>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _enableControl() {
|
||||||
|
this._controlEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -23,6 +23,9 @@ class HassioAddonRouter extends HassRouterPage {
|
|||||||
| HassioAddonDetails
|
| HassioAddonDetails
|
||||||
| StoreAddonDetails;
|
| StoreAddonDetails;
|
||||||
|
|
||||||
|
@property({ type: Boolean, attribute: "control-enabled" })
|
||||||
|
public controlEnabled = false;
|
||||||
|
|
||||||
protected routerOptions: RouterOptions = {
|
protected routerOptions: RouterOptions = {
|
||||||
defaultPage: "info",
|
defaultPage: "info",
|
||||||
showLoading: true,
|
showLoading: true,
|
||||||
@ -48,6 +51,7 @@ class HassioAddonRouter extends HassRouterPage {
|
|||||||
el.supervisor = this.supervisor;
|
el.supervisor = this.supervisor;
|
||||||
el.addon = this.addon;
|
el.addon = this.addon;
|
||||||
el.narrow = this.narrow;
|
el.narrow = this.narrow;
|
||||||
|
el.controlEnabled = this.controlEnabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ class HassioAddonInfoDashboard extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||||
|
|
||||||
|
@property({ type: Boolean, attribute: "control-enabled" })
|
||||||
|
public controlEnabled = false;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.addon) {
|
if (!this.addon) {
|
||||||
return html`<ha-spinner></ha-spinner>`;
|
return html`<ha-spinner></ha-spinner>`;
|
||||||
@ -34,6 +37,7 @@ class HassioAddonInfoDashboard extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.supervisor=${this.supervisor}
|
.supervisor=${this.supervisor}
|
||||||
.addon=${this.addon}
|
.addon=${this.addon}
|
||||||
|
.controlEnabled=${this.controlEnabled}
|
||||||
></hassio-addon-info>
|
></hassio-addon-info>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import "@material/mwc-button";
|
|
||||||
import {
|
import {
|
||||||
mdiCheckCircle,
|
mdiCheckCircle,
|
||||||
mdiChip,
|
mdiChip,
|
||||||
mdiPlayCircle,
|
|
||||||
mdiCircleOffOutline,
|
mdiCircleOffOutline,
|
||||||
mdiCursorDefaultClickOutline,
|
mdiCursorDefaultClickOutline,
|
||||||
mdiDocker,
|
mdiDocker,
|
||||||
@ -19,27 +17,30 @@ import {
|
|||||||
mdiNumeric6,
|
mdiNumeric6,
|
||||||
mdiNumeric7,
|
mdiNumeric7,
|
||||||
mdiNumeric8,
|
mdiNumeric8,
|
||||||
|
mdiPlayCircle,
|
||||||
mdiPound,
|
mdiPound,
|
||||||
mdiShield,
|
mdiShield,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||||
import { LitElement, css, html } from "lit";
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { atLeastVersion } from "../../../../src/common/config/version";
|
import { atLeastVersion } from "../../../../src/common/config/version";
|
||||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
import { navigate } from "../../../../src/common/navigate";
|
import { navigate } from "../../../../src/common/navigate";
|
||||||
|
import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter";
|
||||||
import "../../../../src/components/buttons/ha-progress-button";
|
import "../../../../src/components/buttons/ha-progress-button";
|
||||||
import "../../../../src/components/ha-alert";
|
|
||||||
import "../../../../src/components/ha-card";
|
|
||||||
import "../../../../src/components/chips/ha-chip-set";
|
|
||||||
import "../../../../src/components/chips/ha-assist-chip";
|
import "../../../../src/components/chips/ha-assist-chip";
|
||||||
|
import "../../../../src/components/chips/ha-chip-set";
|
||||||
|
import "../../../../src/components/ha-alert";
|
||||||
|
import "../../../../src/components/ha-button";
|
||||||
|
import "../../../../src/components/ha-card";
|
||||||
|
import "../../../../src/components/ha-formfield";
|
||||||
import "../../../../src/components/ha-markdown";
|
import "../../../../src/components/ha-markdown";
|
||||||
import "../../../../src/components/ha-settings-row";
|
import "../../../../src/components/ha-settings-row";
|
||||||
import "../../../../src/components/ha-svg-icon";
|
import "../../../../src/components/ha-svg-icon";
|
||||||
import "../../../../src/components/ha-switch";
|
import "../../../../src/components/ha-switch";
|
||||||
import "../../../../src/components/ha-formfield";
|
|
||||||
import type { HaSwitch } from "../../../../src/components/ha-switch";
|
import type { HaSwitch } from "../../../../src/components/ha-switch";
|
||||||
import type {
|
import type {
|
||||||
AddonCapability,
|
AddonCapability,
|
||||||
@ -81,10 +82,11 @@ import { bytesToString } from "../../../../src/util/bytes-to-string";
|
|||||||
import "../../components/hassio-card-content";
|
import "../../components/hassio-card-content";
|
||||||
import "../../components/supervisor-metric";
|
import "../../components/supervisor-metric";
|
||||||
import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown";
|
import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown";
|
||||||
|
import { showSystemManagedDialog } from "../../dialogs/system-managed/show-dialog-system-managed";
|
||||||
import { hassioStyle } from "../../resources/hassio-style";
|
import { hassioStyle } from "../../resources/hassio-style";
|
||||||
import "../../update-available/update-available-card";
|
import "../../update-available/update-available-card";
|
||||||
import { addonArchIsSupported, extractChangelog } from "../../util/addon";
|
import { addonArchIsSupported, extractChangelog } from "../../util/addon";
|
||||||
import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter";
|
import "./hassio-addon-system-managed";
|
||||||
|
|
||||||
const STAGE_ICON = {
|
const STAGE_ICON = {
|
||||||
stable: mdiCheckCircle,
|
stable: mdiCheckCircle,
|
||||||
@ -117,6 +119,9 @@ class HassioAddonInfo extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
|
@property({ type: Boolean, attribute: "control-enabled" })
|
||||||
|
public controlEnabled = false;
|
||||||
|
|
||||||
@state() private _metrics?: HassioStats;
|
@state() private _metrics?: HassioStats;
|
||||||
|
|
||||||
@state() private _error?: string;
|
@state() private _error?: string;
|
||||||
@ -155,6 +160,9 @@ class HassioAddonInfo extends LitElement {
|
|||||||
)}`,
|
)}`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const systemManaged = this._isSystemManaged(this.addon);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${this.addon.update_available
|
${this.addon.update_available
|
||||||
? html`
|
? html`
|
||||||
@ -166,7 +174,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
@update-complete=${this._updateComplete}
|
@update-complete=${this._updateComplete}
|
||||||
></update-available-card>
|
></update-available-card>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${"protected" in this.addon && !this.addon.protected
|
${"protected" in this.addon && !this.addon.protected
|
||||||
? html`
|
? html`
|
||||||
<ha-alert
|
<ha-alert
|
||||||
@ -178,22 +186,31 @@ class HassioAddonInfo extends LitElement {
|
|||||||
${this.supervisor.localize(
|
${this.supervisor.localize(
|
||||||
"addon.dashboard.protection_mode.content"
|
"addon.dashboard.protection_mode.content"
|
||||||
)}
|
)}
|
||||||
<mwc-button
|
<ha-button
|
||||||
slot="action"
|
slot="action"
|
||||||
.label=${this.supervisor.localize(
|
.label=${this.supervisor.localize(
|
||||||
"addon.dashboard.protection_mode.enable"
|
"addon.dashboard.protection_mode.enable"
|
||||||
)}
|
)}
|
||||||
@click=${this._protectionToggled}
|
@click=${this._protectionToggled}
|
||||||
>
|
>
|
||||||
</mwc-button>
|
</ha-button>
|
||||||
</ha-alert>
|
</ha-alert>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
|
${systemManaged
|
||||||
|
? html`
|
||||||
|
<hassio-addon-system-managed
|
||||||
|
.supervisor=${this.supervisor}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.hideButton=${this.controlEnabled}
|
||||||
|
></hassio-addon-system-managed>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
|
||||||
<ha-card outlined>
|
<ha-card outlined>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="addon-header">
|
<div class="addon-header">
|
||||||
${!this.narrow ? this.addon.name : ""}
|
${!this.narrow ? this.addon.name : nothing}
|
||||||
<div class="addon-version light-color">
|
<div class="addon-version light-color">
|
||||||
${this.addon.version
|
${this.addon.version
|
||||||
? html`
|
? html`
|
||||||
@ -266,7 +283,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
</ha-svg-icon>
|
</ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
|
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
filled
|
filled
|
||||||
@ -301,7 +318,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
<ha-svg-icon slot="icon" .path=${mdiNetwork}> </ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiNetwork}> </ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.full_access
|
${this.addon.full_access
|
||||||
? html`
|
? html`
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
@ -317,7 +334,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
<ha-svg-icon slot="icon" .path=${mdiChip}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiChip}></ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.homeassistant_api
|
${this.addon.homeassistant_api
|
||||||
? html`
|
? html`
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
@ -336,7 +353,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this._computeHassioApi
|
${this._computeHassioApi
|
||||||
? html`
|
? html`
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
@ -355,7 +372,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.docker_api
|
${this.addon.docker_api
|
||||||
? html`
|
? html`
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
@ -371,7 +388,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
<ha-svg-icon slot="icon" .path=${mdiDocker}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiDocker}></ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.host_pid
|
${this.addon.host_pid
|
||||||
? html`
|
? html`
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
@ -387,7 +404,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
<ha-svg-icon slot="icon" .path=${mdiPound}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiPound}></ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.apparmor !== "default"
|
${this.addon.apparmor !== "default"
|
||||||
? html`
|
? html`
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
@ -404,7 +421,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
<ha-svg-icon slot="icon" .path=${mdiShield}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiShield}></ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.auth_api
|
${this.addon.auth_api
|
||||||
? html`
|
? html`
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
@ -420,7 +437,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
<ha-svg-icon slot="icon" .path=${mdiKey}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiKey}></ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.ingress
|
${this.addon.ingress
|
||||||
? html`
|
? html`
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
@ -439,7 +456,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.signed
|
${this.addon.signed
|
||||||
? html`
|
? html`
|
||||||
<ha-assist-chip
|
<ha-assist-chip
|
||||||
@ -455,7 +472,24 @@ class HassioAddonInfo extends LitElement {
|
|||||||
<ha-svg-icon slot="icon" .path=${mdiLinkLock}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiLinkLock}></ha-svg-icon>
|
||||||
</ha-assist-chip>
|
</ha-assist-chip>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
|
${systemManaged
|
||||||
|
? html`
|
||||||
|
<ha-assist-chip
|
||||||
|
filled
|
||||||
|
@click=${this._showSystemManagedDialog}
|
||||||
|
id="system_managed"
|
||||||
|
.label=${capitalizeFirstLetter(
|
||||||
|
this.supervisor.localize("addon.system_managed.badge")
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="icon"
|
||||||
|
.path=${mdiHomeAssistant}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</ha-assist-chip>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
</ha-chip-set>
|
</ha-chip-set>
|
||||||
|
|
||||||
<div class="description light-color">
|
<div class="description light-color">
|
||||||
@ -479,7 +513,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
src="/api/hassio/addons/${this.addon.slug}/logo"
|
src="/api/hassio/addons/${this.addon.slug}/logo"
|
||||||
/>
|
/>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.version
|
${this.addon.version
|
||||||
? html`
|
? html`
|
||||||
<div
|
<div
|
||||||
@ -500,6 +534,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<ha-switch
|
<ha-switch
|
||||||
|
.disabled=${systemManaged && !this.controlEnabled}
|
||||||
@change=${this._startOnBootToggled}
|
@change=${this._startOnBootToggled}
|
||||||
.checked=${this.addon.boot === "auto"}
|
.checked=${this.addon.boot === "auto"}
|
||||||
haptic
|
haptic
|
||||||
@ -520,13 +555,15 @@ class HassioAddonInfo extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<ha-switch
|
<ha-switch
|
||||||
|
.disabled=${systemManaged &&
|
||||||
|
!this.controlEnabled}
|
||||||
@change=${this._watchdogToggled}
|
@change=${this._watchdogToggled}
|
||||||
.checked=${this.addon.watchdog}
|
.checked=${this.addon.watchdog || false}
|
||||||
haptic
|
haptic
|
||||||
></ha-switch>
|
></ha-switch>
|
||||||
</ha-settings-row>
|
</ha-settings-row>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this.addon.auto_update ||
|
${this.addon.auto_update ||
|
||||||
this.hass.userData?.showAdvanced
|
this.hass.userData?.showAdvanced
|
||||||
? html`
|
? html`
|
||||||
@ -542,13 +579,15 @@ class HassioAddonInfo extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<ha-switch
|
<ha-switch
|
||||||
|
.disabled=${systemManaged &&
|
||||||
|
!this.controlEnabled}
|
||||||
@change=${this._autoUpdateToggled}
|
@change=${this._autoUpdateToggled}
|
||||||
.checked=${this.addon.auto_update}
|
.checked=${this.addon.auto_update}
|
||||||
haptic
|
haptic
|
||||||
></ha-switch>
|
></ha-switch>
|
||||||
</ha-settings-row>
|
</ha-settings-row>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${!this._computeCannotIngressSidebar && this.addon.ingress
|
${!this._computeCannotIngressSidebar && this.addon.ingress
|
||||||
? html`
|
? html`
|
||||||
<ha-settings-row ?three-line=${this.narrow}>
|
<ha-settings-row ?three-line=${this.narrow}>
|
||||||
@ -563,13 +602,15 @@ class HassioAddonInfo extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<ha-switch
|
<ha-switch
|
||||||
|
.disabled=${systemManaged &&
|
||||||
|
!this.controlEnabled}
|
||||||
@change=${this._panelToggled}
|
@change=${this._panelToggled}
|
||||||
.checked=${this.addon.ingress_panel}
|
.checked=${this.addon.ingress_panel}
|
||||||
haptic
|
haptic
|
||||||
></ha-switch>
|
></ha-switch>
|
||||||
</ha-settings-row>
|
</ha-settings-row>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this._computeUsesProtectedOptions
|
${this._computeUsesProtectedOptions
|
||||||
? html`
|
? html`
|
||||||
<ha-settings-row ?three-line=${this.narrow}>
|
<ha-settings-row ?three-line=${this.narrow}>
|
||||||
@ -584,16 +625,18 @@ class HassioAddonInfo extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<ha-switch
|
<ha-switch
|
||||||
|
.disabled=${systemManaged &&
|
||||||
|
!this.controlEnabled}
|
||||||
@change=${this._protectionToggled}
|
@change=${this._protectionToggled}
|
||||||
.checked=${this.addon.protected}
|
.checked=${this.addon.protected}
|
||||||
haptic
|
haptic
|
||||||
></ha-switch>
|
></ha-switch>
|
||||||
</ha-settings-row>
|
</ha-settings-row>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
${this.addon.version && this.addon.state === "started"
|
${this.addon.version && this.addon.state === "started"
|
||||||
@ -612,12 +655,12 @@ class HassioAddonInfo extends LitElement {
|
|||||||
></supervisor-metric>
|
></supervisor-metric>
|
||||||
`
|
`
|
||||||
)}`
|
)}`
|
||||||
: ""}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${this._error
|
${this._error
|
||||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||||
: ""}
|
: nothing}
|
||||||
${!this.addon.version && addonStoreInfo && !this.addon.available
|
${!this.addon.version && addonStoreInfo && !this.addon.available
|
||||||
? !addonArchIsSupported(
|
? !addonArchIsSupported(
|
||||||
this.supervisor.info.supported_arch,
|
this.supervisor.info.supported_arch,
|
||||||
@ -641,7 +684,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</ha-alert>
|
</ha-alert>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<div>
|
<div>
|
||||||
@ -651,6 +694,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
class="warning"
|
class="warning"
|
||||||
@click=${this._stopClicked}
|
@click=${this._stopClicked}
|
||||||
|
.disabled=${systemManaged && !this.controlEnabled}
|
||||||
>
|
>
|
||||||
${this.supervisor.localize("addon.dashboard.stop")}
|
${this.supervisor.localize("addon.dashboard.stop")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
@ -688,26 +732,27 @@ class HassioAddonInfo extends LitElement {
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
>
|
>
|
||||||
<mwc-button>
|
<ha-button>
|
||||||
${this.supervisor.localize(
|
${this.supervisor.localize(
|
||||||
"addon.dashboard.open_web_ui"
|
"addon.dashboard.open_web_ui"
|
||||||
)}
|
)}
|
||||||
</mwc-button>
|
</ha-button>
|
||||||
</a>
|
</a>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${this._computeShowIngressUI
|
${this._computeShowIngressUI
|
||||||
? html`
|
? html`
|
||||||
<mwc-button @click=${this._openIngress}>
|
<ha-button @click=${this._openIngress}>
|
||||||
${this.supervisor.localize(
|
${this.supervisor.localize(
|
||||||
"addon.dashboard.open_web_ui"
|
"addon.dashboard.open_web_ui"
|
||||||
)}
|
)}
|
||||||
</mwc-button>
|
</ha-button>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
class="warning"
|
class="warning"
|
||||||
@click=${this._uninstallClicked}
|
@click=${this._uninstallClicked}
|
||||||
|
.disabled=${systemManaged && !this.controlEnabled}
|
||||||
>
|
>
|
||||||
${this.supervisor.localize("addon.dashboard.uninstall")}
|
${this.supervisor.localize("addon.dashboard.uninstall")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
@ -720,8 +765,8 @@ class HassioAddonInfo extends LitElement {
|
|||||||
${this.supervisor.localize("addon.dashboard.rebuild")}
|
${this.supervisor.localize("addon.dashboard.rebuild")}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
`
|
`
|
||||||
: ""}`
|
: nothing}`
|
||||||
: ""}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
@ -737,7 +782,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,6 +867,13 @@ class HassioAddonInfo extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _showSystemManagedDialog() {
|
||||||
|
showSystemManagedDialog(this, {
|
||||||
|
addon: this.addon as HassioAddonDetails,
|
||||||
|
supervisor: this.supervisor,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private get _computeIsRunning(): boolean {
|
private get _computeIsRunning(): boolean {
|
||||||
return (this.addon as HassioAddonDetails)?.state === "started";
|
return (this.addon as HassioAddonDetails)?.state === "started";
|
||||||
}
|
}
|
||||||
@ -1014,6 +1066,10 @@ class HassioAddonInfo extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _stopClicked(ev: CustomEvent): Promise<void> {
|
private async _stopClicked(ev: CustomEvent): Promise<void> {
|
||||||
|
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
button.progress = true;
|
button.progress = true;
|
||||||
|
|
||||||
@ -1125,6 +1181,10 @@ class HassioAddonInfo extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _uninstallClicked(ev: CustomEvent): Promise<void> {
|
private async _uninstallClicked(ev: CustomEvent): Promise<void> {
|
||||||
|
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
button.progress = true;
|
button.progress = true;
|
||||||
let removeData = false;
|
let removeData = false;
|
||||||
@ -1179,6 +1239,11 @@ class HassioAddonInfo extends LitElement {
|
|||||||
button.progress = false;
|
button.progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _isSystemManaged = memoizeOne(
|
||||||
|
(addon: HassioAddonDetails | StoreAddonDetails) =>
|
||||||
|
"system_managed" in addon && addon.system_managed
|
||||||
|
);
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
@ -1201,7 +1266,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
ha-card.warning .card-content {
|
ha-card.warning .card-content {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
ha-card.warning mwc-button {
|
ha-card.warning ha-button {
|
||||||
--mdc-theme-primary: white !important;
|
--mdc-theme-primary: white !important;
|
||||||
}
|
}
|
||||||
.warning {
|
.warning {
|
||||||
@ -1246,7 +1311,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
ha-svg-icon.stopped {
|
ha-svg-icon.stopped {
|
||||||
color: var(--error-color);
|
color: var(--error-color);
|
||||||
}
|
}
|
||||||
protection-enable mwc-button {
|
protection-enable ha-button {
|
||||||
--mdc-theme-primary: white;
|
--mdc-theme-primary: white;
|
||||||
}
|
}
|
||||||
.description a {
|
.description a {
|
||||||
@ -1328,7 +1393,7 @@ class HassioAddonInfo extends LitElement {
|
|||||||
align-self: end;
|
align-self: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-alert mwc-button {
|
ha-alert ha-button {
|
||||||
--mdc-theme-primary: var(--primary-text-color);
|
--mdc-theme-primary: var(--primary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
60
hassio/src/addon-view/info/hassio-addon-system-managed.ts
Normal file
60
hassio/src/addon-view/info/hassio-addon-system-managed.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import "@material/mwc-button";
|
||||||
|
import type { TemplateResult } from "lit";
|
||||||
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
|
import "../../../../src/components/ha-alert";
|
||||||
|
import "../../../../src/components/ha-button";
|
||||||
|
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
|
|
||||||
|
@customElement("hassio-addon-system-managed")
|
||||||
|
class HassioAddonSystemManaged extends LitElement {
|
||||||
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
|
@property({ type: Boolean, attribute: "hide-button" }) public hideButton =
|
||||||
|
false;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<ha-alert
|
||||||
|
alert-type="warning"
|
||||||
|
.title=${this.supervisor.localize("addon.system_managed.title")}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
>
|
||||||
|
${this.supervisor.localize("addon.system_managed.description")}
|
||||||
|
${!this.hideButton
|
||||||
|
? html`
|
||||||
|
<ha-button slot="action" @click=${this._takeControl}>
|
||||||
|
${this.supervisor.localize("addon.system_managed.take_control")}
|
||||||
|
</ha-button>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
</ha-alert>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _takeControl() {
|
||||||
|
fireEvent(this, "system-managed-take-control");
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
ha-alert {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
ha-button {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hassio-addon-system-managed": HassioAddonSystemManaged;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HASSDomEvents {
|
||||||
|
"system-managed-take-control": undefined;
|
||||||
|
}
|
||||||
|
}
|
@ -38,6 +38,7 @@ class HassioMarkdownDialog extends LitElement {
|
|||||||
open
|
open
|
||||||
@closed=${this.closeDialog}
|
@closed=${this.closeDialog}
|
||||||
.heading=${createCloseHeading(this.hass, this.title)}
|
.heading=${createCloseHeading(this.hass, this.title)}
|
||||||
|
hideactions
|
||||||
>
|
>
|
||||||
<ha-markdown
|
<ha-markdown
|
||||||
.content=${this.content || ""}
|
.content=${this.content || ""}
|
||||||
|
192
hassio/src/dialogs/system-managed/dialog-system-managed.ts
Normal file
192
hassio/src/dialogs/system-managed/dialog-system-managed.ts
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
import { mdiClose, mdiPuzzle, mdiSwapHorizontal } from "@mdi/js";
|
||||||
|
import type { CSSResultGroup } from "lit";
|
||||||
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
|
import { atLeastVersion } from "../../../../src/common/config/version";
|
||||||
|
import "../../../../src/components/ha-dialog-header";
|
||||||
|
import "../../../../src/components/ha-icon-button";
|
||||||
|
import "../../../../src/components/ha-icon-next";
|
||||||
|
import "../../../../src/components/ha-md-dialog";
|
||||||
|
import type { HaMdDialog } from "../../../../src/components/ha-md-dialog";
|
||||||
|
import "../../../../src/components/ha-md-list";
|
||||||
|
import "../../../../src/components/ha-md-list-item";
|
||||||
|
import "../../../../src/components/ha-svg-icon";
|
||||||
|
import {
|
||||||
|
getConfigEntry,
|
||||||
|
type ConfigEntry,
|
||||||
|
} from "../../../../src/data/config_entries";
|
||||||
|
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
|
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
|
import { mdiHomeAssistant } from "../../../../src/resources/home-assistant-logo-svg";
|
||||||
|
import { haStyle } from "../../../../src/resources/styles";
|
||||||
|
import type { HomeAssistant } from "../../../../src/types";
|
||||||
|
import { brandsUrl } from "../../../../src/util/brands-url";
|
||||||
|
import type { SystemManagedDialogParams } from "./show-dialog-system-managed";
|
||||||
|
|
||||||
|
@customElement("dialog-system-managed")
|
||||||
|
class HassioSystemManagedDialog extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private _supervisor?: Supervisor;
|
||||||
|
|
||||||
|
@state() private _addon?: HassioAddonDetails;
|
||||||
|
|
||||||
|
@state() private _open = false;
|
||||||
|
|
||||||
|
@state() private _configEntry?: ConfigEntry;
|
||||||
|
|
||||||
|
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||||
|
|
||||||
|
public async showDialog(
|
||||||
|
dialogParams: SystemManagedDialogParams
|
||||||
|
): Promise<void> {
|
||||||
|
this._addon = dialogParams.addon;
|
||||||
|
this._supervisor = dialogParams.supervisor;
|
||||||
|
this._open = true;
|
||||||
|
this._loadConfigEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _dialogClosed() {
|
||||||
|
this._addon = undefined;
|
||||||
|
this._supervisor = undefined;
|
||||||
|
this._configEntry = undefined;
|
||||||
|
this._open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog() {
|
||||||
|
this._dialog?.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this._addon || !this._open || !this._supervisor) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
const addonImage =
|
||||||
|
atLeastVersion(this.hass.config.version, 0, 105) && this._addon.icon
|
||||||
|
? `/api/hassio/addons/${this._addon.slug}/icon`
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-md-dialog open @closed=${this._dialogClosed}>
|
||||||
|
<ha-dialog-header slot="headline">
|
||||||
|
<ha-icon-button
|
||||||
|
slot="navigationIcon"
|
||||||
|
.path=${mdiClose}
|
||||||
|
@click=${this.closeDialog}
|
||||||
|
></ha-icon-button>
|
||||||
|
<span slot="title">${this._addon?.name}</span>
|
||||||
|
</ha-dialog-header>
|
||||||
|
<div slot="content">
|
||||||
|
<div class="icons">
|
||||||
|
<ha-svg-icon
|
||||||
|
class="primary"
|
||||||
|
.path=${mdiHomeAssistant}
|
||||||
|
></ha-svg-icon>
|
||||||
|
<ha-svg-icon .path=${mdiSwapHorizontal}></ha-svg-icon>
|
||||||
|
${addonImage
|
||||||
|
? html`<img src=${addonImage} alt=${this._addon.name} />`
|
||||||
|
: html`<ha-svg-icon .path=${mdiPuzzle}></ha-svg-icon>`}
|
||||||
|
</div>
|
||||||
|
${this._supervisor.localize("addon.system_managed.title")}.<br />
|
||||||
|
${this._supervisor.localize("addon.system_managed.description")}
|
||||||
|
${this._configEntry
|
||||||
|
? html`
|
||||||
|
<h3>
|
||||||
|
${this._supervisor.localize(
|
||||||
|
"addon.system_managed.managed_by"
|
||||||
|
)}:
|
||||||
|
</h3>
|
||||||
|
<ha-md-list>
|
||||||
|
<ha-md-list-item
|
||||||
|
type="link"
|
||||||
|
href=${`/config/integrations/integration/${this._configEntry.domain}`}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
slot="start"
|
||||||
|
class="integration-icon"
|
||||||
|
alt=${this._configEntry.title}
|
||||||
|
src=${brandsUrl({
|
||||||
|
domain: this._configEntry.domain,
|
||||||
|
type: "icon",
|
||||||
|
darkOptimized: this.hass.themes?.darkMode,
|
||||||
|
})}
|
||||||
|
crossorigin="anonymous"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
@error=${this._onImageError}
|
||||||
|
@load=${this._onImageLoad}
|
||||||
|
/>
|
||||||
|
${this._configEntry.title}
|
||||||
|
<ha-icon-next slot="end"></ha-icon-next>
|
||||||
|
</ha-md-list-item>
|
||||||
|
</ha-md-list>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
</div>
|
||||||
|
</ha-md-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onImageLoad(ev) {
|
||||||
|
ev.target.style.visibility = "initial";
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onImageError(ev) {
|
||||||
|
ev.target.style.visibility = "hidden";
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _loadConfigEntry() {
|
||||||
|
if (this._addon?.system_managed_config_entry) {
|
||||||
|
try {
|
||||||
|
const { config_entry } = await getConfigEntry(
|
||||||
|
this.hass,
|
||||||
|
this._addon.system_managed_config_entry
|
||||||
|
);
|
||||||
|
this._configEntry = config_entry;
|
||||||
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
.icons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
--mdc-icon-size: 48px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
.icons img {
|
||||||
|
width: 48px;
|
||||||
|
}
|
||||||
|
.icons .primary {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.integration-icon {
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
ha-md-list-item {
|
||||||
|
--md-list-item-leading-space: 4px;
|
||||||
|
--md-list-item-trailing-space: 4px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-system-managed": HassioSystemManagedDialog;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||||
|
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||||
|
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||||
|
|
||||||
|
export interface SystemManagedDialogParams {
|
||||||
|
addon: HassioAddonDetails;
|
||||||
|
supervisor: Supervisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const showSystemManagedDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
dialogParams: SystemManagedDialogParams
|
||||||
|
): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-system-managed",
|
||||||
|
dialogImport: () => import("./dialog-system-managed"),
|
||||||
|
dialogParams,
|
||||||
|
});
|
||||||
|
};
|
@ -101,6 +101,8 @@ export interface HassioAddonDetails extends HassioAddonInfo {
|
|||||||
slug: string;
|
slug: string;
|
||||||
startup: AddonStartup;
|
startup: AddonStartup;
|
||||||
stdin: boolean;
|
stdin: boolean;
|
||||||
|
system_managed: boolean;
|
||||||
|
system_managed_config_entry: string | null;
|
||||||
translations: Record<string, AddonTranslations>;
|
translations: Record<string, AddonTranslations>;
|
||||||
watchdog: null | boolean;
|
watchdog: null | boolean;
|
||||||
webui: null | string;
|
webui: null | string;
|
||||||
|
@ -8932,6 +8932,13 @@
|
|||||||
},
|
},
|
||||||
"logs": {
|
"logs": {
|
||||||
"get_logs": "Failed to get add-on logs, {error}"
|
"get_logs": "Failed to get add-on logs, {error}"
|
||||||
|
},
|
||||||
|
"system_managed": {
|
||||||
|
"badge": "System-managed",
|
||||||
|
"title": "This add-on is managed by Home Assistant",
|
||||||
|
"description": "Manually modifying this configuration may cause the add-on or integration to stop working properly.",
|
||||||
|
"managed_by": "Managed by",
|
||||||
|
"take_control": "Take control"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
@ -8955,6 +8962,7 @@
|
|||||||
"running_version": "You are currently running version {version}",
|
"running_version": "You are currently running version {version}",
|
||||||
"save": "[%key:ui::common::save%]",
|
"save": "[%key:ui::common::save%]",
|
||||||
"close": "[%key:ui::common::close%]",
|
"close": "[%key:ui::common::close%]",
|
||||||
|
"back": "[%key:ui::common::back%]",
|
||||||
"menu": "[%key:ui::common::menu%]",
|
"menu": "[%key:ui::common::menu%]",
|
||||||
"show": "[%key:ui::panel::config::updates::show%]",
|
"show": "[%key:ui::panel::config::updates::show%]",
|
||||||
"show_more": "Show more information about this",
|
"show_more": "Show more information about this",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user