mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 09:16:38 +00:00
Allow downloading diagnostics of a config entry (#11345)
Co-authored-by: Zack Barett <arnett.zackary@gmail.com>
This commit is contained in:
parent
09a27a6791
commit
441f1fbcb5
18
src/data/diagnostics.ts
Normal file
18
src/data/diagnostics.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
|
interface DiagnosticInfo {
|
||||||
|
domain: string;
|
||||||
|
handlers: {
|
||||||
|
config_entry: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetchDiagnosticHandlers = (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<DiagnosticInfo[]> =>
|
||||||
|
hass.callWS<DiagnosticInfo[]>({
|
||||||
|
type: "diagnostics/list",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getConfigEntryDiagnosticsDownloadUrl = (entry_id: string) =>
|
||||||
|
`/api/diagnostics/config_entry/${entry_id}`;
|
@ -61,6 +61,7 @@ import "./ha-config-flow-card";
|
|||||||
import "./ha-ignored-config-entry-card";
|
import "./ha-ignored-config-entry-card";
|
||||||
import "./ha-integration-card";
|
import "./ha-integration-card";
|
||||||
import type { HaIntegrationCard } from "./ha-integration-card";
|
import type { HaIntegrationCard } from "./ha-integration-card";
|
||||||
|
import { fetchDiagnosticHandlers } from "../../../data/diagnostics";
|
||||||
|
|
||||||
export interface ConfigEntryUpdatedEvent {
|
export interface ConfigEntryUpdatedEvent {
|
||||||
entry: ConfigEntry;
|
entry: ConfigEntry;
|
||||||
@ -138,6 +139,8 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _filter?: string;
|
@state() private _filter?: string;
|
||||||
|
|
||||||
|
@state() private _diagnosticHandlers?: Record<string, boolean>;
|
||||||
|
|
||||||
public hassSubscribe(): UnsubscribeFunc[] {
|
public hassSubscribe(): UnsubscribeFunc[] {
|
||||||
return [
|
return [
|
||||||
subscribeEntityRegistry(this.hass.connection, (entries) => {
|
subscribeEntityRegistry(this.hass.connection, (entries) => {
|
||||||
@ -252,6 +255,15 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
this._handleAdd(localizePromise);
|
this._handleAdd(localizePromise);
|
||||||
}
|
}
|
||||||
this._scanUSBDevices();
|
this._scanUSBDevices();
|
||||||
|
if (isComponentLoaded(this.hass, "diagnostics")) {
|
||||||
|
fetchDiagnosticHandlers(this.hass).then((infos) => {
|
||||||
|
const handlers = {};
|
||||||
|
for (const info of infos) {
|
||||||
|
handlers[info.domain] = info.handlers.config_entry;
|
||||||
|
}
|
||||||
|
this._diagnosticHandlers = handlers;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changed: PropertyValues) {
|
protected updated(changed: PropertyValues) {
|
||||||
@ -423,6 +435,9 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
.manifest=${this._manifests[domain]}
|
.manifest=${this._manifests[domain]}
|
||||||
.entityRegistryEntries=${this._entityRegistryEntries}
|
.entityRegistryEntries=${this._entityRegistryEntries}
|
||||||
.deviceRegistryEntries=${this._deviceRegistryEntries}
|
.deviceRegistryEntries=${this._deviceRegistryEntries}
|
||||||
|
.supportsDiagnostics=${this._diagnosticHandlers
|
||||||
|
? this._diagnosticHandlers[domain]
|
||||||
|
: false}
|
||||||
></ha-integration-card>`
|
></ha-integration-card>`
|
||||||
)
|
)
|
||||||
: this._filter &&
|
: this._filter &&
|
||||||
|
@ -20,6 +20,7 @@ import "../../../components/ha-card";
|
|||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-icon-next";
|
import "../../../components/ha-icon-next";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
|
import { getSignedPath } from "../../../data/auth";
|
||||||
import {
|
import {
|
||||||
ConfigEntry,
|
ConfigEntry,
|
||||||
deleteConfigEntry,
|
deleteConfigEntry,
|
||||||
@ -31,6 +32,7 @@ import {
|
|||||||
ERROR_STATES,
|
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 { getConfigEntryDiagnosticsDownloadUrl } from "../../../data/diagnostics";
|
||||||
import type { EntityRegistryEntry } from "../../../data/entity_registry";
|
import type { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||||
import type { IntegrationManifest } from "../../../data/integration";
|
import type { IntegrationManifest } from "../../../data/integration";
|
||||||
import { integrationIssuesUrl } from "../../../data/integration";
|
import { integrationIssuesUrl } from "../../../data/integration";
|
||||||
@ -73,6 +75,8 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public supportsDiagnostics = false;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
let item = this._selectededConfigEntry;
|
let item = this._selectededConfigEntry;
|
||||||
|
|
||||||
@ -357,6 +361,19 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</mwc-list-item>`
|
</mwc-list-item>`
|
||||||
: ""}
|
: ""}
|
||||||
|
${this.supportsDiagnostics
|
||||||
|
? html`<a
|
||||||
|
href=${getConfigEntryDiagnosticsDownloadUrl(item.entry_id)}
|
||||||
|
target="_blank"
|
||||||
|
@click=${this._signUrl}
|
||||||
|
>
|
||||||
|
<mwc-list-item>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.integrations.config_entry.download_diagnostics"
|
||||||
|
)}
|
||||||
|
</mwc-list-item>
|
||||||
|
</a>`
|
||||||
|
: ""}
|
||||||
${item.disabled_by === "user"
|
${item.disabled_by === "user"
|
||||||
? html`<mwc-list-item @request-selected=${this._handleEnable}>
|
? html`<mwc-list-item @request-selected=${this._handleEnable}>
|
||||||
${this.hass.localize("ui.common.enable")}
|
${this.hass.localize("ui.common.enable")}
|
||||||
@ -623,6 +640,16 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
fireEvent(this, "entry-updated", { entry: result.config_entry });
|
fireEvent(this, "entry-updated", { entry: result.config_entry });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _signUrl(ev) {
|
||||||
|
const anchor = ev.target.closest("a");
|
||||||
|
ev.preventDefault();
|
||||||
|
const signedUrl = await getSignedPath(
|
||||||
|
this.hass,
|
||||||
|
anchor.getAttribute("href")
|
||||||
|
);
|
||||||
|
document.location.assign(signedUrl.path);
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -2440,6 +2440,7 @@
|
|||||||
"configure": "Configure",
|
"configure": "Configure",
|
||||||
"system_options": "System options",
|
"system_options": "System options",
|
||||||
"documentation": "Documentation",
|
"documentation": "Documentation",
|
||||||
|
"download_diagnostics": "Download diagnostics",
|
||||||
"known_issues": "Known issues",
|
"known_issues": "Known issues",
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"delete_confirm": "Are you sure you want to delete the {title} integration?",
|
"delete_confirm": "Are you sure you want to delete the {title} integration?",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user