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; } as const;
export const voiceAssistantKeys = Object.keys(voiceAssistants);
export const setExposeNewEntities = ( export const setExposeNewEntities = (
hass: HomeAssistant, hass: HomeAssistant,
assistant: string, assistant: string,

View File

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

View File

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

View File

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

View File

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