diff --git a/src/components/ha-conversation-agent-picker.ts b/src/components/ha-conversation-agent-picker.ts index 0e3e66fbcc..2208b1555e 100644 --- a/src/components/ha-conversation-agent-picker.ts +++ b/src/components/ha-conversation-agent-picker.ts @@ -17,6 +17,7 @@ import "./ha-select"; import type { HaSelect } from "./ha-select"; const NONE = "__NONE_OPTION__"; + @customElement("ha-conversation-agent-picker") export class HaConversationAgentPicker extends LitElement { @property() public value?: string; @@ -43,7 +44,7 @@ export class HaConversationAgentPicker extends LitElement { (!this.language || this._agents .find((agent) => agent.id === "homeassistant") - ?.supported_languages?.includes(this.language)) + ?.supported_languages.includes(this.language)) ? "homeassistant" : NONE); return html` @@ -71,7 +72,8 @@ export class HaConversationAgentPicker extends LitElement { (agent) => html` ${agent.name} ` @@ -110,7 +112,11 @@ export class HaConversationAgentPicker extends LitElement { value: selectedAgent?.supported_languages, }); - if (!selectedAgent || selectedAgent.supported_languages?.length === 0) { + if ( + !selectedAgent || + (selectedAgent.supported_languages !== "*" && + selectedAgent.supported_languages.length === 0) + ) { this.value = undefined; fireEvent(this, "value-changed", { value: this.value }); } @@ -148,6 +154,6 @@ declare global { "ha-conversation-agent-picker": HaConversationAgentPicker; } interface HASSDomEvents { - "supported-languages-changed": { value: string[] | undefined }; + "supported-languages-changed": { value: "*" | string[] | undefined }; } } diff --git a/src/components/ha-language-picker.ts b/src/components/ha-language-picker.ts index 49c5b419bb..ac8a11579d 100644 --- a/src/components/ha-language-picker.ts +++ b/src/components/ha-language-picker.ts @@ -27,6 +27,8 @@ export class HaLanguagePicker extends LitElement { @property({ type: Boolean }) public nativeName = false; + @property({ type: Boolean }) public noSort = false; + @state() _defaultLanguages: string[] = []; @query("ha-select") private _select!: HaSelect; @@ -77,9 +79,11 @@ export class HaLanguagePicker extends LitElement { })); } - options.sort((a, b) => - caseInsensitiveStringCompare(a.label, b.label, locale.language) - ); + if (!this.noSort) { + options.sort((a, b) => + caseInsensitiveStringCompare(a.label, b.label, locale.language) + ); + } return options; } ); diff --git a/src/components/ha-selector/ha-selector-language.ts b/src/components/ha-selector/ha-selector-language.ts index b9b76362d6..79b6dc69f2 100644 --- a/src/components/ha-selector/ha-selector-language.ts +++ b/src/components/ha-selector/ha-selector-language.ts @@ -29,6 +29,7 @@ export class HaLanguageSelector extends LitElement { .helper=${this.helper} .languages=${this.selector.language?.languages} .nativeName=${Boolean(this.selector?.language?.native_name)} + .noSort=${Boolean(this.selector?.language?.no_sort)} .disabled=${this.disabled} .required=${this.required} > diff --git a/src/components/ha-tts-voice-picker.ts b/src/components/ha-tts-voice-picker.ts index ace393379d..ce4830df64 100644 --- a/src/components/ha-tts-voice-picker.ts +++ b/src/components/ha-tts-voice-picker.ts @@ -6,7 +6,7 @@ import { nothing, PropertyValues, } from "lit"; -import { customElement, property, state } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; import { stopPropagation } from "../common/dom/stop_propagation"; import { debounce } from "../common/util/debounce"; @@ -36,6 +36,8 @@ export class HaTTSVoicePicker extends LitElement { @state() _voices?: TTSVoice[] | null; + @query("ha-select") private _select!: HaSelect; + protected render() { if (!this._voices) { return nothing; @@ -104,6 +106,14 @@ export class HaTTSVoicePicker extends LitElement { } } + protected updated(changedProperties: PropertyValues) { + super.updated(changedProperties); + if (changedProperties.has("_voices") && this._select.value !== this.value) { + this._select.layoutOptions(); + fireEvent(this, "value-changed", { value: this._select.value }); + } + } + static get styles(): CSSResultGroup { return css` ha-select { diff --git a/src/data/conversation.ts b/src/data/conversation.ts index f8427f779d..a51006a562 100644 --- a/src/data/conversation.ts +++ b/src/data/conversation.ts @@ -59,7 +59,7 @@ export interface AgentInfo { export interface Agent { id: string; name: string; - supported_languages?: string[]; + supported_languages: "*" | string[]; } export const processConversationInput = ( diff --git a/src/data/selector.ts b/src/data/selector.ts index 3376191bed..fcfa1ac983 100644 --- a/src/data/selector.ts +++ b/src/data/selector.ts @@ -215,6 +215,7 @@ export interface LanguageSelector { language: { languages?: string[]; native_name?: boolean; + no_sort?: boolean; } | null; } diff --git a/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-conversation.ts b/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-conversation.ts index 4fc2c49610..6f75b38aa5 100644 --- a/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-conversation.ts +++ b/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-conversation.ts @@ -5,6 +5,7 @@ import { LocalizeKeys } from "../../../../common/translations/localize"; import { AssistPipeline } from "../../../../data/assist_pipeline"; import { HomeAssistant } from "../../../../types"; import "../../../../components/ha-form/ha-form"; +import { fireEvent } from "../../../../common/dom/fire_event"; @customElement("assist-pipeline-detail-conversation") export class AssistPipelineDetailConversation extends LitElement { @@ -12,10 +13,10 @@ export class AssistPipelineDetailConversation extends LitElement { @property() public data?: Partial; - @state() private _supportedLanguages?: string[]; + @state() private _supportedLanguages?: "*" | string[]; private _schema = memoizeOne( - (language?: string, supportedLanguages?: string[]) => + (language?: string, supportedLanguages?: "*" | string[]) => [ { name: "", @@ -30,12 +31,12 @@ export class AssistPipelineDetailConversation extends LitElement { }, }, }, - supportedLanguages?.length + supportedLanguages !== "*" && supportedLanguages?.length ? { name: "conversation_language", required: true, selector: { - language: { languages: supportedLanguages }, + language: { languages: supportedLanguages, no_sort: true }, }, } : { name: "", type: "constant" }, @@ -73,6 +74,14 @@ export class AssistPipelineDetailConversation extends LitElement { } private _supportedLanguagesChanged(ev) { + if (ev.detail.value === "*") { + // wait for update of conversation_engine + setTimeout(() => { + const value = { ...this.data }; + value.conversation_language = "*"; + fireEvent(this, "value-changed", { value }); + }, 0); + } this._supportedLanguages = ev.detail.value; } diff --git a/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-stt.ts b/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-stt.ts index e0f9fad801..deb5c603c3 100644 --- a/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-stt.ts +++ b/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-stt.ts @@ -34,7 +34,7 @@ export class AssistPipelineDetailSTT extends LitElement { name: "stt_language", required: true, selector: { - language: { languages: supportedLanguages }, + language: { languages: supportedLanguages, no_sort: true }, }, } : { name: "", type: "constant" }, diff --git a/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-tts.ts b/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-tts.ts index 605600176c..be72b4913f 100644 --- a/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-tts.ts +++ b/src/panels/config/voice-assistants/assist-pipeline-detail/assist-pipeline-detail-tts.ts @@ -34,7 +34,7 @@ export class AssistPipelineDetailTTS extends LitElement { name: "tts_language", required: true, selector: { - language: { languages: supportedLanguages }, + language: { languages: supportedLanguages, no_sort: true }, }, } : { name: "", type: "constant" }, diff --git a/src/panels/profile/ha-pick-language-row.ts b/src/panels/profile/ha-pick-language-row.ts index d33eb48941..1ee3074b09 100644 --- a/src/panels/profile/ha-pick-language-row.ts +++ b/src/panels/profile/ha-pick-language-row.ts @@ -44,7 +44,7 @@ export class HaPickLanguageRow extends LitElement { // Only fire event if language was changed. This prevents select updates when // responding to hass changes. if (ev.detail.value !== this.hass.language) { - fireEvent(this, "hass-language-select", ev.target.value); + fireEvent(this, "hass-language-select", ev.detail.value); } }