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