mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-09 02:49:51 +00:00
415 lines
12 KiB
TypeScript
415 lines
12 KiB
TypeScript
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-expansion-panel";
|
|
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
|
|
multiline-secondary
|
|
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
|
|
multiline-secondary
|
|
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>
|
|
</mwc-list>
|
|
|
|
${showRebootShutdown
|
|
? html`
|
|
<ha-expansion-panel
|
|
.header=${this.hass.localize(
|
|
"ui.dialogs.restart.advanced_options"
|
|
)}
|
|
>
|
|
<mwc-list>
|
|
<ha-list-item
|
|
graphic="avatar"
|
|
twoline
|
|
multiline-secondary
|
|
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
|
|
multiline-secondary
|
|
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>
|
|
</mwc-list>
|
|
</ha-expansion-panel>
|
|
`
|
|
: null}
|
|
`}
|
|
</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,
|
|
});
|
|
|
|
try {
|
|
await this.hass.callService("homeassistant", "reload_all");
|
|
} catch (err: any) {
|
|
showAlertDialog(this, {
|
|
title: this.hass.localize("ui.dialogs.restart.reload.failed"),
|
|
text: err.message,
|
|
});
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
@media all and (min-width: 550px) {
|
|
ha-dialog {
|
|
--mdc-dialog-min-width: 500px;
|
|
--mdc-dialog-max-width: 500px;
|
|
}
|
|
}
|
|
|
|
ha-expansion-panel {
|
|
border-top: 1px solid var(--divider-color);
|
|
margin-bottom: 10px;
|
|
box-shadow: none;
|
|
--expansion-panel-content-padding: 0;
|
|
--expansion-panel-summary-padding: 0
|
|
var(--mdc-list-side-padding, 20px);
|
|
--ha-card-border-radius: 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;
|
|
}
|
|
}
|