mirror of
https://github.com/home-assistant/frontend.git
synced 2026-07-18 00:57:04 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 40bfd1b70a | |||
| 91670c8412 |
@@ -3,9 +3,12 @@ import {
|
|||||||
mdiChip,
|
mdiChip,
|
||||||
mdiCircleOffOutline,
|
mdiCircleOffOutline,
|
||||||
mdiCursorDefaultClickOutline,
|
mdiCursorDefaultClickOutline,
|
||||||
|
mdiDelete,
|
||||||
mdiDocker,
|
mdiDocker,
|
||||||
|
mdiDotsVertical,
|
||||||
mdiExclamationThick,
|
mdiExclamationThick,
|
||||||
mdiFlask,
|
mdiFlask,
|
||||||
|
mdiHammer,
|
||||||
mdiKey,
|
mdiKey,
|
||||||
mdiLinkLock,
|
mdiLinkLock,
|
||||||
mdiNetwork,
|
mdiNetwork,
|
||||||
@@ -19,7 +22,9 @@ import {
|
|||||||
mdiNumeric8,
|
mdiNumeric8,
|
||||||
mdiPlayCircle,
|
mdiPlayCircle,
|
||||||
mdiPound,
|
mdiPound,
|
||||||
|
mdiRestart,
|
||||||
mdiShield,
|
mdiShield,
|
||||||
|
mdiStop,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||||
import { LitElement, css, html, nothing } from "lit";
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
@@ -37,7 +42,10 @@ import "../../../../../components/chips/ha-chip-set";
|
|||||||
import "../../../../../components/ha-alert";
|
import "../../../../../components/ha-alert";
|
||||||
import "../../../../../components/ha-button";
|
import "../../../../../components/ha-button";
|
||||||
import "../../../../../components/ha-card";
|
import "../../../../../components/ha-card";
|
||||||
|
import "../../../../../components/ha-dropdown";
|
||||||
|
import "../../../../../components/ha-dropdown-item";
|
||||||
import "../../../../../components/ha-formfield";
|
import "../../../../../components/ha-formfield";
|
||||||
|
import "../../../../../components/ha-icon-button";
|
||||||
import "../../../../../components/ha-markdown";
|
import "../../../../../components/ha-markdown";
|
||||||
import "../../../../../components/ha-settings-row";
|
import "../../../../../components/ha-settings-row";
|
||||||
import "../../../../../components/ha-svg-icon";
|
import "../../../../../components/ha-svg-icon";
|
||||||
@@ -119,15 +127,16 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
|
|
||||||
@state() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
private _fetchDataTimeout?: number;
|
private _pollInterval?: number;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._startPolling();
|
||||||
|
}
|
||||||
|
|
||||||
public disconnectedCallback() {
|
public disconnectedCallback() {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
|
this._stopPolling();
|
||||||
if (this._fetchDataTimeout) {
|
|
||||||
clearTimeout(this._fetchDataTimeout);
|
|
||||||
this._fetchDataTimeout = undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
@@ -223,6 +232,74 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
.path=${mdiCircleOffOutline}
|
.path=${mdiCircleOffOutline}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
`}
|
`}
|
||||||
|
<ha-dropdown>
|
||||||
|
<ha-icon-button
|
||||||
|
slot="trigger"
|
||||||
|
.path=${mdiDotsVertical}
|
||||||
|
.label=${this.hass.localize("ui.common.overflow_menu")}
|
||||||
|
></ha-icon-button>
|
||||||
|
${this._computeIsRunning
|
||||||
|
? html`
|
||||||
|
<ha-dropdown-item
|
||||||
|
@click=${this._stopClicked}
|
||||||
|
.disabled=${this._isSystemManaged(this.addon) &&
|
||||||
|
!this.controlEnabled}
|
||||||
|
variant="danger"
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="icon"
|
||||||
|
.path=${mdiStop}
|
||||||
|
></ha-svg-icon>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.apps.dashboard.stop"
|
||||||
|
)}
|
||||||
|
</ha-dropdown-item>
|
||||||
|
<ha-dropdown-item
|
||||||
|
@click=${this._restartClicked}
|
||||||
|
.disabled=${this._isSystemManaged(this.addon) &&
|
||||||
|
!this.controlEnabled}
|
||||||
|
variant="danger"
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="icon"
|
||||||
|
.path=${mdiRestart}
|
||||||
|
></ha-svg-icon>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.apps.dashboard.restart"
|
||||||
|
)}
|
||||||
|
</ha-dropdown-item>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
${this.addon.build
|
||||||
|
? html`
|
||||||
|
<ha-dropdown-item
|
||||||
|
@click=${this._rebuildClicked}
|
||||||
|
variant="danger"
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="icon"
|
||||||
|
.path=${mdiHammer}
|
||||||
|
></ha-svg-icon>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.apps.dashboard.rebuild"
|
||||||
|
)}
|
||||||
|
</ha-dropdown-item>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
<ha-dropdown-item
|
||||||
|
@click=${this._uninstallClicked}
|
||||||
|
.disabled=${systemManaged && !this.controlEnabled}
|
||||||
|
variant="danger"
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="icon"
|
||||||
|
.path=${mdiDelete}
|
||||||
|
></ha-svg-icon>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.apps.dashboard.uninstall"
|
||||||
|
)}
|
||||||
|
</ha-dropdown-item>
|
||||||
|
</ha-dropdown>
|
||||||
`
|
`
|
||||||
: html` ${this.addon.version_latest} `}
|
: html` ${this.addon.version_latest} `}
|
||||||
</div>
|
</div>
|
||||||
@@ -654,95 +731,46 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
: nothing}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
|
<div></div>
|
||||||
<div>
|
<div>
|
||||||
${this.addon.version
|
${this.addon.version
|
||||||
? this._computeIsRunning
|
? this._computeIsRunning
|
||||||
? html`
|
? html`
|
||||||
<ha-progress-button
|
${this._computeShowWebUI || this._computeShowIngressUI
|
||||||
variant="danger"
|
? html`
|
||||||
appearance="plain"
|
<ha-button
|
||||||
@click=${this._stopClicked}
|
href=${ifDefined(
|
||||||
.disabled=${systemManaged && !this.controlEnabled}
|
!this._computeShowIngressUI
|
||||||
>
|
? this._pathWebui!
|
||||||
${this.hass.localize(
|
: nothing
|
||||||
"ui.panel.config.apps.dashboard.stop"
|
)}
|
||||||
)}
|
target=${ifDefined(
|
||||||
</ha-progress-button>
|
!this._computeShowIngressUI ? "_blank" : nothing
|
||||||
<ha-progress-button
|
)}
|
||||||
variant="danger"
|
rel=${ifDefined(
|
||||||
appearance="plain"
|
!this._computeShowIngressUI ? "noopener" : nothing
|
||||||
@click=${this._restartClicked}
|
)}
|
||||||
.disabled=${systemManaged && !this.controlEnabled}
|
@click=${!this._computeShowWebUI
|
||||||
>
|
? this._openIngress
|
||||||
${this.hass.localize(
|
: undefined}
|
||||||
"ui.panel.config.apps.dashboard.restart"
|
>
|
||||||
)}
|
${this.hass.localize(
|
||||||
</ha-progress-button>
|
"ui.panel.config.apps.dashboard.open_web_ui"
|
||||||
|
)}
|
||||||
|
</ha-button>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
`
|
`
|
||||||
: html`
|
: html`
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
@click=${this._startClicked}
|
@click=${this._startClicked}
|
||||||
.progress=${this.addon.state === "startup"}
|
.progress=${this.addon.state === "startup"}
|
||||||
appearance="plain"
|
|
||||||
>
|
>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.apps.dashboard.start"
|
"ui.panel.config.apps.dashboard.start"
|
||||||
)}
|
)}
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
`
|
`
|
||||||
: nothing}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
${this.addon.version
|
|
||||||
? html`
|
|
||||||
<ha-progress-button
|
|
||||||
variant="danger"
|
|
||||||
appearance="plain"
|
|
||||||
@click=${this._uninstallClicked}
|
|
||||||
.disabled=${systemManaged && !this.controlEnabled}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.apps.dashboard.uninstall"
|
|
||||||
)}
|
|
||||||
</ha-progress-button>
|
|
||||||
${this.addon.build
|
|
||||||
? html`
|
|
||||||
<ha-progress-button
|
|
||||||
variant="danger"
|
|
||||||
appearance="plain"
|
|
||||||
@click=${this._rebuildClicked}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.apps.dashboard.rebuild"
|
|
||||||
)}
|
|
||||||
</ha-progress-button>
|
|
||||||
`
|
|
||||||
: nothing}
|
|
||||||
${this._computeShowWebUI || this._computeShowIngressUI
|
|
||||||
? html`
|
|
||||||
<ha-button
|
|
||||||
href=${ifDefined(
|
|
||||||
!this._computeShowIngressUI
|
|
||||||
? this._pathWebui!
|
|
||||||
: nothing
|
|
||||||
)}
|
|
||||||
target=${ifDefined(
|
|
||||||
!this._computeShowIngressUI ? "_blank" : nothing
|
|
||||||
)}
|
|
||||||
rel=${ifDefined(
|
|
||||||
!this._computeShowIngressUI ? "noopener" : nothing
|
|
||||||
)}
|
|
||||||
@click=${!this._computeShowWebUI
|
|
||||||
? this._openIngress
|
|
||||||
: undefined}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.apps.dashboard.open_web_ui"
|
|
||||||
)}
|
|
||||||
</ha-button>
|
|
||||||
`
|
|
||||||
: nothing}
|
|
||||||
`
|
|
||||||
: html`
|
: html`
|
||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
.disabled=${!this.addon.available}
|
.disabled=${!this.addon.available}
|
||||||
@@ -775,38 +803,39 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
protected updated(changedProps) {
|
protected updated(changedProps) {
|
||||||
super.updated(changedProps);
|
super.updated(changedProps);
|
||||||
if (changedProps.has("addon")) {
|
if (changedProps.has("addon")) {
|
||||||
this._loadData();
|
this._loadMetrics();
|
||||||
if (
|
|
||||||
!this._fetchDataTimeout &&
|
|
||||||
this.addon &&
|
|
||||||
"state" in this.addon &&
|
|
||||||
this.addon.state === "startup"
|
|
||||||
) {
|
|
||||||
// App is starting up, wait for it to start
|
|
||||||
this._scheduleDataUpdate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _scheduleDataUpdate() {
|
private _startPolling() {
|
||||||
this._fetchDataTimeout = window.setTimeout(async () => {
|
if (this._pollInterval) {
|
||||||
const addon = await fetchHassioAddonInfo(this.hass, this.addon.slug);
|
return;
|
||||||
if (addon.state !== "startup") {
|
}
|
||||||
this._fetchDataTimeout = undefined;
|
this._pollInterval = window.setInterval(() => {
|
||||||
this.addon = addon;
|
this._refreshAddonInfo();
|
||||||
const eventdata = {
|
}, 5000);
|
||||||
success: true,
|
|
||||||
response: undefined,
|
|
||||||
path: "start",
|
|
||||||
};
|
|
||||||
fireEvent(this, "hass-api-called", eventdata);
|
|
||||||
} else {
|
|
||||||
this._scheduleDataUpdate();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _loadData(): Promise<void> {
|
private _stopPolling() {
|
||||||
|
if (this._pollInterval) {
|
||||||
|
clearInterval(this._pollInterval);
|
||||||
|
this._pollInterval = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _refreshAddonInfo(): Promise<void> {
|
||||||
|
if (!this.addon?.slug) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const addon = await fetchHassioAddonInfo(this.hass, this.addon.slug);
|
||||||
|
this.addon = addon;
|
||||||
|
} catch {
|
||||||
|
// Ignore errors during polling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _loadMetrics(): Promise<void> {
|
||||||
if ("state" in this.addon && this.addon.state === "started") {
|
if ("state" in this.addon && this.addon.state === "started") {
|
||||||
this._metrics = await fetchHassioStats(
|
this._metrics = await fetchHassioStats(
|
||||||
this.hass,
|
this.hass,
|
||||||
@@ -1069,14 +1098,11 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
button.progress = false;
|
button.progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _stopClicked(ev: CustomEvent): Promise<void> {
|
private async _stopClicked(): Promise<void> {
|
||||||
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const button = ev.currentTarget as any;
|
|
||||||
button.progress = true;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await stopHassioAddon(this.hass, this.addon.slug);
|
await stopHassioAddon(this.hass, this.addon.slug);
|
||||||
const eventdata = {
|
const eventdata = {
|
||||||
@@ -1093,17 +1119,13 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
text: extractApiErrorMessage(err),
|
text: extractApiErrorMessage(err),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
button.progress = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _restartClicked(ev: CustomEvent): Promise<void> {
|
private async _restartClicked(): Promise<void> {
|
||||||
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const button = ev.currentTarget as any;
|
|
||||||
button.progress = true;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await restartHassioAddon(this.hass, this.addon.slug);
|
await restartHassioAddon(this.hass, this.addon.slug);
|
||||||
const eventdata = {
|
const eventdata = {
|
||||||
@@ -1120,13 +1142,9 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
text: extractApiErrorMessage(err),
|
text: extractApiErrorMessage(err),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
button.progress = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _rebuildClicked(ev: CustomEvent): Promise<void> {
|
private async _rebuildClicked(): Promise<void> {
|
||||||
const button = ev.currentTarget as any;
|
|
||||||
button.progress = true;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await rebuildLocalAddon(this.hass, this.addon.slug);
|
await rebuildLocalAddon(this.hass, this.addon.slug);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
@@ -1137,7 +1155,6 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
text: extractApiErrorMessage(err),
|
text: extractApiErrorMessage(err),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
button.progress = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _startClicked(ev: CustomEvent): Promise<void> {
|
private async _startClicked(ev: CustomEvent): Promise<void> {
|
||||||
@@ -1204,13 +1221,11 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
navigate(`/config/app/${this.addon.slug}/config`);
|
navigate(`/config/app/${this.addon.slug}/config`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _uninstallClicked(ev: CustomEvent): Promise<void> {
|
private async _uninstallClicked(): Promise<void> {
|
||||||
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const button = ev.currentTarget as any;
|
|
||||||
button.progress = true;
|
|
||||||
let removeData = false;
|
let removeData = false;
|
||||||
const _removeDataToggled = (e: Event) => {
|
const _removeDataToggled = (e: Event) => {
|
||||||
removeData = (e.target as HaSwitch).checked;
|
removeData = (e.target as HaSwitch).checked;
|
||||||
@@ -1246,7 +1261,6 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
button.progress = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1259,7 +1273,6 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
path: "uninstall",
|
path: "uninstall",
|
||||||
};
|
};
|
||||||
fireEvent(this, "hass-api-called", eventdata);
|
fireEvent(this, "hass-api-called", eventdata);
|
||||||
button.actionSuccess();
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
@@ -1267,9 +1280,7 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
),
|
),
|
||||||
text: extractApiErrorMessage(err),
|
text: extractApiErrorMessage(err),
|
||||||
});
|
});
|
||||||
button.actionError();
|
|
||||||
}
|
}
|
||||||
button.progress = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isSystemManaged = memoizeOne(
|
private _isSystemManaged = memoizeOne(
|
||||||
@@ -1318,7 +1329,8 @@ class SupervisorAppInfo extends LitElement {
|
|||||||
.addon-version {
|
.addon-version {
|
||||||
float: var(--float-end);
|
float: var(--float-end);
|
||||||
font-size: var(--ha-font-size-l);
|
font-size: var(--ha-font-size-l);
|
||||||
vertical-align: middle;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
.errors {
|
.errors {
|
||||||
color: var(--error-color);
|
color: var(--error-color);
|
||||||
|
|||||||
Reference in New Issue
Block a user