Only show assistants that are active (#16325)

* Only show assistants that are active

* also use in texts

* Add entity id

* Update ha-config-voice-assistants-expose.ts

* remove voiceAssistantKeys

* Update entity-voice-settings.ts

* update styling

* search case
This commit is contained in:
Bram Kragten 2023-04-26 18:15:10 +02:00 committed by GitHub
parent 3a2d7baa25
commit 3e2844a65a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 42 deletions

View File

@ -12,8 +12,6 @@ export const voiceAssistants = {
},
} as const;
export const voiceAssistantKeys = Object.keys(voiceAssistants);
export const setExposeNewEntities = (
hass: HomeAssistant,
assistant: string,

View File

@ -12,6 +12,7 @@ import {
computeEntityRegistryName,
ExtEntityRegistryEntry,
} from "../../../data/entity_registry";
import { voiceAssistants } from "../../../data/voice";
import { haStyle, haStyleDialog } from "../../../resources/styles";
import { HomeAssistant } from "../../../types";
import "./entity-voice-settings";
@ -43,19 +44,24 @@ class DialogExposeEntity extends LitElement {
return nothing;
}
const header = this.hass.localize(
"ui.panel.config.voice_assistants.expose.expose_dialog.header"
);
return html`
<ha-dialog
open
@closed=${this.closeDialog}
.heading=${this.hass.localize(
"ui.panel.config.voice_assistants.expose.expose_dialog.header"
)}
>
<ha-dialog open @closed=${this.closeDialog} .heading=${header}>
<div slot="heading">
<h2 class="header">
${this.hass.localize(
"ui.panel.config.voice_assistants.expose.expose_dialog.header"
)}
${header}<span class="subtitle"
>${this.hass.localize(
"ui.panel.config.voice_assistants.expose.expose_dialog.expose_to",
{
assistants: this._params.filterAssistants
.map((ass) => voiceAssistants[ass].name)
.join(", "),
}
)}</span
>
</h2>
<ha-icon-button
.label=${this.hass.localize("ui.dialogs.generic.close")}
@ -109,22 +115,27 @@ class DialogExposeEntity extends LitElement {
}
private _filterEntities = memoizeOne(
(RegEntries: Record<string, ExtEntityRegistryEntry>, filter?: string) =>
Object.values(RegEntries).filter(
(RegEntries: Record<string, ExtEntityRegistryEntry>, filter?: string) => {
const lowerFilter = filter?.toLowerCase();
return Object.values(RegEntries).filter(
(entity) =>
this._params!.filterAssistants.some(
(ass) => !entity.options?.[ass]?.should_expose
) &&
(!filter ||
entity.entity_id.includes(filter) ||
computeEntityRegistryName(this.hass!, entity)?.includes(filter))
)
(!lowerFilter ||
entity.entity_id.toLowerCase().includes(lowerFilter) ||
computeEntityRegistryName(this.hass!, entity)
?.toLowerCase()
.includes(lowerFilter))
);
}
);
private _renderItem = (entity: ExtEntityRegistryEntry) => {
const entityState = this.hass.states[entity.entity_id];
return html`<ha-check-list-item
graphic="icon"
twoLine
.value=${entity.entity_id}
.selected=${this._selected.includes(entity.entity_id)}
@request-selected=${this._handleSelected}
@ -135,6 +146,7 @@ class DialogExposeEntity extends LitElement {
.state=${entityState}
></ha-state-icon>
${computeEntityRegistryName(this.hass!, entity)}
<span slot="secondary">${entity.entity_id}</span>
</ha-check-list-item>`;
};
@ -151,6 +163,12 @@ class DialogExposeEntity extends LitElement {
ha-dialog {
--dialog-content-padding: 0;
}
@media all and (min-width: 600px) {
ha-dialog {
--mdc-dialog-min-width: 600px;
--mdc-dialog-max-height: 80%;
}
}
search-input {
width: 100%;
display: block;
@ -193,6 +211,13 @@ class DialogExposeEntity extends LitElement {
--mdc-dialog-scroll-divider-color,
rgba(0, 0, 0, 0.12)
);
display: flex;
flex-direction: column;
}
.subtitle {
color: var(--secondary-text-color);
font-size: 1rem;
line-height: normal;
}
.header_button {
position: absolute;

View File

@ -34,11 +34,7 @@ import {
GoogleEntity,
fetchCloudGoogleEntity,
} from "../../../data/google_assistant";
import {
exposeEntities,
voiceAssistantKeys,
voiceAssistants,
} from "../../../data/voice";
import { exposeEntities, voiceAssistants } from "../../../data/voice";
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import { haStyle } from "../../../resources/styles";
import type { HomeAssistant } from "../../../types";
@ -101,8 +97,8 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
this._cloudStatus?.logged_in === true &&
this._cloudStatus.prefs.alexa_enabled === true;
const showAssistants = [...voiceAssistantKeys];
const uiAssistants = [...voiceAssistantKeys];
const showAssistants = [...Object.keys(voiceAssistants)];
const uiAssistants = [...showAssistants];
const alexaManual =
alexaEnabled &&
@ -162,6 +158,7 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
</h3>
<ha-switch
@change=${this._toggleAll}
.assistants=${uiAssistants}
.checked=${anyExposed}
></ha-switch>
</ha-settings-row>
@ -288,7 +285,7 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
private async _toggleAll(ev) {
exposeEntities(
this.hass,
voiceAssistantKeys,
ev.target.assistants,
[this.entry.entity_id],
ev.target.checked
);

View File

@ -35,11 +35,7 @@ import {
ExtEntityRegistryEntry,
getExtendedEntityRegistryEntries,
} from "../../../data/entity_registry";
import {
exposeEntities,
voiceAssistantKeys,
voiceAssistants,
} from "../../../data/voice";
import { exposeEntities, voiceAssistants } from "../../../data/voice";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import "../../../layouts/hass-loading-screen";
import "../../../layouts/hass-tabs-subpage-data-table";
@ -98,7 +94,7 @@ export class VoiceAssistantsExpose extends LitElement {
);
private _columns = memoize(
(narrow, _language): DataTableColumnContainer => ({
(narrow, availableAssistants, _language): DataTableColumnContainer => ({
icon: {
title: "",
type: "icon",
@ -143,7 +139,7 @@ export class VoiceAssistantsExpose extends LitElement {
width: "160px",
type: "flex",
template: (assistants, entry) =>
html`${voiceAssistantKeys.map((key) =>
html`${availableAssistants.map((key) =>
assistants.includes(key)
? html`<div>
<img
@ -221,6 +217,32 @@ export class VoiceAssistantsExpose extends LitElement {
})
);
private _availableAssistants = memoize(
(cloudStatus: CloudStatus | undefined) => {
const googleEnabled =
cloudStatus?.logged_in === true &&
cloudStatus.prefs.google_enabled === true;
const alexaEnabled =
cloudStatus?.logged_in === true &&
cloudStatus.prefs.alexa_enabled === true;
const showAssistants = [...Object.keys(voiceAssistants)];
if (!googleEnabled) {
showAssistants.splice(
showAssistants.indexOf("cloud.google_assistant"),
1
);
}
if (!alexaEnabled) {
showAssistants.splice(showAssistants.indexOf("cloud.alexa"), 1);
}
return showAssistants;
}
);
private _filteredEntities = memoize(
(
entities: HomeAssistant["entities"],
@ -237,7 +259,7 @@ export class VoiceAssistantsExpose extends LitElement {
cloudStatus?.logged_in === true &&
cloudStatus.prefs.alexa_enabled === true;
const showAssistants = [...voiceAssistantKeys];
const showAssistants = [...this._availableAssistants(cloudStatus)];
const alexaManual =
alexaEnabled &&
@ -250,14 +272,14 @@ export class VoiceAssistantsExpose extends LitElement {
(this.cloudStatus as CloudStatusLoggedIn).google_entities
);
if (!googleEnabled || googleManual) {
if (googleManual) {
showAssistants.splice(
showAssistants.indexOf("cloud.google_assistant"),
1
);
}
if (!alexaEnabled || alexaManual) {
if (alexaManual) {
showAssistants.splice(showAssistants.indexOf("cloud.alexa"), 1);
}
@ -438,7 +460,11 @@ export class VoiceAssistantsExpose extends LitElement {
: "/config"}
.route=${this.route}
.tabs=${voiceAssistantTabs}
.columns=${this._columns(this.narrow, this.hass.language)}
.columns=${this._columns(
this.narrow,
this._availableAssistants(this.cloudStatus),
this.hass.language
)}
.data=${filteredEntities}
.activeFilters=${activeFilters}
.numHidden=${this._numHiddenEntities}
@ -541,7 +567,7 @@ export class VoiceAssistantsExpose extends LitElement {
private _addEntry() {
const assistants = this._searchParms.has("assistants")
? this._searchParms.get("assistants")!.split(",")
: voiceAssistantKeys;
: this._availableAssistants(this.cloudStatus);
showExposeEntityDialog(this, {
filterAssistants: assistants,
extendedEntities: this._extEntities!,
@ -567,14 +593,14 @@ export class VoiceAssistantsExpose extends LitElement {
const entityId = ev.currentTarget.closest(".mdc-data-table__row").rowId;
const assistants = this._searchParms.has("assistants")
? this._searchParms.get("assistants")!.split(",")
: voiceAssistantKeys;
: this._availableAssistants(this.cloudStatus);
exposeEntities(this.hass, assistants, [entityId], false);
};
private _unexposeSelected() {
const assistants = this._searchParms.has("assistants")
? this._searchParms.get("assistants")!.split(",")
: voiceAssistantKeys;
: this._availableAssistants(this.cloudStatus);
showConfirmationDialog(this, {
title: this.hass.localize(
"ui.panel.config.voice_assistants.expose.unexpose_confirm_title"
@ -602,7 +628,7 @@ export class VoiceAssistantsExpose extends LitElement {
private _exposeSelected() {
const assistants = this._searchParms.has("assistants")
? this._searchParms.get("assistants")!.split(",")
: voiceAssistantKeys;
: this._availableAssistants(this.cloudStatus);
showConfirmationDialog(this, {
title: this.hass.localize(
"ui.panel.config.voice_assistants.expose.expose_confirm_title"

View File

@ -2106,7 +2106,8 @@
"unexpose_confirm_title": "Stop exposing selected entities?",
"unexpose_confirm_text": "Do you want to stop exposing {entities} entities to {assistants}?",
"expose_dialog": {
"header": "Expose entity",
"header": "Expose entities",
"expose_to": "to {assistants}",
"expose_entities": "Expose {count} {count, plural,\n one {entity}\n other {entities}\n}"
}
}