Add support for Supported Brands (#13184)

This commit is contained in:
Zack Barett 2022-07-13 10:51:17 -05:00 committed by GitHub
parent 24e54554ad
commit b611a58fce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 120 additions and 31 deletions

View File

@ -0,0 +1,8 @@
import type { HomeAssistant } from "../types";
export type SupportedBrandHandler = Record<string, string>;
export const getSupportedBrands = (hass: HomeAssistant) =>
hass.callWS<Record<string, SupportedBrandHandler>>({
type: "supported_brands",
});

View File

@ -7,6 +7,7 @@ import {
handleConfigFlowStep,
} from "../../data/config_flow";
import { domainToName } from "../../data/integration";
import { getSupportedBrands } from "../../data/supported_brands";
import {
DataEntryFlowDialogParams,
loadDataEntryFlowDialog,
@ -22,12 +23,14 @@ export const showConfigFlowDialog = (
showFlowDialog(element, dialogParams, {
loadDevicesAndAreas: true,
getFlowHandlers: async (hass) => {
const [integrations, helpers] = await Promise.all([
const [integrations, helpers, supportedBrands] = await Promise.all([
getConfigFlowHandlers(hass, "integration"),
getConfigFlowHandlers(hass, "helper"),
getSupportedBrands(hass),
hass.loadBackendTranslation("title", undefined, true),
]);
return { integrations, helpers };
return { integrations, helpers, supportedBrands };
},
createFlow: async (hass, handler) => {
const [step] = await Promise.all([

View File

@ -10,12 +10,14 @@ import {
DataEntryFlowStepMenu,
DataEntryFlowStepProgress,
} from "../../data/data_entry_flow";
import { IntegrationManifest } from "../../data/integration";
import { HomeAssistant } from "../../types";
import type { IntegrationManifest } from "../../data/integration";
import type { SupportedBrandHandler } from "../../data/supported_brands";
import type { HomeAssistant } from "../../types";
export interface FlowHandlers {
integrations: string[];
helpers: string[];
supportedBrands: Record<string, SupportedBrandHandler>;
}
export interface FlowConfig {
loadDevicesAndAreas: boolean;

View File

@ -1,5 +1,6 @@
import "@polymer/paper-item";
import "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-item/paper-item-body";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";

View File

@ -15,18 +15,19 @@ import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { fireEvent } from "../../common/dom/fire_event";
import { navigate } from "../../common/navigate";
import "../../components/search-input";
import { caseInsensitiveStringCompare } from "../../common/string/compare";
import { LocalizeFunc } from "../../common/translations/localize";
import "../../components/ha-icon-next";
import "../../components/search-input";
import { getConfigEntries } from "../../data/config_entries";
import { domainToName } from "../../data/integration";
import { showZWaveJSAddNodeDialog } from "../../panels/config/integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node";
import { HomeAssistant } from "../../types";
import { brandsUrl } from "../../util/brands-url";
import { documentationUrl } from "../../util/documentation-url";
import { configFlowContentStyles } from "./styles";
import { showConfirmationDialog } from "../generic/show-dialog-box";
import { FlowHandlers } from "./show-dialog-data-entry-flow";
import { configFlowContentStyles } from "./styles";
interface HandlerObj {
name: string;
@ -35,6 +36,10 @@ interface HandlerObj {
is_helper?: boolean;
}
interface SupportedBrandObj extends HandlerObj {
supported_flows: string[];
}
declare global {
// for fire event
interface HASSDomEvents {
@ -63,11 +68,22 @@ class StepFlowPickHandler extends LitElement {
h: FlowHandlers,
filter?: string,
_localize?: LocalizeFunc
): [HandlerObj[], HandlerObj[]] => {
const integrations: HandlerObj[] = h.integrations.map((handler) => ({
name: domainToName(this.hass.localize, handler),
slug: handler,
}));
): [(HandlerObj | SupportedBrandObj)[], HandlerObj[]] => {
const integrations: (HandlerObj | SupportedBrandObj)[] =
h.integrations.map((handler) => ({
name: domainToName(this.hass.localize, handler),
slug: handler,
}));
for (const [domain, domainBrands] of Object.entries(h.supportedBrands)) {
for (const [slug, name] of Object.entries(domainBrands)) {
integrations.push({
slug,
name,
supported_flows: [domain],
});
}
}
if (filter) {
const options: Fuse.IFuseOptions<HandlerObj> = {
@ -238,27 +254,10 @@ class StepFlowPickHandler extends LitElement {
}
private async _handlerPicked(ev) {
const handler: HandlerObj = ev.currentTarget.handler;
const handler: HandlerObj | SupportedBrandObj = ev.currentTarget.handler;
if (handler.is_add) {
if (handler.slug === "zwave_js") {
const entries = await getConfigEntries(this.hass, {
domain: "zwave_js",
});
if (!entries.length) {
return;
}
showZWaveJSAddNodeDialog(this, {
entry_id: entries[0].entry_id,
});
} else if (handler.slug === "zha") {
navigate("/config/zha/add");
}
// This closes dialog.
fireEvent(this, "flow-update");
this._handleAddPicked(handler.slug);
return;
}
@ -269,11 +268,84 @@ class StepFlowPickHandler extends LitElement {
return;
}
if ("supported_flows" in handler) {
const slug = handler.supported_flows[0];
showConfirmationDialog(this, {
text: this.hass.localize(
"ui.panel.config.integrations.config_flow.supported_brand_flow",
{
supported_brand: handler.name,
flow_domain_name: domainToName(this.hass.localize, slug),
}
),
confirm: () => {
if (["zha", "zwave_js"].includes(slug)) {
this._handleAddPicked(slug);
return;
}
fireEvent(this, "handler-picked", {
handler: slug,
});
},
});
return;
}
fireEvent(this, "handler-picked", {
handler: handler.slug,
});
}
private async _handleAddPicked(slug: string): Promise<void> {
if (slug === "zwave_js") {
const entries = await getConfigEntries(this.hass, {
domain: "zwave_js",
});
if (!entries.length) {
// If the component isn't loaded, ask them to load the integration first
showConfirmationDialog(this, {
text: this.hass.localize(
"ui.panel.config.integrations.config_flow.missing_zwave_js"
),
confirm: () => {
fireEvent(this, "handler-picked", {
handler: "zwave_js",
});
},
});
return;
}
showZWaveJSAddNodeDialog(this, {
entry_id: entries[0].entry_id,
});
} else if (slug === "zha") {
// If the component isn't loaded, ask them to load the integration first
if (!isComponentLoaded(this.hass, "zha")) {
showConfirmationDialog(this, {
text: this.hass.localize(
"ui.panel.config.integrations.config_flow.missing_zha"
),
confirm: () => {
fireEvent(this, "handler-picked", {
handler: "zha",
});
},
});
return;
}
navigate("/config/zha/add");
}
// This closes dialog.
fireEvent(this, "flow-update");
}
private _maybeSubmit(ev: KeyboardEvent) {
if (ev.key !== "Enter") {
return;

View File

@ -2850,7 +2850,10 @@
"error": "Error",
"could_not_load": "Config flow could not be loaded",
"not_loaded": "The integration could not be loaded, try to restart Home Assistant.",
"missing_credentials": "Setting up {integration} requires configuring application credentials. Do you want to do that now?"
"missing_credentials": "Setting up {integration} requires configuring application credentials. Do you want to do that now?",
"supported_brand_flow": "Support for {supported_brand} devices is provided by {flow_domain_name}. Do you want to continue?",
"missing_zwave_js": "To add a Z-Wave device, you first need to set up the Z-Wave integration. Do you want to do that now?",
"missing_zha": "To add a Zigbee device, you first need to set up the Zigbee Home Automation integration. Do you want to do that now?"
}
},
"users": {