mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-27 14:57:20 +00:00
Add support for Supported Brands (#13184)
This commit is contained in:
parent
24e54554ad
commit
b611a58fce
8
src/data/supported_brands.ts
Normal file
8
src/data/supported_brands.ts
Normal 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",
|
||||||
|
});
|
@ -7,6 +7,7 @@ import {
|
|||||||
handleConfigFlowStep,
|
handleConfigFlowStep,
|
||||||
} from "../../data/config_flow";
|
} from "../../data/config_flow";
|
||||||
import { domainToName } from "../../data/integration";
|
import { domainToName } from "../../data/integration";
|
||||||
|
import { getSupportedBrands } from "../../data/supported_brands";
|
||||||
import {
|
import {
|
||||||
DataEntryFlowDialogParams,
|
DataEntryFlowDialogParams,
|
||||||
loadDataEntryFlowDialog,
|
loadDataEntryFlowDialog,
|
||||||
@ -22,12 +23,14 @@ export const showConfigFlowDialog = (
|
|||||||
showFlowDialog(element, dialogParams, {
|
showFlowDialog(element, dialogParams, {
|
||||||
loadDevicesAndAreas: true,
|
loadDevicesAndAreas: true,
|
||||||
getFlowHandlers: async (hass) => {
|
getFlowHandlers: async (hass) => {
|
||||||
const [integrations, helpers] = await Promise.all([
|
const [integrations, helpers, supportedBrands] = await Promise.all([
|
||||||
getConfigFlowHandlers(hass, "integration"),
|
getConfigFlowHandlers(hass, "integration"),
|
||||||
getConfigFlowHandlers(hass, "helper"),
|
getConfigFlowHandlers(hass, "helper"),
|
||||||
|
getSupportedBrands(hass),
|
||||||
hass.loadBackendTranslation("title", undefined, true),
|
hass.loadBackendTranslation("title", undefined, true),
|
||||||
]);
|
]);
|
||||||
return { integrations, helpers };
|
|
||||||
|
return { integrations, helpers, supportedBrands };
|
||||||
},
|
},
|
||||||
createFlow: async (hass, handler) => {
|
createFlow: async (hass, handler) => {
|
||||||
const [step] = await Promise.all([
|
const [step] = await Promise.all([
|
||||||
|
@ -10,12 +10,14 @@ import {
|
|||||||
DataEntryFlowStepMenu,
|
DataEntryFlowStepMenu,
|
||||||
DataEntryFlowStepProgress,
|
DataEntryFlowStepProgress,
|
||||||
} from "../../data/data_entry_flow";
|
} from "../../data/data_entry_flow";
|
||||||
import { IntegrationManifest } from "../../data/integration";
|
import type { IntegrationManifest } from "../../data/integration";
|
||||||
import { HomeAssistant } from "../../types";
|
import type { SupportedBrandHandler } from "../../data/supported_brands";
|
||||||
|
import type { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
export interface FlowHandlers {
|
export interface FlowHandlers {
|
||||||
integrations: string[];
|
integrations: string[];
|
||||||
helpers: string[];
|
helpers: string[];
|
||||||
|
supportedBrands: Record<string, SupportedBrandHandler>;
|
||||||
}
|
}
|
||||||
export interface FlowConfig {
|
export interface FlowConfig {
|
||||||
loadDevicesAndAreas: boolean;
|
loadDevicesAndAreas: boolean;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import "@polymer/paper-item";
|
import "@polymer/paper-item";
|
||||||
import "@polymer/paper-item/paper-icon-item";
|
import "@polymer/paper-item/paper-icon-item";
|
||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
import "@polymer/paper-item/paper-item-body";
|
import "@polymer/paper-item/paper-item-body";
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
|
@ -15,18 +15,19 @@ 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 { navigate } from "../../common/navigate";
|
import { navigate } from "../../common/navigate";
|
||||||
import "../../components/search-input";
|
|
||||||
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 { getConfigEntries } from "../../data/config_entries";
|
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 { 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";
|
||||||
import { configFlowContentStyles } from "./styles";
|
import { showConfirmationDialog } from "../generic/show-dialog-box";
|
||||||
import { FlowHandlers } from "./show-dialog-data-entry-flow";
|
import { FlowHandlers } from "./show-dialog-data-entry-flow";
|
||||||
|
import { configFlowContentStyles } from "./styles";
|
||||||
|
|
||||||
interface HandlerObj {
|
interface HandlerObj {
|
||||||
name: string;
|
name: string;
|
||||||
@ -35,6 +36,10 @@ interface HandlerObj {
|
|||||||
is_helper?: boolean;
|
is_helper?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SupportedBrandObj extends HandlerObj {
|
||||||
|
supported_flows: string[];
|
||||||
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
// for fire event
|
// for fire event
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
@ -63,11 +68,22 @@ class StepFlowPickHandler extends LitElement {
|
|||||||
h: FlowHandlers,
|
h: FlowHandlers,
|
||||||
filter?: string,
|
filter?: string,
|
||||||
_localize?: LocalizeFunc
|
_localize?: LocalizeFunc
|
||||||
): [HandlerObj[], HandlerObj[]] => {
|
): [(HandlerObj | SupportedBrandObj)[], HandlerObj[]] => {
|
||||||
const integrations: HandlerObj[] = h.integrations.map((handler) => ({
|
const integrations: (HandlerObj | SupportedBrandObj)[] =
|
||||||
name: domainToName(this.hass.localize, handler),
|
h.integrations.map((handler) => ({
|
||||||
slug: 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) {
|
if (filter) {
|
||||||
const options: Fuse.IFuseOptions<HandlerObj> = {
|
const options: Fuse.IFuseOptions<HandlerObj> = {
|
||||||
@ -238,27 +254,10 @@ class StepFlowPickHandler extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _handlerPicked(ev) {
|
private async _handlerPicked(ev) {
|
||||||
const handler: HandlerObj = ev.currentTarget.handler;
|
const handler: HandlerObj | SupportedBrandObj = ev.currentTarget.handler;
|
||||||
|
|
||||||
if (handler.is_add) {
|
if (handler.is_add) {
|
||||||
if (handler.slug === "zwave_js") {
|
this._handleAddPicked(handler.slug);
|
||||||
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");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,11 +268,84 @@ class StepFlowPickHandler extends LitElement {
|
|||||||
return;
|
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", {
|
fireEvent(this, "handler-picked", {
|
||||||
handler: handler.slug,
|
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) {
|
private _maybeSubmit(ev: KeyboardEvent) {
|
||||||
if (ev.key !== "Enter") {
|
if (ev.key !== "Enter") {
|
||||||
return;
|
return;
|
||||||
|
@ -2850,7 +2850,10 @@
|
|||||||
"error": "Error",
|
"error": "Error",
|
||||||
"could_not_load": "Config flow could not be loaded",
|
"could_not_load": "Config flow could not be loaded",
|
||||||
"not_loaded": "The integration could not be loaded, try to restart Home Assistant.",
|
"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": {
|
"users": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user