mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Add restart dialog (#15337)
This commit is contained in:
parent
ec66e8331e
commit
e81f596d76
382
src/dialogs/restart/dialog-restart.ts
Normal file
382
src/dialogs/restart/dialog-restart.ts
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
import "@material/mwc-list/mwc-list";
|
||||||
|
import { mdiAutoFix, mdiPower, mdiPowerCycle, mdiRefresh } from "@mdi/js";
|
||||||
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
import { shouldHandleRequestSelectedEvent } from "../../common/mwc/handle-request-selected-event";
|
||||||
|
import "../../components/ha-circular-progress";
|
||||||
|
import { createCloseHeading } from "../../components/ha-dialog";
|
||||||
|
import "../../components/ha-list-item";
|
||||||
|
import {
|
||||||
|
extractApiErrorMessage,
|
||||||
|
ignoreSupervisorError,
|
||||||
|
} from "../../data/hassio/common";
|
||||||
|
import {
|
||||||
|
fetchHassioHostInfo,
|
||||||
|
HassioHostInfo,
|
||||||
|
rebootHost,
|
||||||
|
shutdownHost,
|
||||||
|
} from "../../data/hassio/host";
|
||||||
|
import { haStyle, haStyleDialog } from "../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
import { showToast } from "../../util/toast";
|
||||||
|
import {
|
||||||
|
showAlertDialog,
|
||||||
|
showConfirmationDialog,
|
||||||
|
} from "../generic/show-dialog-box";
|
||||||
|
|
||||||
|
@customElement("dialog-restart")
|
||||||
|
class DialogRestart extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private _open = false;
|
||||||
|
|
||||||
|
@state()
|
||||||
|
private _loadingHostInfo = false;
|
||||||
|
|
||||||
|
@state()
|
||||||
|
private _hostInfo?: HassioHostInfo;
|
||||||
|
|
||||||
|
public async showDialog(): Promise<void> {
|
||||||
|
const isHassioLoaded = isComponentLoaded(this.hass, "hassio");
|
||||||
|
|
||||||
|
this._open = true;
|
||||||
|
|
||||||
|
if (isHassioLoaded && !this._hostInfo) {
|
||||||
|
this._loadingHostInfo = true;
|
||||||
|
try {
|
||||||
|
this._hostInfo = await fetchHassioHostInfo(this.hass);
|
||||||
|
} catch (_err) {
|
||||||
|
// Do nothing
|
||||||
|
} finally {
|
||||||
|
this._loadingHostInfo = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const showReload = this.hass.userData?.showAdvanced;
|
||||||
|
const showRebootShutdown = !!this._hostInfo;
|
||||||
|
|
||||||
|
// Present restart core dialog if no host actions and not advanced mode as it's the only option
|
||||||
|
if (!showReload && !showRebootShutdown) {
|
||||||
|
this._open = false;
|
||||||
|
this._showRestartDialog().then(() => this.closeDialog());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.updateComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog(): void {
|
||||||
|
this._open = false;
|
||||||
|
this._loadingHostInfo = false;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
if (!this._open) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
|
||||||
|
const showReload = this.hass.userData?.showAdvanced;
|
||||||
|
const showRebootShutdown = !!this._hostInfo;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-dialog
|
||||||
|
open
|
||||||
|
@closed=${this.closeDialog}
|
||||||
|
hideActions
|
||||||
|
.heading=${!this._loadingHostInfo
|
||||||
|
? createCloseHeading(
|
||||||
|
this.hass,
|
||||||
|
this.hass.localize("ui.dialogs.restart.heading")
|
||||||
|
)
|
||||||
|
: undefined}
|
||||||
|
>
|
||||||
|
${this._loadingHostInfo
|
||||||
|
? html`
|
||||||
|
<div class="loader">
|
||||||
|
<ha-circular-progress active></ha-circular-progress>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<mwc-list dialogInitialFocus>
|
||||||
|
${showReload
|
||||||
|
? html`
|
||||||
|
<ha-list-item
|
||||||
|
graphic="avatar"
|
||||||
|
twoline
|
||||||
|
hasMeta
|
||||||
|
@request-selected=${this._reload}
|
||||||
|
>
|
||||||
|
<div slot="graphic" class="icon-background reload">
|
||||||
|
<ha-svg-icon .path=${mdiAutoFix}></ha-svg-icon>
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.dialogs.restart.reload.title"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<span slot="secondary">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.dialogs.restart.reload.description"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</ha-list-item>
|
||||||
|
`
|
||||||
|
: null}
|
||||||
|
<ha-list-item
|
||||||
|
graphic="avatar"
|
||||||
|
twoline
|
||||||
|
hasMeta
|
||||||
|
@request-selected=${this._restart}
|
||||||
|
>
|
||||||
|
<div slot="graphic" class="icon-background restart">
|
||||||
|
<ha-svg-icon .path=${mdiRefresh}></ha-svg-icon>
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
${this.hass.localize("ui.dialogs.restart.restart.title")}
|
||||||
|
</span>
|
||||||
|
<span slot="secondary">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.dialogs.restart.restart.description"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</ha-list-item>
|
||||||
|
${showRebootShutdown
|
||||||
|
? html`
|
||||||
|
<div class="divider"></div>
|
||||||
|
<p class="section">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.dialogs.restart.advanced_options"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<ha-list-item
|
||||||
|
graphic="avatar"
|
||||||
|
twoline
|
||||||
|
hasMeta
|
||||||
|
@request-selected=${this._hostReboot}
|
||||||
|
>
|
||||||
|
<div slot="graphic" class="icon-background reboot">
|
||||||
|
<ha-svg-icon .path=${mdiPowerCycle}></ha-svg-icon>
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.dialogs.restart.reboot.title"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<span slot="secondary">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.dialogs.restart.reboot.description"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</ha-list-item>
|
||||||
|
<ha-list-item
|
||||||
|
graphic="avatar"
|
||||||
|
twoline
|
||||||
|
hasMeta
|
||||||
|
@request-selected=${this._hostShutdown}
|
||||||
|
>
|
||||||
|
<div slot="graphic" class="icon-background shutdown">
|
||||||
|
<ha-svg-icon .path=${mdiPower}></ha-svg-icon>
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.dialogs.restart.shutdown.title"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<span slot="secondary">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.dialogs.restart.shutdown.description"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</ha-list-item>
|
||||||
|
`
|
||||||
|
: null}
|
||||||
|
</mwc-list>
|
||||||
|
`}
|
||||||
|
</ha-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _reload(ev) {
|
||||||
|
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.closeDialog();
|
||||||
|
|
||||||
|
showToast(this, {
|
||||||
|
message: this.hass.localize("ui.dialogs.restart.reload.reloading"),
|
||||||
|
duration: 1000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.hass.callService("homeassistant", "reload_all");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _restart(ev) {
|
||||||
|
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._showRestartDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _showRestartDialog() {
|
||||||
|
const confirmed = await showConfirmationDialog(this, {
|
||||||
|
title: this.hass.localize("ui.dialogs.restart.restart.confirm_title"),
|
||||||
|
text: this.hass.localize(
|
||||||
|
"ui.dialogs.restart.restart.confirm_description"
|
||||||
|
),
|
||||||
|
confirmText: this.hass.localize(
|
||||||
|
"ui.dialogs.restart.restart.confirm_action"
|
||||||
|
),
|
||||||
|
destructive: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.closeDialog();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.hass.callService("homeassistant", "restart");
|
||||||
|
} catch (err: any) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: this.hass.localize("ui.dialogs.restart.restart.failed"),
|
||||||
|
text: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _hostReboot(ev): Promise<void> {
|
||||||
|
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const confirmed = await showConfirmationDialog(this, {
|
||||||
|
title: this.hass.localize("ui.dialogs.restart.reboot.confirm_title"),
|
||||||
|
text: this.hass.localize("ui.dialogs.restart.reboot.confirm_description"),
|
||||||
|
confirmText: this.hass.localize(
|
||||||
|
"ui.dialogs.restart.reboot.confirm_action"
|
||||||
|
),
|
||||||
|
destructive: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.closeDialog();
|
||||||
|
|
||||||
|
showToast(this, {
|
||||||
|
message: this.hass.localize("ui.dialogs.restart.reboot.rebooting"),
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await rebootHost(this.hass);
|
||||||
|
} catch (err: any) {
|
||||||
|
// Ignore connection errors, these are all expected
|
||||||
|
if (this.hass.connection.connected && !ignoreSupervisorError(err)) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: this.hass.localize("ui.dialogs.restart.reboot.failed"),
|
||||||
|
text: extractApiErrorMessage(err),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _hostShutdown(ev): Promise<void> {
|
||||||
|
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const confirmed = await showConfirmationDialog(this, {
|
||||||
|
title: this.hass.localize("ui.dialogs.restart.shutdown.confirm_title"),
|
||||||
|
text: this.hass.localize(
|
||||||
|
"ui.dialogs.restart.shutdown.confirm_description"
|
||||||
|
),
|
||||||
|
confirmText: this.hass.localize(
|
||||||
|
"ui.dialogs.restart.shutdown.confirm_action"
|
||||||
|
),
|
||||||
|
destructive: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.closeDialog();
|
||||||
|
|
||||||
|
showToast(this, {
|
||||||
|
message: this.hass.localize("ui.dialogs.restart.shutdown.shutting_down"),
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await shutdownHost(this.hass);
|
||||||
|
} catch (err: any) {
|
||||||
|
// Ignore connection errors, these are all expected
|
||||||
|
if (this.hass.connection.connected && !ignoreSupervisorError(err)) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: this.hass.localize("ui.dialogs.restart.shutdown.failed"),
|
||||||
|
text: extractApiErrorMessage(err),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
|
ha-dialog {
|
||||||
|
--dialog-content-padding: 0;
|
||||||
|
}
|
||||||
|
.icon-background {
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.reload {
|
||||||
|
background-color: #5f8a49;
|
||||||
|
}
|
||||||
|
.restart {
|
||||||
|
background-color: #ffd500;
|
||||||
|
color: #665500;
|
||||||
|
}
|
||||||
|
.reboot {
|
||||||
|
background-color: #ba1b1b;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.shutdown {
|
||||||
|
background-color: #0b1d29;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.divider {
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--divider-color);
|
||||||
|
}
|
||||||
|
.section {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
margin: 8px 0 4px 0;
|
||||||
|
padding-left: var(--mdc-list-side-padding, 20px);
|
||||||
|
padding-right: var(--mdc-list-side-padding, 20px);
|
||||||
|
}
|
||||||
|
.loader {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-restart": DialogRestart;
|
||||||
|
}
|
||||||
|
}
|
14
src/dialogs/restart/show-dialog-restart.ts
Normal file
14
src/dialogs/restart/show-dialog-restart.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||||
|
export interface RestartDialogParams {}
|
||||||
|
|
||||||
|
export const loadRestartDialog = () => import("./dialog-restart");
|
||||||
|
|
||||||
|
export const showRestartDialog = (element: HTMLElement): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-restart",
|
||||||
|
dialogImport: loadRestartDialog,
|
||||||
|
dialogParams: {},
|
||||||
|
});
|
||||||
|
};
|
@ -1,3 +1,4 @@
|
|||||||
|
import { mdiPower } from "@mdi/js";
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { canShowPage } from "../../../common/config/can_show_page";
|
import { canShowPage } from "../../../common/config/can_show_page";
|
||||||
@ -5,6 +6,7 @@ import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
|||||||
import { relativeTime } from "../../../common/datetime/relative_time";
|
import { relativeTime } from "../../../common/datetime/relative_time";
|
||||||
import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
|
import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-navigation-list";
|
import "../../../components/ha-navigation-list";
|
||||||
import "../../../components/ha-tip";
|
import "../../../components/ha-tip";
|
||||||
import { BackupContent, fetchBackupInfo } from "../../../data/backup";
|
import { BackupContent, fetchBackupInfo } from "../../../data/backup";
|
||||||
@ -17,10 +19,7 @@ import {
|
|||||||
HassioHassOSInfo,
|
HassioHassOSInfo,
|
||||||
HassioHostInfo,
|
HassioHostInfo,
|
||||||
} from "../../../data/hassio/host";
|
} from "../../../data/hassio/host";
|
||||||
import {
|
import { showRestartDialog } from "../../../dialogs/restart/show-dialog-restart";
|
||||||
showAlertDialog,
|
|
||||||
showConfirmationDialog,
|
|
||||||
} from "../../../dialogs/generic/show-dialog-box";
|
|
||||||
import "../../../layouts/hass-subpage";
|
import "../../../layouts/hass-subpage";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
@ -121,13 +120,14 @@ class HaConfigSystemNavigation extends LitElement {
|
|||||||
back-path="/config"
|
back-path="/config"
|
||||||
.header=${this.hass.localize("ui.panel.config.dashboard.system.main")}
|
.header=${this.hass.localize("ui.panel.config.dashboard.system.main")}
|
||||||
>
|
>
|
||||||
<mwc-button
|
<ha-icon-button
|
||||||
slot="toolbar-icon"
|
slot="toolbar-icon"
|
||||||
|
.path=${mdiPower}
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.system_dashboard.restart_homeassistant_short"
|
"ui.panel.config.system_dashboard.restart_homeassistant"
|
||||||
)}
|
)}
|
||||||
@click=${this._restart}
|
@click=${this._showRestartDialog}
|
||||||
></mwc-button>
|
></ha-icon-button>
|
||||||
<ha-config-section
|
<ha-config-section
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.isWide=${this.isWide}
|
.isWide=${this.isWide}
|
||||||
@ -161,31 +161,6 @@ class HaConfigSystemNavigation extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _restart() {
|
|
||||||
showConfirmationDialog(this, {
|
|
||||||
title: this.hass.localize(
|
|
||||||
"ui.panel.config.system_dashboard.confirm_restart_title"
|
|
||||||
),
|
|
||||||
text: this.hass.localize(
|
|
||||||
"ui.panel.config.system_dashboard.confirm_restart_text"
|
|
||||||
),
|
|
||||||
confirmText: this.hass.localize(
|
|
||||||
"ui.panel.config.system_dashboard.restart_homeassistant_short"
|
|
||||||
),
|
|
||||||
confirm: () => {
|
|
||||||
this.hass.callService("homeassistant", "restart").catch((reason) => {
|
|
||||||
showAlertDialog(this, {
|
|
||||||
title: this.hass.localize(
|
|
||||||
"ui.panel.config.system_dashboard.restart_error"
|
|
||||||
),
|
|
||||||
text: reason.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
destructive: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _fetchBackupInfo(isHassioLoaded: boolean) {
|
private async _fetchBackupInfo(isHassioLoaded: boolean) {
|
||||||
const backups: BackupContent[] | HassioBackup[] = isHassioLoaded
|
const backups: BackupContent[] | HassioBackup[] = isHassioLoaded
|
||||||
? await fetchHassioBackups(this.hass)
|
? await fetchHassioBackups(this.hass)
|
||||||
@ -238,6 +213,10 @@ class HaConfigSystemNavigation extends LitElement {
|
|||||||
this._externalAccess = this.hass.config.external_url !== null;
|
this._externalAccess = this.hass.config.external_url !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _showRestartDialog() {
|
||||||
|
showRestartDialog(this);
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
@ -269,6 +248,14 @@ class HaConfigSystemNavigation extends LitElement {
|
|||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.restart-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
@media all and (max-width: 600px) {
|
@media all and (max-width: 600px) {
|
||||||
ha-card {
|
ha-card {
|
||||||
border-width: 1px 0;
|
border-width: 1px 0;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "@material/mwc-list/mwc-list";
|
import "@material/mwc-list/mwc-list";
|
||||||
import "@material/mwc-list/mwc-list-item";
|
import "@material/mwc-list/mwc-list-item";
|
||||||
import { mdiDotsVertical } from "@mdi/js";
|
import { mdiPower } from "@mdi/js";
|
||||||
import type { ChartOptions } from "chart.js";
|
import type { ChartOptions } from "chart.js";
|
||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
|
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
@ -13,9 +13,9 @@ import { blankBeforePercent } from "../../../common/translations/blank_before_pe
|
|||||||
import "../../../components/buttons/ha-progress-button";
|
import "../../../components/buttons/ha-progress-button";
|
||||||
import "../../../components/chart/ha-chart-base";
|
import "../../../components/chart/ha-chart-base";
|
||||||
import "../../../components/ha-alert";
|
import "../../../components/ha-alert";
|
||||||
import "../../../components/ha-button-menu";
|
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-clickable-list-item";
|
import "../../../components/ha-clickable-list-item";
|
||||||
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-icon-next";
|
import "../../../components/ha-icon-next";
|
||||||
import "../../../components/ha-settings-row";
|
import "../../../components/ha-settings-row";
|
||||||
import {
|
import {
|
||||||
@ -27,31 +27,19 @@ import {
|
|||||||
HardwareInfo,
|
HardwareInfo,
|
||||||
SystemStatusStreamMessage,
|
SystemStatusStreamMessage,
|
||||||
} from "../../../data/hardware";
|
} from "../../../data/hardware";
|
||||||
import {
|
|
||||||
extractApiErrorMessage,
|
|
||||||
ignoreSupervisorError,
|
|
||||||
} from "../../../data/hassio/common";
|
|
||||||
import {
|
import {
|
||||||
fetchHassioHassOsInfo,
|
fetchHassioHassOsInfo,
|
||||||
fetchHassioHostInfo,
|
|
||||||
HassioHassOSInfo,
|
HassioHassOSInfo,
|
||||||
HassioHostInfo,
|
|
||||||
rebootHost,
|
|
||||||
shutdownHost,
|
|
||||||
} from "../../../data/hassio/host";
|
} from "../../../data/hassio/host";
|
||||||
import { scanUSBDevices } from "../../../data/usb";
|
import { scanUSBDevices } from "../../../data/usb";
|
||||||
import { showOptionsFlowDialog } from "../../../dialogs/config-flow/show-dialog-options-flow";
|
import { showOptionsFlowDialog } from "../../../dialogs/config-flow/show-dialog-options-flow";
|
||||||
import {
|
import { showRestartDialog } from "../../../dialogs/restart/show-dialog-restart";
|
||||||
showAlertDialog,
|
|
||||||
showConfirmationDialog,
|
|
||||||
} from "../../../dialogs/generic/show-dialog-box";
|
|
||||||
import "../../../layouts/hass-subpage";
|
import "../../../layouts/hass-subpage";
|
||||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||||
import { DEFAULT_PRIMARY_COLOR } from "../../../resources/ha-style";
|
import { DEFAULT_PRIMARY_COLOR } from "../../../resources/ha-style";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import { hardwareBrandsUrl } from "../../../util/brands-url";
|
import { hardwareBrandsUrl } from "../../../util/brands-url";
|
||||||
import { showToast } from "../../../util/toast";
|
|
||||||
import { showhardwareAvailableDialog } from "./show-dialog-hardware-available";
|
import { showhardwareAvailableDialog } from "./show-dialog-hardware-available";
|
||||||
|
|
||||||
const DATASAMPLES = 60;
|
const DATASAMPLES = 60;
|
||||||
@ -75,8 +63,6 @@ class HaConfigHardware extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _OSData?: HassioHassOSInfo;
|
@state() private _OSData?: HassioHassOSInfo;
|
||||||
|
|
||||||
@state() private _hostData?: HassioHostInfo;
|
|
||||||
|
|
||||||
@state() private _hardwareInfo?: HardwareInfo;
|
@state() private _hardwareInfo?: HardwareInfo;
|
||||||
|
|
||||||
@state() private _chartOptions?: ChartOptions;
|
@state() private _chartOptions?: ChartOptions;
|
||||||
@ -273,32 +259,16 @@ class HaConfigHardware extends SubscribeMixin(LitElement) {
|
|||||||
.header=${this.hass.localize("ui.panel.config.hardware.caption")}
|
.header=${this.hass.localize("ui.panel.config.hardware.caption")}
|
||||||
>
|
>
|
||||||
${isComponentLoaded(this.hass, "hassio")
|
${isComponentLoaded(this.hass, "hassio")
|
||||||
? html`<ha-button-menu corner="BOTTOM_START" slot="toolbar-icon">
|
? html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.label=${this.hass.localize("ui.common.menu")}
|
slot="toolbar-icon"
|
||||||
.path=${mdiDotsVertical}
|
.path=${mdiPower}
|
||||||
slot="trigger"
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.hardware.restart_homeassistant"
|
||||||
|
)}
|
||||||
|
@click=${this._showRestartDialog}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
<mwc-list-item @click=${this._openHardware}
|
`
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.config.hardware.available_hardware.title"
|
|
||||||
)}</mwc-list-item
|
|
||||||
>
|
|
||||||
${this._hostData
|
|
||||||
? html`
|
|
||||||
<mwc-list-item class="warning" @click=${this._hostReboot}
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.config.hardware.reboot_host"
|
|
||||||
)}</mwc-list-item
|
|
||||||
>
|
|
||||||
<mwc-list-item class="warning" @click=${this._hostShutdown}
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.config.hardware.shutdown_host"
|
|
||||||
)}</mwc-list-item
|
|
||||||
>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</ha-button-menu>`
|
|
||||||
: ""}
|
: ""}
|
||||||
${this._error
|
${this._error
|
||||||
? html`
|
? html`
|
||||||
@ -367,6 +337,15 @@ class HaConfigHardware extends SubscribeMixin(LitElement) {
|
|||||||
"ui.panel.config.hardware.configure"
|
"ui.panel.config.hardware.configure"
|
||||||
)}
|
)}
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
|
${isComponentLoaded(this.hass, "hassio")
|
||||||
|
? html`
|
||||||
|
<mwc-button @click=${this._openHardware}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.hardware.available_hardware.title"
|
||||||
|
)}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: null}
|
||||||
</div>`
|
</div>`
|
||||||
: ""}
|
: ""}
|
||||||
</ha-card>
|
</ha-card>
|
||||||
@ -475,10 +454,6 @@ class HaConfigHardware extends SubscribeMixin(LitElement) {
|
|||||||
if (isHassioLoaded && !this._hardwareInfo?.hardware.length) {
|
if (isHassioLoaded && !this._hardwareInfo?.hardware.length) {
|
||||||
this._OSData = await fetchHassioHassOsInfo(this.hass);
|
this._OSData = await fetchHassioHassOsInfo(this.hass);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHassioLoaded) {
|
|
||||||
this._hostData = await fetchHassioHostInfo(this.hass);
|
|
||||||
}
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
this._error = err.message || err;
|
this._error = err.message || err;
|
||||||
}
|
}
|
||||||
@ -496,72 +471,8 @@ class HaConfigHardware extends SubscribeMixin(LitElement) {
|
|||||||
showhardwareAvailableDialog(this);
|
showhardwareAvailableDialog(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _hostReboot(): Promise<void> {
|
private async _showRestartDialog() {
|
||||||
const confirmed = await showConfirmationDialog(this, {
|
showRestartDialog(this);
|
||||||
title: this.hass.localize("ui.panel.config.hardware.reboot_host_title"),
|
|
||||||
text: this.hass.localize("ui.panel.config.hardware.reboot_host_text"),
|
|
||||||
confirmText: this.hass.localize("ui.panel.config.hardware.reboot"),
|
|
||||||
dismissText: this.hass.localize("ui.common.cancel"),
|
|
||||||
destructive: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!confirmed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
showToast(this, {
|
|
||||||
message: this.hass.localize("ui.panel.config.hardware.rebooting_host"),
|
|
||||||
duration: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await rebootHost(this.hass);
|
|
||||||
} catch (err: any) {
|
|
||||||
// Ignore connection errors, these are all expected
|
|
||||||
if (this.hass.connection.connected && !ignoreSupervisorError(err)) {
|
|
||||||
showAlertDialog(this, {
|
|
||||||
title: this.hass.localize(
|
|
||||||
"ui.panel.config.hardware.failed_to_reboot_host"
|
|
||||||
),
|
|
||||||
text: extractApiErrorMessage(err),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _hostShutdown(): Promise<void> {
|
|
||||||
const confirmed = await showConfirmationDialog(this, {
|
|
||||||
title: this.hass.localize("ui.panel.config.hardware.shutdown_host_title"),
|
|
||||||
text: this.hass.localize("ui.panel.config.hardware.shutdown_host_text"),
|
|
||||||
confirmText: this.hass.localize("ui.panel.config.hardware.shutdown"),
|
|
||||||
dismissText: this.hass.localize("ui.common.cancel"),
|
|
||||||
destructive: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!confirmed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
showToast(this, {
|
|
||||||
message: this.hass.localize(
|
|
||||||
"ui.panel.config.hardware.host_shutting_down"
|
|
||||||
),
|
|
||||||
duration: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await shutdownHost(this.hass);
|
|
||||||
} catch (err: any) {
|
|
||||||
// Ignore connection errors, these are all expected
|
|
||||||
if (this.hass.connection.connected && !ignoreSupervisorError(err)) {
|
|
||||||
showAlertDialog(this, {
|
|
||||||
title: this.hass.localize(
|
|
||||||
"ui.panel.config.hardware.failed_to_shutdown_host"
|
|
||||||
),
|
|
||||||
text: extractApiErrorMessage(err),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [
|
static styles = [
|
||||||
@ -587,10 +498,6 @@ class HaConfigHardware extends SubscribeMixin(LitElement) {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
ha-button-menu {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
--mdc-menu-min-width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.primary-text {
|
.primary-text {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@ -620,6 +527,10 @@ class HaConfigHardware extends SubscribeMixin(LitElement) {
|
|||||||
height: 48px;
|
height: 48px;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
}
|
}
|
||||||
|
.card-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1008,6 +1008,41 @@
|
|||||||
"aliases_description": "Aliases are alternative names used in voice assistants to refer to this entity."
|
"aliases_description": "Aliases are alternative names used in voice assistants to refer to this entity."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"restart": {
|
||||||
|
"heading": "Restart Home Assistant",
|
||||||
|
"advanced_options": "Advanced options",
|
||||||
|
"reload": {
|
||||||
|
"title": "Quick reload",
|
||||||
|
"description": "Load new YAML configurations without a restart.",
|
||||||
|
"reloading": "Reloading configuration"
|
||||||
|
},
|
||||||
|
"restart": {
|
||||||
|
"title": "Restart Home Assistant",
|
||||||
|
"description": "Interrupts all running automations and scripts.",
|
||||||
|
"confirm_title": "Restart?",
|
||||||
|
"confirm_description": "This will interrupt all running automations and scripts.",
|
||||||
|
"confirm_action": "Restart Home Assistant",
|
||||||
|
"failed": "Failed to restart Home Assistant"
|
||||||
|
},
|
||||||
|
"reboot": {
|
||||||
|
"title": "Reboot system",
|
||||||
|
"description": "Restart the system running Home Assistant and all Add-ons.",
|
||||||
|
"confirm_title": "Reboot system?",
|
||||||
|
"confirm_description": "This will reboot the complete system which includes Home Assistant and all the Add-ons.",
|
||||||
|
"confirm_action": "Reboot",
|
||||||
|
"rebooting": "Rebooting system",
|
||||||
|
"failed": "Failed to reboot system"
|
||||||
|
},
|
||||||
|
"shutdown": {
|
||||||
|
"title": "Shutdown system",
|
||||||
|
"description": "Shutdown the system running Home Assistant and all Add-ons.",
|
||||||
|
"confirm_title": "Shutdown system?",
|
||||||
|
"confirm_description": "This will shutdown the complete system whitch includes Home Assistant and all Add-ons.",
|
||||||
|
"confirm_action": "Shutdown",
|
||||||
|
"shutting_down": "Shutting down system",
|
||||||
|
"failed": "Failed to shutdown system"
|
||||||
|
}
|
||||||
|
},
|
||||||
"aliases": {
|
"aliases": {
|
||||||
"heading": "{name} aliases",
|
"heading": "{name} aliases",
|
||||||
"remove_alias": "Remove alias {number}",
|
"remove_alias": "Remove alias {number}",
|
||||||
@ -1742,24 +1777,16 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"attributes": "Attributes"
|
"attributes": "Attributes"
|
||||||
},
|
},
|
||||||
|
"reboot_moved_title": "Reboot and shutdown moved",
|
||||||
|
"reboot_moved_description": "Reboot and shutdown actions has been moved to system page.",
|
||||||
|
"reboot_moved_link": "Go to system page.",
|
||||||
"processor": "Processor",
|
"processor": "Processor",
|
||||||
"memory": "Memory",
|
"memory": "Memory",
|
||||||
"rebooting_host": "Rebooting system",
|
|
||||||
"reboot": "Reboot",
|
|
||||||
"reboot_host": "Reboot system",
|
|
||||||
"reboot_host_title": "Reboot system?",
|
|
||||||
"reboot_host_text": "This will reboot the complete system which includes the Core and all Add-ons.",
|
|
||||||
"failed_to_reboot_host": "Failed to reboot system",
|
|
||||||
"host_shutting_down": "system shutting down",
|
|
||||||
"shutdown": "Shutdown",
|
|
||||||
"shutdown_host": "Shutdown system",
|
|
||||||
"shutdown_host_title": "Shutdown system?",
|
|
||||||
"shutdown_host_text": "This will shutdown the complete system which includes the Core and all Add-ons.",
|
|
||||||
"failed_to_shutdown_host": "Failed to shutdown system",
|
|
||||||
"board": "Board",
|
"board": "Board",
|
||||||
"documentation": "Documentation",
|
"documentation": "Documentation",
|
||||||
"configure": "Configure",
|
"configure": "Configure",
|
||||||
"documentation_description": "Find extra information about your device"
|
"documentation_description": "Find extra information about your device",
|
||||||
|
"restart_homeassistant": "[%key:ui::panel::config::system_dashboard::restart_homeassistant%]"
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"caption": "About",
|
"caption": "About",
|
||||||
@ -3734,10 +3761,7 @@
|
|||||||
"integration_start_time": "Integration Startup Time"
|
"integration_start_time": "Integration Startup Time"
|
||||||
},
|
},
|
||||||
"system_dashboard": {
|
"system_dashboard": {
|
||||||
"confirm_restart_text": "This will stop all your active dashboards, automations and scripts.",
|
"restart_homeassistant": "Restart Home Assistant"
|
||||||
"confirm_restart_title": "Restart Home Assistant?",
|
|
||||||
"restart_homeassistant_short": "Restart",
|
|
||||||
"restart_error": "Failed to restart Home Assistant"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lovelace": {
|
"lovelace": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user