mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
20230901.0 (#17782)
This commit is contained in:
commit
f90ab60354
@ -1,3 +0,0 @@
|
||||
---
|
||||
title: Temp Color Picker
|
||||
---
|
@ -1,117 +0,0 @@
|
||||
import "../../../../src/components/ha-temp-color-picker";
|
||||
|
||||
import { css, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-slider";
|
||||
|
||||
@customElement("demo-components-ha-temp-color-picker")
|
||||
export class DemoHaTempColorPicker extends LitElement {
|
||||
@state()
|
||||
min = 3000;
|
||||
|
||||
@state()
|
||||
max = 7000;
|
||||
|
||||
@state()
|
||||
value = 4000;
|
||||
|
||||
@state()
|
||||
liveValue?: number;
|
||||
|
||||
private _minChanged(ev) {
|
||||
this.min = Number(ev.target.value);
|
||||
}
|
||||
|
||||
private _maxChanged(ev) {
|
||||
this.max = Number(ev.target.value);
|
||||
}
|
||||
|
||||
private _valueChanged(ev) {
|
||||
this.value = Number(ev.target.value);
|
||||
}
|
||||
|
||||
private _tempColorCursor(ev) {
|
||||
this.liveValue = ev.detail.value;
|
||||
}
|
||||
|
||||
private _tempColorChanged(ev) {
|
||||
this.value = ev.detail.value;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<p class="value">${this.liveValue ?? this.value} K</p>
|
||||
<ha-temp-color-picker
|
||||
.min=${this.min}
|
||||
.max=${this.max}
|
||||
.value=${this.value}
|
||||
@value-changed=${this._tempColorChanged}
|
||||
@cursor-moved=${this._tempColorCursor}
|
||||
></ha-temp-color-picker>
|
||||
<p>Min temp : ${this.min} K</p>
|
||||
<ha-slider
|
||||
step="1"
|
||||
pin
|
||||
min="2000"
|
||||
max="10000"
|
||||
.value=${this.min}
|
||||
@change=${this._minChanged}
|
||||
>
|
||||
</ha-slider>
|
||||
<p>Max temp : ${this.max} K</p>
|
||||
<ha-slider
|
||||
step="1"
|
||||
pin
|
||||
min="2000"
|
||||
max="10000"
|
||||
.value=${this.max}
|
||||
@change=${this._maxChanged}
|
||||
>
|
||||
</ha-slider>
|
||||
<p>Value : ${this.value} K</p>
|
||||
<ha-slider
|
||||
step="1"
|
||||
pin
|
||||
min=${this.min}
|
||||
max=${this.max}
|
||||
.value=${this.value}
|
||||
@change=${this._valueChanged}
|
||||
>
|
||||
</ha-slider>
|
||||
</div>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
ha-temp-color-picker {
|
||||
width: 400px;
|
||||
}
|
||||
.value {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin: 0 0 12px 0;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"demo-components-ha-temp-color-picker": DemoHaTempColorPicker;
|
||||
}
|
||||
}
|
@ -181,12 +181,12 @@
|
||||
"@types/mocha": "10.0.1",
|
||||
"@types/qrcode": "1.5.1",
|
||||
"@types/serve-handler": "6.1.1",
|
||||
"@types/sortablejs": "1.15.1",
|
||||
"@types/sortablejs": "1.15.2",
|
||||
"@types/tar": "6.1.5",
|
||||
"@types/ua-parser-js": "0.7.36",
|
||||
"@types/webspeechapi": "0.0.29",
|
||||
"@typescript-eslint/eslint-plugin": "6.4.1",
|
||||
"@typescript-eslint/parser": "6.4.1",
|
||||
"@typescript-eslint/eslint-plugin": "6.5.0",
|
||||
"@typescript-eslint/parser": "6.5.0",
|
||||
"@web/dev-server": "0.1.38",
|
||||
"@web/dev-server-rollup": "0.4.1",
|
||||
"babel-loader": "9.1.3",
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20230831.0"
|
||||
version = "20230901.0"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
@ -108,7 +108,7 @@ export const formatNumber = (
|
||||
* @returns An `Intl.NumberFormatOptions` object with `maximumFractionDigits` set to 0, or `undefined`
|
||||
*/
|
||||
export const getNumberFormatOptions = (
|
||||
entityState: HassEntity,
|
||||
entityState?: HassEntity,
|
||||
entity?: EntityRegistryDisplayEntry
|
||||
): Intl.NumberFormatOptions | undefined => {
|
||||
const precision = entity?.display_precision;
|
||||
@ -119,8 +119,8 @@ export const getNumberFormatOptions = (
|
||||
};
|
||||
}
|
||||
if (
|
||||
Number.isInteger(Number(entityState.attributes?.step)) &&
|
||||
Number.isInteger(Number(entityState.state))
|
||||
Number.isInteger(Number(entityState?.attributes?.step)) &&
|
||||
Number.isInteger(Number(entityState?.state))
|
||||
) {
|
||||
return { maximumFractionDigits: 0 };
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { html, LitElement, PropertyValues, nothing } from "lit";
|
||||
import { LitElement, PropertyValues, html, nothing } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeStateDisplay } from "../../common/entity/compute_state_display";
|
||||
import { getStates } from "../../common/entity/get_states";
|
||||
import { computeAttributeValueDisplay } from "../../common/entity/compute_attribute_display";
|
||||
import { ValueChangedEvent, HomeAssistant } from "../../types";
|
||||
import { HomeAssistant, ValueChangedEvent } from "../../types";
|
||||
import "../ha-combo-box";
|
||||
import type { HaComboBox } from "../ha-combo-box";
|
||||
|
||||
@ -58,20 +56,9 @@ class HaEntityStatePicker extends LitElement {
|
||||
? getStates(state, this.attribute).map((key) => ({
|
||||
value: key,
|
||||
label: !this.attribute
|
||||
? computeStateDisplay(
|
||||
this.hass.localize,
|
||||
? this.hass.formatEntityState(state, key)
|
||||
: this.hass.formatEntityAttributeValue(
|
||||
state,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
key
|
||||
)
|
||||
: computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
state,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
this.attribute,
|
||||
key
|
||||
),
|
||||
|
@ -12,7 +12,6 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { arrayLiteralIncludes } from "../../common/array/literal-includes";
|
||||
import secondsToDuration from "../../common/datetime/seconds_to_duration";
|
||||
import { computeStateDisplay } from "../../common/entity/compute_state_display";
|
||||
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import { FIXED_DOMAIN_STATES } from "../../common/entity/get_states";
|
||||
@ -192,13 +191,7 @@ export class HaStateLabelBadge extends LitElement {
|
||||
this.hass!.locale,
|
||||
getNumberFormatOptions(entityState, entry)
|
||||
)
|
||||
: computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
entityState,
|
||||
this.hass!.locale,
|
||||
this.hass!.config,
|
||||
this.hass!.entities
|
||||
);
|
||||
: this.hass!.formatEntityState(entityState);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,14 @@
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
nothing,
|
||||
TemplateResult,
|
||||
} from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import { CLIMATE_PRESET_NONE, ClimateEntity } from "../data/climate";
|
||||
import { isUnavailableState } from "../data/entity";
|
||||
import { isUnavailableState, OFF } from "../data/entity";
|
||||
import type { HomeAssistant } from "../types";
|
||||
|
||||
@customElement("ha-climate-state")
|
||||
@ -22,26 +27,24 @@ class HaClimateState extends LitElement {
|
||||
${this.stateObj.attributes.preset_mode &&
|
||||
this.stateObj.attributes.preset_mode !== CLIMATE_PRESET_NONE
|
||||
? html`-
|
||||
${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"preset_mode"
|
||||
)}`
|
||||
: ""}
|
||||
: nothing}
|
||||
</span>
|
||||
<div class="unit">${this._computeTarget()}</div>`
|
||||
: this._localizeState()}
|
||||
</div>
|
||||
|
||||
${currentStatus && !isUnavailableState(this.stateObj.state)
|
||||
? html`<div class="current">
|
||||
${this.hass.localize("ui.card.climate.currently")}:
|
||||
<div class="unit">${currentStatus}</div>
|
||||
</div>`
|
||||
: ""}`;
|
||||
? html`
|
||||
<div class="current">
|
||||
${this.hass.localize("ui.card.climate.currently")}:
|
||||
<div class="unit">${currentStatus}</div>
|
||||
</div>
|
||||
`
|
||||
: nothing}`;
|
||||
}
|
||||
|
||||
private _computeCurrentStatus(): string | undefined {
|
||||
@ -125,24 +128,17 @@ class HaClimateState extends LitElement {
|
||||
return this.hass.localize(`state.default.${this.stateObj.state}`);
|
||||
}
|
||||
|
||||
const stateString = computeStateDisplay(
|
||||
this.hass.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
);
|
||||
const stateString = this.hass.formatEntityState(this.stateObj);
|
||||
|
||||
return this.stateObj.attributes.hvac_action
|
||||
? `${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"hvac_action"
|
||||
)} (${stateString})`
|
||||
: stateString;
|
||||
if (this.stateObj.attributes.hvac_action && this.stateObj.state !== OFF) {
|
||||
const actionString = this.hass.formatEntityAttributeValue(
|
||||
this.stateObj,
|
||||
"hvac_action"
|
||||
);
|
||||
return `${actionString} (${stateString})`;
|
||||
}
|
||||
|
||||
return stateString;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
|
@ -81,6 +81,7 @@ export class HaControlNumberButton extends LitElement {
|
||||
}
|
||||
|
||||
_handleKeyDown(e: KeyboardEvent) {
|
||||
if (this.disabled) return;
|
||||
if (!A11Y_KEY_CODES.has(e.code)) return;
|
||||
e.preventDefault();
|
||||
switch (e.code) {
|
||||
@ -116,7 +117,7 @@ export class HaControlNumberButton extends LitElement {
|
||||
const displayedValue =
|
||||
this.value != null
|
||||
? formatNumber(this.value, this.locale, this.formatOptions)
|
||||
: "-";
|
||||
: "";
|
||||
|
||||
return html`
|
||||
<div class="container">
|
||||
@ -124,12 +125,12 @@ export class HaControlNumberButton extends LitElement {
|
||||
id="input"
|
||||
class="value"
|
||||
role="number-button"
|
||||
tabindex="0"
|
||||
.tabIndex=${this.disabled ? "-1" : "0"}
|
||||
aria-valuenow=${this.value}
|
||||
aria-valuemin=${this.min}
|
||||
aria-valuemax=${this.max}
|
||||
aria-label=${ifDefined(this.label)}
|
||||
.disabled=${this.disabled}
|
||||
?disabled=${this.disabled}
|
||||
@keydown=${this._handleKeyDown}
|
||||
>
|
||||
${displayedValue}
|
||||
@ -240,6 +241,7 @@ export class HaControlNumberButton extends LitElement {
|
||||
.button[disabled] {
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.button.minus {
|
||||
left: 0;
|
||||
|
@ -217,6 +217,7 @@ export class HaControlSelect extends LitElement {
|
||||
transition: box-shadow 180ms ease-in-out;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
color: var(--primary-text-color);
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
@ -267,7 +268,6 @@ export class HaControlSelect extends LitElement {
|
||||
justify-content: center;
|
||||
border-radius: var(--control-select-button-border-radius);
|
||||
overflow: hidden;
|
||||
color: var(--primary-text-color);
|
||||
/* For safari border-radius overflow */
|
||||
z-index: 0;
|
||||
}
|
||||
@ -331,6 +331,7 @@ export class HaControlSelect extends LitElement {
|
||||
:host([disabled]) {
|
||||
--control-select-color: var(--disabled-color);
|
||||
--control-select-focused-opacity: 0;
|
||||
color: var(--disabled-color);
|
||||
}
|
||||
:host([disabled]) .option {
|
||||
cursor: not-allowed;
|
||||
|
@ -7,6 +7,12 @@ import { hsv2rgb, rgb2hex } from "../common/color/convert-color";
|
||||
import { rgbw2rgb, rgbww2rgb } from "../common/color/convert-light-color";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
"cursor-moved": { value?: any };
|
||||
}
|
||||
}
|
||||
|
||||
function xy2polar(x: number, y: number) {
|
||||
const r = Math.sqrt(x * x + y * y);
|
||||
const phi = Math.atan2(y, x);
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import { isUnavailableState, OFF } from "../data/entity";
|
||||
import { HumidifierEntity } from "../data/humidifier";
|
||||
import type { HomeAssistant } from "../types";
|
||||
@ -21,12 +19,8 @@ class HaHumidifierState extends LitElement {
|
||||
${this._localizeState()}
|
||||
${this.stateObj.attributes.mode
|
||||
? html`-
|
||||
${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"mode"
|
||||
)}`
|
||||
: ""}
|
||||
@ -78,24 +72,17 @@ class HaHumidifierState extends LitElement {
|
||||
return this.hass.localize(`state.default.${this.stateObj.state}`);
|
||||
}
|
||||
|
||||
const stateString = computeStateDisplay(
|
||||
this.hass.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
);
|
||||
const stateString = this.hass.formatEntityState(this.stateObj);
|
||||
|
||||
return this.stateObj.attributes.action && this.stateObj.state !== OFF
|
||||
? `${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"action"
|
||||
)} (${stateString})`
|
||||
: stateString;
|
||||
if (this.stateObj.attributes.action && this.stateObj.state !== OFF) {
|
||||
const actionString = this.hass.formatEntityAttributeValue(
|
||||
this.stateObj,
|
||||
"action"
|
||||
);
|
||||
return `${actionString} (${stateString})`;
|
||||
}
|
||||
|
||||
return stateString;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
|
@ -1,440 +0,0 @@
|
||||
import { DIRECTION_ALL, Manager, Pan, Tap } from "@egjs/hammerjs";
|
||||
import { LitElement, PropertyValues, css, html, svg } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { rgb2hex } from "../common/color/convert-color";
|
||||
import {
|
||||
DEFAULT_MAX_KELVIN,
|
||||
DEFAULT_MIN_KELVIN,
|
||||
temperature2rgb,
|
||||
} from "../common/color/convert-light-color";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
|
||||
const SAFE_ZONE_FACTOR = 0.9;
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
"cursor-moved": { value?: any };
|
||||
}
|
||||
}
|
||||
|
||||
const A11Y_KEY_CODES = new Set([
|
||||
"ArrowRight",
|
||||
"ArrowUp",
|
||||
"ArrowLeft",
|
||||
"ArrowDown",
|
||||
"PageUp",
|
||||
"PageDown",
|
||||
"Home",
|
||||
"End",
|
||||
]);
|
||||
|
||||
function xy2polar(x: number, y: number) {
|
||||
const r = Math.sqrt(x * x + y * y);
|
||||
const phi = Math.atan2(y, x);
|
||||
return [r, phi];
|
||||
}
|
||||
|
||||
function polar2xy(r: number, phi: number) {
|
||||
const x = Math.cos(phi) * r;
|
||||
const y = Math.sin(phi) * r;
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
function drawColorWheel(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
minTemp: number,
|
||||
maxTemp: number
|
||||
) {
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
const radius = ctx.canvas.width / 2;
|
||||
|
||||
const min = Math.max(minTemp, 2000);
|
||||
const max = Math.min(maxTemp, 40000);
|
||||
|
||||
for (let y = -radius; y < radius; y += 1) {
|
||||
const x = radius * Math.sqrt(1 - (y / radius) ** 2);
|
||||
|
||||
const fraction = (y / (radius * SAFE_ZONE_FACTOR) + 1) / 2;
|
||||
|
||||
const temperature = Math.max(
|
||||
Math.min(min + fraction * (max - min), max),
|
||||
min
|
||||
);
|
||||
|
||||
const color = rgb2hex(temperature2rgb(temperature));
|
||||
|
||||
ctx.fillStyle = color;
|
||||
ctx.fillRect(radius - x, radius + y - 0.5, 2 * x, 2);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
@customElement("ha-temp-color-picker")
|
||||
class HaTempColorPicker extends LitElement {
|
||||
@property({ type: Boolean, reflect: true })
|
||||
public disabled = false;
|
||||
|
||||
@property({ type: Number, attribute: false })
|
||||
public renderSize?: number;
|
||||
|
||||
@property({ type: Number })
|
||||
public value?: number;
|
||||
|
||||
@property({ type: Number })
|
||||
public min = DEFAULT_MIN_KELVIN;
|
||||
|
||||
@property({ type: Number })
|
||||
public max = DEFAULT_MAX_KELVIN;
|
||||
|
||||
@query("#canvas") private _canvas!: HTMLCanvasElement;
|
||||
|
||||
private _mc?: HammerManager;
|
||||
|
||||
@state()
|
||||
private _pressed?: string;
|
||||
|
||||
@state()
|
||||
private _cursorPosition?: [number, number];
|
||||
|
||||
@state()
|
||||
private _localValue?: number;
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues): void {
|
||||
super.firstUpdated(changedProps);
|
||||
this._setupListeners();
|
||||
this._generateColorWheel();
|
||||
this.setAttribute("role", "slider");
|
||||
this.setAttribute("aria-orientation", "vertical");
|
||||
if (!this.hasAttribute("tabindex")) {
|
||||
this.setAttribute("tabindex", "0");
|
||||
}
|
||||
}
|
||||
|
||||
private _generateColorWheel() {
|
||||
const ctx = this._canvas.getContext("2d")!;
|
||||
drawColorWheel(ctx, this.min, this.max);
|
||||
}
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this._setupListeners();
|
||||
}
|
||||
|
||||
disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
this._destroyListeners();
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
super.updated(changedProps);
|
||||
if (changedProps.has("_localValue")) {
|
||||
this.setAttribute("aria-valuenow", this._localValue?.toString() ?? "");
|
||||
}
|
||||
if (changedProps.has("min") || changedProps.has("max")) {
|
||||
this._generateColorWheel();
|
||||
this._resetPosition();
|
||||
}
|
||||
if (changedProps.has("min")) {
|
||||
this.setAttribute("aria-valuemin", this.min.toString());
|
||||
}
|
||||
if (changedProps.has("max")) {
|
||||
this.setAttribute("aria-valuemax", this.max.toString());
|
||||
}
|
||||
if (changedProps.has("value")) {
|
||||
if (this._localValue !== this.value) {
|
||||
this._resetPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _setupListeners() {
|
||||
if (this._canvas && !this._mc) {
|
||||
this._mc = new Manager(this._canvas);
|
||||
this._mc.add(
|
||||
new Pan({
|
||||
direction: DIRECTION_ALL,
|
||||
enable: true,
|
||||
threshold: 0,
|
||||
})
|
||||
);
|
||||
|
||||
this._mc.add(new Tap({ event: "singletap" }));
|
||||
|
||||
let savedPosition;
|
||||
this._mc.on("panstart", (e) => {
|
||||
if (this.disabled) return;
|
||||
this._pressed = e.pointerType;
|
||||
savedPosition = this._cursorPosition;
|
||||
});
|
||||
this._mc.on("pancancel", () => {
|
||||
if (this.disabled) return;
|
||||
this._pressed = undefined;
|
||||
this._cursorPosition = savedPosition;
|
||||
});
|
||||
this._mc.on("panmove", (e) => {
|
||||
if (this.disabled) return;
|
||||
this._cursorPosition = this._getPositionFromEvent(e);
|
||||
this._localValue = this._getValueFromCoord(...this._cursorPosition);
|
||||
fireEvent(this, "cursor-moved", { value: this._localValue });
|
||||
});
|
||||
this._mc.on("panend", (e) => {
|
||||
if (this.disabled) return;
|
||||
this._pressed = undefined;
|
||||
this._cursorPosition = this._getPositionFromEvent(e);
|
||||
this._localValue = this._getValueFromCoord(...this._cursorPosition);
|
||||
fireEvent(this, "cursor-moved", { value: undefined });
|
||||
fireEvent(this, "value-changed", { value: this._localValue });
|
||||
});
|
||||
|
||||
this._mc.on("singletap", (e) => {
|
||||
if (this.disabled) return;
|
||||
this._cursorPosition = this._getPositionFromEvent(e);
|
||||
this._localValue = this._getValueFromCoord(...this._cursorPosition);
|
||||
fireEvent(this, "value-changed", { value: this._localValue });
|
||||
});
|
||||
|
||||
this.addEventListener("keydown", this._handleKeyDown);
|
||||
this.addEventListener("keyup", this._handleKeyUp);
|
||||
}
|
||||
}
|
||||
|
||||
private _resetPosition() {
|
||||
if (this.value === undefined) {
|
||||
this._cursorPosition = undefined;
|
||||
this._localValue = undefined;
|
||||
return;
|
||||
}
|
||||
const [, y] = this._getCoordsFromValue(this.value);
|
||||
const currentX = this._cursorPosition?.[0] ?? 0;
|
||||
const x =
|
||||
Math.sign(currentX) * Math.min(Math.sqrt(1 - y ** 2), Math.abs(currentX));
|
||||
this._cursorPosition = [x, y];
|
||||
this._localValue = this.value;
|
||||
}
|
||||
|
||||
private _getCoordsFromValue = (temperature: number): [number, number] => {
|
||||
if (this.value === this.min) {
|
||||
return [0, -1];
|
||||
}
|
||||
if (this.value === this.max) {
|
||||
return [0, 1];
|
||||
}
|
||||
const fraction = (temperature - this.min) / (this.max - this.min);
|
||||
const y = (2 * fraction - 1) * SAFE_ZONE_FACTOR;
|
||||
return [0, y];
|
||||
};
|
||||
|
||||
private _getValueFromCoord = (_x: number, y: number): number => {
|
||||
const fraction = (y / SAFE_ZONE_FACTOR + 1) / 2;
|
||||
const temperature = Math.max(
|
||||
Math.min(this.min + fraction * (this.max - this.min), this.max),
|
||||
this.min
|
||||
);
|
||||
return Math.round(temperature);
|
||||
};
|
||||
|
||||
private _getPositionFromEvent = (e: HammerInput): [number, number] => {
|
||||
const x = e.center.x;
|
||||
const y = e.center.y;
|
||||
const boundingRect = e.target.getBoundingClientRect();
|
||||
const offsetX = boundingRect.left;
|
||||
const offsetY = boundingRect.top;
|
||||
const maxX = e.target.clientWidth;
|
||||
const maxY = e.target.clientHeight;
|
||||
|
||||
const _x = (2 * (x - offsetX)) / maxX - 1;
|
||||
const _y = (2 * (y - offsetY)) / maxY - 1;
|
||||
|
||||
const [r, phi] = xy2polar(_x, _y);
|
||||
const [__x, __y] = polar2xy(Math.min(1, r), phi);
|
||||
return [__x, __y];
|
||||
};
|
||||
|
||||
private _destroyListeners() {
|
||||
if (this._mc) {
|
||||
this._mc.destroy();
|
||||
this._mc = undefined;
|
||||
}
|
||||
this.removeEventListener("keydown", this._handleKeyDown);
|
||||
this.removeEventListener("keyup", this._handleKeyDown);
|
||||
}
|
||||
|
||||
_handleKeyDown(e: KeyboardEvent) {
|
||||
if (!A11Y_KEY_CODES.has(e.code)) return;
|
||||
e.preventDefault();
|
||||
|
||||
const step = 1;
|
||||
const tenPercentStep = Math.max(step, (this.max - this.min) / 10);
|
||||
const currentValue =
|
||||
this._localValue ?? Math.round((this.max + this.min) / 2);
|
||||
switch (e.code) {
|
||||
case "ArrowRight":
|
||||
case "ArrowUp":
|
||||
this._localValue = Math.round(Math.min(currentValue + step, this.max));
|
||||
break;
|
||||
case "ArrowLeft":
|
||||
case "ArrowDown":
|
||||
this._localValue = Math.round(Math.max(currentValue - step, this.min));
|
||||
break;
|
||||
case "PageUp":
|
||||
this._localValue = Math.round(
|
||||
Math.min(currentValue + tenPercentStep, this.max)
|
||||
);
|
||||
break;
|
||||
case "PageDown":
|
||||
this._localValue = Math.round(
|
||||
Math.max(currentValue - tenPercentStep, this.min)
|
||||
);
|
||||
break;
|
||||
case "Home":
|
||||
this._localValue = this.min;
|
||||
break;
|
||||
case "End":
|
||||
this._localValue = this.max;
|
||||
break;
|
||||
}
|
||||
if (this._localValue != null) {
|
||||
const [_, y] = this._getCoordsFromValue(this._localValue);
|
||||
const currentX = this._cursorPosition?.[0] ?? 0;
|
||||
const x =
|
||||
Math.sign(currentX) *
|
||||
Math.min(Math.sqrt(1 - y ** 2), Math.abs(currentX));
|
||||
this._cursorPosition = [x, y];
|
||||
fireEvent(this, "cursor-moved", { value: this._localValue });
|
||||
}
|
||||
}
|
||||
|
||||
_handleKeyUp(e: KeyboardEvent) {
|
||||
if (!A11Y_KEY_CODES.has(e.code)) return;
|
||||
e.preventDefault();
|
||||
this.value = this._localValue;
|
||||
fireEvent(this, "value-changed", { value: this._localValue });
|
||||
}
|
||||
|
||||
render() {
|
||||
const size = this.renderSize || 400;
|
||||
const canvasSize = size * window.devicePixelRatio;
|
||||
|
||||
const rgb = temperature2rgb(
|
||||
this._localValue ?? Math.round((this.max + this.min) / 2)
|
||||
);
|
||||
|
||||
const [x, y] = this._cursorPosition ?? [0, 0];
|
||||
|
||||
const cx = ((x + 1) * size) / 2;
|
||||
const cy = ((y + 1) * size) / 2;
|
||||
|
||||
const markerPosition = `${cx}px, ${cy}px`;
|
||||
const markerScale = this._pressed
|
||||
? this._pressed === "touch"
|
||||
? "2.5"
|
||||
: "1.5"
|
||||
: "1";
|
||||
const markerOffset =
|
||||
this._pressed === "touch" ? `0px, -${size / 16}px` : "0px, 0px";
|
||||
|
||||
return html`
|
||||
<div class="container ${classMap({ pressed: Boolean(this._pressed) })}">
|
||||
<canvas id="canvas" .width=${canvasSize} .height=${canvasSize}></canvas>
|
||||
<svg
|
||||
id="interaction"
|
||||
viewBox="0 0 ${size} ${size}"
|
||||
overflow="visible"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<defs>${this.renderSVGFilter()}</defs>
|
||||
<g
|
||||
style=${styleMap({
|
||||
fill: rgb2hex(rgb),
|
||||
transform: `translate(${markerPosition})`,
|
||||
})}
|
||||
class="cursor"
|
||||
>
|
||||
<circle
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="16"
|
||||
style=${styleMap({
|
||||
fill: rgb2hex(rgb),
|
||||
transform: `translate(${markerOffset}) scale(${markerScale})`,
|
||||
visibility: this._cursorPosition ? undefined : "hidden",
|
||||
})}
|
||||
></circle>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderSVGFilter() {
|
||||
return svg`
|
||||
<filter
|
||||
id="marker-shadow"
|
||||
x="-50%"
|
||||
y="-50%"
|
||||
width="200%"
|
||||
height="200%"
|
||||
filterUnits="objectBoundingBox"
|
||||
>
|
||||
<feDropShadow dx="0" dy="1" stdDeviation="2" flood-opacity="0.3" flood-color="rgba(0, 0, 0, 1)"/>
|
||||
<feDropShadow dx="0" dy="1" stdDeviation="3" flood-opacity="0.15" flood-color="rgba(0, 0, 0, 1)"/>
|
||||
</filter>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
outline: none;
|
||||
}
|
||||
.container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
}
|
||||
canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
border-radius: 50%;
|
||||
transition: box-shadow 180ms ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
:host(:focus-visible) canvas {
|
||||
box-shadow: 0 0 0 2px rgb(255, 160, 0);
|
||||
}
|
||||
svg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
circle {
|
||||
fill: black;
|
||||
stroke: white;
|
||||
stroke-width: 2;
|
||||
filter: url(#marker-shadow);
|
||||
}
|
||||
.container:not(.pressed) circle {
|
||||
transition:
|
||||
transform 100ms ease-in-out,
|
||||
fill 100ms ease-in-out;
|
||||
}
|
||||
.container:not(.pressed) .cursor {
|
||||
transition: transform 200ms ease-in-out;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-temp-color-picker": HaTempColorPicker;
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import { formatNumber } from "../common/number/format_number";
|
||||
import LocalizeMixin from "../mixins/localize-mixin";
|
||||
|
||||
@ -84,12 +83,7 @@ class HaWaterHeaterState extends LocalizeMixin(PolymerElement) {
|
||||
}
|
||||
|
||||
_localizeState(stateObj) {
|
||||
return computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.entities
|
||||
);
|
||||
return this.hass.formatEntityState(stateObj);
|
||||
}
|
||||
}
|
||||
customElements.define("ha-water_heater-state", HaWaterHeaterState);
|
||||
|
@ -6,11 +6,7 @@ import {
|
||||
formatTimeWithSeconds,
|
||||
} from "../common/datetime/format_time";
|
||||
import secondsToDuration from "../common/datetime/seconds_to_duration";
|
||||
import {
|
||||
computeAttributeNameDisplay,
|
||||
computeAttributeValueDisplay,
|
||||
} from "../common/entity/compute_attribute_display";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import { computeAttributeNameDisplay } from "../common/entity/compute_attribute_display";
|
||||
import { computeStateName } from "../common/entity/compute_state_name";
|
||||
import "../resources/intl-polyfill";
|
||||
import type { HomeAssistant } from "../types";
|
||||
@ -235,23 +231,14 @@ const tryDescribeTrigger = (
|
||||
for (const state of trigger.from.values()) {
|
||||
from.push(
|
||||
trigger.attribute
|
||||
? computeAttributeValueDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
trigger.attribute,
|
||||
state
|
||||
).toString()
|
||||
: computeStateDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
state
|
||||
)
|
||||
? hass
|
||||
.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
trigger.attribute,
|
||||
state
|
||||
)
|
||||
.toString()
|
||||
: hass.formatEntityState(stateObj, state)
|
||||
);
|
||||
}
|
||||
if (from.length !== 0) {
|
||||
@ -261,23 +248,16 @@ const tryDescribeTrigger = (
|
||||
} else {
|
||||
base += ` from ${
|
||||
trigger.attribute
|
||||
? computeAttributeValueDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
trigger.attribute,
|
||||
trigger.from
|
||||
).toString()
|
||||
: computeStateDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
trigger.from.toString()
|
||||
).toString()
|
||||
? hass
|
||||
.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
trigger.attribute,
|
||||
trigger.from
|
||||
)
|
||||
.toString()
|
||||
: hass
|
||||
.formatEntityState(stateObj, trigger.from.toString())
|
||||
.toString()
|
||||
}`;
|
||||
}
|
||||
}
|
||||
@ -292,23 +272,14 @@ const tryDescribeTrigger = (
|
||||
for (const state of trigger.to.values()) {
|
||||
to.push(
|
||||
trigger.attribute
|
||||
? computeAttributeValueDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
trigger.attribute,
|
||||
state
|
||||
).toString()
|
||||
: computeStateDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
state
|
||||
).toString()
|
||||
? hass
|
||||
.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
trigger.attribute,
|
||||
state
|
||||
)
|
||||
.toString()
|
||||
: hass.formatEntityState(stateObj, state).toString()
|
||||
);
|
||||
}
|
||||
if (to.length !== 0) {
|
||||
@ -318,23 +289,14 @@ const tryDescribeTrigger = (
|
||||
} else {
|
||||
base += ` to ${
|
||||
trigger.attribute
|
||||
? computeAttributeValueDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
trigger.attribute,
|
||||
trigger.to
|
||||
).toString()
|
||||
: computeStateDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
trigger.to.toString()
|
||||
)
|
||||
? hass
|
||||
.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
trigger.attribute,
|
||||
trigger.to
|
||||
)
|
||||
.toString()
|
||||
: hass.formatEntityState(stateObj, trigger.to.toString())
|
||||
}`;
|
||||
}
|
||||
}
|
||||
@ -822,45 +784,27 @@ const tryDescribeCondition = (
|
||||
for (const state of condition.state.values()) {
|
||||
states.push(
|
||||
condition.attribute
|
||||
? computeAttributeValueDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
condition.attribute,
|
||||
state
|
||||
).toString()
|
||||
: computeStateDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
state
|
||||
)
|
||||
? hass
|
||||
.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
condition.attribute,
|
||||
state
|
||||
)
|
||||
.toString()
|
||||
: hass.formatEntityState(stateObj, state)
|
||||
);
|
||||
}
|
||||
} else if (condition.state !== "") {
|
||||
states.push(
|
||||
condition.attribute
|
||||
? computeAttributeValueDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
condition.attribute,
|
||||
condition.state
|
||||
).toString()
|
||||
: computeStateDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
condition.state.toString()
|
||||
)
|
||||
? hass
|
||||
.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
condition.attribute,
|
||||
condition.state
|
||||
)
|
||||
.toString()
|
||||
: hass.formatEntityState(stateObj, condition.state.toString())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -5,14 +5,12 @@ import {
|
||||
DOMAINS_WITH_DYNAMIC_PICTURE,
|
||||
} from "../common/const";
|
||||
import { computeDomain } from "../common/entity/compute_domain";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import { computeStateDomain } from "../common/entity/compute_state_domain";
|
||||
import { autoCaseNoun } from "../common/translations/auto_case_noun";
|
||||
import { LocalizeFunc } from "../common/translations/localize";
|
||||
import { HaEntityPickerEntityFilterFunc } from "../components/entity/ha-entity-picker";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { UNAVAILABLE, UNKNOWN } from "./entity";
|
||||
import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display";
|
||||
|
||||
const LOGBOOK_LOCALIZE_PATH = "ui.components.logbook.messages";
|
||||
export const CONTINUOUS_DOMAINS = ["counter", "proximity", "sensor", "zone"];
|
||||
@ -339,14 +337,9 @@ export const localizeStateMessage = (
|
||||
|
||||
// TODO: This is not working yet, as we don't get historic attribute values
|
||||
|
||||
const event_type = computeAttributeValueDisplay(
|
||||
hass!.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
"event_type"
|
||||
)?.toString();
|
||||
const event_type = hass
|
||||
.formatEntityAttributeValue(stateObj, "event_type")
|
||||
?.toString();
|
||||
|
||||
if (!event_type) {
|
||||
return localize(`${LOGBOOK_LOCALIZE_PATH}.detected_unknown_event`);
|
||||
@ -392,16 +385,7 @@ export const localizeStateMessage = (
|
||||
return hass.localize(
|
||||
`${LOGBOOK_LOCALIZE_PATH}.changed_to_state`,
|
||||
"state",
|
||||
stateObj
|
||||
? computeStateDisplay(
|
||||
localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
state
|
||||
)
|
||||
: state
|
||||
stateObj ? hass.formatEntityState(stateObj, state) : state
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,6 @@ import {
|
||||
} 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";
|
||||
|
||||
export type TimerEntity = HassEntityBase & {
|
||||
@ -90,25 +89,13 @@ export const computeDisplayTimer = (
|
||||
}
|
||||
|
||||
if (stateObj.state === "idle" || timeRemaining === 0) {
|
||||
return computeStateDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities
|
||||
);
|
||||
return hass.formatEntityState(stateObj);
|
||||
}
|
||||
|
||||
let display = secondsToDuration(timeRemaining || 0);
|
||||
|
||||
if (stateObj.state === "paused") {
|
||||
display = `${display} (${computeStateDisplay(
|
||||
hass.localize,
|
||||
stateObj,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities
|
||||
)})`;
|
||||
display = `${display} (${hass.formatEntityState(stateObj)})`;
|
||||
}
|
||||
|
||||
return display;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { isUnavailableState } from "../../../data/entity";
|
||||
import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor";
|
||||
@ -21,6 +20,7 @@ class EntityPreviewRow extends LitElement {
|
||||
return html`<state-badge
|
||||
.hass=${this.hass}
|
||||
.stateObj=${stateObj}
|
||||
stateColor
|
||||
></state-badge>
|
||||
<div class="name" .title=${computeStateName(stateObj)}>
|
||||
${computeStateName(stateObj)}
|
||||
@ -35,13 +35,7 @@ class EntityPreviewRow extends LitElement {
|
||||
capitalize
|
||||
></hui-timestamp-display>
|
||||
`
|
||||
: computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
: this.hass.formatEntityState(stateObj)}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { UNIT_F } from "../../../../common/const";
|
||||
import { computeAttributeValueDisplay } from "../../../../common/entity/compute_attribute_display";
|
||||
import { stateActive } from "../../../../common/entity/state_active";
|
||||
import { stateColorCss } from "../../../../common/entity/state_color";
|
||||
import { supportsFeature } from "../../../../common/entity/supports-feature";
|
||||
@ -162,14 +161,10 @@ export class HaMoreInfoClimateTemperature extends LitElement {
|
||||
|
||||
const action = this.stateObj.attributes.hvac_action;
|
||||
|
||||
const actionLabel = computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
const actionLabel = this.hass.formatEntityAttributeValue(
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"hvac_action"
|
||||
) as string;
|
||||
);
|
||||
|
||||
return html`
|
||||
<p class="label">
|
||||
|
@ -2,7 +2,6 @@ import { css, CSSResultGroup, html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { computeAttributeNameDisplay } from "../../../../common/entity/compute_attribute_display";
|
||||
import { computeStateDisplay } from "../../../../common/entity/compute_state_display";
|
||||
import { stateActive } from "../../../../common/entity/state_active";
|
||||
import { stateColorCss } from "../../../../common/entity/state_color";
|
||||
import "../../../../components/ha-control-select";
|
||||
@ -12,12 +11,12 @@ import { UNAVAILABLE } from "../../../../data/entity";
|
||||
import {
|
||||
computeFanSpeedCount,
|
||||
computeFanSpeedIcon,
|
||||
FAN_SPEED_COUNT_MAX_FOR_BUTTONS,
|
||||
FAN_SPEEDS,
|
||||
FanEntity,
|
||||
fanPercentageToSpeed,
|
||||
FanSpeed,
|
||||
fanSpeedToPercentage,
|
||||
FAN_SPEEDS,
|
||||
FAN_SPEED_COUNT_MAX_FOR_BUTTONS,
|
||||
} from "../../../../data/fan";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
|
||||
@ -68,14 +67,7 @@ export class HaMoreInfoFanSpeed extends LitElement {
|
||||
|
||||
private _localizeSpeed(speed: FanSpeed) {
|
||||
if (speed === "on" || speed === "off") {
|
||||
return computeStateDisplay(
|
||||
this.hass.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
speed
|
||||
);
|
||||
return this.hass.formatEntityState(this.stateObj, speed);
|
||||
}
|
||||
return (
|
||||
this.hass.localize(`ui.dialogs.more_info_control.fan.speed.${speed}`) ||
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import "../../../components/ha-absolute-time";
|
||||
import "../../../components/ha-relative-time";
|
||||
import { isUnavailableState } from "../../../data/entity";
|
||||
@ -20,30 +18,22 @@ export class HaMoreInfoStateHeader extends LitElement {
|
||||
|
||||
@state() private _absoluteTime = false;
|
||||
|
||||
private _computeStateDisplay(stateObj: HassEntity): TemplateResult | string {
|
||||
private _localizeState(): TemplateResult | string {
|
||||
if (
|
||||
stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP &&
|
||||
!isUnavailableState(stateObj.state)
|
||||
this.stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP &&
|
||||
!isUnavailableState(this.stateObj.state)
|
||||
) {
|
||||
return html`
|
||||
<hui-timestamp-display
|
||||
.hass=${this.hass}
|
||||
.ts=${new Date(stateObj.state)}
|
||||
.ts=${new Date(this.stateObj.state)}
|
||||
format="relative"
|
||||
capitalize
|
||||
></hui-timestamp-display>
|
||||
`;
|
||||
}
|
||||
|
||||
const stateDisplay = computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass!.locale,
|
||||
this.hass!.config,
|
||||
this.hass!.entities
|
||||
);
|
||||
|
||||
return stateDisplay;
|
||||
return this.hass.formatEntityState(this.stateObj);
|
||||
}
|
||||
|
||||
private _toggleAbsolute() {
|
||||
@ -51,8 +41,7 @@ export class HaMoreInfoStateHeader extends LitElement {
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const stateDisplay =
|
||||
this.stateOverride ?? this._computeStateDisplay(this.stateObj);
|
||||
const stateDisplay = this.stateOverride ?? this._localizeState();
|
||||
|
||||
return html`
|
||||
<p class="state">${stateDisplay}</p>
|
||||
|
@ -2,7 +2,6 @@ import { mdiMinus, mdiPlus } from "@mdi/js";
|
||||
import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { computeAttributeValueDisplay } from "../../../../common/entity/compute_attribute_display";
|
||||
import { stateActive } from "../../../../common/entity/state_active";
|
||||
import { stateColorCss } from "../../../../common/entity/state_color";
|
||||
import { clamp } from "../../../../common/number/clamp";
|
||||
@ -92,14 +91,10 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
|
||||
|
||||
const action = this.stateObj.attributes.action;
|
||||
|
||||
const actionLabel = computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
const actionLabel = this.hass.formatEntityAttributeValue(
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"action"
|
||||
) as string;
|
||||
);
|
||||
|
||||
return html`
|
||||
<p class="label">
|
||||
|
@ -26,7 +26,6 @@ import "../../../../components/ha-hs-color-picker";
|
||||
import "../../../../components/ha-icon";
|
||||
import "../../../../components/ha-icon-button-prev";
|
||||
import "../../../../components/ha-labeled-slider";
|
||||
import "../../../../components/ha-temp-color-picker";
|
||||
import {
|
||||
getLightCurrentModeRgbColor,
|
||||
LightColor,
|
||||
|
@ -1,25 +1,31 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
nothing,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { rgb2hex } from "../../../../common/color/convert-color";
|
||||
import {
|
||||
DEFAULT_MAX_KELVIN,
|
||||
DEFAULT_MIN_KELVIN,
|
||||
temperature2rgb,
|
||||
} from "../../../../common/color/convert-light-color";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { stateColorCss } from "../../../../common/entity/state_color";
|
||||
import { throttle } from "../../../../common/util/throttle";
|
||||
import "../../../../components/ha-temp-color-picker";
|
||||
import "../../../../components/ha-control-slider";
|
||||
import { UNAVAILABLE } from "../../../../data/entity";
|
||||
import {
|
||||
LightColor,
|
||||
LightColorMode,
|
||||
LightEntity,
|
||||
} from "../../../../data/light";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import {
|
||||
DEFAULT_MAX_KELVIN,
|
||||
DEFAULT_MIN_KELVIN,
|
||||
} from "../../../../common/color/convert-light-color";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
@ -28,6 +34,26 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
export const generateColorTemperatureGradient = (min: number, max: number) => {
|
||||
const count = 10;
|
||||
|
||||
const gradient: [number, string][] = [];
|
||||
|
||||
const step = (max - min) / count;
|
||||
const percentageStep = 1 / count;
|
||||
|
||||
for (let i = 0; i < count + 1; i++) {
|
||||
const value = min + step * i;
|
||||
|
||||
const hex = rgb2hex(temperature2rgb(value));
|
||||
gradient.push([percentageStep * i, hex]);
|
||||
}
|
||||
|
||||
return gradient
|
||||
.map(([stop, color]) => `${color} ${(stop as number) * 100}%`)
|
||||
.join(", ");
|
||||
};
|
||||
|
||||
@customElement("light-color-temp-picker")
|
||||
class LightColorTempPicker extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@ -46,18 +72,36 @@ class LightColorTempPicker extends LitElement {
|
||||
const maxKelvin =
|
||||
this.stateObj.attributes.max_color_temp_kelvin ?? DEFAULT_MAX_KELVIN;
|
||||
|
||||
const gradient = this._generateTemperatureGradient(minKelvin!, maxKelvin);
|
||||
const color = stateColorCss(this.stateObj);
|
||||
|
||||
return html`
|
||||
<ha-temp-color-picker
|
||||
@value-changed=${this._ctColorChanged}
|
||||
@cursor-moved=${this._ctColorCursorMoved}
|
||||
<ha-control-slider
|
||||
inverted
|
||||
vertical
|
||||
.value=${this._ctPickerValue}
|
||||
.min=${minKelvin}
|
||||
.max=${maxKelvin}
|
||||
.value=${this._ctPickerValue}
|
||||
mode="cursor"
|
||||
@value-changed=${this._ctColorChanged}
|
||||
@slider-moved=${this._ctColorCursorMoved}
|
||||
.ariaLabel=${this.hass.localize(
|
||||
"ui.dialogs.more_info_control.light.color_temp"
|
||||
)}
|
||||
style=${styleMap({
|
||||
"--control-slider-color": color,
|
||||
"--gradient": gradient,
|
||||
})}
|
||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||
>
|
||||
</ha-temp-color-picker>
|
||||
</ha-control-slider>
|
||||
`;
|
||||
}
|
||||
|
||||
private _generateTemperatureGradient = memoizeOne(
|
||||
(min: number, max: number) => generateColorTemperatureGradient(min, max)
|
||||
);
|
||||
|
||||
public _updateSliderValues() {
|
||||
const stateObj = this.stateObj;
|
||||
|
||||
@ -138,10 +182,18 @@ class LightColorTempPicker extends LitElement {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
ha-temp-color-picker {
|
||||
ha-control-slider {
|
||||
height: 45vh;
|
||||
max-height: 320px;
|
||||
min-height: 200px;
|
||||
--control-slider-thickness: 100px;
|
||||
--control-slider-border-radius: 24px;
|
||||
--control-slider-color: var(--primary-color);
|
||||
--control-slider-background: -webkit-linear-gradient(
|
||||
top,
|
||||
var(--gradient)
|
||||
);
|
||||
--control-slider-background-opacity: 1;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
@ -1,22 +1,21 @@
|
||||
import { mdiMenu, mdiSwapVertical } from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
nothing,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import "../../../components/ha-attributes";
|
||||
import "../../../components/ha-icon-button-group";
|
||||
import "../../../components/ha-icon-button-toggle";
|
||||
import {
|
||||
computeCoverPositionStateDisplay,
|
||||
CoverEntity,
|
||||
CoverEntityFeature,
|
||||
computeCoverPositionStateDisplay,
|
||||
} from "../../../data/cover";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import "../components/cover/ha-more-info-cover-buttons";
|
||||
@ -83,12 +82,8 @@ class MoreInfoCover extends LitElement {
|
||||
const forcedState =
|
||||
liveValue != null ? (liveValue ? "open" : "closed") : undefined;
|
||||
|
||||
const stateDisplay = computeStateDisplay(
|
||||
this.hass.localize,
|
||||
const stateDisplay = this.hass.formatEntityState(
|
||||
this.stateObj!,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
forcedState
|
||||
);
|
||||
|
||||
|
@ -10,11 +10,6 @@ import {
|
||||
import { property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { stopPropagation } from "../../../common/dom/stop_propagation";
|
||||
import {
|
||||
computeAttributeNameDisplay,
|
||||
computeAttributeValueDisplay,
|
||||
} from "../../../common/entity/compute_attribute_display";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import "../../../components/ha-control-select-menu";
|
||||
import "../../../components/ha-list-item";
|
||||
@ -58,26 +53,21 @@ class MoreInfoHumidifier extends LitElement {
|
||||
HumidifierEntityFeature.MODES
|
||||
);
|
||||
|
||||
const currentHumidity = this.stateObj.attributes.current_humidity as number;
|
||||
|
||||
return html`
|
||||
<div class="current">
|
||||
${currentHumidity != null
|
||||
${this.stateObj.attributes.current_humidity != null
|
||||
? html`
|
||||
<div>
|
||||
<p class="label">
|
||||
${computeAttributeNameDisplay(
|
||||
this.hass.localize,
|
||||
${this.hass.formatEntityAttributeName(
|
||||
this.stateObj,
|
||||
this.hass.entities,
|
||||
"current_humidity"
|
||||
)}
|
||||
</p>
|
||||
<p class="value">
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
this.stateObj,
|
||||
"current_humidity",
|
||||
currentHumidity
|
||||
"current_humidity"
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
@ -104,24 +94,10 @@ class MoreInfoHumidifier extends LitElement {
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiPower}></ha-svg-icon>
|
||||
<ha-list-item value="off">
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"off"
|
||||
)}
|
||||
${this.hass.formatEntityState(this.stateObj, "off")}
|
||||
</ha-list-item>
|
||||
<ha-list-item value="on">
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"on"
|
||||
)}
|
||||
${this.hass.formatEntityState(this.stateObj, "on")}
|
||||
</ha-list-item>
|
||||
</ha-control-select-menu>
|
||||
|
||||
@ -144,12 +120,8 @@ class MoreInfoHumidifier extends LitElement {
|
||||
slot="graphic"
|
||||
.path=${computeHumidiferModeIcon(mode)}
|
||||
></ha-svg-icon>
|
||||
${computeAttributeValueDisplay(
|
||||
hass.localize,
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
stateObj!,
|
||||
hass.locale,
|
||||
hass.config,
|
||||
hass.entities,
|
||||
"mode",
|
||||
mode
|
||||
)}
|
||||
|
@ -2,7 +2,6 @@ import { mdiHomeImportOutline, mdiPause, mdiPlay } from "@mdi/js";
|
||||
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
|
||||
@ -74,15 +73,7 @@ class MoreInfoLawnMower extends LitElement {
|
||||
)}:
|
||||
</span>
|
||||
<span>
|
||||
<strong>
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
</strong>
|
||||
<strong>${this.hass.formatEntityState(stateObj)}</strong>
|
||||
</span>
|
||||
</div>
|
||||
${this._renderBattery()}
|
||||
|
@ -9,24 +9,23 @@ import {
|
||||
mdiVolumeOff,
|
||||
mdiVolumePlus,
|
||||
} from "@mdi/js";
|
||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { stopPropagation } from "../../../common/dom/stop_propagation";
|
||||
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import { computeRTLDirection } from "../../../common/util/compute_rtl";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-select";
|
||||
import "../../../components/ha-slider";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog";
|
||||
import {
|
||||
computeMediaControls,
|
||||
handleMediaControlClick,
|
||||
MediaPickedEvent,
|
||||
MediaPlayerEntity,
|
||||
MediaPlayerEntityFeature,
|
||||
computeMediaControls,
|
||||
handleMediaControlClick,
|
||||
mediaPlayerPlayMedia,
|
||||
} from "../../../data/media-player";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
@ -157,24 +156,20 @@ class MoreInfoMediaPlayer extends LitElement {
|
||||
>
|
||||
${stateObj.attributes.source_list!.map(
|
||||
(source) => html`
|
||||
<mwc-list-item .value=${source}
|
||||
>${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
<mwc-list-item .value=${source}>
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"source",
|
||||
source
|
||||
)}</mwc-list-item
|
||||
>
|
||||
)}
|
||||
</mwc-list-item>
|
||||
`
|
||||
)}
|
||||
<ha-svg-icon .path=${mdiLoginVariant} slot="icon"></ha-svg-icon>
|
||||
</ha-select>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${stateActive(stateObj) &&
|
||||
supportsFeature(stateObj, MediaPlayerEntityFeature.SELECT_SOUND_MODE) &&
|
||||
stateObj.attributes.sound_mode_list?.length
|
||||
@ -191,17 +186,13 @@ class MoreInfoMediaPlayer extends LitElement {
|
||||
>
|
||||
${stateObj.attributes.sound_mode_list.map(
|
||||
(mode) => html`
|
||||
<mwc-list-item .value=${mode}
|
||||
>${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
<mwc-list-item .value=${mode}>
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"sound_mode",
|
||||
mode
|
||||
)}</mwc-list-item
|
||||
>
|
||||
)}
|
||||
</mwc-list-item>
|
||||
`
|
||||
)}
|
||||
<ha-svg-icon .path=${mdiMusicNote} slot="icon"></ha-svg-icon>
|
||||
|
@ -2,11 +2,10 @@ import "@material/mwc-list/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { html, LitElement, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
||||
import { stopPropagation } from "../../../common/dom/stop_propagation";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import "../../../components/ha-attributes";
|
||||
import { RemoteEntity, REMOTE_SUPPORT_ACTIVITY } from "../../../data/remote";
|
||||
import { REMOTE_SUPPORT_ACTIVITY, RemoteEntity } from "../../../data/remote";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
|
||||
const filterExtraAttributes = "activity_list,current_activity";
|
||||
@ -40,12 +39,8 @@ class MoreInfoRemote extends LitElement {
|
||||
${stateObj.attributes.activity_list!.map(
|
||||
(activity) => html`
|
||||
<mwc-list-item .value=${activity}>
|
||||
${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"activity",
|
||||
activity
|
||||
)}
|
||||
@ -54,7 +49,7 @@ class MoreInfoRemote extends LitElement {
|
||||
)}
|
||||
</mwc-list>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
|
||||
<ha-attributes
|
||||
.hass=${this.hass}
|
||||
|
@ -13,8 +13,6 @@ import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { stopPropagation } from "../../../common/dom/stop_propagation";
|
||||
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import "../../../components/entity/ha-battery-icon";
|
||||
@ -127,21 +125,8 @@ class MoreInfoVacuum extends LitElement {
|
||||
<strong>
|
||||
${supportsFeature(stateObj, VacuumEntityFeature.STATUS) &&
|
||||
stateObj.attributes.status
|
||||
? computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"status"
|
||||
)
|
||||
: computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
? this.hass.formatEntityAttributeValue(stateObj, "status")
|
||||
: this.hass.formatEntityState(stateObj)}
|
||||
</strong>
|
||||
</span>
|
||||
</div>
|
||||
@ -197,12 +182,8 @@ class MoreInfoVacuum extends LitElement {
|
||||
${stateObj.attributes.fan_speed_list!.map(
|
||||
(mode) => html`
|
||||
<mwc-list-item .value=${mode}>
|
||||
${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"fan_speed",
|
||||
mode
|
||||
)}
|
||||
@ -215,12 +196,8 @@ class MoreInfoVacuum extends LitElement {
|
||||
>
|
||||
<span>
|
||||
<ha-svg-icon .path=${mdiFan}></ha-svg-icon>
|
||||
${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"fan_speed"
|
||||
)}
|
||||
</span>
|
||||
|
@ -2,7 +2,6 @@ import "@material/mwc-button";
|
||||
import { html, LitElement, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeStateDisplay } from "../../common/entity/compute_state_display";
|
||||
import { domainToName } from "../../data/integration";
|
||||
import { PersitentNotificationEntity } from "../../data/persistent_notification";
|
||||
import { HomeAssistant } from "../../types";
|
||||
@ -33,15 +32,9 @@ export class HuiConfiguratorNotificationItem extends LitElement {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<mwc-button slot="actions" @click=${this._handleClick}
|
||||
>${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
this.notification,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}</mwc-button
|
||||
>
|
||||
<mwc-button slot="actions" @click=${this._handleClick}>
|
||||
${this.hass.formatEntityState(this.notification)}
|
||||
</mwc-button>
|
||||
</notification-item-template>
|
||||
`;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ const HIDDEN_DOMAINS = new Set([
|
||||
"radio_browser",
|
||||
"rpi_power",
|
||||
"sun",
|
||||
"google_translate",
|
||||
]);
|
||||
|
||||
@customElement("onboarding-integrations")
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { mdiPencilOff, mdiPlus } from "@mdi/js";
|
||||
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
||||
import { mdiAlertCircle, mdiPencilOff, mdiPlus } from "@mdi/js";
|
||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, PropertyValues, TemplateResult, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { domainIcon } from "../../../common/entity/domain_icon";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import { extractSearchParam } from "../../../common/url/search-params";
|
||||
@ -15,6 +14,7 @@ import {
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-icon";
|
||||
import "../../../components/ha-state-icon";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import { ConfigEntry, getConfigEntries } from "../../../data/config_entries";
|
||||
import { getConfigFlowHandlers } from "../../../data/config_flow";
|
||||
@ -37,6 +37,7 @@ import { configSections } from "../ha-panel-config";
|
||||
import "../integrations/ha-integration-overflow-menu";
|
||||
import { HelperDomain, isHelperDomain } from "./const";
|
||||
import { showHelperDetailDialog } from "./show-dialog-helper-detail";
|
||||
import { showOptionsFlowDialog } from "../../../dialogs/config-flow/show-dialog-options-flow";
|
||||
|
||||
// This groups items by a key but only returns last entry per key.
|
||||
const groupByOne = <T>(
|
||||
@ -83,10 +84,11 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
||||
label: localize("ui.panel.config.helpers.picker.headers.icon"),
|
||||
type: "icon",
|
||||
template: (icon, helper: any) =>
|
||||
icon
|
||||
? html` <ha-icon .icon=${icon}></ha-icon> `
|
||||
helper.entity
|
||||
? html`<ha-state-icon .state=${helper.entity}></ha-state-icon>`
|
||||
: html`<ha-svg-icon
|
||||
.path=${domainIcon(helper.type)}
|
||||
.path=${icon}
|
||||
style="color: var(--error-color)"
|
||||
></ha-svg-icon>`,
|
||||
},
|
||||
name: {
|
||||
@ -99,7 +101,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
||||
template: (name, item: any) => html`
|
||||
${name}
|
||||
${narrow
|
||||
? html` <div class="secondary">${item.entity_id}</div> `
|
||||
? html`<div class="secondary">${item.entity_id}</div> `
|
||||
: ""}
|
||||
`,
|
||||
},
|
||||
@ -157,17 +159,22 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
||||
stateItems: HassEntity[],
|
||||
entityEntries: Record<string, EntityRegistryEntry>,
|
||||
configEntries: Record<string, ConfigEntry>
|
||||
) =>
|
||||
stateItems.map((entityState) => {
|
||||
) => {
|
||||
const configEntriesCopy = { ...configEntries };
|
||||
|
||||
const states = stateItems.map((entityState) => {
|
||||
const configEntry = getConfigEntry(
|
||||
entityEntries,
|
||||
configEntries,
|
||||
entityState.entity_id
|
||||
);
|
||||
|
||||
if (configEntry) {
|
||||
delete configEntriesCopy[configEntry!.entry_id];
|
||||
}
|
||||
|
||||
return {
|
||||
id: entityState.entity_id,
|
||||
icon: entityState.attributes.icon,
|
||||
name: entityState.attributes.friendly_name || "",
|
||||
entity_id: entityState.entity_id,
|
||||
editable:
|
||||
@ -176,8 +183,27 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
||||
? configEntry.domain
|
||||
: computeStateDomain(entityState),
|
||||
configEntry,
|
||||
entity: entityState,
|
||||
};
|
||||
})
|
||||
});
|
||||
|
||||
if (!Object.keys(configEntriesCopy).length) {
|
||||
return states;
|
||||
}
|
||||
|
||||
const entries = Object.values(configEntriesCopy).map((configEntry) => ({
|
||||
id: configEntry.entry_id,
|
||||
entity_id: "",
|
||||
icon: mdiAlertCircle,
|
||||
name: configEntry.title || "",
|
||||
editable: true,
|
||||
type: configEntry.domain,
|
||||
configEntry,
|
||||
entity: undefined,
|
||||
}));
|
||||
|
||||
return [...states, ...entries];
|
||||
}
|
||||
);
|
||||
|
||||
protected render(): TemplateResult {
|
||||
@ -356,8 +382,12 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
|
||||
private async _openEditDialog(ev: CustomEvent): Promise<void> {
|
||||
const entityId = (ev.detail as RowClickedEvent).id;
|
||||
showMoreInfoDialog(this, { entityId });
|
||||
const id = (ev.detail as RowClickedEvent).id;
|
||||
if (id.includes(".")) {
|
||||
showMoreInfoDialog(this, { entityId: id });
|
||||
} else {
|
||||
showOptionsFlowDialog(this, this._configEntries![id]);
|
||||
}
|
||||
}
|
||||
|
||||
private _createHelpler() {
|
||||
|
@ -12,7 +12,6 @@ import { ifDefined } from "lit/directives/if-defined";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import {
|
||||
@ -176,13 +175,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
|
||||
this.hass.entities[this._config.entity]
|
||||
)
|
||||
)
|
||||
: computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}</span
|
||||
: this.hass.formatEntityState(stateObj)}</span
|
||||
>${showUnit
|
||||
? html`
|
||||
<span class="measurement"
|
||||
|
@ -1,10 +1,10 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
@ -12,7 +12,6 @@ import { classMap } from "lit/directives/class-map";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import "../../../components/entity/state-badge";
|
||||
import "../../../components/ha-card";
|
||||
@ -344,13 +343,7 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard {
|
||||
capitalize
|
||||
></ha-relative-time>
|
||||
`
|
||||
: computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass!.locale,
|
||||
this.hass!.config,
|
||||
this.hass!.entities
|
||||
)}
|
||||
: this.hass!.formatEntityState(stateObj)}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
|
@ -11,12 +11,10 @@ import {
|
||||
svg,
|
||||
} from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stateColorCss } from "../../../common/entity/state_color";
|
||||
import { formatNumber } from "../../../common/number/format_number";
|
||||
@ -168,34 +166,13 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
|
||||
>
|
||||
${
|
||||
stateObj.attributes.action
|
||||
? computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"action"
|
||||
)
|
||||
: computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)
|
||||
? this.hass.formatEntityAttributeValue(stateObj, "action")
|
||||
: this.hass.formatEntityState(stateObj)
|
||||
}
|
||||
${
|
||||
stateObj.state !== UNAVAILABLE && stateObj.attributes.mode
|
||||
? html`
|
||||
-
|
||||
${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"mode"
|
||||
)}
|
||||
- ${this.hass.formatEntityAttributeValue(stateObj, "mode")}
|
||||
`
|
||||
: nothing
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import "@thomasloven/round-slider";
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
@ -13,12 +13,12 @@ import { classMap } from "lit/directives/class-map";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stateColorBrightness } from "../../../common/entity/state_color";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-state-icon";
|
||||
import { isUnavailableState, UNAVAILABLE } from "../../../data/entity";
|
||||
import { UNAVAILABLE, isUnavailableState } from "../../../data/entity";
|
||||
import { LightEntity, lightSupportsBrightness } from "../../../data/light";
|
||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
@ -30,7 +30,6 @@ import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import { LightCardConfig } from "./types";
|
||||
import { stateColorBrightness } from "../../../common/entity/state_color";
|
||||
|
||||
@customElement("hui-light-card")
|
||||
export class HuiLightCard extends LitElement implements LovelaceCard {
|
||||
@ -156,17 +155,7 @@ export class HuiLightCard extends LitElement implements LovelaceCard {
|
||||
|
||||
<div id="info" .title=${name}>
|
||||
${isUnavailableState(stateObj.state)
|
||||
? html`
|
||||
<div>
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
? html` <div>${this.hass.formatEntityState(stateObj)}</div> `
|
||||
: html` <div class="brightness">%</div> `}
|
||||
${name}
|
||||
</div>
|
||||
|
@ -1,20 +1,19 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import "../../../components/ha-card";
|
||||
import { computeImageUrl, ImageEntity } from "../../../data/image";
|
||||
import { ImageEntity, computeImageUrl } from "../../../data/image";
|
||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
@ -120,13 +119,7 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
const name = this._config.name || computeStateName(stateObj);
|
||||
const entityState = computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
);
|
||||
const entityState = this.hass.formatEntityState(stateObj);
|
||||
|
||||
let footer: TemplateResult | string = "";
|
||||
if (this._config.show_name && this._config.show_state) {
|
||||
|
@ -13,7 +13,6 @@ import { ifDefined } from "lit/directives/if-defined";
|
||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-icon-button";
|
||||
@ -273,13 +272,9 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard {
|
||||
class=${classMap({
|
||||
"state-on": !STATES_OFF.has(stateObj.state),
|
||||
})}
|
||||
title=${`${computeStateName(stateObj)} : ${computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass!.locale,
|
||||
this.hass!.config,
|
||||
this.hass!.entities
|
||||
)}`}
|
||||
title=${`${computeStateName(
|
||||
stateObj
|
||||
)} : ${this.hass.formatEntityState(stateObj)}`}
|
||||
>
|
||||
<ha-state-icon
|
||||
.icon=${entityConf.icon}
|
||||
@ -297,13 +292,7 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard {
|
||||
entityConf.attribute
|
||||
]}${entityConf.suffix}
|
||||
`
|
||||
: computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass!.locale,
|
||||
this.hass!.config,
|
||||
this.hass!.entities
|
||||
)}
|
||||
: this.hass.formatEntityState(stateObj)}
|
||||
</div>
|
||||
`}
|
||||
</div>
|
||||
|
@ -11,12 +11,12 @@ import {
|
||||
import "@thomasloven/round-slider";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
nothing,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
svg,
|
||||
} from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
@ -25,8 +25,6 @@ import { styleMap } from "lit/directives/style-map";
|
||||
import { UNIT_F } from "../../../common/const";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stateColorCss } from "../../../common/entity/state_color";
|
||||
import { formatNumber } from "../../../common/number/format_number";
|
||||
@ -34,10 +32,10 @@ import "../../../components/ha-card";
|
||||
import type { HaCard } from "../../../components/ha-card";
|
||||
import "../../../components/ha-icon-button";
|
||||
import {
|
||||
ClimateEntity,
|
||||
CLIMATE_PRESET_NONE,
|
||||
compareClimateHvacModes,
|
||||
ClimateEntity,
|
||||
HvacMode,
|
||||
compareClimateHvacModes,
|
||||
} from "../../../data/climate";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
@ -207,21 +205,8 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
||||
>
|
||||
${
|
||||
stateObj.state !== UNAVAILABLE && stateObj.attributes.hvac_action
|
||||
? computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"hvac_action"
|
||||
)
|
||||
: computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)
|
||||
? this.hass.formatEntityAttributeValue(stateObj, "hvac_action")
|
||||
: this.hass.formatEntityState(stateObj)
|
||||
}
|
||||
${
|
||||
stateObj.state !== UNAVAILABLE &&
|
||||
@ -229,12 +214,8 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
||||
stateObj.attributes.preset_mode !== CLIMATE_PRESET_NONE
|
||||
? html`
|
||||
-
|
||||
${computeAttributeValueDisplay(
|
||||
this.hass.localize,
|
||||
${this.hass.formatEntityAttributeValue(
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"preset_mode"
|
||||
)}
|
||||
`
|
||||
|
@ -49,14 +49,8 @@ import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import "../components/hui-timestamp-display";
|
||||
import { createTileFeatureElement } from "../create-element/create-tile-feature-element";
|
||||
import type { LovelaceTileFeatureConfig } from "../tile-features/types";
|
||||
import type {
|
||||
LovelaceCard,
|
||||
LovelaceCardEditor,
|
||||
LovelaceTileFeature,
|
||||
} from "../types";
|
||||
import type { HuiErrorCard } from "./hui-error-card";
|
||||
import "../tile-features/hui-tile-features";
|
||||
import type { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import { computeTileBadge } from "./tile/badges/tile-badge";
|
||||
import type { ThermostatCardConfig, TileCardConfig } from "./types";
|
||||
|
||||
@ -186,7 +180,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
);
|
||||
|
||||
private _computeStateDisplay(stateObj: HassEntity): TemplateResult | string {
|
||||
private _formatState(stateObj: HassEntity): TemplateResult | string {
|
||||
const domain = computeDomain(stateObj.entity_id);
|
||||
|
||||
if (
|
||||
@ -314,7 +308,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
||||
|
||||
const name = this._config.name || stateObj.attributes.friendly_name;
|
||||
|
||||
const stateDisplay = this._computeStateDisplay(stateObj);
|
||||
const localizedState = this._formatState(stateObj);
|
||||
|
||||
const active = stateActive(stateObj);
|
||||
const color = this._computeStateColor(stateObj, this._config.color);
|
||||
@ -387,49 +381,20 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
||||
<ha-tile-info
|
||||
class="info"
|
||||
.primary=${name}
|
||||
.secondary=${stateDisplay}
|
||||
.secondary=${localizedState}
|
||||
></ha-tile-info>
|
||||
</div>
|
||||
</div>
|
||||
<div class="features">
|
||||
${this._config.features?.map((featureConf) =>
|
||||
this.renderFeature(featureConf, stateObj)
|
||||
)}
|
||||
</div>
|
||||
<hui-tile-features
|
||||
.hass=${this.hass}
|
||||
.stateObj=${stateObj}
|
||||
.color=${this._config.color}
|
||||
.features=${this._config.features}
|
||||
></hui-tile-features>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
private _featuresElements = new WeakMap<
|
||||
LovelaceTileFeatureConfig,
|
||||
LovelaceTileFeature | HuiErrorCard
|
||||
>();
|
||||
|
||||
private _getFeatureElement(feature: LovelaceTileFeatureConfig) {
|
||||
if (!this._featuresElements.has(feature)) {
|
||||
const element = createTileFeatureElement(feature);
|
||||
this._featuresElements.set(feature, element);
|
||||
return element;
|
||||
}
|
||||
|
||||
return this._featuresElements.get(feature)!;
|
||||
}
|
||||
|
||||
private renderFeature(
|
||||
featureConf: LovelaceTileFeatureConfig,
|
||||
stateObj: HassEntity
|
||||
): TemplateResult {
|
||||
const element = this._getFeatureElement(featureConf);
|
||||
|
||||
if (this.hass) {
|
||||
element.hass = this.hass;
|
||||
(element as LovelaceTileFeature).stateObj = stateObj;
|
||||
(element as LovelaceTileFeature).color = this._config!.color;
|
||||
}
|
||||
|
||||
return html`${element}`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
|
@ -1,16 +1,16 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { formatDateWeekdayShort } from "../../../common/datetime/format_date";
|
||||
import { formatTime } from "../../../common/datetime/format_time";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import { formatNumber } from "../../../common/number/format_number";
|
||||
@ -20,28 +20,27 @@ import "../../../components/ha-svg-icon";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||
import {
|
||||
ForecastEvent,
|
||||
WeatherEntity,
|
||||
getForecast,
|
||||
getSecondaryWeatherAttribute,
|
||||
getWeatherStateIcon,
|
||||
getWeatherUnit,
|
||||
getWind,
|
||||
subscribeForecast,
|
||||
ForecastEvent,
|
||||
weatherAttrIcons,
|
||||
WeatherEntity,
|
||||
weatherSVGStyles,
|
||||
} from "../../../data/weather";
|
||||
import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction } from "../common/has-action";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import type { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import type { WeatherForecastCardConfig } from "./types";
|
||||
import { formatDateWeekdayShort } from "../../../common/datetime/format_date";
|
||||
|
||||
@customElement("hui-weather-forecast-card")
|
||||
class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
||||
@ -265,13 +264,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
||||
<div class="info">
|
||||
<div class="name-state">
|
||||
<div class="state">
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
${this.hass.formatEntityState(stateObj)}
|
||||
</div>
|
||||
<div class="name" .title=${name}>${name}</div>
|
||||
</div>
|
||||
|
@ -29,15 +29,16 @@ import { supportsAlarmModesTileFeature } from "../../tile-features/hui-alarm-mod
|
||||
import { supportsClimateHvacModesTileFeature } from "../../tile-features/hui-climate-hvac-modes-tile-feature";
|
||||
import { supportsCoverOpenCloseTileFeature } from "../../tile-features/hui-cover-open-close-tile-feature";
|
||||
import { supportsCoverPositionTileFeature } from "../../tile-features/hui-cover-position-tile-feature";
|
||||
import { supportsCoverTiltPositionTileFeature } from "../../tile-features/hui-cover-tilt-position-tile-feature";
|
||||
import { supportsCoverTiltTileFeature } from "../../tile-features/hui-cover-tilt-tile-feature";
|
||||
import { supportsFanSpeedTileFeature } from "../../tile-features/hui-fan-speed-tile-feature";
|
||||
import { supportsLawnMowerCommandTileFeature } from "../../tile-features/hui-lawn-mower-commands-tile-feature";
|
||||
import { supportsLightBrightnessTileFeature } from "../../tile-features/hui-light-brightness-tile-feature";
|
||||
import { supportsLightColorTempTileFeature } from "../../tile-features/hui-light-color-temp-tile-feature";
|
||||
import { supportsTargetTemperatureTileFeature } from "../../tile-features/hui-target-temperature-tile-feature";
|
||||
import { supportsVacuumCommandTileFeature } from "../../tile-features/hui-vacuum-commands-tile-feature";
|
||||
import { supportsWaterHeaterOperationModesTileFeature } from "../../tile-features/hui-water-heater-operation-modes-tile-feature";
|
||||
import { LovelaceTileFeatureConfig } from "../../tile-features/types";
|
||||
import { supportsTargetTemperatureTileFeature } from "../../tile-features/hui-target-temperature-tile-feature";
|
||||
|
||||
type FeatureType = LovelaceTileFeatureConfig["type"];
|
||||
type SupportsFeature = (stateObj: HassEntity) => boolean;
|
||||
@ -72,7 +73,7 @@ const SUPPORTS_FEATURE_TYPES: Record<FeatureType, SupportsFeature | undefined> =
|
||||
"climate-hvac-modes": supportsClimateHvacModesTileFeature,
|
||||
"cover-open-close": supportsCoverOpenCloseTileFeature,
|
||||
"cover-position": supportsCoverPositionTileFeature,
|
||||
"cover-tilt-position": supportsCoverPositionTileFeature,
|
||||
"cover-tilt-position": supportsCoverTiltPositionTileFeature,
|
||||
"cover-tilt": supportsCoverTiltTileFeature,
|
||||
"fan-speed": supportsFanSpeedTileFeature,
|
||||
"lawn-mower-commands": supportsLawnMowerCommandTileFeature,
|
||||
|
@ -1,14 +1,13 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { computeTooltip } from "../common/compute-tooltip";
|
||||
@ -83,13 +82,7 @@ class HuiStateLabelElement extends LitElement implements LovelaceElement {
|
||||
)}
|
||||
>
|
||||
${this._config.prefix}${!this._config.attribute
|
||||
? computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)
|
||||
? this.hass.formatEntityState(stateObj)
|
||||
: stateObj.attributes[this._config.attribute]}${this._config.suffix}
|
||||
</div>
|
||||
`;
|
||||
|
@ -1,14 +1,12 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
||||
import { isUnavailableState } from "../../../data/entity";
|
||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
@ -70,13 +68,7 @@ class HuiEventEntityRow extends LitElement implements LovelaceRow {
|
||||
>
|
||||
<div class="when">
|
||||
${isUnavailableState(stateObj.state)
|
||||
? computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)
|
||||
? this.hass.formatEntityState(stateObj)
|
||||
: html`<hui-timestamp-display
|
||||
.hass=${this.hass}
|
||||
.ts=${new Date(stateObj.state)}
|
||||
@ -86,15 +78,8 @@ class HuiEventEntityRow extends LitElement implements LovelaceRow {
|
||||
</div>
|
||||
<div class="what">
|
||||
${isUnavailableState(stateObj.state)
|
||||
? ``
|
||||
: computeAttributeValueDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"event_type"
|
||||
)}
|
||||
? nothing
|
||||
: this.hass.formatEntityAttributeValue(stateObj, "event_type")}
|
||||
</div>
|
||||
</div>
|
||||
</hui-generic-entity-row>
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { html, LitElement, PropertyValues, nothing } from "lit";
|
||||
import { LitElement, PropertyValues, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import "../../../components/entity/ha-entity-toggle";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
@ -66,13 +65,7 @@ class HuiGroupEntityRow extends LitElement implements LovelaceRow {
|
||||
`
|
||||
: html`
|
||||
<div class="text-content">
|
||||
${computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
${this.hass.formatEntityState(stateObj)}
|
||||
</div>
|
||||
`}
|
||||
</hui-generic-entity-row>
|
||||
|
@ -1,22 +1,21 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeRTLDirection } from "../../../common/util/compute_rtl";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
import "../../../components/ha-slider";
|
||||
import "../../../components/ha-textfield";
|
||||
import { isUnavailableState } from "../../../data/entity";
|
||||
import { setValue } from "../../../data/input_text";
|
||||
import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill";
|
||||
import "../components/hui-generic-entity-row";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import { EntityConfig, LovelaceRow } from "./types";
|
||||
@ -97,14 +96,7 @@ class HuiInputNumberEntityRow extends LitElement implements LovelaceRow {
|
||||
ignore-bar-touch
|
||||
></ha-slider>
|
||||
<span class="state">
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
stateObj.state
|
||||
)}
|
||||
${this.hass.formatEntityState(stateObj)}
|
||||
</span>
|
||||
</div>
|
||||
`
|
||||
|
@ -13,31 +13,30 @@ import {
|
||||
} from "@mdi/js";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import { computeRTLDirection } from "../../../common/util/compute_rtl";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-slider";
|
||||
import { isUnavailableState } from "../../../data/entity";
|
||||
import {
|
||||
computeMediaDescription,
|
||||
ControlButton,
|
||||
MediaPlayerEntity,
|
||||
MediaPlayerEntityFeature,
|
||||
computeMediaDescription,
|
||||
} from "../../../data/media-player";
|
||||
import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill";
|
||||
import "../components/hui-generic-entity-row";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import type { EntityConfig, LovelaceRow } from "./types";
|
||||
@ -191,13 +190,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
||||
.hass=${this.hass}
|
||||
.config=${this._config}
|
||||
.secondaryText=${mediaDescription ||
|
||||
computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
this.hass.formatEntityState(stateObj)}
|
||||
>
|
||||
<div class="controls">
|
||||
${supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_ON) &&
|
||||
|
@ -1,22 +1,21 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeRTLDirection } from "../../../common/util/compute_rtl";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
import "../../../components/ha-slider";
|
||||
import "../../../components/ha-textfield";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { setValue } from "../../../data/input_text";
|
||||
import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill";
|
||||
import "../components/hui-generic-entity-row";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import { EntityConfig, LovelaceRow } from "./types";
|
||||
@ -101,14 +100,7 @@ class HuiNumberEntityRow extends LitElement implements LovelaceRow {
|
||||
ignore-bar-touch
|
||||
></ha-slider>
|
||||
<span class="state">
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
stateObj.state
|
||||
)}
|
||||
${this.hass.formatEntityState(stateObj)}
|
||||
</span>
|
||||
</div>
|
||||
`
|
||||
|
@ -1,15 +1,14 @@
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { stopPropagation } from "../../../common/dom/stop_propagation";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import "../../../components/ha-select";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
@ -77,14 +76,7 @@ class HuiSelectEntityRow extends LitElement implements LovelaceRow {
|
||||
? stateObj.attributes.options.map(
|
||||
(option) => html`
|
||||
<mwc-list-item .value=${option}>
|
||||
${computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass!.locale,
|
||||
this.hass!.config,
|
||||
this.hass!.entities,
|
||||
option
|
||||
)}
|
||||
${this.hass!.formatEntityState(stateObj, option)}
|
||||
</mwc-list-item>
|
||||
`
|
||||
)
|
||||
|
@ -1,13 +1,12 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { isUnavailableState } from "../../../data/entity";
|
||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||
import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor";
|
||||
@ -79,13 +78,7 @@ class HuiSensorEntityRow extends LitElement implements LovelaceRow {
|
||||
capitalize
|
||||
></hui-timestamp-display>
|
||||
`
|
||||
: computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
: this.hass.formatEntityState(stateObj)}
|
||||
</div>
|
||||
</hui-generic-entity-row>
|
||||
`;
|
||||
|
@ -1,13 +1,12 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { EntitiesCardEntityConfig } from "../cards/types";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
@ -49,13 +48,7 @@ class HuiSimpleEntityRow extends LitElement implements LovelaceRow {
|
||||
|
||||
return html`
|
||||
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
|
||||
${computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
${this.hass.formatEntityState(stateObj)}
|
||||
</hui-generic-entity-row>
|
||||
`;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { html, LitElement, PropertyValues, nothing } from "lit";
|
||||
import { LitElement, PropertyValues, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import "../../../components/entity/ha-entity-toggle";
|
||||
import { isUnavailableState } from "../../../data/entity";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
@ -61,13 +60,7 @@ class HuiToggleEntityRow extends LitElement implements LovelaceRow {
|
||||
`
|
||||
: html`
|
||||
<div class="text-content">
|
||||
${computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
stateObj,
|
||||
this.hass!.locale,
|
||||
this.hass.config,
|
||||
this.hass!.entities
|
||||
)}
|
||||
${this.hass.formatEntityState(stateObj)}
|
||||
</div>
|
||||
`}
|
||||
</hui-generic-entity-row>
|
||||
|
@ -3,7 +3,6 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeAttributeNameDisplay } from "../../../common/entity/compute_attribute_display";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import "../../../components/ha-control-select";
|
||||
@ -13,13 +12,13 @@ import { UNAVAILABLE } from "../../../data/entity";
|
||||
import {
|
||||
computeFanSpeedCount,
|
||||
computeFanSpeedIcon,
|
||||
FAN_SPEED_COUNT_MAX_FOR_BUTTONS,
|
||||
FAN_SPEEDS,
|
||||
FanEntity,
|
||||
FanEntityFeature,
|
||||
fanPercentageToSpeed,
|
||||
FanSpeed,
|
||||
fanSpeedToPercentage,
|
||||
FAN_SPEEDS,
|
||||
FAN_SPEED_COUNT_MAX_FOR_BUTTONS,
|
||||
} from "../../../data/fan";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { LovelaceTileFeature } from "../types";
|
||||
@ -55,14 +54,7 @@ class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature {
|
||||
|
||||
private _localizeSpeed(speed: FanSpeed) {
|
||||
if (speed === "on" || speed === "off") {
|
||||
return computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
this.stateObj!,
|
||||
this.hass!.locale,
|
||||
this.hass!.config,
|
||||
this.hass!.entities,
|
||||
speed
|
||||
);
|
||||
return this.hass!.formatEntityState(this.stateObj!, speed);
|
||||
}
|
||||
return (
|
||||
this.hass!.localize(`ui.dialogs.more_info_control.fan.speed.${speed}`) ||
|
||||
|
@ -3,17 +3,16 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { rgb2hex } from "../../../common/color/convert-color";
|
||||
import {
|
||||
DEFAULT_MAX_KELVIN,
|
||||
DEFAULT_MIN_KELVIN,
|
||||
temperature2rgb,
|
||||
} from "../../../common/color/convert-light-color";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
import "../../../components/ha-control-slider";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { LightColorMode, lightSupportsColorMode } from "../../../data/light";
|
||||
import { generateColorTemperatureGradient } from "../../../dialogs/more-info/components/lights/light-color-temp-picker";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { LovelaceTileFeature } from "../types";
|
||||
import { LightColorTempTileFeatureConfig } from "./types";
|
||||
@ -70,7 +69,7 @@ class HuiLightColorTempTileFeature
|
||||
const maxKelvin =
|
||||
this.stateObj.attributes.max_color_temp_kelvin ?? DEFAULT_MAX_KELVIN;
|
||||
|
||||
const gradient = this.generateTemperatureGradient(minKelvin!, maxKelvin);
|
||||
const gradient = this._generateTemperatureGradient(minKelvin!, maxKelvin);
|
||||
|
||||
return html`
|
||||
<div class="container">
|
||||
@ -91,26 +90,8 @@ class HuiLightColorTempTileFeature
|
||||
`;
|
||||
}
|
||||
|
||||
private generateTemperatureGradient = memoizeOne(
|
||||
(min: number, max: number) => {
|
||||
const count = 10;
|
||||
|
||||
const gradient: [number, string][] = [];
|
||||
|
||||
const step = (max - min) / count;
|
||||
const percentageStep = 1 / count;
|
||||
|
||||
for (let i = 0; i < count + 1; i++) {
|
||||
const value = min + step * i;
|
||||
|
||||
const hex = rgb2hex(temperature2rgb(value));
|
||||
gradient.push([percentageStep * i, hex]);
|
||||
}
|
||||
|
||||
return gradient
|
||||
.map(([stop, color]) => `${color} ${(stop as number) * 100}%`)
|
||||
.join(", ");
|
||||
}
|
||||
private _generateTemperatureGradient = memoizeOne(
|
||||
(min: number, max: number) => generateColorTemperatureGradient(min, max)
|
||||
);
|
||||
|
||||
private _valueChanged(ev: CustomEvent) {
|
||||
|
@ -129,6 +129,33 @@ class HuiTargetTemperatureTileFeature
|
||||
});
|
||||
}
|
||||
|
||||
private _supportsTarget() {
|
||||
const domain = computeStateDomain(this.stateObj!);
|
||||
return (
|
||||
(domain === "climate" &&
|
||||
supportsFeature(
|
||||
this.stateObj!,
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
)) ||
|
||||
(domain === "water_heater" &&
|
||||
supportsFeature(
|
||||
this.stateObj!,
|
||||
WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
private _supportsTargetRange() {
|
||||
const domain = computeStateDomain(this.stateObj!);
|
||||
return (
|
||||
domain === "climate" &&
|
||||
supportsFeature(
|
||||
this.stateObj!,
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (
|
||||
!this._config ||
|
||||
@ -147,94 +174,104 @@ class HuiTargetTemperatureTileFeature
|
||||
minimumFractionDigits: digits,
|
||||
};
|
||||
|
||||
const domain = computeStateDomain(this.stateObj!);
|
||||
|
||||
if (
|
||||
(domain === "climate" &&
|
||||
supportsFeature(
|
||||
this.stateObj,
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
)) ||
|
||||
(domain === "water_heater" &&
|
||||
supportsFeature(
|
||||
this.stateObj,
|
||||
WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||
))
|
||||
this._supportsTarget() &&
|
||||
this._targetTemperature.value != null &&
|
||||
this.stateObj.state !== UNAVAILABLE
|
||||
) {
|
||||
return html`
|
||||
<ha-control-button-group>
|
||||
<ha-control-number-buttons
|
||||
.formatOptions=${options}
|
||||
.target="value"
|
||||
.value=${this.stateObj.attributes.temperature}
|
||||
.min=${this._min}
|
||||
.max=${this._max}
|
||||
.step=${this._step}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass.formatEntityAttributeName(
|
||||
this.stateObj,
|
||||
"temperature"
|
||||
)}
|
||||
style=${styleMap({
|
||||
"--control-number-buttons-focus-color": stateColor,
|
||||
})}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
>
|
||||
</ha-control-number-buttons>
|
||||
</ha-control-number-buttons>
|
||||
`;
|
||||
<ha-control-button-group>
|
||||
<ha-control-number-buttons
|
||||
.formatOptions=${options}
|
||||
.target="value"
|
||||
.value=${this.stateObj.attributes.temperature}
|
||||
.min=${this._min}
|
||||
.max=${this._max}
|
||||
.step=${this._step}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass.formatEntityAttributeName(
|
||||
this.stateObj,
|
||||
"temperature"
|
||||
)}
|
||||
style=${styleMap({
|
||||
"--control-number-buttons-focus-color": stateColor,
|
||||
})}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
>
|
||||
</ha-control-number-buttons>
|
||||
</ha-control-button-group>
|
||||
`;
|
||||
}
|
||||
|
||||
if (
|
||||
domain === "climate" &&
|
||||
supportsFeature(
|
||||
this.stateObj,
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
)
|
||||
this._supportsTargetRange() &&
|
||||
this._targetTemperature.low != null &&
|
||||
this._targetTemperature.high != null &&
|
||||
this.stateObj.state !== UNAVAILABLE
|
||||
) {
|
||||
return html`
|
||||
<ha-control-button-group>
|
||||
<ha-control-number-buttons
|
||||
.formatOptions=${options}
|
||||
.target=${"low"}
|
||||
.value=${(this.stateObj as ClimateEntity).attributes.target_temp_low}
|
||||
.min=${this._min}
|
||||
.max=${Math.min(this._max, this._targetTemperature.high ?? this._max)}
|
||||
.step=${this._step}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass.formatEntityAttributeName(
|
||||
this.stateObj,
|
||||
"temperature"
|
||||
)}
|
||||
style=${styleMap({
|
||||
"--control-number-buttons-focus-color": stateColor,
|
||||
})}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
>
|
||||
</ha-control-number-buttons>
|
||||
<ha-control-number-buttons
|
||||
.formatOptions=${options}
|
||||
.target=${"high"}
|
||||
.value=${(this.stateObj as ClimateEntity).attributes.target_temp_high}
|
||||
.min=${Math.max(this._min, this._targetTemperature.low ?? this._min)}
|
||||
.max=${this._max}
|
||||
.step=${this._step}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass.formatEntityAttributeName(
|
||||
this.stateObj,
|
||||
"temperature"
|
||||
)}
|
||||
style=${styleMap({
|
||||
"--control-number-buttons-focus-color": stateColor,
|
||||
})}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
>
|
||||
</ha-control-number-buttons>
|
||||
</ha-control-number-buttons>
|
||||
`;
|
||||
<ha-control-button-group>
|
||||
<ha-control-number-buttons
|
||||
.formatOptions=${options}
|
||||
.target=${"low"}
|
||||
.value=${this._targetTemperature.low}
|
||||
.min=${this._min}
|
||||
.max=${Math.min(
|
||||
this._max,
|
||||
this._targetTemperature.high ?? this._max
|
||||
)}
|
||||
.step=${this._step}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass.formatEntityAttributeName(
|
||||
this.stateObj,
|
||||
"target_temp_low"
|
||||
)}
|
||||
style=${styleMap({
|
||||
"--control-number-buttons-focus-color": stateColor,
|
||||
})}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
>
|
||||
</ha-control-number-buttons>
|
||||
<ha-control-number-buttons
|
||||
.formatOptions=${options}
|
||||
.target=${"high"}
|
||||
.value=${this._targetTemperature.high}
|
||||
.min=${Math.max(
|
||||
this._min,
|
||||
this._targetTemperature.low ?? this._min
|
||||
)}
|
||||
.max=${this._max}
|
||||
.step=${this._step}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass.formatEntityAttributeName(
|
||||
this.stateObj,
|
||||
"target_temp_high"
|
||||
)}
|
||||
style=${styleMap({
|
||||
"--control-number-buttons-focus-color": stateColor,
|
||||
})}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
>
|
||||
</ha-control-number-buttons>
|
||||
</ha-control-button-group>
|
||||
`;
|
||||
}
|
||||
|
||||
return nothing;
|
||||
return html`
|
||||
<ha-control-button-group>
|
||||
<ha-control-number-buttons
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
.label=${this.hass.formatEntityAttributeName(
|
||||
this.stateObj,
|
||||
"temperature"
|
||||
)}
|
||||
style=${styleMap({
|
||||
"--control-number-buttons-focus-color": stateColor,
|
||||
})}
|
||||
>
|
||||
</ha-control-number-buttons>
|
||||
</ha-control-button-group>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
|
82
src/panels/lovelace/tile-features/hui-tile-features.ts
Normal file
82
src/panels/lovelace/tile-features/hui-tile-features.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import type { HuiErrorCard } from "../cards/hui-error-card";
|
||||
import { createTileFeatureElement } from "../create-element/create-tile-feature-element";
|
||||
import type { LovelaceTileFeature } from "../types";
|
||||
import type { LovelaceTileFeatureConfig } from "./types";
|
||||
|
||||
@customElement("hui-tile-features")
|
||||
export class HuiTileFeatures extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public stateObj!: HassEntity;
|
||||
|
||||
@property({ attribute: false }) public features?: LovelaceTileFeatureConfig[];
|
||||
|
||||
@property({ attribute: false }) public color?: string;
|
||||
|
||||
private _featuresElements = new WeakMap<
|
||||
LovelaceTileFeatureConfig,
|
||||
LovelaceTileFeature | HuiErrorCard
|
||||
>();
|
||||
|
||||
private _getFeatureElement(feature: LovelaceTileFeatureConfig) {
|
||||
if (!this._featuresElements.has(feature)) {
|
||||
const element = createTileFeatureElement(feature);
|
||||
this._featuresElements.set(feature, element);
|
||||
return element;
|
||||
}
|
||||
|
||||
return this._featuresElements.get(feature)!;
|
||||
}
|
||||
|
||||
private renderFeature(
|
||||
featureConf: LovelaceTileFeatureConfig,
|
||||
stateObj: HassEntity
|
||||
): TemplateResult {
|
||||
const element = this._getFeatureElement(featureConf);
|
||||
|
||||
if (this.hass) {
|
||||
element.hass = this.hass;
|
||||
(element as LovelaceTileFeature).stateObj = stateObj;
|
||||
(element as LovelaceTileFeature).color = this.color;
|
||||
}
|
||||
|
||||
return html`${element}`;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this.features) {
|
||||
return nothing;
|
||||
}
|
||||
return html`
|
||||
${this.features.map((featureConf) =>
|
||||
this.renderFeature(featureConf, this.stateObj)
|
||||
)}
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-tile-features": HuiTileFeatures;
|
||||
}
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import { stateActive } from "../common/entity/state_active";
|
||||
import { computeRTL } from "../common/util/compute_rtl";
|
||||
import "../components/entity/state-info";
|
||||
import { haStyle } from "../resources/styles";
|
||||
import { stateActive } from "../common/entity/state_active";
|
||||
import type { HomeAssistant } from "../types";
|
||||
|
||||
@customElement("state-card-alert")
|
||||
@ -34,13 +33,7 @@ export class StateCardAlert extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.stateObj=${this.stateObj}
|
||||
></ha-entity-toggle>`
|
||||
: computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
: this.hass.formatEntityState(this.stateObj)}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -3,7 +3,6 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { computeDomain } from "../common/entity/compute_domain";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import { computeRTL } from "../common/util/compute_rtl";
|
||||
import "../components/entity/state-info";
|
||||
import { isUnavailableState } from "../data/entity";
|
||||
@ -48,13 +47,7 @@ export class StateCardDisplay extends LitElement {
|
||||
format="datetime"
|
||||
capitalize
|
||||
></hui-timestamp-display>`
|
||||
: computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
: this.hass.formatEntityState(this.stateObj)}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -3,10 +3,8 @@ import { css, CSSResultGroup, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../components/entity/ha-entity-toggle";
|
||||
import "../components/entity/state-info";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import { haStyle } from "../resources/styles";
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
@customElement("state-card-event")
|
||||
export class StateCardEvent extends LitElement {
|
||||
@ -26,23 +24,10 @@ export class StateCardEvent extends LitElement {
|
||||
></state-info>
|
||||
<div class="container">
|
||||
<div class="event_type">
|
||||
${computeStateDisplay(
|
||||
this.hass!.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities
|
||||
)}
|
||||
${this.hass.formatEntityState(this.stateObj)}
|
||||
</div>
|
||||
<div class="event_data">
|
||||
${computeAttributeValueDisplay(
|
||||
this.hass!.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
"event_type"
|
||||
)}
|
||||
${this.hass.formatEntityAttributeValue(this.stateObj, "event_type")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,16 +1,15 @@
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
import { computeRTLDirection } from "../common/util/compute_rtl";
|
||||
import { debounce } from "../common/util/debounce";
|
||||
import "../components/entity/state-info";
|
||||
import "../components/ha-slider";
|
||||
import "../components/ha-textfield";
|
||||
import "../components/entity/state-info";
|
||||
import { isUnavailableState } from "../data/entity";
|
||||
import { setValue } from "../data/input_text";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { loadPolyfillIfNeeded } from "../resources/resize-observer.polyfill";
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
@customElement("state-card-input_number")
|
||||
class StateCardInputNumber extends LitElement {
|
||||
@ -69,14 +68,7 @@ class StateCardInputNumber extends LitElement {
|
||||
ignore-bar-touch
|
||||
></ha-slider>
|
||||
<span class="state">
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
this.stateObj.state
|
||||
)}
|
||||
${this.hass.formatEntityState(this.stateObj)}
|
||||
</span>
|
||||
</div>
|
||||
`
|
||||
|
@ -1,14 +1,13 @@
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import "../components/ha-select";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { stopPropagation } from "../common/dom/stop_propagation";
|
||||
import { computeStateName } from "../common/entity/compute_state_name";
|
||||
import "../components/entity/state-badge";
|
||||
import "../components/ha-select";
|
||||
import { UNAVAILABLE } from "../data/entity";
|
||||
import { SelectEntity, setSelectOption } from "../data/select";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||
|
||||
@customElement("state-card-select")
|
||||
class StateCardSelect extends LitElement {
|
||||
@ -31,14 +30,7 @@ class StateCardSelect extends LitElement {
|
||||
${this.stateObj.attributes.options.map(
|
||||
(option) => html`
|
||||
<mwc-list-item .value=${option}>
|
||||
${computeStateDisplay(
|
||||
this.hass.localize,
|
||||
this.stateObj,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
this.hass.entities,
|
||||
option
|
||||
)}
|
||||
${this.hass.formatEntityState(this.stateObj, option)}
|
||||
</mwc-list-item>
|
||||
`
|
||||
)}
|
||||
|
@ -1750,8 +1750,8 @@
|
||||
"delete_return": "Delete return",
|
||||
"add_return": "Add return",
|
||||
"grid_carbon_footprint": "Grid carbon footprint",
|
||||
"remove_co2_signal": "Remove CO2 signal integration",
|
||||
"add_co2_signal": "Add CO2 signal integration",
|
||||
"remove_co2_signal": "Remove Electricity Maps integration",
|
||||
"add_co2_signal": "Add Electricity Maps integration",
|
||||
"flow_dialog": {
|
||||
"from": {
|
||||
"header": "Configure grid consumption",
|
||||
|
@ -18,9 +18,9 @@ describe("stateMoreInfoType", () => {
|
||||
assert.strictEqual(stateMoreInfoType(stateObj), "hidden");
|
||||
});
|
||||
|
||||
it("Returns default for switch states", () => {
|
||||
it("Returns default for tts states", () => {
|
||||
const stateObj: any = {
|
||||
entity_id: "switch.bla",
|
||||
entity_id: "tts.bla",
|
||||
attributes: {},
|
||||
};
|
||||
assert.strictEqual(stateMoreInfoType(stateObj), "default");
|
||||
|
114
yarn.lock
114
yarn.lock
@ -4554,10 +4554,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/sortablejs@npm:1.15.1":
|
||||
version: 1.15.1
|
||||
resolution: "@types/sortablejs@npm:1.15.1"
|
||||
checksum: 242c0350f63b86541d667d5aa5d1695a9b98644a1c1f52b537f7733baf187dd2618fadde4deab01e655ebf06294cebf0a889ebebf9202ef0a8750a7afed3ecfd
|
||||
"@types/sortablejs@npm:1.15.2":
|
||||
version: 1.15.2
|
||||
resolution: "@types/sortablejs@npm:1.15.2"
|
||||
checksum: 7e2be1a44efb0df012152f6bd1424dd40a490f90a856b6cf29ffed5fb184cb3fbf61302d0cb0a04f64fe9929ced72eb1c9a1e9b2164e269592130e9f983f54be
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -4610,15 +4610,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/eslint-plugin@npm:6.4.1":
|
||||
version: 6.4.1
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:6.4.1"
|
||||
"@typescript-eslint/eslint-plugin@npm:6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:6.5.0"
|
||||
dependencies:
|
||||
"@eslint-community/regexpp": ^4.5.1
|
||||
"@typescript-eslint/scope-manager": 6.4.1
|
||||
"@typescript-eslint/type-utils": 6.4.1
|
||||
"@typescript-eslint/utils": 6.4.1
|
||||
"@typescript-eslint/visitor-keys": 6.4.1
|
||||
"@typescript-eslint/scope-manager": 6.5.0
|
||||
"@typescript-eslint/type-utils": 6.5.0
|
||||
"@typescript-eslint/utils": 6.5.0
|
||||
"@typescript-eslint/visitor-keys": 6.5.0
|
||||
debug: ^4.3.4
|
||||
graphemer: ^1.4.0
|
||||
ignore: ^5.2.4
|
||||
@ -4631,44 +4631,44 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: aa5f2f516a4ea07d1a9878d347dcb915808862f41efd3c4acd4955e616d265e051c4c93d597d30e54bee10bab9b965e2ef9cea1b497bf16f23a475d7911a8078
|
||||
checksum: d81525c9a081186ec1ae7d957972065d50bae8fe4b3de111e573adc7267bb830baaec8f1ae47d3b937984ac34324bacc3951868b7986d4f9974bbe480f2261c0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/parser@npm:6.4.1":
|
||||
version: 6.4.1
|
||||
resolution: "@typescript-eslint/parser@npm:6.4.1"
|
||||
"@typescript-eslint/parser@npm:6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@typescript-eslint/parser@npm:6.5.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager": 6.4.1
|
||||
"@typescript-eslint/types": 6.4.1
|
||||
"@typescript-eslint/typescript-estree": 6.4.1
|
||||
"@typescript-eslint/visitor-keys": 6.4.1
|
||||
"@typescript-eslint/scope-manager": 6.5.0
|
||||
"@typescript-eslint/types": 6.5.0
|
||||
"@typescript-eslint/typescript-estree": 6.5.0
|
||||
"@typescript-eslint/visitor-keys": 6.5.0
|
||||
debug: ^4.3.4
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: cb61c757963f2a7964c2f846087eadda044720da769d96600f9f0069fe796d612caef5d9bb0c785aa4fa95028b2d231e7c83847ce44f02b1fa41f2102d6f444c
|
||||
checksum: e9a70886ec2660aee5c77cdff67ba11651eb855b7ecd3ad1e70837fce997d6e6db9dfe1e1eab46a9b2147cbc034ae9c109951f3bc24ce54e78cae669b6bc9c95
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/scope-manager@npm:6.4.1":
|
||||
version: 6.4.1
|
||||
resolution: "@typescript-eslint/scope-manager@npm:6.4.1"
|
||||
"@typescript-eslint/scope-manager@npm:6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:6.5.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": 6.4.1
|
||||
"@typescript-eslint/visitor-keys": 6.4.1
|
||||
checksum: 8f7f90aa378a19838301b31cfa58a4b0641d2b84891705c8c006c67aacb5c0d07112b714e1f0e7a159c5736779c934ec26dadef42a0711fccb635596aba391fc
|
||||
"@typescript-eslint/types": 6.5.0
|
||||
"@typescript-eslint/visitor-keys": 6.5.0
|
||||
checksum: 30d78143f68e07d6bd15a147f64cc16830f8a8c8409b37aa7c7d205d7585f3648ec1c5365b3f177b7561971b407f773f6dba83b3b78fa63091045f2d6bbc6b9f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/type-utils@npm:6.4.1":
|
||||
version: 6.4.1
|
||||
resolution: "@typescript-eslint/type-utils@npm:6.4.1"
|
||||
"@typescript-eslint/type-utils@npm:6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:6.5.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree": 6.4.1
|
||||
"@typescript-eslint/utils": 6.4.1
|
||||
"@typescript-eslint/typescript-estree": 6.5.0
|
||||
"@typescript-eslint/utils": 6.5.0
|
||||
debug: ^4.3.4
|
||||
ts-api-utils: ^1.0.1
|
||||
peerDependencies:
|
||||
@ -4676,23 +4676,23 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 33bcdd48bd4e07258ed1919b598d50354dd67d8f01702cd2fd46aa9250b7b7cba9caab640df01f4dc0e45dabeddbb3ca47bee88f81fe2087350ed6f70a4cbe5d
|
||||
checksum: 80b9e5099f5bdb05348ea8664c0a5084efc851de43ef6c1997041e1f07e9cc34ac874cc9e8afb317c887513d657e2583ad360e3d57feaab775bde0acc1807982
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/types@npm:6.4.1":
|
||||
version: 6.4.1
|
||||
resolution: "@typescript-eslint/types@npm:6.4.1"
|
||||
checksum: 16ba46140dbe426407bbb940e87fb347e7eb53b64f74e8f6a819cd662aa25ccd0c25b1e588867ce3cd36a8b4eccea7bd81f4d429595e6e86d9a24c655b1c8617
|
||||
"@typescript-eslint/types@npm:6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@typescript-eslint/types@npm:6.5.0"
|
||||
checksum: 950ec16991d71494d10cb752535bbc4395295e3f03a716d53ec55bbb0aaff487aa774cc5002f775ffcc80b9f0e16ac53ecebf7cac1444ca4f7a847b0859ffbfb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/typescript-estree@npm:6.4.1":
|
||||
version: 6.4.1
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:6.4.1"
|
||||
"@typescript-eslint/typescript-estree@npm:6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:6.5.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": 6.4.1
|
||||
"@typescript-eslint/visitor-keys": 6.4.1
|
||||
"@typescript-eslint/types": 6.5.0
|
||||
"@typescript-eslint/visitor-keys": 6.5.0
|
||||
debug: ^4.3.4
|
||||
globby: ^11.1.0
|
||||
is-glob: ^4.0.3
|
||||
@ -4701,34 +4701,34 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 34c289e50a6337321154efe6c20c762e94fea308f9032971e356a266f63e99b908b1a00dd8cf51eba50a6f69db01d665faf2cf13454b355767fd167eebe60f1c
|
||||
checksum: 05717fa1f2609fa5669803191cf309a379c815aaf4fff6850f40560eec8749759c36b288f05cecffd5c1d0be8de1fe414ecfee6ecf99b6ae521baa48c8b58455
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/utils@npm:6.4.1":
|
||||
version: 6.4.1
|
||||
resolution: "@typescript-eslint/utils@npm:6.4.1"
|
||||
"@typescript-eslint/utils@npm:6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@typescript-eslint/utils@npm:6.5.0"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": ^4.4.0
|
||||
"@types/json-schema": ^7.0.12
|
||||
"@types/semver": ^7.5.0
|
||||
"@typescript-eslint/scope-manager": 6.4.1
|
||||
"@typescript-eslint/types": 6.4.1
|
||||
"@typescript-eslint/typescript-estree": 6.4.1
|
||||
"@typescript-eslint/scope-manager": 6.5.0
|
||||
"@typescript-eslint/types": 6.5.0
|
||||
"@typescript-eslint/typescript-estree": 6.5.0
|
||||
semver: ^7.5.4
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0
|
||||
checksum: 54e642a345790f912393a6f2821495e2359eff0f874a94cbe6fb3ef4411702983ed54fe88ca3ea9d28f2e93800a74dee22b7888838154bc1afd57c7e119e17ec
|
||||
checksum: 58a82213c8a7bac97a6538b9845c1de5c5692fbf72548f95ed5e044a222608590bcafbb9eacba92a8c4e9eb3e5d0a2fd553eae0d6694ed2d6152aed4dabf9480
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/visitor-keys@npm:6.4.1":
|
||||
version: 6.4.1
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:6.4.1"
|
||||
"@typescript-eslint/visitor-keys@npm:6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:6.5.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": 6.4.1
|
||||
"@typescript-eslint/types": 6.5.0
|
||||
eslint-visitor-keys: ^3.4.1
|
||||
checksum: bd9cd56fc793e1d880c24193f939c4992b2653f330baece41cd461d1fb48edb2c53696987cba0e29074bbb452dd181fd009db92dd19060fdcc417ad76768f18a
|
||||
checksum: 768a02dd0d8aae45708646bb0c51e67da09e71dc101bb0a0e55d7e0c8eadfea2f531acd3035d1ec34bf2380b66188f3fc47c6bef0201eae36b2dcc48d1934442
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -9677,12 +9677,12 @@ __metadata:
|
||||
"@types/mocha": 10.0.1
|
||||
"@types/qrcode": 1.5.1
|
||||
"@types/serve-handler": 6.1.1
|
||||
"@types/sortablejs": 1.15.1
|
||||
"@types/sortablejs": 1.15.2
|
||||
"@types/tar": 6.1.5
|
||||
"@types/ua-parser-js": 0.7.36
|
||||
"@types/webspeechapi": 0.0.29
|
||||
"@typescript-eslint/eslint-plugin": 6.4.1
|
||||
"@typescript-eslint/parser": 6.4.1
|
||||
"@typescript-eslint/eslint-plugin": 6.5.0
|
||||
"@typescript-eslint/parser": 6.5.0
|
||||
"@vaadin/combo-box": 24.1.6
|
||||
"@vaadin/vaadin-themable-mixin": 24.1.6
|
||||
"@vibrant/color": 3.2.1-alpha.1
|
||||
|
Loading…
x
Reference in New Issue
Block a user