mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Handle config entry not loaded on Z-Wave JS config panel (#9451)
* Handle config entry not loaded on Z-Wave JS config panel * Move ERROR_STATES to data/config_entries and import
This commit is contained in:
parent
db37dffdbb
commit
ed4809b71e
@ -27,6 +27,12 @@ export type ConfigEntryMutableParams = Partial<
|
|||||||
>
|
>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
export const ERROR_STATES: ConfigEntry["state"][] = [
|
||||||
|
"migration_error",
|
||||||
|
"setup_error",
|
||||||
|
"setup_retry",
|
||||||
|
];
|
||||||
|
|
||||||
export const getConfigEntries = (hass: HomeAssistant) =>
|
export const getConfigEntries = (hass: HomeAssistant) =>
|
||||||
hass.callApi<ConfigEntry[]>("GET", "config/config_entries/entry");
|
hass.callApi<ConfigEntry[]>("GET", "config/config_entries/entry");
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
enableConfigEntry,
|
enableConfigEntry,
|
||||||
reloadConfigEntry,
|
reloadConfigEntry,
|
||||||
updateConfigEntry,
|
updateConfigEntry,
|
||||||
|
ERROR_STATES,
|
||||||
} from "../../../data/config_entries";
|
} from "../../../data/config_entries";
|
||||||
import type { DeviceRegistryEntry } from "../../../data/device_registry";
|
import type { DeviceRegistryEntry } from "../../../data/device_registry";
|
||||||
import type { EntityRegistryEntry } from "../../../data/entity_registry";
|
import type { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||||
@ -38,12 +39,6 @@ import type { HomeAssistant } from "../../../types";
|
|||||||
import type { ConfigEntryExtended } from "./ha-config-integrations";
|
import type { ConfigEntryExtended } from "./ha-config-integrations";
|
||||||
import "./ha-integration-header";
|
import "./ha-integration-header";
|
||||||
|
|
||||||
const ERROR_STATES: ConfigEntry["state"][] = [
|
|
||||||
"migration_error",
|
|
||||||
"setup_error",
|
|
||||||
"setup_retry",
|
|
||||||
];
|
|
||||||
|
|
||||||
const integrationsWithPanel = {
|
const integrationsWithPanel = {
|
||||||
hassio: "/hassio/dashboard",
|
hassio: "/hassio/dashboard",
|
||||||
mqtt: "/config/mqtt",
|
mqtt: "/config/mqtt",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
import "@material/mwc-icon-button/mwc-icon-button";
|
import "@material/mwc-icon-button/mwc-icon-button";
|
||||||
import { mdiCheckCircle, mdiCircle, mdiRefresh } from "@mdi/js";
|
import { mdiAlertCircle, mdiCheckCircle, mdiCircle, mdiRefresh } 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 { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
@ -17,6 +17,11 @@ import {
|
|||||||
ZWaveJSNetwork,
|
ZWaveJSNetwork,
|
||||||
ZWaveJSNode,
|
ZWaveJSNode,
|
||||||
} from "../../../../../data/zwave_js";
|
} from "../../../../../data/zwave_js";
|
||||||
|
import {
|
||||||
|
ConfigEntry,
|
||||||
|
getConfigEntries,
|
||||||
|
ERROR_STATES,
|
||||||
|
} from "../../../../../data/config_entries";
|
||||||
import {
|
import {
|
||||||
showAlertDialog,
|
showAlertDialog,
|
||||||
showConfirmationDialog,
|
showConfirmationDialog,
|
||||||
@ -30,7 +35,6 @@ import { showZWaveJSAddNodeDialog } from "./show-dialog-zwave_js-add-node";
|
|||||||
import { showZWaveJSHealNetworkDialog } from "./show-dialog-zwave_js-heal-network";
|
import { showZWaveJSHealNetworkDialog } from "./show-dialog-zwave_js-heal-network";
|
||||||
import { showZWaveJSRemoveNodeDialog } from "./show-dialog-zwave_js-remove-node";
|
import { showZWaveJSRemoveNodeDialog } from "./show-dialog-zwave_js-remove-node";
|
||||||
import { configTabs } from "./zwave_js-config-router";
|
import { configTabs } from "./zwave_js-config-router";
|
||||||
import { getConfigEntries } from "../../../../../data/config_entries";
|
|
||||||
import { showOptionsFlowDialog } from "../../../../../dialogs/config-flow/show-dialog-options-flow";
|
import { showOptionsFlowDialog } from "../../../../../dialogs/config-flow/show-dialog-options-flow";
|
||||||
|
|
||||||
@customElement("zwave_js-config-dashboard")
|
@customElement("zwave_js-config-dashboard")
|
||||||
@ -45,6 +49,8 @@ class ZWaveJSConfigDashboard extends LitElement {
|
|||||||
|
|
||||||
@property() public configEntryId?: string;
|
@property() public configEntryId?: string;
|
||||||
|
|
||||||
|
@state() private _configEntry?: ConfigEntry;
|
||||||
|
|
||||||
@state() private _network?: ZWaveJSNetwork;
|
@state() private _network?: ZWaveJSNetwork;
|
||||||
|
|
||||||
@state() private _nodes?: ZWaveJSNode[];
|
@state() private _nodes?: ZWaveJSNode[];
|
||||||
@ -62,6 +68,14 @@ class ZWaveJSConfigDashboard extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
if (!this._configEntry) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ERROR_STATES.includes(this._configEntry.state)) {
|
||||||
|
return this._renderErrorScreen();
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage
|
<hass-tabs-subpage
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -222,10 +236,83 @@ class ZWaveJSConfigDashboard extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _renderErrorScreen() {
|
||||||
|
const item = this._configEntry!;
|
||||||
|
let stateText: [string, ...unknown[]] | undefined;
|
||||||
|
let stateTextExtra: TemplateResult | string | undefined;
|
||||||
|
|
||||||
|
if (item.disabled_by) {
|
||||||
|
stateText = [
|
||||||
|
"ui.panel.config.integrations.config_entry.disable.disabled_cause",
|
||||||
|
{
|
||||||
|
cause:
|
||||||
|
this.hass.localize(
|
||||||
|
`ui.panel.config.integrations.config_entry.disable.disabled_by.${item.disabled_by}`
|
||||||
|
) || item.disabled_by,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (item.state === "failed_unload") {
|
||||||
|
stateTextExtra = html`.
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.integrations.config_entry.disable_restart_confirm"
|
||||||
|
)}.`;
|
||||||
|
}
|
||||||
|
} else if (item.state === "not_loaded") {
|
||||||
|
stateText = ["ui.panel.config.integrations.config_entry.not_loaded"];
|
||||||
|
} else if (ERROR_STATES.includes(item.state)) {
|
||||||
|
stateText = [
|
||||||
|
`ui.panel.config.integrations.config_entry.state.${item.state}`,
|
||||||
|
];
|
||||||
|
if (item.reason) {
|
||||||
|
this.hass.loadBackendTranslation("config", item.domain);
|
||||||
|
stateTextExtra = html` ${this.hass.localize(
|
||||||
|
`component.${item.domain}.config.error.${item.reason}`
|
||||||
|
) || item.reason}`;
|
||||||
|
} else {
|
||||||
|
stateTextExtra = html`
|
||||||
|
<br />
|
||||||
|
<a href="/config/logs"
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.config.integrations.config_entry.check_the_logs"
|
||||||
|
)}</a
|
||||||
|
>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return html` ${stateText
|
||||||
|
? html`
|
||||||
|
<div class="error-message">
|
||||||
|
<ha-svg-icon .path=${mdiAlertCircle}></ha-svg-icon>
|
||||||
|
<h3>
|
||||||
|
${this._configEntry!.title}: ${this.hass.localize(...stateText)}
|
||||||
|
</h3>
|
||||||
|
<p>${stateTextExtra}</p>
|
||||||
|
<mwc-button @click=${this._handleBack}>
|
||||||
|
${this.hass?.localize("ui.panel.error.go_back") || "go back"}
|
||||||
|
</mwc-button>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleBack(): void {
|
||||||
|
history.back();
|
||||||
|
}
|
||||||
|
|
||||||
private async _fetchData() {
|
private async _fetchData() {
|
||||||
if (!this.configEntryId) {
|
if (!this.configEntryId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const configEntries = await getConfigEntries(this.hass);
|
||||||
|
this._configEntry = configEntries.find(
|
||||||
|
(entry) => entry.entry_id === this.configEntryId!
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ERROR_STATES.includes(this._configEntry!.state)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const [network, dataCollectionStatus] = await Promise.all([
|
const [network, dataCollectionStatus] = await Promise.all([
|
||||||
fetchNetworkStatus(this.hass!, this.configEntryId),
|
fetchNetworkStatus(this.hass!, this.configEntryId),
|
||||||
fetchDataCollectionStatus(this.hass!, this.configEntryId),
|
fetchDataCollectionStatus(this.hass!, this.configEntryId),
|
||||||
@ -363,6 +450,27 @@ class ZWaveJSConfigDashboard extends LitElement {
|
|||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
display: flex;
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
height: calc(100% - var(--header-height));
|
||||||
|
padding: 16px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message h3 {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message ha-svg-icon {
|
||||||
|
color: var(--error-color);
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user