Add more info controls for date/time/datetime (#16775)

* Add more info controls for date/time/datetime

* Discard changes to src/panels/lovelace/entity-rows/hui-date-entity-row.ts

* handle unavailable
This commit is contained in:
Bram Kragten 2023-06-05 16:10:38 +02:00 committed by GitHub
parent 10ee8fda5b
commit 1470eb484f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 218 additions and 31 deletions

View File

@ -34,6 +34,8 @@ export const DOMAINS_WITH_MORE_INFO = [
"configurator", "configurator",
"counter", "counter",
"cover", "cover",
"date",
"datetime",
"fan", "fan",
"group", "group",
"humidifier", "humidifier",
@ -49,6 +51,7 @@ export const DOMAINS_WITH_MORE_INFO = [
"siren", "siren",
"sun", "sun",
"switch", "switch",
"time",
"timer", "timer",
"update", "update",
"vacuum", "vacuum",

View File

@ -0,0 +1,51 @@
import { HassEntity } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../components/ha-date-input";
import "../../../components/ha-time-input";
import { setDateValue } from "../../../data/date";
import { isUnavailableState } from "../../../data/entity";
import type { HomeAssistant } from "../../../types";
@customElement("more-info-date")
class MoreInfoDate extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public stateObj?: HassEntity;
protected render() {
if (!this.stateObj || isUnavailableState(this.stateObj.state)) {
return nothing;
}
return html`
<ha-date-input
.locale=${this.hass.locale}
.value=${this.stateObj.state}
.disabled=${isUnavailableState(this.stateObj.state)}
@value-changed=${this._dateChanged}
>
</ha-date-input>
`;
}
private _dateChanged(ev: CustomEvent<{ value: string }>): void {
setDateValue(this.hass!, this.stateObj!.entity_id, ev.detail.value);
}
static get styles(): CSSResultGroup {
return css`
:host {
display: flex;
align-items: center;
justify-content: flex-end;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"more-info-date": MoreInfoDate;
}
}

View File

@ -0,0 +1,80 @@
import { format } from "date-fns";
import { HassEntity } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../components/ha-date-input";
import "../../../components/ha-time-input";
import { setDateTimeValue } from "../../../data/datetime";
import { isUnavailableState } from "../../../data/entity";
import type { HomeAssistant } from "../../../types";
@customElement("more-info-datetime")
class MoreInfoDatetime extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public stateObj?: HassEntity;
protected render() {
if (!this.stateObj || isUnavailableState(this.stateObj.state)) {
return nothing;
}
const dateObj = new Date(this.stateObj.state);
const time = format(dateObj, "HH:mm:ss");
const date = format(dateObj, "yyyy-MM-dd");
return html`<ha-date-input
.locale=${this.hass.locale}
.value=${date}
.disabled=${isUnavailableState(this.stateObj.state)}
@value-changed=${this._dateChanged}
>
</ha-date-input>
<ha-time-input
.value=${time}
.locale=${this.hass.locale}
.disabled=${isUnavailableState(this.stateObj.state)}
@value-changed=${this._timeChanged}
@click=${this._stopEventPropagation}
></ha-time-input>`;
}
private _stopEventPropagation(ev: Event): void {
ev.stopPropagation();
}
private _timeChanged(ev: CustomEvent<{ value: string }>): void {
const dateObj = new Date(this.stateObj!.state);
const newTime = ev.detail.value.split(":").map(Number);
dateObj.setHours(newTime[0], newTime[1], newTime[2]);
setDateTimeValue(this.hass!, this.stateObj!.entity_id, dateObj);
}
private _dateChanged(ev: CustomEvent<{ value: string }>): void {
const dateObj = new Date(this.stateObj!.state);
const newDate = ev.detail.value.split("-").map(Number);
dateObj.setFullYear(newDate[0], newDate[1] - 1, newDate[2]);
setDateTimeValue(this.hass!, this.stateObj!.entity_id, dateObj);
}
static get styles(): CSSResultGroup {
return css`
:host {
display: flex;
align-items: center;
justify-content: flex-end;
}
ha-date-input + ha-time-input {
margin-left: 4px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"more-info-datetime": MoreInfoDatetime;
}
}

View File

@ -22,37 +22,32 @@ class MoreInfoInputDatetime extends LitElement {
} }
return html` return html`
${ ${this.stateObj.attributes.has_date
this.stateObj.attributes.has_date ? html`
? html` <ha-date-input
<ha-date-input .locale=${this.hass.locale}
.locale=${this.hass.locale} .value=${stateToIsoDateString(this.stateObj)}
.value=${stateToIsoDateString(this.stateObj)} .disabled=${isUnavailableState(this.stateObj.state)}
.disabled=${isUnavailableState(this.stateObj.state)} @value-changed=${this._dateChanged}
@value-changed=${this._dateChanged} >
> </ha-date-input>
</ha-date-input> `
` : ``}
: `` ${this.stateObj.attributes.has_time
} ? html`
${ <ha-time-input
this.stateObj.attributes.has_time .value=${this.stateObj.state === UNKNOWN
? html` ? ""
<ha-time-input : this.stateObj.attributes.has_date
.value=${this.stateObj.state === UNKNOWN ? this.stateObj.state.split(" ")[1]
? "" : this.stateObj.state}
: this.stateObj.attributes.has_date .locale=${this.hass.locale}
? this.stateObj.state.split(" ")[1] .disabled=${isUnavailableState(this.stateObj.state)}
: this.stateObj.state} @value-changed=${this._timeChanged}
.locale=${this.hass.locale} @click=${this._stopEventPropagation}
.disabled=${isUnavailableState(this.stateObj.state)} ></ha-time-input>
@value-changed=${this._timeChanged} `
@click=${this._stopEventPropagation} : ``}
></ha-time-input>
`
: ``
}
</hui-generic-entity-row>
`; `;
} }

View File

@ -0,0 +1,55 @@
import { HassEntity } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../components/ha-date-input";
import "../../../components/ha-time-input";
import { isUnavailableState } from "../../../data/entity";
import { setTimeValue } from "../../../data/time";
import type { HomeAssistant } from "../../../types";
@customElement("more-info-time")
class MoreInfoTime extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public stateObj?: HassEntity;
protected render() {
if (!this.stateObj || isUnavailableState(this.stateObj.state)) {
return nothing;
}
return html`
<ha-time-input
.value=${this.stateObj.state}
.locale=${this.hass.locale}
.disabled=${isUnavailableState(this.stateObj.state)}
@value-changed=${this._timeChanged}
@click=${this._stopEventPropagation}
></ha-time-input>
`;
}
private _stopEventPropagation(ev: Event): void {
ev.stopPropagation();
}
private _timeChanged(ev: CustomEvent<{ value: string }>): void {
setTimeValue(this.hass!, this.stateObj!.entity_id, ev.detail.value);
}
static get styles(): CSSResultGroup {
return css`
:host {
display: flex;
align-items: center;
justify-content: flex-end;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"more-info-time": MoreInfoTime;
}
}

View File

@ -13,6 +13,8 @@ const LAZY_LOADED_MORE_INFO_CONTROL = {
configurator: () => import("./controls/more-info-configurator"), configurator: () => import("./controls/more-info-configurator"),
counter: () => import("./controls/more-info-counter"), counter: () => import("./controls/more-info-counter"),
cover: () => import("./controls/more-info-cover"), cover: () => import("./controls/more-info-cover"),
date: () => import("./controls/more-info-date"),
datetime: () => import("./controls/more-info-datetime"),
fan: () => import("./controls/more-info-fan"), fan: () => import("./controls/more-info-fan"),
group: () => import("./controls/more-info-group"), group: () => import("./controls/more-info-group"),
humidifier: () => import("./controls/more-info-humidifier"), humidifier: () => import("./controls/more-info-humidifier"),
@ -27,6 +29,7 @@ const LAZY_LOADED_MORE_INFO_CONTROL = {
siren: () => import("./controls/more-info-siren"), siren: () => import("./controls/more-info-siren"),
sun: () => import("./controls/more-info-sun"), sun: () => import("./controls/more-info-sun"),
switch: () => import("./controls/more-info-switch"), switch: () => import("./controls/more-info-switch"),
time: () => import("./controls/more-info-time"),
timer: () => import("./controls/more-info-timer"), timer: () => import("./controls/more-info-timer"),
update: () => import("./controls/more-info-update"), update: () => import("./controls/more-info-update"),
vacuum: () => import("./controls/more-info-vacuum"), vacuum: () => import("./controls/more-info-vacuum"),