+
${this._resolutionInfo
? html`${this._resolutionInfo.unhealthy.length
? html`
@@ -265,66 +176,63 @@ class HaConfigSystemHealth extends SubscribeMixin(LitElement) {
: ""} `
: ""}
-
- ${sections}
-
+ ${sections}
+
${!this._coreStats && !this._supervisorStats
? ""
: html`
-
-
- ${this._coreStats
- ? html`
-
- ${this.hass.localize(
- "ui.panel.config.system_health.core_stats"
- )}
-
-
-
- `
- : ""}
- ${this._supervisorStats
- ? html`
-
- ${this.hass.localize(
- "ui.panel.config.system_health.supervisor_stats"
- )}
-
-
-
- `
- : ""}
-
-
+
+ ${this._coreStats
+ ? html`
+
+ ${this.hass.localize(
+ "ui.panel.config.system_health.core_stats"
+ )}
+
+
+
+ `
+ : ""}
+ ${this._supervisorStats
+ ? html`
+
+ ${this.hass.localize(
+ "ui.panel.config.system_health.supervisor_stats"
+ )}
+
+
+
+ `
+ : ""}
+
`}
-
-
-
+
+
`;
}
@@ -386,17 +294,111 @@ class HaConfigSystemHealth extends SubscribeMixin(LitElement) {
});
}
- private async _copyInfo(ev: CustomEvent
): Promise {
- const github = ev.detail.index === 1;
+ private _getSections(): TemplateResult[] {
+ const sections: TemplateResult[] = [];
+
+ if (!this._systemInfo) {
+ sections.push(
+ html`
+
+
+
+ `
+ );
+ } else {
+ const domains = Object.keys(this._systemInfo).sort(sortKeys);
+ for (const domain of domains) {
+ const domainInfo = this._systemInfo[domain];
+ const keys: TemplateResult[] = [];
+
+ for (const key of Object.keys(domainInfo.info)) {
+ let value: unknown;
+
+ if (
+ domainInfo.info[key] &&
+ typeof domainInfo.info[key] === "object"
+ ) {
+ const info = domainInfo.info[key] as SystemCheckValueObject;
+
+ if (info.type === "pending") {
+ value = html`
+
+ `;
+ } else if (info.type === "failed") {
+ value = html`
+ ${info.error}${!info.more_info
+ ? ""
+ : html`
+ –
+
+ ${this.hass.localize(
+ "ui.panel.config.info.system_health.more_systemInfo"
+ )}
+
+ `}
+ `;
+ } else if (info.type === "date") {
+ value = formatDateTime(new Date(info.value), this.hass.locale);
+ }
+ } else {
+ value = domainInfo.info[key];
+ }
+
+ keys.push(html`
+
+
+ ${this.hass.localize(
+ `component.${domain}.system_health.info.${key}`
+ ) || key}
+ |
+ ${value} |
+
+ `);
+ }
+ if (domain !== "homeassistant") {
+ sections.push(
+ html`
+
+ `
+ );
+ }
+ sections.push(html`
+
+ `);
+ }
+ }
+ return sections;
+ }
+
+ private async _copyInfo(): Promise {
let haContent: string | undefined;
const domainParts: string[] = [];
- for (const domain of Object.keys(this._info!).sort(sortKeys)) {
- const domainInfo = this._info![domain];
+ for (const domain of Object.keys(this._systemInfo!).sort(sortKeys)) {
+ const domainInfo = this._systemInfo![domain];
let first = true;
const parts = [
`${
- github && domain !== "homeassistant"
+ domain !== "homeassistant"
? `${domainToName(
this.hass.localize,
domain
@@ -408,7 +410,7 @@ class HaConfigSystemHealth extends SubscribeMixin(LitElement) {
for (const key of Object.keys(domainInfo.info)) {
let value: unknown;
- if (typeof domainInfo.info[key] === "object") {
+ if (domainInfo.info[key] && typeof domainInfo.info[key] === "object") {
const info = domainInfo.info[key] as SystemCheckValueObject;
if (info.type === "pending") {
@@ -421,11 +423,11 @@ class HaConfigSystemHealth extends SubscribeMixin(LitElement) {
} else {
value = domainInfo.info[key];
}
- if (github && first) {
+ if (first) {
parts.push(`${key} | ${value}\n-- | --`);
first = false;
} else {
- parts.push(`${key}${github ? " | " : ": "}${value}`);
+ parts.push(`${key} | ${value}`);
}
}
@@ -433,16 +435,14 @@ class HaConfigSystemHealth extends SubscribeMixin(LitElement) {
haContent = parts.join("\n");
} else {
domainParts.push(parts.join("\n"));
- if (github && domain !== "homeassistant") {
+ if (domain !== "homeassistant") {
domainParts.push("
");
}
}
}
await copyToClipboard(
- `${github ? "## " : ""}System Health\n${haContent}\n\n${domainParts.join(
- "\n\n"
- )}`
+ `${"## "}System Information\n${haContent}\n\n${domainParts.join("\n\n")}`
);
showToast(this, {
@@ -450,73 +450,50 @@ class HaConfigSystemHealth extends SubscribeMixin(LitElement) {
});
}
- static styles: CSSResultGroup = css`
- .content {
- padding: 28px 20px 0;
- max-width: 1040px;
- margin: 0 auto;
- }
- integrations-card {
- max-width: 600px;
- display: block;
- max-width: 600px;
- margin: 0 auto;
- margin-bottom: 24px;
- margin-bottom: max(24px, env(safe-area-inset-bottom));
- }
- ha-card {
- display: block;
- max-width: 600px;
- margin: 0 auto;
- padding-bottom: 16px;
- margin-bottom: 24px;
- }
- ha-alert {
- display: block;
- max-width: 500px;
- margin: 0 auto;
- margin-bottom: max(24px, env(safe-area-inset-bottom));
- }
- table {
- width: 100%;
- }
+ static styles: CSSResultGroup = [
+ haStyleDialog,
+ css`
+ ha-alert {
+ margin-bottom: 16px;
+ display: block;
+ }
+ table {
+ width: 100%;
+ }
- td:first-child {
- width: 45%;
- }
+ td:first-child {
+ width: 45%;
+ }
- td:last-child {
- direction: ltr;
- }
+ td:last-child {
+ direction: ltr;
+ }
- .loading-container {
- display: flex;
- align-items: center;
- justify-content: center;
- }
+ .loading-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
- .card-header {
- justify-content: space-between;
- display: flex;
- align-items: center;
- }
+ .card-header {
+ justify-content: space-between;
+ display: flex;
+ align-items: center;
+ }
- .error {
- color: var(--error-color);
- }
+ .error {
+ color: var(--error-color);
+ }
- a {
- color: var(--primary-color);
- }
-
- a.manage {
- text-decoration: none;
- }
- `;
+ a.manage {
+ text-decoration: none;
+ }
+ `,
+ ];
}
declare global {
interface HTMLElementTagNameMap {
- "ha-config-system-health": HaConfigSystemHealth;
+ "dialog-system-information": DialogSystemInformation;
}
}
diff --git a/src/panels/config/repairs/ha-config-repairs-dashboard.ts b/src/panels/config/repairs/ha-config-repairs-dashboard.ts
index 21f46e0db0..7b1968b572 100644
--- a/src/panels/config/repairs/ha-config-repairs-dashboard.ts
+++ b/src/panels/config/repairs/ha-config-repairs-dashboard.ts
@@ -1,8 +1,10 @@
-import type { ActionDetail } from "@material/mwc-list";
+import { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item-base";
import { mdiDotsVertical } from "@mdi/js";
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
+import { isComponentLoaded } from "../../../common/config/is_component_loaded";
+import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
import "../../../components/ha-card";
import {
fetchRepairsIssues,
@@ -10,11 +12,14 @@ import {
severitySort,
} from "../../../data/repairs";
import "../../../layouts/hass-subpage";
+import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import type { HomeAssistant } from "../../../types";
import "./ha-config-repairs";
+import { showIntegrationStartupDialog } from "./show-integration-startup-dialog";
+import { showSystemInformationDialog } from "./show-system-information-dialog";
@customElement("ha-config-repairs-dashboard")
-class HaConfigRepairsDashboard extends LitElement {
+class HaConfigRepairsDashboard extends SubscribeMixin(LitElement) {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ type: Boolean }) public narrow!: boolean;
@@ -40,6 +45,7 @@ class HaConfigRepairsDashboard extends LitElement {
this._showIgnored,
this._repairsIssues
);
+
return html`
-
+
-
+ ${isComponentLoaded(this.hass, "system_health") ||
+ isComponentLoaded(this.hass, "hassio")
+ ? html`
+
+ ${this.hass.localize(
+ "ui.panel.config.repairs.system_information"
+ )}
+
+ `
+ : ""}
+
+ ${this.hass.localize(
+ "ui.panel.config.repairs.integration_startup_time"
+ )}
+
+
${this._showIgnored
? this.hass.localize("ui.panel.config.repairs.hide_ignored")
: this.hass.localize("ui.panel.config.repairs.show_ignored")}
@@ -98,12 +123,32 @@ class HaConfigRepairsDashboard extends LitElement {
this.hass.loadBackendTranslation("issues", [...integrations]);
}
- private _handleAction(ev: CustomEvent) {
- switch (ev.detail.index) {
- case 0:
- this._showIgnored = !this._showIgnored;
- break;
+ private _showSystemInformationDialog(
+ ev: CustomEvent
+ ): void {
+ if (!shouldHandleRequestSelectedEvent(ev)) {
+ return;
}
+
+ showSystemInformationDialog(this);
+ }
+
+ private _showIntegrationStartupDialog(
+ ev: CustomEvent
+ ): void {
+ if (!shouldHandleRequestSelectedEvent(ev)) {
+ return;
+ }
+
+ showIntegrationStartupDialog(this);
+ }
+
+ private _toggleIgnored(ev: CustomEvent): void {
+ if (!shouldHandleRequestSelectedEvent(ev)) {
+ return;
+ }
+
+ this._showIgnored = !this._showIgnored;
}
static styles = css`
diff --git a/src/panels/config/system-health/integrations-card.ts b/src/panels/config/repairs/integrations-startup-time.ts
similarity index 55%
rename from src/panels/config/system-health/integrations-card.ts
rename to src/panels/config/repairs/integrations-startup-time.ts
index 2188160eb7..fb73329905 100644
--- a/src/panels/config/system-health/integrations-card.ts
+++ b/src/panels/config/repairs/integrations-startup-time.ts
@@ -21,8 +21,8 @@ import type { HomeAssistant } from "../../../types";
import { brandsUrl } from "../../../util/brands-url";
import { documentationUrl } from "../../../util/documentation-url";
-@customElement("integrations-card")
-class IntegrationsCard extends LitElement {
+@customElement("integrations-startup-time")
+class IntegrationsStartupTime extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ type: Boolean }) public narrow = false;
@@ -45,57 +45,47 @@ class IntegrationsCard extends LitElement {
}
return html`
-
-
- ${this._setups?.map((setup) => {
- const manifest = this._manifests && this._manifests[setup.domain];
- const docLink = manifest
- ? manifest.is_built_in
- ? documentationUrl(
- this.hass,
- `/integrations/${manifest.domain}`
- )
- : manifest.documentation
- : "";
+
+ ${this._setups?.map((setup) => {
+ const manifest = this._manifests && this._manifests[setup.domain];
+ const docLink = manifest
+ ? manifest.is_built_in
+ ? documentationUrl(this.hass, `/integrations/${manifest.domain}`)
+ : manifest.documentation
+ : "";
- const setupSeconds = setup.seconds?.toFixed(2);
- return html`
-
-
-
- ${domainToName(this.hass.localize, setup.domain, manifest)}
-
- ${setup.domain}
-
- ${setupSeconds ? html`${setupSeconds} s` : ""}
-
-
- `;
- })}
-
-
+ const setupSeconds = setup.seconds?.toFixed(2);
+ return html`
+
+
+
+ ${domainToName(this.hass.localize, setup.domain, manifest)}
+
+ ${setup.domain}
+
+ ${setupSeconds ? html`${setupSeconds} s` : ""}
+
+
+ `;
+ })}
+
`;
}
@@ -149,6 +139,6 @@ class IntegrationsCard extends LitElement {
declare global {
interface HTMLElementTagNameMap {
- "integrations-card": IntegrationsCard;
+ "integrations-startup-time": IntegrationsStartupTime;
}
}
diff --git a/src/panels/config/repairs/show-integration-startup-dialog.ts b/src/panels/config/repairs/show-integration-startup-dialog.ts
new file mode 100644
index 0000000000..5eb9124645
--- /dev/null
+++ b/src/panels/config/repairs/show-integration-startup-dialog.ts
@@ -0,0 +1,12 @@
+import { fireEvent } from "../../../common/dom/fire_event";
+
+export const loadIntegrationStartupDialog = () =>
+ import("./dialog-integration-startup");
+
+export const showIntegrationStartupDialog = (element: HTMLElement): void => {
+ fireEvent(element, "show-dialog", {
+ dialogTag: "dialog-integration-startup",
+ dialogImport: loadIntegrationStartupDialog,
+ dialogParams: {},
+ });
+};
diff --git a/src/panels/config/repairs/show-system-information-dialog.ts b/src/panels/config/repairs/show-system-information-dialog.ts
new file mode 100644
index 0000000000..1cbf5917f3
--- /dev/null
+++ b/src/panels/config/repairs/show-system-information-dialog.ts
@@ -0,0 +1,12 @@
+import { fireEvent } from "../../../common/dom/fire_event";
+
+export const loadSystemInformationDialog = () =>
+ import("./dialog-system-information");
+
+export const showSystemInformationDialog = (element: HTMLElement): void => {
+ fireEvent(element, "show-dialog", {
+ dialogTag: "dialog-system-information",
+ dialogImport: loadSystemInformationDialog,
+ dialogParams: undefined,
+ });
+};
diff --git a/src/translations/en.json b/src/translations/en.json
index 1bcdd0cd4f..117feb5073 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -1237,6 +1237,9 @@
"critical": "Critical",
"error": "Error",
"warning": "Warning",
+ "system_information": "System information",
+ "integration_startup_time": "Integration startup time",
+ "copy": "Copy",
"dialog": {
"title": "Repair",
"fix": "Repair",