mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 08:16:36 +00:00
Basic input-datetime entity row (#3121)
* Basic input-datetime entity row * Address review comments * Fix imports
This commit is contained in:
parent
cd6250c495
commit
981dd5df63
126
src/components/ha-date-input.ts
Normal file
126
src/components/ha-date-input.ts
Normal file
@ -0,0 +1,126 @@
|
||||
import {
|
||||
html,
|
||||
css,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
property,
|
||||
customElement,
|
||||
} from "lit-element";
|
||||
|
||||
import "@polymer/paper-input/paper-input";
|
||||
// tslint:disable-next-line:no-duplicate-imports
|
||||
import { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||
|
||||
@customElement("ha-date-input")
|
||||
export class HaDateInput extends LitElement {
|
||||
@property() public year?: string;
|
||||
@property() public month?: string;
|
||||
@property() public day?: string;
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
font-family: var(--paper-font-common-base_-_font-family);
|
||||
-webkit-font-smoothing: var(
|
||||
--paper-font-common-base_-_-webkit-font-smoothing
|
||||
);
|
||||
}
|
||||
|
||||
paper-input {
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
--paper-input-container-input_-_-moz-appearance: textfield;
|
||||
--paper-input-container-input-webkit-spinner_-_-webkit-appearance: none;
|
||||
--paper-input-container-input-webkit-spinner_-_margin: 0;
|
||||
--paper-input-container-input-webkit-spinner_-_display: none;
|
||||
}
|
||||
|
||||
paper-input#year {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.date-input-wrap {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<div class="date-input-wrap">
|
||||
<paper-input
|
||||
id="year"
|
||||
type="number"
|
||||
.value=${this.year}
|
||||
@change=${this._formatYear}
|
||||
maxlength="4"
|
||||
max="9999"
|
||||
min="0"
|
||||
.disabled=${this.disabled}
|
||||
no-label-float
|
||||
>
|
||||
<span suffix="" slot="suffix">-</span>
|
||||
</paper-input>
|
||||
<paper-input
|
||||
id="month"
|
||||
type="number"
|
||||
.value=${this.month}
|
||||
@change=${this._formatMonth}
|
||||
maxlength="2"
|
||||
max="12"
|
||||
min="1"
|
||||
.disabled=${this.disabled}
|
||||
no-label-float
|
||||
>
|
||||
<span suffix="" slot="suffix">-</span>
|
||||
</paper-input>
|
||||
<paper-input
|
||||
id="day"
|
||||
type="number"
|
||||
.value=${this.day}
|
||||
@change=${this._formatDay}
|
||||
maxlength="2"
|
||||
max="31"
|
||||
min="1"
|
||||
.disabled=${this.disabled}
|
||||
no-label-float
|
||||
>
|
||||
</paper-input>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _formatYear() {
|
||||
const yearElement = this.shadowRoot!.getElementById(
|
||||
"year"
|
||||
) as PaperInputElement;
|
||||
this.year = yearElement.value!;
|
||||
}
|
||||
|
||||
private _formatMonth() {
|
||||
const monthElement = this.shadowRoot!.getElementById(
|
||||
"month"
|
||||
) as PaperInputElement;
|
||||
this.month = ("0" + monthElement.value!).slice(-2);
|
||||
}
|
||||
|
||||
private _formatDay() {
|
||||
const dayElement = this.shadowRoot!.getElementById(
|
||||
"day"
|
||||
) as PaperInputElement;
|
||||
this.day = ("0" + dayElement.value!).slice(-2);
|
||||
}
|
||||
|
||||
get value() {
|
||||
return `${this.year}-${this.month}-${this.day}`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-date-input": HaDateInput;
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
|
||||
class PaperTimeInput extends PolymerElement {
|
||||
export class PaperTimeInput extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
|
11
src/data/input_datetime.ts
Normal file
11
src/data/input_datetime.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
export const setInputDateTimeValue = (
|
||||
hass: HomeAssistant,
|
||||
entityId: string,
|
||||
time: string | undefined = undefined,
|
||||
date: string | undefined = undefined
|
||||
) => {
|
||||
const param = { entity_id: entityId, time, date };
|
||||
hass.callService(entityId.split(".", 1)[0], "set_datetime", param);
|
||||
};
|
@ -10,6 +10,7 @@ import {
|
||||
import "../entity-rows/hui-climate-entity-row";
|
||||
import "../entity-rows/hui-cover-entity-row";
|
||||
import "../entity-rows/hui-group-entity-row";
|
||||
import "../entity-rows/hui-input-datetime-entity-row";
|
||||
import "../entity-rows/hui-input-number-entity-row";
|
||||
import "../entity-rows/hui-input-select-entity-row";
|
||||
import "../entity-rows/hui-input-text-entity-row";
|
||||
@ -58,6 +59,7 @@ const DOMAIN_TO_ELEMENT_TYPE = {
|
||||
// Temporary. Once climate is rewritten,
|
||||
// water heater should get it's own row.
|
||||
water_heater: "climate",
|
||||
input_datetime: "input-datetime",
|
||||
};
|
||||
const TIMEOUT = 2000;
|
||||
|
||||
|
128
src/panels/lovelace/entity-rows/hui-input-datetime-entity-row.ts
Normal file
128
src/panels/lovelace/entity-rows/hui-input-datetime-entity-row.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import {
|
||||
html,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
property,
|
||||
PropertyValues,
|
||||
customElement,
|
||||
} from "lit-element";
|
||||
|
||||
import "../components/hui-generic-entity-row";
|
||||
import "../../../components/paper-time-input.js";
|
||||
// tslint:disable-next-line:no-duplicate-imports
|
||||
import { PaperTimeInput } from "../../../components/paper-time-input.js";
|
||||
import "../../../components/ha-date-input";
|
||||
// tslint:disable-next-line:no-duplicate-imports
|
||||
import { HaDateInput } from "../../../components/ha-date-input";
|
||||
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { EntityRow, EntityConfig } from "./types";
|
||||
import { setInputDateTimeValue } from "../../../data/input_datetime";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
|
||||
@customElement("hui-input-datetime-entity-row")
|
||||
class HuiInputDatetimeEntityRow extends LitElement implements EntityRow {
|
||||
@property() public hass?: HomeAssistant;
|
||||
@property() private _config?: EntityConfig;
|
||||
|
||||
public setConfig(config: EntityConfig): void {
|
||||
if (!config) {
|
||||
throw new Error("Configuration error");
|
||||
}
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||
return hasConfigOrEntityChanged(this, changedProps);
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
if (!this._config || !this.hass) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
const stateObj = this.hass.states[this._config.entity];
|
||||
|
||||
if (!stateObj) {
|
||||
return html`
|
||||
<hui-warning
|
||||
>${this.hass.localize(
|
||||
"ui.panel.lovelace.warning.entity_not_found",
|
||||
"entity",
|
||||
this._config.entity
|
||||
)}</hui-warning
|
||||
>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<hui-generic-entity-row .hass="${this.hass}" .config="${this._config}">
|
||||
${stateObj.attributes.has_date
|
||||
? html`
|
||||
<ha-date-input
|
||||
.year=${stateObj.attributes.year}
|
||||
.month=${("0" + stateObj.attributes.month).slice(-2)}
|
||||
.day=${("0" + stateObj.attributes.day).slice(-2)}
|
||||
@change=${this._selectedValueChanged}
|
||||
@click=${this._stopEventPropagation}
|
||||
></ha-date-input>
|
||||
${stateObj.attributes.has_time ? "," : ""}
|
||||
`
|
||||
: ``}
|
||||
${stateObj.attributes.has_time
|
||||
? html`
|
||||
<paper-time-input
|
||||
.hour=${stateObj.state === "unknown"
|
||||
? ""
|
||||
: ("0" + stateObj.attributes.hour).slice(-2)}
|
||||
.min=${stateObj.state === "unknown"
|
||||
? ""
|
||||
: ("0" + stateObj.attributes.minute).slice(-2)}
|
||||
.amPm=${false}
|
||||
@change=${this._selectedValueChanged}
|
||||
@click=${this._stopEventPropagation}
|
||||
hide-label
|
||||
format="24"
|
||||
></paper-time-input>
|
||||
`
|
||||
: ``}
|
||||
</hui-generic-entity-row>
|
||||
`;
|
||||
}
|
||||
|
||||
private _stopEventPropagation(ev: Event): void {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
private get _timeInputEl(): PaperTimeInput {
|
||||
return this.shadowRoot!.querySelector("paper-time-input")!;
|
||||
}
|
||||
|
||||
private get _dateInputEl(): HaDateInput {
|
||||
return this.shadowRoot!.querySelector("ha-date-input")!;
|
||||
}
|
||||
|
||||
private _selectedValueChanged(ev): void {
|
||||
const stateObj = this.hass!.states[this._config!.entity];
|
||||
|
||||
const time =
|
||||
this._timeInputEl !== null
|
||||
? this._timeInputEl.value.trim() + ":00"
|
||||
: undefined;
|
||||
|
||||
const date =
|
||||
this._dateInputEl !== null ? this._dateInputEl.value : undefined;
|
||||
|
||||
if (time !== stateObj.state) {
|
||||
setInputDateTimeValue(this.hass!, stateObj.entity_id, time, date);
|
||||
}
|
||||
|
||||
ev.target.blur();
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-input-datetime-entity-row": HuiInputDatetimeEntityRow;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user