diff --git a/package.json b/package.json
index 3f4e61c24329..0d2a855179f1 100644
--- a/package.json
+++ b/package.json
@@ -119,7 +119,7 @@
"leaflet-draw": "1.0.4",
"lit": "2.8.0",
"luxon": "3.4.4",
- "marked": "11.1.0",
+ "marked": "11.1.1",
"memoize-one": "6.0.0",
"node-vibrant": "3.2.1-alpha.1",
"proxy-polyfill": "0.3.2",
diff --git a/pyproject.toml b/pyproject.toml
index b1f2ee8ea705..d9414825fabf 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240103.3"
+version = "20240104.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
diff --git a/src/auth/ha-auth-textfield.ts b/src/auth/ha-auth-textfield.ts
index 123deef03fe9..20d5e66174c8 100644
--- a/src/auth/ha-auth-textfield.ts
+++ b/src/auth/ha-auth-textfield.ts
@@ -47,7 +47,7 @@ export class HaAuthTextField extends HaTextField {
// TODO: live() directive needs casting for lit-analyzer
// https://github.com/runem/lit-analyzer/pull/91/files
// TODO: lit-analyzer labels min/max as (number|string) instead of string
- return html` 0
? html`
`;
} else if (info.type === "failed") {
diff --git a/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts b/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts
index 67b902ba6581..f7df3507fa4e 100644
--- a/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts
+++ b/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts
@@ -247,7 +247,7 @@ export class AssistPipelineRunDebug extends LitElement {
}
// Play audio when we're done.
- if (updatedRun.stage === "done") {
+ if (updatedRun.stage === "done" && !updatedRun.error) {
const url = updatedRun.tts!.tts_output!.url;
const audio = new Audio(url);
audio.addEventListener("ended", () => {
@@ -261,7 +261,10 @@ export class AssistPipelineRunDebug extends LitElement {
}
});
audio.play();
- } else if (updatedRun.stage === "error") {
+ } else if (
+ (updatedRun.stage === "done" && updatedRun.error) ||
+ updatedRun.stage === "error"
+ ) {
this._finished = true;
}
},
diff --git a/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts b/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts
index 05da128692af..ae455152beb0 100644
--- a/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts
+++ b/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts
@@ -90,7 +90,7 @@ const renderProgress = (
return html`❌`;
}
return html`
-
+
`;
}
diff --git a/src/panels/lovelace/cards/hui-todo-list-card.ts b/src/panels/lovelace/cards/hui-todo-list-card.ts
index d1d62880f8ed..1d1c6b6c8243 100644
--- a/src/panels/lovelace/cards/hui-todo-list-card.ts
+++ b/src/panels/lovelace/cards/hui-todo-list-card.ts
@@ -335,7 +335,7 @@ export class HuiTodoListCard extends LitElement implements LovelaceCard {
const due = item.due
? item.due.includes("T")
? new Date(item.due)
- : endOfDay(new Date(item.due))
+ : endOfDay(new Date(`${item.due}T00:00:00`))
: undefined;
const today =
due && !item.due!.includes("T") && isSameDay(new Date(), due);
diff --git a/src/panels/lovelace/common/entity/turn-on-off-entity.ts b/src/panels/lovelace/common/entity/turn-on-off-entity.ts
index 701c2c4996ab..5be6beaea844 100644
--- a/src/panels/lovelace/common/entity/turn-on-off-entity.ts
+++ b/src/panels/lovelace/common/entity/turn-on-off-entity.ts
@@ -24,6 +24,9 @@ export const turnOnOffEntity = (
case "scene":
service = "turn_on";
break;
+ case "valve":
+ service = turnOn ? "open_valve" : "close_valve";
+ break;
default:
service = turnOn ? "turn_on" : "turn_off";
}
diff --git a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts
index 6a9c8eb04fdc..5f3e073f3a4f 100644
--- a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts
+++ b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts
@@ -8,6 +8,7 @@ import { stopPropagation } from "../../../../common/dom/stop_propagation";
import { createCloseHeading } from "../../../../components/ha-dialog";
import "../../../../components/ha-icon";
import "../../../../components/ha-select";
+import "../../../../components/ha-alert";
import {
fetchConfig,
LovelaceConfig,
@@ -104,8 +105,15 @@ export class HuiDialogSelectView extends LitElement {
})}
`
: ""}
- ${this._config
- ? this._config.views.length > 1
+ ${!this._config || (this._config.views || []).length < 1
+ ? html`${this.hass.localize(
+ this._config
+ ? "ui.panel.lovelace.editor.select_view.no_views"
+ : "ui.panel.lovelace.editor.select_view.no_config"
+ )}`
+ : this._config.views.length > 1
? html`
${this._config.views.map(
@@ -125,8 +133,7 @@ export class HuiDialogSelectView extends LitElement {
)}
`
- : ""
- : html`
No config found.
`}
+ : ""}
${this.hass!.localize("ui.common.cancel")}
-
+
${this._params.actionLabel || this.hass!.localize("ui.common.move")}
diff --git a/src/panels/profile/ha-panel-profile.ts b/src/panels/profile/ha-panel-profile.ts
index 1756af4d9333..9e82e842df5f 100644
--- a/src/panels/profile/ha-panel-profile.ts
+++ b/src/panels/profile/ha-panel-profile.ts
@@ -250,7 +250,6 @@ class HaPanelProfile extends LitElement {
max-width: 600px;
margin: 0 auto;
padding-bottom: env(safe-area-inset-bottom);
- overflow: hidden;
}
.content > * {
diff --git a/src/panels/todo/dialog-todo-item-editor.ts b/src/panels/todo/dialog-todo-item-editor.ts
index daa5eff68627..be03e260eccf 100644
--- a/src/panels/todo/dialog-todo-item-editor.ts
+++ b/src/panels/todo/dialog-todo-item-editor.ts
@@ -60,8 +60,10 @@ class DialogTodoItemEditor extends LitElement {
this._checked = entry.status === TodoItemStatus.Completed;
this._summary = entry.summary;
this._description = entry.description || "";
- this._due = entry.due ? new Date(entry.due) : undefined;
this._hasTime = entry.due?.includes("T") || false;
+ this._due = entry.due
+ ? new Date(this._hasTime ? entry.due : `${entry.due}T00:00:00`)
+ : undefined;
} else {
this._hasTime = false;
this._checked = false;
diff --git a/src/state-control/climate/ha-state-control-climate-temperature.ts b/src/state-control/climate/ha-state-control-climate-temperature.ts
index 7634fd2f2d18..0264af5ec7b3 100644
--- a/src/state-control/climate/ha-state-control-climate-temperature.ts
+++ b/src/state-control/climate/ha-state-control-climate-temperature.ts
@@ -177,11 +177,20 @@ export class HaStateControlClimateTemperature extends LitElement {
const action = this.stateObj.attributes.hvac_action;
+ const isTemperatureDisplayed =
+ (this.stateObj.attributes.current_temperature != null &&
+ this.showCurrentAsPrimary) ||
+ ((this._supportsTargetTemperature ||
+ this._supportsTargetTemperatureRange) &&
+ !this.showCurrentAsPrimary);
+
return html`
- ${action
+ ${action && action !== "off"
? this.hass.formatEntityAttributeValue(this.stateObj, "hvac_action")
- : this.hass.formatEntityState(this.stateObj)}
+ : isTemperatureDisplayed
+ ? this.hass.formatEntityState(this.stateObj)
+ : nothing}
`;
}
@@ -315,6 +324,14 @@ export class HaStateControlClimateTemperature extends LitElement {
`;
}
+ if (this.stateObj.state !== UNAVAILABLE) {
+ return html`
+
+ ${this.hass.formatEntityState(this.stateObj)}
+
+ `;
+ }
+
return nothing;
}
@@ -373,6 +390,14 @@ export class HaStateControlClimateTemperature extends LitElement {
return html``;
}
+ private _renderInfo() {
+ return html`
+
+ ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
+
+ `;
+ }
+
get _supportsTargetTemperature() {
return (
supportsFeature(this.stateObj, ClimateEntityFeature.TARGET_TEMPERATURE) &&
@@ -447,10 +472,7 @@ export class HaStateControlClimateTemperature extends LitElement {
@value-changing=${this._valueChanging}
>
-
- ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
-
- ${this._renderTemperatureButtons("value")}
+ ${this._renderInfo()} ${this._renderTemperatureButtons("value")}
`;
}
@@ -484,9 +506,7 @@ export class HaStateControlClimateTemperature extends LitElement {
@high-changing=${this._valueChanging}
>
-
- ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
-
+ ${this._renderInfo()}
${this._renderTemperatureButtons(this._selectTargetTemperature, true)}
`;
@@ -497,6 +517,7 @@ export class HaStateControlClimateTemperature extends LitElement {
class="container${containerSizeClass}"
style=${styleMap({
"--state-color": stateColor,
+ "--action-color": actionColor,
})}
>
-
- ${this._renderLabel()} ${this._renderSecondary()}
-
+ ${this._renderInfo()}
`;
}
diff --git a/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts b/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts
index 6078180cd849..459e8d611730 100644
--- a/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts
+++ b/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts
@@ -105,11 +105,18 @@ export class HaStateControlHumidifierHumidity extends LitElement {
const action = this.stateObj.attributes.action;
+ const isHumidityDisplayed =
+ (this.stateObj.attributes.current_humidity != null &&
+ this.showCurrentAsPrimary) ||
+ (this._targetHumidity != null && !this.showCurrentAsPrimary);
+
return html`
- ${action
+ ${action && action !== "off"
? this.hass.formatEntityAttributeValue(this.stateObj, "action")
- : this.hass.formatEntityState(this.stateObj)}
+ : isHumidityDisplayed
+ ? this.hass.formatEntityState(this.stateObj)
+ : nothing}
`;
}
@@ -144,6 +151,14 @@ export class HaStateControlHumidifierHumidity extends LitElement {
return this._renderTarget(this._targetHumidity!, "big");
}
+ if (this.stateObj.state !== UNAVAILABLE) {
+ return html`
+
+ ${this.hass.formatEntityState(this.stateObj)}
+
+ `;
+ }
+
return nothing;
}
@@ -225,6 +240,14 @@ export class HaStateControlHumidifierHumidity extends LitElement {
`;
}
+ private _renderInfo() {
+ return html`
+
+ ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
+
+ `;
+ }
+
protected render() {
const stateColor = stateColorCss(this.stateObj);
const active = stateActive(this.stateObj);
@@ -272,10 +295,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
@value-changing=${this._valueChanging}
>
-
- ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
-
- ${this._renderButtons()}
+ ${this._renderInfo()} ${this._renderButtons()}
`;
}
@@ -284,6 +304,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
@@ -296,9 +317,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
disabled
>
-
- ${this._renderLabel()} ${this._renderSecondary()}
-
+ ${this._renderInfo()}
`;
}
diff --git a/src/state-control/state-control-circular-slider-style.ts b/src/state-control/state-control-circular-slider-style.ts
index cc1c9366d7e9..b5d4d5281a03 100644
--- a/src/state-control/state-control-circular-slider-style.ts
+++ b/src/state-control/state-control-circular-slider-style.ts
@@ -54,7 +54,6 @@ export const stateControlCircularSliderStyle = css`
.label.disabled {
color: var(--secondary-text-color);
}
-
.buttons {
position: absolute;
bottom: 10px;
@@ -67,6 +66,9 @@ export const stateControlCircularSliderStyle = css`
align-items: center;
justify-content: center;
}
+ .primary-state {
+ font-size: 36px;
+ }
.buttons ha-outlined-icon-button {
--md-outlined-icon-button-container-width: 48px;
@@ -77,6 +79,9 @@ export const stateControlCircularSliderStyle = css`
.container.md ha-big-number {
font-size: 44px;
}
+ .container.md .state {
+ font-size: 30px;
+ }
.container.md .info {
margin-top: 12px;
gap: 6px;
@@ -91,6 +96,9 @@ export const stateControlCircularSliderStyle = css`
.container.sm ha-big-number {
font-size: 32px;
}
+ .container.sm .state {
+ font-size: 26px;
+ }
.container.sm .info {
margin-top: 12px;
font-size: 14px;
@@ -107,6 +115,9 @@ export const stateControlCircularSliderStyle = css`
.container.xs ha-big-number {
font-size: 32px;
}
+ .container.xs .state {
+ font-size: 16px;
+ }
.container.xs .info {
margin-top: 12px;
}
diff --git a/src/translations/en.json b/src/translations/en.json
index 53306cd8b77d..74467bcbf1ab 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -5020,7 +5020,9 @@
"select_view": {
"header": "Choose a view",
"dashboard_label": "Dashboard",
- "views_label": "View"
+ "views_label": "View",
+ "no_config": "No config found.",
+ "no_views": "No views in this dashboard."
},
"suggest_card": {
"header": "We created a suggestion for you",
diff --git a/yarn.lock b/yarn.lock
index 510c103b2e84..3997cc2fa300 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9679,7 +9679,7 @@ __metadata:
luxon: "npm:3.4.4"
magic-string: "npm:0.30.5"
map-stream: "npm:0.0.7"
- marked: "npm:11.1.0"
+ marked: "npm:11.1.1"
memoize-one: "npm:6.0.0"
mocha: "npm:10.2.0"
node-vibrant: "npm:3.2.1-alpha.1"
@@ -11655,12 +11655,12 @@ __metadata:
languageName: node
linkType: hard
-"marked@npm:11.1.0":
- version: 11.1.0
- resolution: "marked@npm:11.1.0"
+"marked@npm:11.1.1":
+ version: 11.1.1
+ resolution: "marked@npm:11.1.1"
bin:
marked: bin/marked.js
- checksum: 4636b16283c1963a715e97578d9fd91588b11949276e633a4de53dc408bcdab7b846d2b5c2cf3239f6d2dc8affe5294a0895954b5e3d9562d77301d8847a8915
+ checksum: c2e15a330ac75cca2e12e25aae09985a78ad7e96a84418964dcdd3ee776764a38812dc0e94e9fcbacac43113d1650ca7946f9dc0bab800d72181e56a37e7631e
languageName: node
linkType: hard