Allows for My to support Supported Brands (#13256)

This commit is contained in:
Zack Barett 2022-07-25 04:35:13 -05:00 committed by GitHub
parent 5be624f45d
commit 63ea8e6568
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 183 additions and 109 deletions

View File

@ -0,0 +1,88 @@
import { html } from "lit";
import { getConfigEntries } from "../../data/config_entries";
import { showConfirmationDialog } from "../../dialogs/generic/show-dialog-box";
import { showZWaveJSAddNodeDialog } from "../../panels/config/integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node";
import type { HomeAssistant } from "../../types";
import { documentationUrl } from "../../util/documentation-url";
import { isComponentLoaded } from "../config/is_component_loaded";
import { fireEvent } from "../dom/fire_event";
import { navigate } from "../navigate";
export const protocolIntegrationPicked = async (
element: HTMLElement,
hass: HomeAssistant,
slug: string
) => {
if (slug === "zwave_js") {
const entries = await getConfigEntries(hass, {
domain: "zwave_js",
});
if (!entries.length) {
// If the component isn't loaded, ask them to load the integration first
showConfirmationDialog(element, {
text: hass.localize(
"ui.panel.config.integrations.config_flow.missing_zwave_zigbee",
{
integration: "Z-Wave",
supported_hardware_link: html`<a
href=${documentationUrl(hass, "/docs/z-wave/controllers")}
target="_blank"
rel="noreferrer"
>${hass.localize(
"ui.panel.config.integrations.config_flow.supported_hardware"
)}</a
>`,
}
),
confirmText: hass.localize(
"ui.panel.config.integrations.config_flow.proceed"
),
confirm: () => {
fireEvent(element, "handler-picked", {
handler: "zwave_js",
});
},
});
return;
}
showZWaveJSAddNodeDialog(element, {
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(hass, "zha")) {
showConfirmationDialog(element, {
text: hass.localize(
"ui.panel.config.integrations.config_flow.missing_zwave_zigbee",
{
integration: "Zigbee",
supported_hardware_link: html`<a
href=${documentationUrl(
hass,
"/integrations/zha/#known-working-zigbee-radio-modules"
)}
target="_blank"
rel="noreferrer"
>${hass.localize(
"ui.panel.config.integrations.config_flow.supported_hardware"
)}</a
>`,
}
),
confirmText: hass.localize(
"ui.panel.config.integrations.config_flow.proceed"
),
confirm: () => {
fireEvent(element, "handler-picked", {
handler: "zha",
});
},
});
return;
}
navigate("/config/zha/add");
}
};

View File

@ -1,3 +1,4 @@
import { SupportedBrandObj } from "../dialogs/config-flow/step-flow-pick-handler";
import type { HomeAssistant } from "../types"; import type { HomeAssistant } from "../types";
export type SupportedBrandHandler = Record<string, string>; export type SupportedBrandHandler = Record<string, string>;
@ -6,3 +7,21 @@ export const getSupportedBrands = (hass: HomeAssistant) =>
hass.callWS<Record<string, SupportedBrandHandler>>({ hass.callWS<Record<string, SupportedBrandHandler>>({
type: "supported_brands", type: "supported_brands",
}); });
export const getSupportedBrandsLookup = (
supportedBrands: Record<string, SupportedBrandHandler>
): Record<string, Partial<SupportedBrandObj>> => {
const supportedBrandsIntegrations: Record<
string,
Partial<SupportedBrandObj>
> = {};
for (const [d, domainBrands] of Object.entries(supportedBrands)) {
for (const [slug, name] of Object.entries(domainBrands)) {
supportedBrandsIntegrations[slug] = {
name,
supported_flows: [d],
};
}
}
return supportedBrandsIntegrations;
};

View File

@ -14,14 +14,13 @@ import { styleMap } from "lit/directives/style-map";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import { protocolIntegrationPicked } from "../../common/integrations/protocolIntegrationPicked";
import { navigate } from "../../common/navigate"; import { navigate } from "../../common/navigate";
import { caseInsensitiveStringCompare } from "../../common/string/compare"; import { caseInsensitiveStringCompare } from "../../common/string/compare";
import { LocalizeFunc } from "../../common/translations/localize"; import { LocalizeFunc } from "../../common/translations/localize";
import "../../components/ha-icon-next"; import "../../components/ha-icon-next";
import "../../components/search-input"; import "../../components/search-input";
import { getConfigEntries } from "../../data/config_entries";
import { domainToName } from "../../data/integration"; 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 { HomeAssistant } from "../../types";
import { brandsUrl } from "../../util/brands-url"; import { brandsUrl } from "../../util/brands-url";
import { documentationUrl } from "../../util/documentation-url"; import { documentationUrl } from "../../util/documentation-url";
@ -36,7 +35,7 @@ interface HandlerObj {
is_helper?: boolean; is_helper?: boolean;
} }
interface SupportedBrandObj extends HandlerObj { export interface SupportedBrandObj extends HandlerObj {
supported_flows: string[]; supported_flows: string[];
} }
@ -300,79 +299,7 @@ class StepFlowPickHandler extends LitElement {
} }
private async _handleAddPicked(slug: string): Promise<void> { private async _handleAddPicked(slug: string): Promise<void> {
if (slug === "zwave_js") { await protocolIntegrationPicked(this, this.hass, slug);
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_zigbee",
{
integration: "Z-Wave",
supported_hardware_link: html`<a
href=${documentationUrl(this.hass, "/docs/z-wave/controllers")}
target="_blank"
rel="noreferrer"
>${this.hass.localize(
"ui.panel.config.integrations.config_flow.supported_hardware"
)}</a
>`,
}
),
confirmText: this.hass.localize(
"ui.panel.config.integrations.config_flow.proceed"
),
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_zwave_zigbee",
{
integration: "Zigbee",
supported_hardware_link: html`<a
href=${documentationUrl(
this.hass,
"/integrations/zha/#known-working-zigbee-radio-modules"
)}
target="_blank"
rel="noreferrer"
>${this.hass.localize(
"ui.panel.config.integrations.config_flow.supported_hardware"
)}</a
>`,
}
),
confirmText: this.hass.localize(
"ui.panel.config.integrations.config_flow.proceed"
),
confirm: () => {
fireEvent(this, "handler-picked", {
handler: "zha",
});
},
});
return;
}
navigate("/config/zha/add");
}
// This closes dialog. // This closes dialog.
fireEvent(this, "flow-update"); fireEvent(this, "flow-update");
} }

View File

@ -14,7 +14,8 @@ import { customElement, property, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined"; import { ifDefined } from "lit/directives/if-defined";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import type { HASSDomEvent } from "../../../common/dom/fire_event"; import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event";
import { protocolIntegrationPicked } from "../../../common/integrations/protocolIntegrationPicked";
import { navigate } from "../../../common/navigate"; import { navigate } from "../../../common/navigate";
import { caseInsensitiveStringCompare } from "../../../common/string/compare"; import { caseInsensitiveStringCompare } from "../../../common/string/compare";
import type { LocalizeFunc } from "../../../common/translations/localize"; import type { LocalizeFunc } from "../../../common/translations/localize";
@ -49,6 +50,10 @@ import {
fetchIntegrationManifests, fetchIntegrationManifests,
IntegrationManifest, IntegrationManifest,
} from "../../../data/integration"; } from "../../../data/integration";
import {
getSupportedBrands,
getSupportedBrandsLookup,
} from "../../../data/supported_brands";
import { scanUSBDevices } from "../../../data/usb"; import { scanUSBDevices } from "../../../data/usb";
import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-config-flow"; import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-config-flow";
import { import {
@ -677,49 +682,84 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
if (!domain) { if (!domain) {
return; return;
} }
const handlers = await getConfigFlowHandlers(this.hass, "integration"); const handlers = await getConfigFlowHandlers(this.hass, "integration");
if (!handlers.includes(domain)) { // Integration exists, so we can just create a flow
if (HELPER_DOMAINS.includes(domain)) { if (handlers.includes(domain)) {
navigate(`/config/helpers/add?domain=${domain}`, { const localize = await localizePromise;
replace: true, if (
}); !(await showConfirmationDialog(this, {
title: localize("ui.panel.config.integrations.confirm_new", {
integration: domainToName(localize, domain),
}),
}))
) {
return; return;
} }
const helpers = await getConfigFlowHandlers(this.hass, "helper"); showConfigFlowDialog(this, {
if (helpers.includes(domain)) { dialogClosedCallback: () => {
navigate(`/config/helpers/add?domain=${domain}`, { this._handleFlowUpdated();
replace: true, },
}); startFlowHandler: domain,
return; manifest: this._manifests[domain],
} showAdvanced: this.hass.userData?.showAdvanced,
showAlertDialog(this, { });
title: this.hass.localize( }
"ui.panel.config.integrations.config_flow.error"
), const supportedBrands = await getSupportedBrands(this.hass);
const supportedBrandsIntegrations =
getSupportedBrandsLookup(supportedBrands);
// Supported brand exists, so we can just create a flow
if (Object.keys(supportedBrandsIntegrations).includes(domain)) {
const brand = supportedBrandsIntegrations[domain];
const slug = brand.supported_flows![0];
showConfirmationDialog(this, {
text: this.hass.localize( text: this.hass.localize(
"ui.panel.config.integrations.config_flow.no_config_flow" "ui.panel.config.integrations.config_flow.supported_brand_flow",
{
supported_brand: brand.name,
flow_domain_name: domainToName(this.hass.localize, slug),
}
), ),
confirm: () => {
if (["zha", "zwave_js"].includes(slug)) {
protocolIntegrationPicked(this, this.hass, slug);
return;
}
fireEvent(this, "handler-picked", {
handler: slug,
});
},
});
return;
}
// If not an integration or supported brand, try helper else show alert
if (HELPER_DOMAINS.includes(domain)) {
navigate(`/config/helpers/add?domain=${domain}`, {
replace: true,
}); });
return; return;
} }
const localize = await localizePromise; const helpers = await getConfigFlowHandlers(this.hass, "helper");
if ( if (helpers.includes(domain)) {
!(await showConfirmationDialog(this, { navigate(`/config/helpers/add?domain=${domain}`, {
title: localize("ui.panel.config.integrations.confirm_new", { replace: true,
integration: domainToName(localize, domain), });
}),
}))
) {
return; return;
} }
showConfigFlowDialog(this, { showAlertDialog(this, {
dialogClosedCallback: () => { title: this.hass.localize(
this._handleFlowUpdated(); "ui.panel.config.integrations.config_flow.error"
}, ),
startFlowHandler: domain, text: this.hass.localize(
manifest: this._manifests[domain], "ui.panel.config.integrations.config_flow.no_config_flow"
showAdvanced: this.hass.userData?.showAdvanced, ),
}); });
} }