mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
20240930.0 (#22166)
This commit is contained in:
commit
268eb4317c
4
.github/workflows/cast_deployment.yaml
vendored
4
.github/workflows/cast_deployment.yaml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
with:
|
||||
ref: dev
|
||||
|
||||
@ -57,7 +57,7 @@ jobs:
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
with:
|
||||
ref: master
|
||||
|
||||
|
8
.github/workflows/ci.yaml
vendored
8
.github/workflows/ci.yaml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.0.4
|
||||
with:
|
||||
@ -58,7 +58,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.0.4
|
||||
with:
|
||||
@ -76,7 +76,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.0.4
|
||||
with:
|
||||
@ -100,7 +100,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.0.4
|
||||
with:
|
||||
|
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
|
4
.github/workflows/demo_deployment.yaml
vendored
4
.github/workflows/demo_deployment.yaml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
with:
|
||||
ref: dev
|
||||
|
||||
@ -58,7 +58,7 @@ jobs:
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
with:
|
||||
ref: master
|
||||
|
||||
|
2
.github/workflows/design_deployment.yaml
vendored
2
.github/workflows/design_deployment.yaml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.0.4
|
||||
|
2
.github/workflows/design_preview.yaml
vendored
2
.github/workflows/design_preview.yaml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
if: github.repository == 'home-assistant/frontend' && contains(github.event.pull_request.labels.*.name, 'needs design preview')
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.0.4
|
||||
|
2
.github/workflows/nightly.yaml
vendored
2
.github/workflows/nightly.yaml
vendored
@ -20,7 +20,7 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
|
||||
- name: Set up Python ${{ env.PYTHON_VERSION }}
|
||||
uses: actions/setup-python@v5
|
||||
|
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
contents: write # Required to upload release assets
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
|
||||
- name: Verify version
|
||||
uses: home-assistant/actions/helpers/verify-version@master
|
||||
|
2
.github/workflows/translations.yaml
vendored
2
.github/workflows/translations.yaml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v4.1.7
|
||||
uses: actions/checkout@v4.2.0
|
||||
|
||||
- name: Upload Translations
|
||||
run: |
|
||||
|
@ -27,3 +27,5 @@ A complete guide can be found at the following [link](https://www.home-assistant
|
||||
Home Assistant is open-source and Apache 2 licensed. Feel free to browse the repository, learn and reuse parts in your own projects.
|
||||
|
||||
We use [BrowserStack](https://www.browserstack.com) to test Home Assistant on a large variety of devices.
|
||||
|
||||
[](https://www.openhomefoundation.org/)
|
||||
|
@ -142,7 +142,7 @@ export class DemoAutomationDescribeAction extends LitElement {
|
||||
<div class="action">
|
||||
<span>
|
||||
${this._action
|
||||
? describeAction(this.hass, [], [], [], this._action)
|
||||
? describeAction(this.hass, [], [], this._action)
|
||||
: "<invalid YAML>"}
|
||||
</span>
|
||||
<ha-yaml-editor
|
||||
@ -155,7 +155,7 @@ export class DemoAutomationDescribeAction extends LitElement {
|
||||
${ACTIONS.map(
|
||||
(conf) => html`
|
||||
<div class="action">
|
||||
<span>${describeAction(this.hass, [], [], [], conf as any)}</span>
|
||||
<span>${describeAction(this.hass, [], [], conf as any)}</span>
|
||||
<pre>${dump(conf)}</pre>
|
||||
</div>
|
||||
`
|
||||
|
@ -33,7 +33,7 @@
|
||||
"@codemirror/legacy-modes": "6.4.1",
|
||||
"@codemirror/search": "6.5.6",
|
||||
"@codemirror/state": "6.4.1",
|
||||
"@codemirror/view": "6.33.0",
|
||||
"@codemirror/view": "6.34.0",
|
||||
"@egjs/hammerjs": "2.0.17",
|
||||
"@formatjs/intl-datetimeformat": "6.12.5",
|
||||
"@formatjs/intl-displaynames": "6.6.8",
|
||||
@ -229,7 +229,7 @@
|
||||
"open": "10.1.0",
|
||||
"pinst": "3.0.0",
|
||||
"prettier": "3.3.3",
|
||||
"rollup": "2.79.1",
|
||||
"rollup": "2.79.2",
|
||||
"rollup-plugin-string": "3.0.0",
|
||||
"rollup-plugin-terser": "7.0.2",
|
||||
"rollup-plugin-visualizer": "5.12.0",
|
||||
@ -241,7 +241,7 @@
|
||||
"transform-async-modules-webpack-plugin": "1.1.1",
|
||||
"ts-lit-plugin": "2.0.2",
|
||||
"typescript": "5.6.2",
|
||||
"webpack": "5.94.0",
|
||||
"webpack": "5.95.0",
|
||||
"webpack-cli": "5.1.4",
|
||||
"webpack-dev-server": "5.1.0",
|
||||
"webpack-manifest-plugin": "5.0.0",
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20240927.0"
|
||||
version = "20240930.0"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
@ -1,36 +1,36 @@
|
||||
import { theme2hex } from "./convert-color";
|
||||
|
||||
export const COLORS = [
|
||||
"#44739e",
|
||||
"#984ea3",
|
||||
"#00d2d5",
|
||||
"#ff7f00",
|
||||
"#af8d00",
|
||||
"#7f80cd",
|
||||
"#b3e900",
|
||||
"#c42e60",
|
||||
"#a65628",
|
||||
"#f781bf",
|
||||
"#8dd3c7",
|
||||
"#bebada",
|
||||
"#fb8072",
|
||||
"#80b1d3",
|
||||
"#fdb462",
|
||||
"#fccde5",
|
||||
"#bc80bd",
|
||||
"#ffed6f",
|
||||
"#c4eaff",
|
||||
"#cf8c00",
|
||||
"#1b9e77",
|
||||
"#d95f02",
|
||||
"#e7298a",
|
||||
"#e6ab02",
|
||||
"#a6761d",
|
||||
"#0097ff",
|
||||
"#00d067",
|
||||
"#f43600",
|
||||
"#4ba93b",
|
||||
"#5779bb",
|
||||
"#4269d0",
|
||||
"#f4bd4a",
|
||||
"#ff725c",
|
||||
"#6cc5b0",
|
||||
"#a463f2",
|
||||
"#ff8ab7",
|
||||
"#9c6b4e",
|
||||
"#97bbf5",
|
||||
"#01ab63",
|
||||
"#9498a0",
|
||||
"#094bad",
|
||||
"#c99000",
|
||||
"#d84f3e",
|
||||
"#49a28f",
|
||||
"#048732",
|
||||
"#d96895",
|
||||
"#8043ce",
|
||||
"#7599d1",
|
||||
"#7a4c31",
|
||||
"#74787f",
|
||||
"#6989f4",
|
||||
"#ffd444",
|
||||
"#ff957c",
|
||||
"#8fe9d3",
|
||||
"#62cc71",
|
||||
"#ffadda",
|
||||
"#c884ff",
|
||||
"#badeff",
|
||||
"#bf8b6d",
|
||||
"#b6bac2",
|
||||
"#927acc",
|
||||
"#97ee3f",
|
||||
"#bf3947",
|
||||
|
@ -1011,6 +1011,7 @@ export class HaDataTable extends LitElement {
|
||||
/* @noflip */
|
||||
padding-inline-end: initial;
|
||||
width: 60px;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
.mdc-data-table__table {
|
||||
|
@ -1,10 +1,17 @@
|
||||
import { TextAreaCharCounter } from "@material/mwc-textfield/mwc-textfield-base";
|
||||
import { mdiEye, mdiEyeOff } from "@mdi/js";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, eventOptions, property, state } from "lit/decorators";
|
||||
import {
|
||||
customElement,
|
||||
eventOptions,
|
||||
property,
|
||||
query,
|
||||
state,
|
||||
} from "lit/decorators";
|
||||
import { HomeAssistant } from "../types";
|
||||
import "./ha-icon-button";
|
||||
import "./ha-textfield";
|
||||
import type { HaTextField } from "./ha-textfield";
|
||||
|
||||
@customElement("ha-password-field")
|
||||
export class HaPasswordField extends LitElement {
|
||||
@ -75,6 +82,8 @@ export class HaPasswordField extends LitElement {
|
||||
|
||||
@state() private _unmaskedPassword = false;
|
||||
|
||||
@query("ha-textfield") private _textField!: HaTextField;
|
||||
|
||||
protected render() {
|
||||
return html`<ha-textfield
|
||||
.invalid=${this.invalid}
|
||||
@ -122,6 +131,22 @@ export class HaPasswordField extends LitElement {
|
||||
></ha-icon-button>`;
|
||||
}
|
||||
|
||||
public checkValidity(): boolean {
|
||||
return this._textField.checkValidity();
|
||||
}
|
||||
|
||||
public reportValidity(): boolean {
|
||||
return this._textField.reportValidity();
|
||||
}
|
||||
|
||||
public setCustomValidity(message: string): void {
|
||||
return this._textField.setCustomValidity(message);
|
||||
}
|
||||
|
||||
public layout(): Promise<void> {
|
||||
return this._textField.layout();
|
||||
}
|
||||
|
||||
private _toggleUnmaskedPassword(): void {
|
||||
this._unmaskedPassword = !this._unmaskedPassword;
|
||||
}
|
||||
|
@ -805,7 +805,8 @@ export class HaServiceControl extends LitElement {
|
||||
const value = ev.detail.value;
|
||||
if (
|
||||
this._value?.data?.[key] === value ||
|
||||
(!this._value?.data?.[key] && (value === "" || value === undefined))
|
||||
((!this._value?.data || !(key in this._value.data)) &&
|
||||
(value === "" || value === undefined))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import type { HaCodeEditor } from "./ha-code-editor";
|
||||
import "./ha-button";
|
||||
|
||||
const isEmpty = (obj: Record<string, unknown>): boolean => {
|
||||
if (typeof obj !== "object") {
|
||||
if (typeof obj !== "object" || obj === null) {
|
||||
return false;
|
||||
}
|
||||
for (const key in obj) {
|
||||
@ -59,14 +59,13 @@ export class HaYamlEditor extends LitElement {
|
||||
|
||||
public setValue(value): void {
|
||||
try {
|
||||
this._yaml =
|
||||
value && !isEmpty(value)
|
||||
? dump(value, {
|
||||
schema: this.yamlSchema,
|
||||
quotingType: '"',
|
||||
noRefs: true,
|
||||
})
|
||||
: "";
|
||||
this._yaml = !isEmpty(value)
|
||||
? dump(value, {
|
||||
schema: this.yamlSchema,
|
||||
quotingType: '"',
|
||||
noRefs: true,
|
||||
})
|
||||
: "";
|
||||
} catch (err: any) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err, value);
|
||||
@ -75,7 +74,7 @@ export class HaYamlEditor extends LitElement {
|
||||
}
|
||||
|
||||
protected firstUpdated(): void {
|
||||
if (this.defaultValue) {
|
||||
if (this.defaultValue !== undefined) {
|
||||
this.setValue(this.defaultValue);
|
||||
}
|
||||
}
|
||||
|
@ -22,13 +22,8 @@ import { formatDateTimeWithSeconds } from "../../common/datetime/format_date_tim
|
||||
import { relativeTime } from "../../common/datetime/relative_time";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { toggleAttribute } from "../../common/dom/toggle_attribute";
|
||||
import {
|
||||
floorsContext,
|
||||
fullEntitiesContext,
|
||||
labelsContext,
|
||||
} from "../../data/context";
|
||||
import { fullEntitiesContext, labelsContext } from "../../data/context";
|
||||
import { EntityRegistryEntry } from "../../data/entity_registry";
|
||||
import { FloorRegistryEntry } from "../../data/floor_registry";
|
||||
import { LabelRegistryEntry } from "../../data/label_registry";
|
||||
import { LogbookEntry } from "../../data/logbook";
|
||||
import {
|
||||
@ -206,7 +201,6 @@ class ActionRenderer {
|
||||
private hass: HomeAssistant,
|
||||
private entityReg: EntityRegistryEntry[],
|
||||
private labelReg: LabelRegistryEntry[],
|
||||
private floorReg: FloorRegistryEntry[],
|
||||
private entries: TemplateResult[],
|
||||
private trace: AutomationTraceExtended,
|
||||
private logbookRenderer: LogbookRenderer,
|
||||
@ -325,7 +319,6 @@ class ActionRenderer {
|
||||
this.hass,
|
||||
this.entityReg,
|
||||
this.labelReg,
|
||||
this.floorReg,
|
||||
data,
|
||||
actionType
|
||||
),
|
||||
@ -493,13 +486,7 @@ class ActionRenderer {
|
||||
|
||||
const name =
|
||||
repeatConfig.alias ||
|
||||
describeAction(
|
||||
this.hass,
|
||||
this.entityReg,
|
||||
this.labelReg,
|
||||
this.floorReg,
|
||||
repeatConfig
|
||||
);
|
||||
describeAction(this.hass, this.entityReg, this.labelReg, repeatConfig);
|
||||
|
||||
this._renderEntry(repeatPath, name, undefined, disabled);
|
||||
|
||||
@ -597,7 +584,6 @@ class ActionRenderer {
|
||||
this.hass,
|
||||
this.entityReg,
|
||||
this.labelReg,
|
||||
this.floorReg,
|
||||
sequenceConfig,
|
||||
"sequence"
|
||||
),
|
||||
@ -694,10 +680,6 @@ export class HaAutomationTracer extends LitElement {
|
||||
@consume({ context: labelsContext, subscribe: true })
|
||||
_labelReg!: LabelRegistryEntry[];
|
||||
|
||||
@state()
|
||||
@consume({ context: floorsContext, subscribe: true })
|
||||
_floorReg!: FloorRegistryEntry[];
|
||||
|
||||
protected render() {
|
||||
if (!this.trace) {
|
||||
return nothing;
|
||||
@ -715,7 +697,6 @@ export class HaAutomationTracer extends LitElement {
|
||||
this.hass,
|
||||
this._entityReg,
|
||||
this._labelReg,
|
||||
this._floorReg,
|
||||
entries,
|
||||
this.trace,
|
||||
logbookRenderer,
|
||||
|
@ -2,7 +2,6 @@ import { createContext } from "@lit-labs/context";
|
||||
import { HassConfig } from "home-assistant-js-websocket";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { EntityRegistryEntry } from "./entity_registry";
|
||||
import { FloorRegistryEntry } from "./floor_registry";
|
||||
import { LabelRegistryEntry } from "./label_registry";
|
||||
|
||||
export const connectionContext =
|
||||
@ -28,6 +27,4 @@ export const panelsContext = createContext<HomeAssistant["panels"]>("panels");
|
||||
export const fullEntitiesContext =
|
||||
createContext<EntityRegistryEntry[]>("extendedEntities");
|
||||
|
||||
export const floorsContext = createContext<FloorRegistryEntry[]>("floors");
|
||||
|
||||
export const labelsContext = createContext<LabelRegistryEntry[]>("labels");
|
||||
|
@ -14,7 +14,6 @@ import {
|
||||
computeEntityRegistryName,
|
||||
entityRegistryById,
|
||||
} from "./entity_registry";
|
||||
import { FloorRegistryEntry } from "./floor_registry";
|
||||
import { domainToName } from "./integration";
|
||||
import { LabelRegistryEntry } from "./label_registry";
|
||||
import {
|
||||
@ -44,7 +43,6 @@ export const describeAction = <T extends ActionType>(
|
||||
hass: HomeAssistant,
|
||||
entityRegistry: EntityRegistryEntry[],
|
||||
labelRegistry: LabelRegistryEntry[],
|
||||
floorRegistry: FloorRegistryEntry[],
|
||||
action: ActionTypes[T],
|
||||
actionType?: T,
|
||||
ignoreAlias = false
|
||||
@ -54,7 +52,6 @@ export const describeAction = <T extends ActionType>(
|
||||
hass,
|
||||
entityRegistry,
|
||||
labelRegistry,
|
||||
floorRegistry,
|
||||
action,
|
||||
actionType,
|
||||
ignoreAlias
|
||||
@ -78,7 +75,6 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
hass: HomeAssistant,
|
||||
entityRegistry: EntityRegistryEntry[],
|
||||
labelRegistry: LabelRegistryEntry[],
|
||||
floorRegistry: FloorRegistryEntry[],
|
||||
action: ActionTypes[T],
|
||||
actionType?: T,
|
||||
ignoreAlias = false
|
||||
@ -168,9 +164,7 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
);
|
||||
}
|
||||
} else if (key === "floor_id") {
|
||||
const floor = floorRegistry.find(
|
||||
(flr) => flr.floor_id === targetThing
|
||||
);
|
||||
const floor = hass.floors[targetThing] ?? undefined;
|
||||
if (floor?.name) {
|
||||
targets.push(floor.name);
|
||||
} else {
|
||||
|
@ -144,7 +144,7 @@ export class HaVoiceAssistantSetupStepPipeline extends LitElement {
|
||||
{ option: "preferred" },
|
||||
{ entity_id: this.assistConfiguration?.pipeline_entity_id }
|
||||
);
|
||||
this._nextStep(STEP.SUCCESS);
|
||||
fireEvent(this, "next-step", { step: STEP.SUCCESS, noPrevious: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -210,15 +210,15 @@ export class HaVoiceAssistantSetupStepPipeline extends LitElement {
|
||||
{ option: cloudPipeline.name },
|
||||
{ entity_id: this.assistConfiguration?.pipeline_entity_id }
|
||||
);
|
||||
this._nextStep(STEP.SUCCESS);
|
||||
fireEvent(this, "next-step", { step: STEP.SUCCESS, noPrevious: true });
|
||||
}
|
||||
|
||||
private async _setupCloud() {
|
||||
fireEvent(this, "next-step", { step: STEP.CLOUD });
|
||||
this._nextStep(STEP.CLOUD);
|
||||
}
|
||||
|
||||
private async _thisSystem() {
|
||||
fireEvent(this, "next-step", { step: STEP.ADDONS });
|
||||
this._nextStep(STEP.ADDONS);
|
||||
}
|
||||
|
||||
private _skip() {
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
import {
|
||||
assistSatelliteAnnounce,
|
||||
AssistSatelliteConfiguration,
|
||||
setWakeWords,
|
||||
} from "../../data/assist_satellite";
|
||||
import { fetchCloudStatus } from "../../data/cloud";
|
||||
import { showVoiceAssistantPipelineDetailDialog } from "../../panels/config/voice-assistants/show-dialog-voice-assistant-pipeline-detail";
|
||||
@ -21,6 +22,8 @@ import "../../panels/lovelace/entity-rows/hui-select-entity-row";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { AssistantSetupStyles } from "./styles";
|
||||
import { STEP } from "./voice-assistant-setup-dialog";
|
||||
import { setSelectOption } from "../../data/select";
|
||||
import { InputSelectEntity } from "../../data/input_select";
|
||||
|
||||
@customElement("ha-voice-assistant-setup-step-success")
|
||||
export class HaVoiceAssistantSetupStepSuccess extends LitElement {
|
||||
@ -58,7 +61,9 @@ export class HaVoiceAssistantSetupStepSuccess extends LitElement {
|
||||
|
||||
protected override render() {
|
||||
const pipelineEntity = this.assistConfiguration
|
||||
? this.hass.states[this.assistConfiguration.pipeline_entity_id]
|
||||
? (this.hass.states[
|
||||
this.assistConfiguration.pipeline_entity_id
|
||||
] as InputSelectEntity)
|
||||
: undefined;
|
||||
|
||||
return html`<div class="content">
|
||||
@ -69,46 +74,53 @@ export class HaVoiceAssistantSetupStepSuccess extends LitElement {
|
||||
settings, you can change that below.
|
||||
</p>
|
||||
<div class="rows">
|
||||
<div class="row">
|
||||
<ha-select
|
||||
.label=${"Wake word"}
|
||||
@closed=${stopPropagation}
|
||||
fixedMenuPosition
|
||||
naturalMenuWidth
|
||||
.value=${this.assistConfiguration?.active_wake_words[0]}
|
||||
>
|
||||
${this.assistConfiguration?.available_wake_words.map(
|
||||
(wakeword) =>
|
||||
html`<ha-list-item .value=${wakeword.id}>
|
||||
${wakeword.wake_word}
|
||||
</ha-list-item>`
|
||||
)}
|
||||
</ha-select>
|
||||
<ha-button @click=${this._testWakeWord}>
|
||||
<ha-svg-icon slot="icon" .path=${mdiMicrophone}></ha-svg-icon>
|
||||
Test
|
||||
</ha-button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<ha-select
|
||||
.label=${"Assistant"}
|
||||
@closed=${stopPropagation}
|
||||
.value=${pipelineEntity?.state}
|
||||
fixedMenuPosition
|
||||
naturalMenuWidth
|
||||
>
|
||||
${pipelineEntity?.attributes.options.map(
|
||||
(pipeline) =>
|
||||
html`<ha-list-item .value=${pipeline}>
|
||||
${this.hass.formatEntityState(pipelineEntity, pipeline)}
|
||||
</ha-list-item>`
|
||||
)}
|
||||
</ha-select>
|
||||
<ha-button @click=${this._openPipeline}>
|
||||
<ha-svg-icon slot="icon" .path=${mdiCog}></ha-svg-icon>
|
||||
Edit
|
||||
</ha-button>
|
||||
</div>
|
||||
${this.assistConfiguration &&
|
||||
this.assistConfiguration.available_wake_words.length > 1
|
||||
? html` <div class="row">
|
||||
<ha-select
|
||||
.label=${"Wake word"}
|
||||
@closed=${stopPropagation}
|
||||
fixedMenuPosition
|
||||
naturalMenuWidth
|
||||
.value=${this.assistConfiguration.active_wake_words[0]}
|
||||
@selected=${this._wakeWordPicked}
|
||||
>
|
||||
${this.assistConfiguration.available_wake_words.map(
|
||||
(wakeword) =>
|
||||
html`<ha-list-item .value=${wakeword.id}>
|
||||
${wakeword.wake_word}
|
||||
</ha-list-item>`
|
||||
)}
|
||||
</ha-select>
|
||||
<ha-button @click=${this._testWakeWord}>
|
||||
<ha-svg-icon slot="icon" .path=${mdiMicrophone}></ha-svg-icon>
|
||||
Test
|
||||
</ha-button>
|
||||
</div>`
|
||||
: nothing}
|
||||
${pipelineEntity
|
||||
? html`<div class="row">
|
||||
<ha-select
|
||||
.label=${"Assistant"}
|
||||
@closed=${stopPropagation}
|
||||
.value=${pipelineEntity?.state}
|
||||
fixedMenuPosition
|
||||
naturalMenuWidth
|
||||
@selected=${this._pipelinePicked}
|
||||
>
|
||||
${pipelineEntity?.attributes.options.map(
|
||||
(pipeline) =>
|
||||
html`<ha-list-item .value=${pipeline}>
|
||||
${this.hass.formatEntityState(pipelineEntity, pipeline)}
|
||||
</ha-list-item>`
|
||||
)}
|
||||
</ha-select>
|
||||
<ha-button @click=${this._openPipeline}>
|
||||
<ha-svg-icon slot="icon" .path=${mdiCog}></ha-svg-icon>
|
||||
Edit
|
||||
</ha-button>
|
||||
</div>`
|
||||
: nothing}
|
||||
${this._ttsSettings
|
||||
? html`<div class="row">
|
||||
<ha-tts-voice-picker
|
||||
@ -156,6 +168,25 @@ export class HaVoiceAssistantSetupStepSuccess extends LitElement {
|
||||
return [pipeline, pipelines.preferred_pipeline];
|
||||
}
|
||||
|
||||
private async _wakeWordPicked(ev) {
|
||||
const option = ev.target.value;
|
||||
await setWakeWords(this.hass, this.assistEntityId!, [option]);
|
||||
}
|
||||
|
||||
private _pipelinePicked(ev) {
|
||||
const stateObj = this.hass!.states[
|
||||
this.assistConfiguration!.pipeline_entity_id
|
||||
] as InputSelectEntity;
|
||||
const option = ev.target.value;
|
||||
if (
|
||||
option === stateObj.state ||
|
||||
!stateObj.attributes.options.includes(option)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setSelectOption(this.hass!, stateObj.entity_id, option);
|
||||
}
|
||||
|
||||
private async _setTtsSettings() {
|
||||
const [pipeline] = await this._getPipeline();
|
||||
if (!pipeline) {
|
||||
@ -197,6 +228,7 @@ export class HaVoiceAssistantSetupStepSuccess extends LitElement {
|
||||
fireEvent(this, "next-step", {
|
||||
step: STEP.WAKEWORD,
|
||||
nextStep: STEP.SUCCESS,
|
||||
updateConfig: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -43,13 +43,8 @@ import type { HaYamlEditor } from "../../../../components/ha-yaml-editor";
|
||||
import { ACTION_ICONS, YAML_ONLY_ACTION_TYPES } from "../../../../data/action";
|
||||
import { AutomationClipboard } from "../../../../data/automation";
|
||||
import { validateConfig } from "../../../../data/config";
|
||||
import {
|
||||
floorsContext,
|
||||
fullEntitiesContext,
|
||||
labelsContext,
|
||||
} from "../../../../data/context";
|
||||
import { fullEntitiesContext, labelsContext } from "../../../../data/context";
|
||||
import { EntityRegistryEntry } from "../../../../data/entity_registry";
|
||||
import { FloorRegistryEntry } from "../../../../data/floor_registry";
|
||||
import { LabelRegistryEntry } from "../../../../data/label_registry";
|
||||
import {
|
||||
Action,
|
||||
@ -159,10 +154,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
@consume({ context: labelsContext, subscribe: true })
|
||||
_labelReg!: LabelRegistryEntry[];
|
||||
|
||||
@state()
|
||||
@consume({ context: floorsContext, subscribe: true })
|
||||
_floorReg!: FloorRegistryEntry[];
|
||||
|
||||
@state() private _warnings?: string[];
|
||||
|
||||
@state() private _uiModeAvailable = true;
|
||||
@ -231,7 +222,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
this.hass,
|
||||
this._entityReg,
|
||||
this._labelReg,
|
||||
this._floorReg,
|
||||
this.action
|
||||
)
|
||||
)}
|
||||
@ -603,7 +593,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
this.hass,
|
||||
this._entityReg,
|
||||
this._labelReg,
|
||||
this._floorReg,
|
||||
this.action,
|
||||
undefined,
|
||||
true
|
||||
|
@ -41,7 +41,9 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
this._newIcon = "icon" in params.config ? params.config.icon : undefined;
|
||||
this._newName =
|
||||
params.config.alias ||
|
||||
this.hass.localize("ui.panel.config.automation.editor.default_name");
|
||||
this.hass.localize(
|
||||
`ui.panel.config.${this._params.domain}.editor.default_name`
|
||||
);
|
||||
this._newDescription = params.config.description || "";
|
||||
}
|
||||
|
||||
@ -83,7 +85,7 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
dialogInitialFocus
|
||||
.value=${this._newName}
|
||||
.placeholder=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.default_name"
|
||||
`ui.panel.config.${this._params.domain}.editor.default_name`
|
||||
)}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.alias"
|
||||
|
@ -1,8 +1,8 @@
|
||||
import "@material/mwc-button";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { mdiDeleteForever, mdiDotsVertical } from "@mdi/js";
|
||||
import { css, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { mdiDeleteForever, mdiDotsVertical } from "@mdi/js";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { navigate } from "../../../../common/navigate";
|
||||
import "../../../../components/buttons/ha-progress-button";
|
||||
@ -10,8 +10,11 @@ import "../../../../components/ha-alert";
|
||||
import "../../../../components/ha-card";
|
||||
import "../../../../components/ha-icon-next";
|
||||
import "../../../../components/ha-list-item";
|
||||
import type { HaTextField } from "../../../../components/ha-textfield";
|
||||
import "../../../../components/ha-password-field";
|
||||
import type { HaPasswordField } from "../../../../components/ha-password-field";
|
||||
import "../../../../components/ha-textfield";
|
||||
import type { HaTextField } from "../../../../components/ha-textfield";
|
||||
import { setAssistPipelinePreferred } from "../../../../data/assist_pipeline";
|
||||
import { cloudLogin, removeCloudData } from "../../../../data/cloud";
|
||||
import {
|
||||
showAlertDialog,
|
||||
@ -21,8 +24,6 @@ import "../../../../layouts/hass-subpage";
|
||||
import { haStyle } from "../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import "../../ha-config-section";
|
||||
import { setAssistPipelinePreferred } from "../../../../data/assist_pipeline";
|
||||
import "../../../../components/ha-password-field";
|
||||
|
||||
@customElement("cloud-login")
|
||||
export class CloudLogin extends LitElement {
|
||||
@ -44,7 +45,7 @@ export class CloudLogin extends LitElement {
|
||||
|
||||
@query("#email", true) private _emailField!: HaTextField;
|
||||
|
||||
@query("#password", true) private _passwordField!: HaTextField;
|
||||
@query("#password", true) private _passwordField!: HaPasswordField;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
|
@ -37,6 +37,7 @@ export const DEFAULT_CONFIG: Partial<EntityHeadingBadgeConfig> = {
|
||||
const entityConfigStruct = object({
|
||||
type: optional(string()),
|
||||
entity: string(),
|
||||
name: optional(string()),
|
||||
icon: optional(string()),
|
||||
state_content: optional(union([string(), array(string())])),
|
||||
show_state: optional(boolean()),
|
||||
@ -86,6 +87,12 @@ export class HuiHeadingEntityEditor
|
||||
name: "",
|
||||
type: "grid",
|
||||
schema: [
|
||||
{
|
||||
name: "name",
|
||||
selector: {
|
||||
text: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "icon",
|
||||
selector: { icon: {} },
|
||||
@ -128,7 +135,7 @@ export class HuiHeadingEntityEditor
|
||||
},
|
||||
{
|
||||
name: "state_content",
|
||||
selector: { ui_state_content: {} },
|
||||
selector: { ui_state_content: { allow_name: true } },
|
||||
context: { filter_entity: "entity" },
|
||||
},
|
||||
],
|
||||
@ -269,6 +276,10 @@ export class HuiHeadingEntityEditor
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.heading.entity_config.${schema.name}_helper`
|
||||
);
|
||||
case "name":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.heading.entity_config.name_helper`
|
||||
);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
|
@ -125,12 +125,15 @@ export class HuiEntityHeadingBadge
|
||||
"--icon-color": color,
|
||||
};
|
||||
|
||||
const name = config.name || stateObj.attributes.friendly_name;
|
||||
|
||||
return html`
|
||||
<ha-heading-badge
|
||||
.type=${hasAction(config.tap_action) ? "button" : "text"}
|
||||
@action=${this._handleAction}
|
||||
.actionHandler=${actionHandler()}
|
||||
style=${styleMap(style)}
|
||||
.title=${name}
|
||||
>
|
||||
${config.show_icon
|
||||
? html`
|
||||
@ -148,6 +151,8 @@ export class HuiEntityHeadingBadge
|
||||
.hass=${this.hass}
|
||||
.stateObj=${stateObj}
|
||||
.content=${config.state_content}
|
||||
.name=${config.name}
|
||||
dash-unavailable
|
||||
></state-display>
|
||||
`
|
||||
: nothing}
|
||||
|
@ -16,6 +16,7 @@ export interface ErrorBadgeConfig extends LovelaceHeadingBadgeConfig {
|
||||
export interface EntityHeadingBadgeConfig extends LovelaceHeadingBadgeConfig {
|
||||
type?: "entity";
|
||||
entity: string;
|
||||
name?: string;
|
||||
state_content?: string | string[];
|
||||
icon?: string;
|
||||
show_state?: boolean;
|
||||
|
@ -57,6 +57,9 @@ class StateDisplay extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public name?: string;
|
||||
|
||||
@property({ type: Boolean, attribute: "dash-unavailable" })
|
||||
public dashUnavailable?: boolean;
|
||||
|
||||
protected createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
@ -73,6 +76,9 @@ class StateDisplay extends LitElement {
|
||||
const domain = computeStateDomain(stateObj);
|
||||
|
||||
if (content === "state") {
|
||||
if (this.dashUnavailable && isUnavailableState(stateObj.state)) {
|
||||
return "—";
|
||||
}
|
||||
if (
|
||||
(stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP ||
|
||||
TIMESTAMP_STATE_DOMAINS.includes(domain)) &&
|
||||
|
@ -6026,6 +6026,8 @@
|
||||
"entity_config": {
|
||||
"color": "[%key:ui::panel::lovelace::editor::card::tile::color%]",
|
||||
"color_helper": "[%key:ui::panel::lovelace::editor::card::tile::color_helper%]",
|
||||
"name": "[%key:ui::panel::lovelace::editor::card::generic::name%]",
|
||||
"name_helper": "Visible if selected in state content",
|
||||
"visibility": "Visibility",
|
||||
"visibility_explanation": "The entity will be shown when ALL conditions below are fulfilled. If no conditions are set, the entity will always be shown.",
|
||||
"appearance": "Appearance",
|
||||
|
@ -67,6 +67,9 @@
|
||||
"fr": {
|
||||
"nativeName": "Français"
|
||||
},
|
||||
"ga": {
|
||||
"nativeName": "Gaeilge"
|
||||
},
|
||||
"gl": {
|
||||
"nativeName": "Galego"
|
||||
},
|
||||
|
30
yarn.lock
30
yarn.lock
@ -1511,14 +1511,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/view@npm:6.33.0, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0":
|
||||
version: 6.33.0
|
||||
resolution: "@codemirror/view@npm:6.33.0"
|
||||
"@codemirror/view@npm:6.34.0, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0":
|
||||
version: 6.34.0
|
||||
resolution: "@codemirror/view@npm:6.34.0"
|
||||
dependencies:
|
||||
"@codemirror/state": "npm:^6.4.0"
|
||||
style-mod: "npm:^4.1.0"
|
||||
w3c-keyname: "npm:^2.2.4"
|
||||
checksum: 10/240f1b5ed6ddbc928b220e241e7c67d2f8aaa04af337729cd80ea435c84fca02fe4136d2d4750a978d39c20e56f5ce332e6af2620c2e72d7bede35eebbf9e8ee
|
||||
checksum: 10/df790659d229b2bd5867d8d424c7d911bf4800e893cf71cf1caf03797a70a1af561a05ce81a03f2e326320eb0a16db078a5ba4af2f89d790b578de94ea83f6ea
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -8908,7 +8908,7 @@ __metadata:
|
||||
"@codemirror/legacy-modes": "npm:6.4.1"
|
||||
"@codemirror/search": "npm:6.5.6"
|
||||
"@codemirror/state": "npm:6.4.1"
|
||||
"@codemirror/view": "npm:6.33.0"
|
||||
"@codemirror/view": "npm:6.34.0"
|
||||
"@egjs/hammerjs": "npm:2.0.17"
|
||||
"@formatjs/intl-datetimeformat": "npm:6.12.5"
|
||||
"@formatjs/intl-displaynames": "npm:6.6.8"
|
||||
@ -9074,7 +9074,7 @@ __metadata:
|
||||
qr-scanner: "npm:1.4.2"
|
||||
qrcode: "npm:1.5.4"
|
||||
roboto-fontface: "npm:0.10.0"
|
||||
rollup: "npm:2.79.1"
|
||||
rollup: "npm:2.79.2"
|
||||
rollup-plugin-string: "npm:3.0.0"
|
||||
rollup-plugin-terser: "npm:7.0.2"
|
||||
rollup-plugin-visualizer: "npm:5.12.0"
|
||||
@ -9099,7 +9099,7 @@ __metadata:
|
||||
vis-network: "npm:9.1.9"
|
||||
vue: "npm:2.7.16"
|
||||
vue2-daterange-picker: "npm:0.6.8"
|
||||
webpack: "npm:5.94.0"
|
||||
webpack: "npm:5.95.0"
|
||||
webpack-cli: "npm:5.1.4"
|
||||
webpack-dev-server: "npm:5.1.0"
|
||||
webpack-manifest-plugin: "npm:5.0.0"
|
||||
@ -12750,9 +12750,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rollup@npm:2.79.1, rollup@npm:^2.43.1, rollup@npm:^2.67.0":
|
||||
version: 2.79.1
|
||||
resolution: "rollup@npm:2.79.1"
|
||||
"rollup@npm:2.79.2, rollup@npm:^2.43.1, rollup@npm:^2.67.0":
|
||||
version: 2.79.2
|
||||
resolution: "rollup@npm:2.79.2"
|
||||
dependencies:
|
||||
fsevents: "npm:~2.3.2"
|
||||
dependenciesMeta:
|
||||
@ -12760,7 +12760,7 @@ __metadata:
|
||||
optional: true
|
||||
bin:
|
||||
rollup: dist/bin/rollup
|
||||
checksum: 10/df087b701304432f30922bbee5f534ab189aa6938bd383b5686c03147e0d00cd1789ea10a462361326ce6b6ebe448ce272ad3f3cc40b82eeb3157df12f33663c
|
||||
checksum: 10/095ba0a82811b1866a76d826987743278db0a87c45092656986bfff490326b66187d5f9ff0c24cf8d5682bc470aa00c36654e0044d6b6335ac0c1201b8280880
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -14902,9 +14902,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webpack@npm:5.94.0":
|
||||
version: 5.94.0
|
||||
resolution: "webpack@npm:5.94.0"
|
||||
"webpack@npm:5.95.0":
|
||||
version: 5.95.0
|
||||
resolution: "webpack@npm:5.95.0"
|
||||
dependencies:
|
||||
"@types/estree": "npm:^1.0.5"
|
||||
"@webassemblyjs/ast": "npm:^1.12.1"
|
||||
@ -14934,7 +14934,7 @@ __metadata:
|
||||
optional: true
|
||||
bin:
|
||||
webpack: bin/webpack.js
|
||||
checksum: 10/648449c5fbbb0839814116e3b2b044ac6c75a7ba272435155ddeb1e64dfaa2f8079be3adfbb691f648b69900756ce0f6fb73beab0ced3cf5e0fd46868b4593a6
|
||||
checksum: 10/0377ad3a550b041f26237c96fb55754625b0ce6bae83c1c2447e3262ad056b0b0ad770dcbb92b59f188e9a2bd56155ce910add17dcf023cfbe78bdec774380c1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user