mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-08 18:06:36 +00:00
Ensure timer row uses correct state translation keys (#9143)
* Ensure timer row uses correct state translation keys * Changes from review * Update src/panels/lovelace/entity-rows/hui-timer-entity-row.ts Co-authored-by: Bram Kragten <mail@bramkragten.nl> * Move logic to data/timer Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
c78382c119
commit
d425767dae
@ -1,19 +0,0 @@
|
|||||||
import { HassEntity } from "home-assistant-js-websocket";
|
|
||||||
import durationToSeconds from "../datetime/duration_to_seconds";
|
|
||||||
|
|
||||||
export const timerTimeRemaining = (
|
|
||||||
stateObj: HassEntity
|
|
||||||
): undefined | number => {
|
|
||||||
if (!stateObj.attributes.remaining) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
let timeRemaining = durationToSeconds(stateObj.attributes.remaining);
|
|
||||||
|
|
||||||
if (stateObj.state === "active") {
|
|
||||||
const now = new Date().getTime();
|
|
||||||
const madeActive = new Date(stateObj.last_changed).getTime();
|
|
||||||
timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return timeRemaining;
|
|
||||||
};
|
|
@ -15,7 +15,7 @@ import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
|||||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||||
import { domainIcon } from "../../common/entity/domain_icon";
|
import { domainIcon } from "../../common/entity/domain_icon";
|
||||||
import { stateIcon } from "../../common/entity/state_icon";
|
import { stateIcon } from "../../common/entity/state_icon";
|
||||||
import { timerTimeRemaining } from "../../common/entity/timer_time_remaining";
|
import { timerTimeRemaining } from "../../data/timer";
|
||||||
import { formatNumber } from "../../common/string/format_number";
|
import { formatNumber } from "../../common/string/format_number";
|
||||||
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
|
HassEntity,
|
||||||
HassEntityAttributeBase,
|
HassEntityAttributeBase,
|
||||||
HassEntityBase,
|
HassEntityBase,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
|
import durationToSeconds from "../common/datetime/duration_to_seconds";
|
||||||
|
import secondsToDuration from "../common/datetime/seconds_to_duration";
|
||||||
|
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
export type TimerEntity = HassEntityBase & {
|
export type TimerEntity = HassEntityBase & {
|
||||||
@ -55,3 +59,46 @@ export const deleteTimer = (hass: HomeAssistant, id: string) =>
|
|||||||
type: "timer/delete",
|
type: "timer/delete",
|
||||||
timer_id: id,
|
timer_id: id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const timerTimeRemaining = (
|
||||||
|
stateObj: HassEntity
|
||||||
|
): undefined | number => {
|
||||||
|
if (!stateObj.attributes.remaining) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
let timeRemaining = durationToSeconds(stateObj.attributes.remaining);
|
||||||
|
|
||||||
|
if (stateObj.state === "active") {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
const madeActive = new Date(stateObj.last_changed).getTime();
|
||||||
|
timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeRemaining;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const computeDisplayTimer = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
stateObj: HassEntity,
|
||||||
|
timeRemaining?: number
|
||||||
|
): string | null => {
|
||||||
|
if (!stateObj) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateObj.state === "idle" || timeRemaining === 0) {
|
||||||
|
return computeStateDisplay(hass.localize, stateObj, hass.locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
let display = secondsToDuration(timeRemaining || 0);
|
||||||
|
|
||||||
|
if (stateObj.state === "paused") {
|
||||||
|
display = `${display} (${computeStateDisplay(
|
||||||
|
hass.localize,
|
||||||
|
stateObj,
|
||||||
|
hass.locale
|
||||||
|
)})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return display;
|
||||||
|
};
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import secondsToDuration from "../../../common/datetime/seconds_to_duration";
|
import { computeDisplayTimer, timerTimeRemaining } from "../../../data/timer";
|
||||||
import { timerTimeRemaining } from "../../../common/entity/timer_time_remaining";
|
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
import "../components/hui-generic-entity-row";
|
import "../components/hui-generic-entity-row";
|
||||||
@ -58,7 +57,9 @@ class HuiTimerEntityRow extends LitElement {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
|
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
|
||||||
<div class="text-content">${this._computeDisplay(stateObj)}</div>
|
<div class="text-content">
|
||||||
|
${computeDisplayTimer(this.hass, stateObj, this._timeRemaining)}
|
||||||
|
</div>
|
||||||
</hui-generic-entity-row>
|
</hui-generic-entity-row>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -111,26 +112,6 @@ class HuiTimerEntityRow extends LitElement {
|
|||||||
private _calculateRemaining(stateObj: HassEntity): void {
|
private _calculateRemaining(stateObj: HassEntity): void {
|
||||||
this._timeRemaining = timerTimeRemaining(stateObj);
|
this._timeRemaining = timerTimeRemaining(stateObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _computeDisplay(stateObj: HassEntity): string | null {
|
|
||||||
if (!stateObj) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stateObj.state === "idle" || this._timeRemaining === 0) {
|
|
||||||
return (
|
|
||||||
this.hass!.localize(`state.timer.${stateObj.state}`) || stateObj.state
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let display = secondsToDuration(this._timeRemaining || 0);
|
|
||||||
|
|
||||||
if (stateObj.state === "paused") {
|
|
||||||
display += ` (${this.hass!.localize("state.timer.paused")})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return display;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -2,9 +2,8 @@ import "@polymer/iron-flex-layout/iron-flex-layout-classes";
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
/* eslint-plugin-disable lit */
|
/* eslint-plugin-disable lit */
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
import secondsToDuration from "../common/datetime/seconds_to_duration";
|
|
||||||
import { timerTimeRemaining } from "../common/entity/timer_time_remaining";
|
|
||||||
import "../components/entity/state-info";
|
import "../components/entity/state-info";
|
||||||
|
import { computeDisplayTimer, timerTimeRemaining } from "../data/timer";
|
||||||
|
|
||||||
class StateCardTimer extends PolymerElement {
|
class StateCardTimer extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@ -18,6 +17,7 @@ class StateCardTimer extends PolymerElement {
|
|||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@ -90,10 +90,8 @@ class StateCardTimer extends PolymerElement {
|
|||||||
this.timeRemaining = timerTimeRemaining(stateObj);
|
this.timeRemaining = timerTimeRemaining(stateObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
_displayState(time, stateObj) {
|
_displayState(timeRemaining, stateObj) {
|
||||||
return time
|
return computeDisplayTimer(this.hass, stateObj, timeRemaining);
|
||||||
? secondsToDuration(time)
|
|
||||||
: this.hass.localize(`state.timer.${stateObj.state}`) || stateObj.state;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define("state-card-timer", StateCardTimer);
|
customElements.define("state-card-timer", StateCardTimer);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
import * as sinon from "sinon";
|
import * as sinon from "sinon";
|
||||||
|
|
||||||
import { timerTimeRemaining } from "../../../src/common/entity/timer_time_remaining";
|
import { timerTimeRemaining } from "../../../src/data/timer";
|
||||||
|
|
||||||
describe("timerTimeRemaining", () => {
|
describe("timerTimeRemaining", () => {
|
||||||
it("works with idle timers", () => {
|
it("works with idle timers", () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user