mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Improve protocol integration add device / integration (#16767)
This commit is contained in:
parent
e044ddcb57
commit
10ee8fda5b
@ -17,7 +17,7 @@ export const protocolIntegrationPicked = async (
|
|||||||
element: HTMLElement,
|
element: HTMLElement,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
domain: string,
|
domain: string,
|
||||||
options?: { brand?: string; domain?: string }
|
options?: { brand?: string; domain?: string; config_entry?: string }
|
||||||
) => {
|
) => {
|
||||||
if (options?.domain) {
|
if (options?.domain) {
|
||||||
const localize = await hass.loadBackendTranslation("title", options.domain);
|
const localize = await hass.loadBackendTranslation("title", options.domain);
|
||||||
@ -32,11 +32,16 @@ export const protocolIntegrationPicked = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (domain === "zwave_js") {
|
if (domain === "zwave_js") {
|
||||||
const entries = await getConfigEntries(hass, {
|
const entries = options?.config_entry
|
||||||
domain,
|
? undefined
|
||||||
});
|
: await getConfigEntries(hass, {
|
||||||
|
domain,
|
||||||
|
});
|
||||||
|
|
||||||
if (!isComponentLoaded(hass, "zwave_js") || !entries.length) {
|
if (
|
||||||
|
!isComponentLoaded(hass, "zwave_js") ||
|
||||||
|
(!options?.config_entry && !entries?.length)
|
||||||
|
) {
|
||||||
// If the component isn't loaded, ask them to load the integration first
|
// If the component isn't loaded, ask them to load the integration first
|
||||||
showConfirmationDialog(element, {
|
showConfirmationDialog(element, {
|
||||||
title: hass.localize(
|
title: hass.localize(
|
||||||
@ -71,14 +76,19 @@ export const protocolIntegrationPicked = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
showZWaveJSAddNodeDialog(element, {
|
showZWaveJSAddNodeDialog(element, {
|
||||||
entry_id: entries[0].entry_id,
|
entry_id: options?.config_entry || entries![0].entry_id,
|
||||||
});
|
});
|
||||||
} else if (domain === "zha") {
|
} else if (domain === "zha") {
|
||||||
const entries = await getConfigEntries(hass, {
|
const entries = options?.config_entry
|
||||||
domain,
|
? undefined
|
||||||
});
|
: await getConfigEntries(hass, {
|
||||||
|
domain,
|
||||||
|
});
|
||||||
|
|
||||||
if (!isComponentLoaded(hass, "zha") || !entries.length) {
|
if (
|
||||||
|
!isComponentLoaded(hass, "zha") ||
|
||||||
|
(!options?.config_entry && !entries?.length)
|
||||||
|
) {
|
||||||
// If the component isn't loaded, ask them to load the integration first
|
// If the component isn't loaded, ask them to load the integration first
|
||||||
showConfirmationDialog(element, {
|
showConfirmationDialog(element, {
|
||||||
title: hass.localize(
|
title: hass.localize(
|
||||||
@ -117,10 +127,15 @@ export const protocolIntegrationPicked = async (
|
|||||||
|
|
||||||
navigate("/config/zha/add");
|
navigate("/config/zha/add");
|
||||||
} else if (domain === "matter") {
|
} else if (domain === "matter") {
|
||||||
const entries = await getConfigEntries(hass, {
|
const entries = options?.config_entry
|
||||||
domain,
|
? undefined
|
||||||
});
|
: await getConfigEntries(hass, {
|
||||||
if (!isComponentLoaded(hass, domain) || !entries.length) {
|
domain,
|
||||||
|
});
|
||||||
|
if (
|
||||||
|
!isComponentLoaded(hass, domain) ||
|
||||||
|
(!options?.config_entry && !entries?.length)
|
||||||
|
) {
|
||||||
// If the component isn't loaded, ask them to load the integration first
|
// If the component isn't loaded, ask them to load the integration first
|
||||||
showConfirmationDialog(element, {
|
showConfirmationDialog(element, {
|
||||||
title: hass.localize(
|
title: hass.localize(
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
||||||
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
|
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
|
||||||
import { mdiCancel, mdiFilterVariant, mdiPlus } from "@mdi/js";
|
import { mdiCancel, mdiFilterVariant, mdiPlus } from "@mdi/js";
|
||||||
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||||
|
import {
|
||||||
|
protocolIntegrationPicked,
|
||||||
|
PROTOCOL_INTEGRATIONS,
|
||||||
|
} from "../../../common/integrations/protocolIntegrationPicked";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
|
import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
|
||||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||||
@ -39,8 +43,6 @@ import { HomeAssistant, Route } from "../../../types";
|
|||||||
import { brandsUrl } from "../../../util/brands-url";
|
import { brandsUrl } from "../../../util/brands-url";
|
||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import "../integrations/ha-integration-overflow-menu";
|
import "../integrations/ha-integration-overflow-menu";
|
||||||
import { showMatterAddDeviceDialog } from "../integrations/integration-panels/matter/show-dialog-add-matter-device";
|
|
||||||
import { showZWaveJSAddNodeDialog } from "../integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node";
|
|
||||||
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
|
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
|
||||||
|
|
||||||
interface DeviceRowData extends DeviceRegistryEntry {
|
interface DeviceRowData extends DeviceRegistryEntry {
|
||||||
@ -186,6 +188,8 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
|
|
||||||
let filterConfigEntry: ConfigEntry | undefined;
|
let filterConfigEntry: ConfigEntry | undefined;
|
||||||
|
|
||||||
|
const filteredDomains = new Set<string>();
|
||||||
|
|
||||||
filters.forEach((value, key) => {
|
filters.forEach((value, key) => {
|
||||||
if (key === "config_entry") {
|
if (key === "config_entry") {
|
||||||
outputDevices = outputDevices.filter((device) =>
|
outputDevices = outputDevices.filter((device) =>
|
||||||
@ -193,6 +197,9 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
);
|
);
|
||||||
startLength = outputDevices.length;
|
startLength = outputDevices.length;
|
||||||
filterConfigEntry = entries.find((entry) => entry.entry_id === value);
|
filterConfigEntry = entries.find((entry) => entry.entry_id === value);
|
||||||
|
if (filterConfigEntry) {
|
||||||
|
filteredDomains.add(filterConfigEntry.domain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (key === "domain") {
|
if (key === "domain") {
|
||||||
const entryIds = entries
|
const entryIds = entries
|
||||||
@ -202,6 +209,7 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
device.config_entries.some((entryId) => entryIds.includes(entryId))
|
device.config_entries.some((entryId) => entryIds.includes(entryId))
|
||||||
);
|
);
|
||||||
startLength = outputDevices.length;
|
startLength = outputDevices.length;
|
||||||
|
filteredDomains.add(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -251,6 +259,7 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
return {
|
return {
|
||||||
devicesOutput: outputDevices,
|
devicesOutput: outputDevices,
|
||||||
filteredConfigEntry: filterConfigEntry,
|
filteredConfigEntry: filterConfigEntry,
|
||||||
|
filteredDomains,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -546,25 +555,25 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _addDevice() {
|
private _addDevice() {
|
||||||
const { filteredConfigEntry } = this._devicesAndFilterDomains(
|
const { filteredConfigEntry, filteredDomains } =
|
||||||
this.devices,
|
this._devicesAndFilterDomains(
|
||||||
this.entries,
|
this.devices,
|
||||||
this.entities,
|
this.entries,
|
||||||
this.areas,
|
this.entities,
|
||||||
this._searchParms,
|
this.areas,
|
||||||
this._showDisabled,
|
this._searchParms,
|
||||||
this.hass.localize
|
this._showDisabled,
|
||||||
);
|
this.hass.localize
|
||||||
if (filteredConfigEntry?.domain === "zha") {
|
);
|
||||||
navigate(`/config/zha/add`);
|
if (
|
||||||
return;
|
filteredDomains.size === 1 &&
|
||||||
}
|
(PROTOCOL_INTEGRATIONS as ReadonlyArray<string>).includes(
|
||||||
if (filteredConfigEntry?.domain === "zwave_js") {
|
[...filteredDomains][0]
|
||||||
this._showZJSAddDeviceDialog(filteredConfigEntry);
|
)
|
||||||
return;
|
) {
|
||||||
}
|
protocolIntegrationPicked(this, this.hass, [...filteredDomains][0], {
|
||||||
if (filteredConfigEntry?.domain === "matter") {
|
config_entry: filteredConfigEntry?.entry_id,
|
||||||
showMatterAddDeviceDialog(this);
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
showAddIntegrationDialog(this, {
|
showAddIntegrationDialog(this, {
|
||||||
@ -572,12 +581,6 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showZJSAddDeviceDialog(filteredConfigEntry: ConfigEntry) {
|
|
||||||
showZWaveJSAddNodeDialog(this, {
|
|
||||||
entry_id: filteredConfigEntry!.entry_id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
css`
|
css`
|
||||||
|
@ -67,6 +67,11 @@ import { haStyle } from "../../../resources/styles";
|
|||||||
import type { HomeAssistant, Route } from "../../../types";
|
import type { HomeAssistant, Route } from "../../../types";
|
||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import "../integrations/ha-integration-overflow-menu";
|
import "../integrations/ha-integration-overflow-menu";
|
||||||
|
import {
|
||||||
|
protocolIntegrationPicked,
|
||||||
|
PROTOCOL_INTEGRATIONS,
|
||||||
|
} from "../../../common/integrations/protocolIntegrationPicked";
|
||||||
|
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
|
||||||
|
|
||||||
export interface StateEntity
|
export interface StateEntity
|
||||||
extends Omit<EntityRegistryEntry, "id" | "unique_id"> {
|
extends Omit<EntityRegistryEntry, "id" | "unique_id"> {
|
||||||
@ -348,7 +353,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
? entities.concat(stateEntities)
|
? entities.concat(stateEntities)
|
||||||
: entities;
|
: entities;
|
||||||
|
|
||||||
const filteredDomains: string[] = [];
|
let filteredConfigEntry: ConfigEntry | undefined;
|
||||||
|
const filteredDomains = new Set<string>();
|
||||||
|
|
||||||
filters.forEach((value, key) => {
|
filters.forEach((value, key) => {
|
||||||
if (key === "config_entry") {
|
if (key === "config_entry") {
|
||||||
@ -373,7 +379,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
const configEntry = entries.find((entry) => entry.entry_id === value);
|
const configEntry = entries.find((entry) => entry.entry_id === value);
|
||||||
|
|
||||||
if (configEntry) {
|
if (configEntry) {
|
||||||
filteredDomains.push(configEntry.domain);
|
filteredDomains.add(configEntry.domain);
|
||||||
|
filteredConfigEntry = configEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (key === "domain") {
|
if (key === "domain") {
|
||||||
@ -389,7 +396,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
entity.config_entry_id &&
|
entity.config_entry_id &&
|
||||||
entryIds.includes(entity.config_entry_id)
|
entryIds.includes(entity.config_entry_id)
|
||||||
);
|
);
|
||||||
filteredDomains.push(value);
|
filteredDomains.add(value);
|
||||||
startLength = filteredEntities.length;
|
startLength = filteredEntities.length;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -444,7 +451,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._numHiddenEntities = startLength - result.length;
|
this._numHiddenEntities = startLength - result.length;
|
||||||
return { filteredEntities: result, filteredDomains: filteredDomains };
|
return { filteredEntities: result, filteredConfigEntry, filteredDomains };
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -509,7 +516,11 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
this._entries
|
this._entries
|
||||||
);
|
);
|
||||||
|
|
||||||
const includeZHAFab = filteredDomains.includes("zha");
|
const includeAddDeviceFab =
|
||||||
|
filteredDomains.size === 1 &&
|
||||||
|
(PROTOCOL_INTEGRATIONS as ReadonlyArray<string>).includes(
|
||||||
|
[...filteredDomains][0]
|
||||||
|
);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage-data-table
|
<hass-tabs-subpage-data-table
|
||||||
@ -545,7 +556,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
@search-changed=${this._handleSearchChange}
|
@search-changed=${this._handleSearchChange}
|
||||||
@row-click=${this._openEditEntry}
|
@row-click=${this._openEditEntry}
|
||||||
id="entity_id"
|
id="entity_id"
|
||||||
.hasFab=${includeZHAFab}
|
.hasFab=${includeAddDeviceFab}
|
||||||
>
|
>
|
||||||
<ha-integration-overflow-menu
|
<ha-integration-overflow-menu
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -701,16 +712,16 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
</ha-check-list-item>
|
</ha-check-list-item>
|
||||||
</ha-button-menu>
|
</ha-button-menu>
|
||||||
`}
|
`}
|
||||||
${includeZHAFab
|
${includeAddDeviceFab
|
||||||
? html`<a href="/config/zha/add" slot="fab">
|
? html`<ha-fab
|
||||||
<ha-fab
|
.label=${this.hass.localize("ui.panel.config.devices.add_device")}
|
||||||
.label=${this.hass.localize("ui.panel.config.zha.add_device")}
|
extended
|
||||||
extended
|
@click=${this._addDevice}
|
||||||
?rtl=${computeRTL(this.hass)}
|
slot="fab"
|
||||||
>
|
?rtl=${computeRTL(this.hass)}
|
||||||
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
>
|
||||||
</ha-fab>
|
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
||||||
</a>`
|
</ha-fab>`
|
||||||
: nothing}
|
: nothing}
|
||||||
</hass-tabs-subpage-data-table>
|
</hass-tabs-subpage-data-table>
|
||||||
`;
|
`;
|
||||||
@ -959,6 +970,36 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
this._showHidden = true;
|
this._showHidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _addDevice() {
|
||||||
|
const { filteredConfigEntry, filteredDomains } =
|
||||||
|
this._filteredEntitiesAndDomains(
|
||||||
|
this._entities!,
|
||||||
|
this._devices,
|
||||||
|
this._areas,
|
||||||
|
this._stateEntities,
|
||||||
|
this._searchParms,
|
||||||
|
this._showDisabled,
|
||||||
|
this._showUnavailable,
|
||||||
|
this._showReadOnly,
|
||||||
|
this._showHidden,
|
||||||
|
this._entries
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
filteredDomains.size === 1 &&
|
||||||
|
(PROTOCOL_INTEGRATIONS as ReadonlyArray<string>).includes(
|
||||||
|
[...filteredDomains][0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
protocolIntegrationPicked(this, this.hass, [...filteredDomains][0], {
|
||||||
|
config_entry: filteredConfigEntry?.entry_id,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showAddIntegrationDialog(this, {
|
||||||
|
domain: this._searchParms.get("domain") || undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -427,13 +427,13 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
<ha-card>
|
<ha-card>
|
||||||
<h1 class="card-header">
|
<h1 class="card-header">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
`ui.panel.config.integrations.integration_page.entries`
|
"ui.panel.config.integrations.integration_page.entries"
|
||||||
)}
|
)}
|
||||||
</h1>
|
</h1>
|
||||||
${normalEntries.length === 0
|
${normalEntries.length === 0
|
||||||
? html`<div class="card-content no-entries">
|
? html`<div class="card-content no-entries">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
`ui.panel.config.integrations.integration_page.no_entries`
|
"ui.panel.config.integrations.integration_page.no_entries"
|
||||||
)}
|
)}
|
||||||
</div>`
|
</div>`
|
||||||
: nothing}
|
: nothing}
|
||||||
@ -446,7 +446,10 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
<ha-fab
|
<ha-fab
|
||||||
slot="fab"
|
slot="fab"
|
||||||
@click=${this._addIntegration}
|
@click=${this._addIntegration}
|
||||||
.label=${`Add ${domainToName(this.hass.localize, this.domain)}`}
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.integrations.integration_page.add",
|
||||||
|
{ integration: domainToName(this.hass.localize, this.domain) }
|
||||||
|
)}
|
||||||
extended
|
extended
|
||||||
>
|
>
|
||||||
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
||||||
|
@ -3252,7 +3252,8 @@
|
|||||||
"integration_page": {
|
"integration_page": {
|
||||||
"entries": "Integration entries",
|
"entries": "Integration entries",
|
||||||
"no_entries": "No entries",
|
"no_entries": "No entries",
|
||||||
"attention_entries": "Needs attention"
|
"attention_entries": "Needs attention",
|
||||||
|
"add": "Add {integration}"
|
||||||
},
|
},
|
||||||
"config_entry": {
|
"config_entry": {
|
||||||
"application_credentials": {
|
"application_credentials": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user