mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-22 00:36:34 +00:00
Add pipeline picker/selector (#16224)
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
This commit is contained in:
parent
be005b4c88
commit
088cc69083
107
src/components/ha-assist-pipeline-picker.ts
Normal file
107
src/components/ha-assist-pipeline-picker.ts
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResultGroup,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
nothing,
|
||||||
|
PropertyValueMap,
|
||||||
|
} from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
|
import { stopPropagation } from "../common/dom/stop_propagation";
|
||||||
|
import { AssistPipeline, fetchAssistPipelines } from "../data/assist_pipeline";
|
||||||
|
import { HomeAssistant } from "../types";
|
||||||
|
import "./ha-list-item";
|
||||||
|
import "./ha-select";
|
||||||
|
import type { HaSelect } from "./ha-select";
|
||||||
|
|
||||||
|
const PREFERRED = "__PREFERRED_PIPELINE_OPTION__";
|
||||||
|
|
||||||
|
@customElement("ha-assist-pipeline-picker")
|
||||||
|
export class HaAssistPipelinePicker extends LitElement {
|
||||||
|
@property() public value?: string;
|
||||||
|
|
||||||
|
@property() public label?: string;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ type: Boolean, reflect: true }) public disabled = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public required = false;
|
||||||
|
|
||||||
|
@state() _pipelines?: AssistPipeline[];
|
||||||
|
|
||||||
|
@state() _preferredPipeline: string | null = null;
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this._pipelines) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
const value = this.value ?? PREFERRED;
|
||||||
|
return html`
|
||||||
|
<ha-select
|
||||||
|
.label=${this.label ||
|
||||||
|
this.hass!.localize("ui.components.pipeline-picker.pipeline")}
|
||||||
|
.value=${value}
|
||||||
|
.required=${this.required}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
@selected=${this._changed}
|
||||||
|
@closed=${stopPropagation}
|
||||||
|
fixedMenuPosition
|
||||||
|
naturalMenuWidth
|
||||||
|
>
|
||||||
|
<ha-list-item .value=${PREFERRED}>
|
||||||
|
${this.hass!.localize("ui.components.pipeline-picker.preferred", {
|
||||||
|
preferred: this._pipelines.find(
|
||||||
|
(pipeline) => pipeline.id === this._preferredPipeline
|
||||||
|
)?.name,
|
||||||
|
})}
|
||||||
|
</ha-list-item>
|
||||||
|
${this._pipelines.map(
|
||||||
|
(pipeline) =>
|
||||||
|
html`<ha-list-item .value=${pipeline.id}>
|
||||||
|
${pipeline.name} (${pipeline.language})
|
||||||
|
</ha-list-item>`
|
||||||
|
)}
|
||||||
|
</ha-select>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(
|
||||||
|
changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>
|
||||||
|
): void {
|
||||||
|
super.firstUpdated(changedProperties);
|
||||||
|
fetchAssistPipelines(this.hass).then((pipelines) => {
|
||||||
|
this._pipelines = pipelines.pipelines;
|
||||||
|
this._preferredPipeline = pipelines.preferred_pipeline;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return css`
|
||||||
|
ha-select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _changed(ev): void {
|
||||||
|
const target = ev.target as HaSelect;
|
||||||
|
if (
|
||||||
|
!this.hass ||
|
||||||
|
target.value === "" ||
|
||||||
|
target.value === this.value ||
|
||||||
|
(this.value === undefined && target.value === PREFERRED)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.value = target.value === PREFERRED ? undefined : target.value;
|
||||||
|
fireEvent(this, "value-changed", { value: this.value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-assist-pipeline-picker": HaAssistPipelinePicker;
|
||||||
|
}
|
||||||
|
}
|
45
src/components/ha-selector/ha-selector-assist-pipeline.ts
Normal file
45
src/components/ha-selector/ha-selector-assist-pipeline.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { css, html, LitElement } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import { AssistPipelineSelector } from "../../data/selector";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
import "../ha-assist-pipeline-picker";
|
||||||
|
|
||||||
|
@customElement("ha-selector-assist_pipeline")
|
||||||
|
export class HaAssistPipelineSelector extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public selector!: AssistPipelineSelector;
|
||||||
|
|
||||||
|
@property() public value?: any;
|
||||||
|
|
||||||
|
@property() public label?: string;
|
||||||
|
|
||||||
|
@property() public helper?: string;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public required = true;
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
return html`<ha-assist-pipeline-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.value=${this.value}
|
||||||
|
.label=${this.label}
|
||||||
|
.helper=${this.helper}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
.required=${this.required}
|
||||||
|
></ha-assist-pipeline-picker>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
ha-conversation-agent-picker {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-selector-assist_pipeline": HaAssistPipelineSelector;
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ const LOAD_ELEMENTS = {
|
|||||||
addon: () => import("./ha-selector-addon"),
|
addon: () => import("./ha-selector-addon"),
|
||||||
area: () => import("./ha-selector-area"),
|
area: () => import("./ha-selector-area"),
|
||||||
attribute: () => import("./ha-selector-attribute"),
|
attribute: () => import("./ha-selector-attribute"),
|
||||||
|
assist_pipeline: () => import("./ha-selector-assist-pipeline"),
|
||||||
boolean: () => import("./ha-selector-boolean"),
|
boolean: () => import("./ha-selector-boolean"),
|
||||||
color_rgb: () => import("./ha-selector-color-rgb"),
|
color_rgb: () => import("./ha-selector-color-rgb"),
|
||||||
config_entry: () => import("./ha-selector-config-entry"),
|
config_entry: () => import("./ha-selector-config-entry"),
|
||||||
|
@ -31,6 +31,7 @@ export type Selector =
|
|||||||
| NavigationSelector
|
| NavigationSelector
|
||||||
| NumberSelector
|
| NumberSelector
|
||||||
| ObjectSelector
|
| ObjectSelector
|
||||||
|
| AssistPipelineSelector
|
||||||
| SelectSelector
|
| SelectSelector
|
||||||
| StateSelector
|
| StateSelector
|
||||||
| StatisticSelector
|
| StatisticSelector
|
||||||
@ -256,6 +257,11 @@ export interface ObjectSelector {
|
|||||||
object: {} | null;
|
object: {} | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AssistPipelineSelector {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
assist_pipeline: {} | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SelectOption {
|
export interface SelectOption {
|
||||||
value: any;
|
value: any;
|
||||||
label: string;
|
label: string;
|
||||||
|
@ -1,26 +1,27 @@
|
|||||||
import { css, html, LitElement, TemplateResult } from "lit";
|
import { css, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
|
import { extractSearchParam } from "../../../../common/url/search-params";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
|
import "../../../../components/ha-checkbox";
|
||||||
|
import type { HaCheckbox } from "../../../../components/ha-checkbox";
|
||||||
|
import "../../../../components/ha-formfield";
|
||||||
|
import "../../../../components/ha-assist-pipeline-picker";
|
||||||
|
import "../../../../components/ha-textfield";
|
||||||
|
import type { HaTextField } from "../../../../components/ha-textfield";
|
||||||
import {
|
import {
|
||||||
PipelineRun,
|
PipelineRun,
|
||||||
PipelineRunOptions,
|
PipelineRunOptions,
|
||||||
runAssistPipeline,
|
runAssistPipeline,
|
||||||
} from "../../../../data/assist_pipeline";
|
} from "../../../../data/assist_pipeline";
|
||||||
import "../../../../layouts/hass-subpage";
|
|
||||||
import "../../../../components/ha-formfield";
|
|
||||||
import "../../../../components/ha-checkbox";
|
|
||||||
import { haStyle } from "../../../../resources/styles";
|
|
||||||
import type { HomeAssistant } from "../../../../types";
|
|
||||||
import {
|
import {
|
||||||
showAlertDialog,
|
showAlertDialog,
|
||||||
showPromptDialog,
|
showPromptDialog,
|
||||||
} from "../../../../dialogs/generic/show-dialog-box";
|
} from "../../../../dialogs/generic/show-dialog-box";
|
||||||
import "./assist-render-pipeline-run";
|
import "../../../../layouts/hass-subpage";
|
||||||
import type { HaCheckbox } from "../../../../components/ha-checkbox";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import type { HaTextField } from "../../../../components/ha-textfield";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import "../../../../components/ha-textfield";
|
|
||||||
import { fileDownload } from "../../../../util/file_download";
|
import { fileDownload } from "../../../../util/file_download";
|
||||||
import { extractSearchParam } from "../../../../common/url/search-params";
|
import "./assist-render-pipeline-run";
|
||||||
|
|
||||||
@customElement("assist-pipeline-run-debug")
|
@customElement("assist-pipeline-run-debug")
|
||||||
export class AssistPipelineRunDebug extends LitElement {
|
export class AssistPipelineRunDebug extends LitElement {
|
||||||
@ -66,16 +67,17 @@ export class AssistPipelineRunDebug extends LitElement {
|
|||||||
Download
|
Download
|
||||||
</ha-button>
|
</ha-button>
|
||||||
`
|
`
|
||||||
: html`
|
: ""}
|
||||||
<ha-button slot="toolbar-icon" @click=${this._pickPipeline}>
|
|
||||||
Pick pipeline
|
|
||||||
</ha-button>
|
|
||||||
`}
|
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="start-row">
|
<div class="start-row">
|
||||||
${this._pipelineRuns.length === 0
|
${this._pipelineRuns.length === 0
|
||||||
? html`
|
? html`
|
||||||
|
<ha-assist-pipeline-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.value=${this._pipelineId}
|
||||||
|
@value-changed=${this._pipelinePicked}
|
||||||
|
></ha-assist-pipeline-picker>
|
||||||
<ha-button raised @click=${this._runTextPipeline}>
|
<ha-button raised @click=${this._runTextPipeline}>
|
||||||
Run Text Pipeline
|
Run Text Pipeline
|
||||||
</ha-button>
|
</ha-button>
|
||||||
@ -324,16 +326,8 @@ export class AssistPipelineRunDebug extends LitElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _pickPipeline() {
|
private _pipelinePicked(ev) {
|
||||||
const pipeline = await showPromptDialog(this, {
|
this._pipelineId = ev.detail.value;
|
||||||
title: "Set pipeline",
|
|
||||||
inputLabel: "Pipeline ID",
|
|
||||||
inputType: "text",
|
|
||||||
confirmText: "Set",
|
|
||||||
});
|
|
||||||
if (pipeline) {
|
|
||||||
this._pipelineId = pipeline;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [
|
static styles = [
|
||||||
@ -349,8 +343,14 @@ export class AssistPipelineRunDebug extends LitElement {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
margin: 0 16px 16px;
|
margin: 0 16px 16px;
|
||||||
}
|
}
|
||||||
|
ha-pipeline-picker {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
.start-row ha-textfield {
|
.start-row ha-textfield {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ export class DialogVoiceAssistantPipelineDetail extends LitElement {
|
|||||||
.disabled=${this._preferred}
|
.disabled=${this._preferred}
|
||||||
slot="secondaryAction"
|
slot="secondaryAction"
|
||||||
@click=${this._setPreferred}
|
@click=${this._setPreferred}
|
||||||
>Set as default</ha-button
|
>Set as preferred</ha-button
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="/config/voice-assistants/debug/${this._params.pipeline
|
href="/config/voice-assistants/debug/${this._params.pipeline
|
||||||
|
@ -405,6 +405,10 @@
|
|||||||
"conversation_agent": "Conversation agent",
|
"conversation_agent": "Conversation agent",
|
||||||
"none": "None"
|
"none": "None"
|
||||||
},
|
},
|
||||||
|
"pipeline-picker": {
|
||||||
|
"pipeline": "Assistant",
|
||||||
|
"preferred": "Preferred assistant ({preferred})"
|
||||||
|
},
|
||||||
"theme-picker": {
|
"theme-picker": {
|
||||||
"theme": "Theme",
|
"theme": "Theme",
|
||||||
"no_theme": "No theme"
|
"no_theme": "No theme"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user