Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add frontend support for date platform #14389

Merged
merged 12 commits into from
May 5, 2023
2 changes: 2 additions & 0 deletions src/common/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export const FIXED_DOMAIN_ICONS = {
configurator: mdiCog,
conversation: mdiMicrophoneMessage,
counter: mdiCounter,
date: mdiCalendar,
demo: mdiHomeAssistant,
google_assistant: mdiGoogleAssistant,
group: mdiGoogleCirclesCommunities,
Expand Down Expand Up @@ -208,6 +209,7 @@ export const DOMAINS_INPUT_ROW = [
"automation",
"button",
"cover",
"date",
"fan",
"group",
"humidifier",
Expand Down
2 changes: 1 addition & 1 deletion src/common/entity/compute_state_display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export const computeStateDisplayFromEntityAttributes = (

const domain = computeDomain(entityId);

if (domain === "input_datetime" || domain === "time") {
if (["date", "input_datetime", "time"].includes(domain)) {
if (state !== undefined) {
// If trying to display an explicit state, need to parse the explicit state to `Date` then format.
// Attributes aren't available, we have to use `state`.
Expand Down
14 changes: 14 additions & 0 deletions src/data/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { HassEntityBase } from "home-assistant-js-websocket";
import { HomeAssistant } from "../types";

export const stateToIsoDateString = (entityState: HassEntityBase) =>
`${entityState}T00:00:00`;

export const setDateValue = (
hass: HomeAssistant,
entityId: string,
date: string | undefined = undefined
) => {
const param = { entity_id: entityId, date };
hass.callService(entityId.split(".", 1)[0], "set_value", param);
};
2 changes: 2 additions & 0 deletions src/panels/lovelace/create-element/create-row-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const LAZY_LOAD_TYPES = {
"button-entity": () => import("../entity-rows/hui-button-entity-row"),
"climate-entity": () => import("../entity-rows/hui-climate-entity-row"),
"cover-entity": () => import("../entity-rows/hui-cover-entity-row"),
"date-entity": () => import("../entity-rows/hui-date-entity-row"),
"group-entity": () => import("../entity-rows/hui-group-entity-row"),
"input-button-entity": () =>
import("../entity-rows/hui-input-button-entity-row"),
Expand Down Expand Up @@ -61,6 +62,7 @@ const DOMAIN_TO_ELEMENT_TYPE = {
button: "button",
climate: "climate",
cover: "cover",
date: "date",
fan: "toggle",
group: "group",
humidifier: "humidifier",
Expand Down
72 changes: 72 additions & 0 deletions src/panels/lovelace/entity-rows/hui-date-entity-row.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { html, LitElement, nothing, PropertyValues, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import "../../../components/ha-date-input";
import { isUnavailableState } from "../../../data/entity";
import { setDateValue, stateToIsoDateString } from "../../../data/date";
import type { HomeAssistant } from "../../../types";
import { hasConfigOrEntityChanged } from "../common/has-changed";
import "../components/hui-generic-entity-row";
import { createEntityNotFoundWarning } from "../components/hui-warning";
import type { EntityConfig, LovelaceRow } from "./types";

@customElement("hui-date-entity-row")
class HuiDateEntityRow extends LitElement implements LovelaceRow {
@property({ attribute: false }) public hass?: HomeAssistant;

@state() private _config?: EntityConfig;

public setConfig(config: EntityConfig): void {
if (!config) {
throw new Error("Invalid configuration");
}
this._config = config;
}

protected shouldUpdate(changedProps: PropertyValues): boolean {
return hasConfigOrEntityChanged(this, changedProps);
}

protected render(): TemplateResult | typeof nothing {
if (!this._config || !this.hass) {
return nothing;
}

const stateObj = this.hass.states[this._config.entity];

if (!stateObj) {
return html`
<hui-warning>
${createEntityNotFoundWarning(this.hass, this._config.entity)}
</hui-warning>
`;
}

return html`
<hui-generic-entity-row
.hass=${this.hass}
.config=${this._config}
hideName="true"
>
<ha-date-input
.locale=${this.hass.locale}
.disabled=${isUnavailableState(stateObj.state)}
.value=${stateToIsoDateString(stateObj)}
@value-changed=${this._dateChanged}
>
</ha-date-input>
</hui-generic-entity-row>
`;
}

private _dateChanged(ev: CustomEvent<{ value: string }>): void {
const stateObj = this.hass!.states[this._config!.entity];

setDateValue(this.hass!, stateObj.entity_id, ev.detail.value);
}
}

declare global {
interface HTMLElementTagNameMap {
"hui-date-entity-row": HuiDateEntityRow;
}
}