diff --git a/src/panels/config/integrations/dialog-add-integration.ts b/src/panels/config/integrations/dialog-add-integration.ts index a775b05506..865cabbd5d 100644 --- a/src/panels/config/integrations/dialog-add-integration.ts +++ b/src/panels/config/integrations/dialog-add-integration.ts @@ -36,10 +36,12 @@ import { } from "../../../dialogs/generic/show-dialog-box"; import { haStyleDialog, haStyleScrollbar } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; -import { documentationUrl } from "../../../util/documentation-url"; import "./ha-domain-integrations"; import "./ha-integration-list-item"; -import { AddIntegrationDialogParams } from "./show-add-integration-dialog"; +import { + AddIntegrationDialogParams, + showYamlIntegrationDialog, +} from "./show-add-integration-dialog"; export interface IntegrationListItem { name: string; @@ -545,35 +547,7 @@ class AddIntegrationDialog extends LitElement { this.hass, integration.domain ); - showAlertDialog(this, { - title: this.hass.localize( - "ui.panel.config.integrations.config_flow.yaml_only_title" - ), - text: this.hass.localize( - "ui.panel.config.integrations.config_flow.yaml_only_text", - { - link: - manifest?.is_built_in || manifest?.documentation - ? html` - ${this.hass.localize( - "ui.panel.config.integrations.config_flow.documentation" - )}` - : this.hass.localize( - "ui.panel.config.integrations.config_flow.documentation" - ), - } - ), - }); + showYamlIntegrationDialog(this, { manifest }); } private async _createFlow(integration: IntegrationListItem) { diff --git a/src/panels/config/integrations/dialog-yaml-integration.ts b/src/panels/config/integrations/dialog-yaml-integration.ts new file mode 100644 index 0000000000..932c955bde --- /dev/null +++ b/src/panels/config/integrations/dialog-yaml-integration.ts @@ -0,0 +1,96 @@ +import "@material/mwc-button/mwc-button"; +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { fireEvent } from "../../../common/dom/fire_event"; +import { HomeAssistant } from "../../../types"; +import { documentationUrl } from "../../../util/documentation-url"; +import { YamlIntegrationDialogParams } from "./show-add-integration-dialog"; + +@customElement("dialog-yaml-integration") +export class DialogYamlIntegration extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @state() private _params?: YamlIntegrationDialogParams; + + public showDialog(params: YamlIntegrationDialogParams): void { + this._params = params; + } + + public closeDialog() { + this._params = undefined; + fireEvent(this, "dialog-closed", { dialog: this.localName }); + } + + protected render(): TemplateResult { + if (!this._params) { + return html``; + } + const manifest = this._params.manifest; + const docLink = manifest.is_built_in + ? documentationUrl(this.hass, `/integrations/${manifest.domain}`) + : manifest.documentation; + return html` + +

+ ${this.hass.localize( + "ui.panel.config.integrations.config_flow.yaml_only" + )} +

+ + ${this.hass.localize("ui.dialogs.generic.cancel")} + + ${docLink + ? html` + + ${this.hass.localize( + "ui.panel.config.integrations.config_flow.open_documentation" + )} + + ` + : html` + ${this.hass.localize("ui.dialogs.generic.ok")} + `} +
+ `; + } + + static get styles(): CSSResultGroup { + return css` + :host([inert]) { + pointer-events: initial !important; + cursor: initial !important; + } + a { + text-decoration: none; + } + ha-dialog { + --mdc-dialog-heading-ink-color: var(--primary-text-color); + --mdc-dialog-content-ink-color: var(--primary-text-color); + /* Place above other dialogs */ + --dialog-z-index: 104; + } + @media all and (min-width: 600px) { + ha-dialog { + --mdc-dialog-min-width: 400px; + } + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "dialog-yaml-integration": DialogYamlIntegration; + } +} diff --git a/src/panels/config/integrations/ha-domain-integrations.ts b/src/panels/config/integrations/ha-domain-integrations.ts index 8df892a620..6b9a89e73d 100644 --- a/src/panels/config/integrations/ha-domain-integrations.ts +++ b/src/panels/config/integrations/ha-domain-integrations.ts @@ -1,8 +1,10 @@ +import { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item-base"; import { css, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { fireEvent } from "../../../common/dom/fire_event"; import { protocolIntegrationPicked } from "../../../common/integrations/protocolIntegrationPicked"; +import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event"; import { navigate } from "../../../common/navigate"; import { caseInsensitiveStringCompare } from "../../../common/string/compare"; import { localizeConfigFlowTitle } from "../../../data/config_flow"; @@ -13,12 +15,11 @@ import { } from "../../../data/integration"; import { Integration } from "../../../data/integrations"; import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-config-flow"; -import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; import { haStyle } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; import { brandsUrl } from "../../../util/brands-url"; -import { documentationUrl } from "../../../util/documentation-url"; import "./ha-integration-list-item"; +import { showYamlIntegrationDialog } from "./show-add-integration-dialog"; const standardToDomain = { zigbee: "zha", zwave: "zwave_js" } as const; @@ -43,7 +44,7 @@ class HaDomainIntegrations extends LitElement { (flow) => html` ` ) @@ -138,7 +139,7 @@ class HaDomainIntegrations extends LitElement { ? html` ${this.hass.localize("ui.panel.config.integrations.new_flow", { @@ -186,15 +187,18 @@ class HaDomainIntegrations extends LitElement { is_built_in: this.integration.is_built_in !== false, cloud: this.integration.iot_class?.startsWith("cloud_"), }} - @click=${this._integrationPicked} + @request-selected=${this._integrationPicked} > `}` : ""} `; } - private async _integrationPicked(ev) { - const domain = ev.currentTarget.domain; + private async _integrationPicked(ev: CustomEvent) { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } + const domain = (ev.currentTarget as any).domain; if ( ["cloud", "google_assistant", "alexa"].includes(domain) && @@ -213,37 +217,10 @@ class HaDomainIntegrations extends LitElement { this.integration!.integrations?.[domain]?.config_flow === false ) { const manifest = await fetchIntegrationManifest(this.hass, domain); - showAlertDialog(this, { - title: this.hass.localize( - "ui.panel.config.integrations.config_flow.yaml_only_title" - ), - text: this.hass.localize( - "ui.panel.config.integrations.config_flow.yaml_only_text", - { - link: - manifest?.is_built_in || manifest?.documentation - ? html` - ${this.hass.localize( - "ui.panel.config.integrations.config_flow.documentation" - )}` - : this.hass.localize( - "ui.panel.config.integrations.config_flow.documentation" - ), - } - ), - }); + showYamlIntegrationDialog(this, { manifest }); return; } + const root = this.getRootNode(); showConfigFlowDialog( root instanceof ShadowRoot ? (root.host as HTMLElement) : this, @@ -256,8 +233,11 @@ class HaDomainIntegrations extends LitElement { fireEvent(this, "close-dialog"); } - private async _flowInProgressPicked(ev) { - const flow: DataEntryFlowProgress = ev.currentTarget.flow; + private async _flowInProgressPicked(ev: CustomEvent) { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } + const flow: DataEntryFlowProgress = (ev.currentTarget as any).flow; const root = this.getRootNode(); showConfigFlowDialog( root instanceof ShadowRoot ? (root.host as HTMLElement) : this, @@ -270,8 +250,11 @@ class HaDomainIntegrations extends LitElement { fireEvent(this, "close-dialog"); } - private _standardPicked(ev) { - const domain = ev.currentTarget.domain; + private _standardPicked(ev: CustomEvent) { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } + const domain = (ev.currentTarget as any).domain; const root = this.getRootNode(); fireEvent(this, "close-dialog"); protocolIntegrationPicked( diff --git a/src/panels/config/integrations/show-add-integration-dialog.ts b/src/panels/config/integrations/show-add-integration-dialog.ts index 1530b73ce6..0bfbf0cb76 100644 --- a/src/panels/config/integrations/show-add-integration-dialog.ts +++ b/src/panels/config/integrations/show-add-integration-dialog.ts @@ -1,10 +1,15 @@ import { fireEvent } from "../../../common/dom/fire_event"; +import { IntegrationManifest } from "../../../data/integration"; export interface AddIntegrationDialogParams { brand?: string; initialFilter?: string; } +export interface YamlIntegrationDialogParams { + manifest: IntegrationManifest; +} + export const showAddIntegrationDialog = ( element: HTMLElement, dialogParams?: AddIntegrationDialogParams @@ -15,3 +20,14 @@ export const showAddIntegrationDialog = ( dialogParams: dialogParams, }); }; + +export const showYamlIntegrationDialog = ( + element: HTMLElement, + dialogParams?: YamlIntegrationDialogParams +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-yaml-integration", + dialogImport: () => import("./dialog-yaml-integration"), + dialogParams: dialogParams, + }); +}; diff --git a/src/translations/en.json b/src/translations/en.json index af79aefb5c..b2c6fbd067 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2965,8 +2965,8 @@ "next": "Next", "found_following_devices": "We found the following devices", "yaml_only_title": "This device can not be added from the UI", - "yaml_only_text": "You can add this device by adding it to your `configuration.yaml`. See the {link} for more information.", - "documentation": "documentation", + "yaml_only": "You can add this device by adding it to your ''configuration.yaml''. See the documentation for more information.", + "open_documentation": "Open documentation", "no_config_flow": "This integration does not support configuration via the UI. If you followed this link from the Home Assistant website, make sure you run the latest version of Home Assistant.", "not_all_required_fields": "Not all required fields are filled in.", "error_saving_area": "Error saving area: {error}",