diff --git a/src/data/integration.ts b/src/data/integration.ts index f19be078eb..f69a763a7c 100644 --- a/src/data/integration.ts +++ b/src/data/integration.ts @@ -24,6 +24,11 @@ export interface IntegrationManifest { | "local_push"; } +export interface IntegrationSetup { + domain: string; + seconds?: number; +} + export const integrationIssuesUrl = ( domain: string, manifest: IntegrationManifest @@ -44,3 +49,6 @@ export const fetchIntegrationManifest = ( hass: HomeAssistant, integration: string ) => hass.callWS({ type: "manifest/get", integration }); + +export const fetchIntegrationSetups = (hass: HomeAssistant) => + hass.callWS({ type: "integration/setup_info" }); diff --git a/src/panels/config/info/ha-config-info.ts b/src/panels/config/info/ha-config-info.ts index c1dd606e57..b3ffe78557 100644 --- a/src/panels/config/info/ha-config-info.ts +++ b/src/panels/config/info/ha-config-info.ts @@ -140,7 +140,10 @@ class HaConfigInfo extends LitElement {
- +
`; diff --git a/src/panels/config/info/integrations-card.ts b/src/panels/config/info/integrations-card.ts index 9ac154d716..a698b7e634 100644 --- a/src/panels/config/info/integrations-card.ts +++ b/src/panels/config/info/integrations-card.ts @@ -13,8 +13,10 @@ import "../../../components/ha-card"; import { domainToName, fetchIntegrationManifests, + fetchIntegrationSetups, integrationIssuesUrl, IntegrationManifest, + IntegrationSetup, } from "../../../data/integration"; import { HomeAssistant } from "../../../types"; import { brandsUrl } from "../../../util/brands-url"; @@ -23,10 +25,16 @@ import { brandsUrl } from "../../../util/brands-url"; class IntegrationsCard extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; + @property({ type: Boolean }) public narrow = false; + @internalProperty() private _manifests?: { [domain: string]: IntegrationManifest; }; + @internalProperty() private _setups?: { + [domain: string]: IntegrationSetup; + }; + private _sortedIntegrations = memoizeOne((components: string[]) => { return Array.from( new Set( @@ -40,6 +48,7 @@ class IntegrationsCard extends LitElement { firstUpdated(changedProps) { super.firstUpdated(changedProps); this._fetchManifests(); + this._fetchSetups(); } protected render(): TemplateResult { @@ -48,10 +57,47 @@ class IntegrationsCard extends LitElement { .header=${this.hass.localize("ui.panel.config.info.integrations")} > + + + + ${!this.narrow + ? html` + + ` + : ""} + + + ${this._sortedIntegrations(this.hass!.config.components).map( (domain) => { const manifest = this._manifests && this._manifests[domain]; + const docLink = manifest + ? html`${this.hass.localize( + "ui.panel.config.info.documentation" + )}` + : ""; + const issueLink = + manifest && (manifest.is_built_in || manifest.issue_tracker) + ? html` + ${this.hass.localize( + "ui.panel.config.info.issues" + )} + ` + : ""; + const setupSeconds = this._setups?.[domain]?.seconds?.toFixed( + 2 + ); return html` - ${!manifest + ${this.narrow ? "" : html` + + - ${manifest.is_built_in || manifest.issue_tracker - ? html` - - ` - : ""} `} `; @@ -116,9 +148,21 @@ class IntegrationsCard extends LitElement { this._manifests = manifests; } + private async _fetchSetups() { + const setups = {}; + for (const setup of await fetchIntegrationSetups(this.hass)) { + setups[setup.domain] = setup; + } + this._setups = setups; + } + static get styles(): CSSResult { return css` - td { + table { + width: 100%; + } + td, + th { padding: 0 8px; } td:first-child { @@ -127,9 +171,22 @@ class IntegrationsCard extends LitElement { td.name { padding: 8px; } + td.setup { + text-align: right; + } + th { + text-align: right; + } .domain { color: var(--secondary-text-color); } + .mobile-row { + display: flex; + justify-content: space-between; + } + .mobile-row a:not(:last-of-type) { + margin-right: 4px; + } img { display: block; max-height: 40px;
Setup time
@@ -64,39 +110,25 @@ class IntegrationsCard extends LitElement { ${domainToName(this.hass.localize, domain, manifest)}
${domain} + ${this.narrow + ? html`
+
${docLink} ${issueLink}
+ ${setupSeconds ? html`${setupSeconds}s` : ""} +
` + : ""}
- - ${this.hass.localize( - "ui.panel.config.info.documentation" - )} - + ${docLink} + + ${issueLink} + + ${setupSeconds ? html`${setupSeconds}s` : ""} - - ${this.hass.localize( - "ui.panel.config.info.issues" - )} - -