mirror of
https://github.com/home-assistant/frontend.git
synced 2026-08-26 08:41:32 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dd0b02d94 |
@@ -15,6 +15,7 @@ import {
|
||||
import {
|
||||
DEFAULT_DOMAIN_ICON,
|
||||
entityIcon,
|
||||
entityStateIconOverride,
|
||||
FALLBACK_DOMAIN_ICONS,
|
||||
} from "../data/icons";
|
||||
import "./ha-icon";
|
||||
@@ -48,9 +49,12 @@ export class HaStateIcon extends LitElement {
|
||||
protected _entities?: ContextType<typeof entitiesContext>;
|
||||
|
||||
private get _overrideIcon(): string | undefined {
|
||||
const entry = this.stateObj && this._entities?.[this.stateObj.entity_id];
|
||||
const stateValue = this.stateValue ?? this.stateObj?.state;
|
||||
return (
|
||||
this.icon ||
|
||||
(this.stateObj && this._entities?.[this.stateObj.entity_id]?.icon) ||
|
||||
(entry && stateValue && entityStateIconOverride(entry, stateValue)) ||
|
||||
entry?.icon ||
|
||||
this.stateObj?.attributes.icon
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ export interface EntityRegistryDisplayEntry {
|
||||
entity_id: string;
|
||||
name?: string;
|
||||
icon?: string;
|
||||
state_icons?: Record<string, string>;
|
||||
range_icons?: Record<string, string>;
|
||||
device_id?: string;
|
||||
area_id?: string;
|
||||
labels: string[];
|
||||
@@ -37,6 +39,8 @@ export interface EntityRegistryDisplayEntryResponse {
|
||||
ec?: number;
|
||||
en?: string;
|
||||
ic?: string;
|
||||
si?: Record<string, string>;
|
||||
ri?: Record<string, string>;
|
||||
pl?: string;
|
||||
tk?: string;
|
||||
hb?: boolean;
|
||||
@@ -74,6 +78,8 @@ export interface ExtEntityRegistryEntry extends EntityRegistryEntry {
|
||||
device_class?: string;
|
||||
original_device_class?: string;
|
||||
aliases: (string | null)[];
|
||||
state_icons: Record<string, string> | null;
|
||||
range_icons: Record<string, string> | null;
|
||||
}
|
||||
|
||||
export interface UpdateEntityRegistryEntryResult {
|
||||
@@ -184,6 +190,8 @@ export interface EntityRegistryOptions {
|
||||
export interface EntityRegistryEntryUpdateParams {
|
||||
name?: string | null;
|
||||
icon?: string | null;
|
||||
state_icons?: Record<string, string> | null;
|
||||
range_icons?: Record<string, string> | null;
|
||||
device_class?: string | null;
|
||||
area_id?: string | null;
|
||||
disabled_by?: string | null;
|
||||
|
||||
@@ -450,6 +450,19 @@ const getIconFromTranslations = (
|
||||
return translations.default;
|
||||
};
|
||||
|
||||
export const entityStateIconOverride = (
|
||||
entry: EntityRegistryDisplayEntry,
|
||||
state: string
|
||||
): string | undefined => {
|
||||
if (entry.state_icons?.[state]) {
|
||||
return entry.state_icons[state];
|
||||
}
|
||||
if (entry.range_icons && !isNaN(Number(state))) {
|
||||
return getIconFromRange(Number(state), entry.range_icons);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const entityIcon = async (
|
||||
entities: HomeAssistant["entities"],
|
||||
hassConfig: HomeAssistant["config"],
|
||||
@@ -459,6 +472,12 @@ export const entityIcon = async (
|
||||
) => {
|
||||
const entry = entities?.[stateObj.entity_id] as
|
||||
EntityRegistryDisplayEntry | undefined;
|
||||
if (entry) {
|
||||
const override = entityStateIconOverride(entry, state ?? stateObj.state);
|
||||
if (override) {
|
||||
return override;
|
||||
}
|
||||
}
|
||||
if (entry?.icon) {
|
||||
return entry.icon;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
import { mdiDeleteOutline, mdiPlus } from "@mdi/js";
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { isNumericState } from "../../../../common/number/format_number";
|
||||
import "../../../../components/entity/ha-entity-state-picker";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-icon-picker";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import "../../../../components/input/ha-input";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { EntityStateIconsViewParams } from "./show-view-entity-state-icons";
|
||||
|
||||
interface IconRule {
|
||||
key: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
@customElement("ha-more-info-view-entity-state-icons")
|
||||
export class HaMoreInfoViewEntityStateIcons extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public params!: EntityStateIconsViewParams;
|
||||
|
||||
@state() private _rules: IconRule[] = [];
|
||||
|
||||
@state() private _defaultIcon = "";
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues<this>) {
|
||||
super.willUpdate(changedProperties);
|
||||
if (!changedProperties.has("params") || !this.params) {
|
||||
return;
|
||||
}
|
||||
|
||||
const icons = this._numeric
|
||||
? this.params.rangeIcons
|
||||
: this.params.stateIcons;
|
||||
this._rules = Object.entries(icons || {})
|
||||
.sort(([a], [b]) => (this._numeric ? Number(a) - Number(b) : 0))
|
||||
.map(([key, icon]) => ({ key, icon }));
|
||||
this._defaultIcon = this.params.defaultIcon;
|
||||
}
|
||||
|
||||
private get _numeric(): boolean {
|
||||
const stateObj = this.hass.states[this.params.entityId];
|
||||
return stateObj ? isNumericState(stateObj) : false;
|
||||
}
|
||||
|
||||
private _emitChange() {
|
||||
const icons: Record<string, string> = {};
|
||||
for (const rule of this._rules) {
|
||||
if (!rule.icon || rule.key === "") {
|
||||
continue;
|
||||
}
|
||||
if (this._numeric) {
|
||||
const threshold = Number(rule.key);
|
||||
if (!Number.isFinite(threshold)) {
|
||||
continue;
|
||||
}
|
||||
icons[String(threshold)] = rule.icon;
|
||||
} else {
|
||||
icons[rule.key] = rule.icon;
|
||||
}
|
||||
}
|
||||
const value = Object.keys(icons).length ? icons : null;
|
||||
|
||||
this.params.onChange({
|
||||
stateIcons: this._numeric ? null : value,
|
||||
rangeIcons: this._numeric ? value : null,
|
||||
defaultIcon: this._defaultIcon,
|
||||
});
|
||||
}
|
||||
|
||||
private _addRule() {
|
||||
this._rules = [...this._rules, { key: "", icon: "" }];
|
||||
}
|
||||
|
||||
private _removeRule(ev: Event) {
|
||||
const index = (ev.currentTarget as HTMLElement & { index: number }).index;
|
||||
this._rules = this._rules.filter((_, i) => i !== index);
|
||||
this._emitChange();
|
||||
}
|
||||
|
||||
private _updateRule(index: number, rule: Partial<IconRule>) {
|
||||
this._rules = this._rules.map((current, i) =>
|
||||
i === index ? { ...current, ...rule } : current
|
||||
);
|
||||
this._emitChange();
|
||||
}
|
||||
|
||||
private _thresholdChanged(ev: Event) {
|
||||
const target = ev.currentTarget as HTMLInputElement & { index: number };
|
||||
this._updateRule(target.index, { key: target.value });
|
||||
}
|
||||
|
||||
private _ruleStateChanged(ev: CustomEvent) {
|
||||
const target = ev.currentTarget as HTMLElement & { index: number };
|
||||
this._updateRule(target.index, { key: ev.detail.value || "" });
|
||||
}
|
||||
|
||||
private _ruleIconChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
const target = ev.currentTarget as HTMLElement & { index: number };
|
||||
this._updateRule(target.index, { icon: ev.detail.value || "" });
|
||||
}
|
||||
|
||||
private _defaultIconChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
this._defaultIcon = ev.detail.value || "";
|
||||
this._emitChange();
|
||||
}
|
||||
|
||||
private _renderRule(rule: IconRule, index: number) {
|
||||
const stateObj = this.hass.states[this.params.entityId];
|
||||
const usedStates = this._rules
|
||||
.filter((_, i) => i !== index)
|
||||
.map((r) => r.key);
|
||||
|
||||
return html`
|
||||
<div class="rule">
|
||||
${
|
||||
this._numeric
|
||||
? html`
|
||||
<ha-input
|
||||
inset-label
|
||||
type="number"
|
||||
.index=${index}
|
||||
.value=${rule.key}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_state_icons.from"
|
||||
)}
|
||||
@input=${this._thresholdChanged}
|
||||
>
|
||||
${
|
||||
stateObj?.attributes.unit_of_measurement
|
||||
? html`<span slot="end"
|
||||
>${stateObj.attributes.unit_of_measurement}</span
|
||||
>`
|
||||
: nothing
|
||||
}
|
||||
</ha-input>
|
||||
`
|
||||
: html`
|
||||
<ha-entity-state-picker
|
||||
.hass=${this.hass}
|
||||
.index=${index}
|
||||
.entityId=${this.params.entityId}
|
||||
.value=${rule.key}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_state_icons.state"
|
||||
)}
|
||||
.hideStates=${usedStates}
|
||||
allow-custom-value
|
||||
@value-changed=${this._ruleStateChanged}
|
||||
></ha-entity-state-picker>
|
||||
`
|
||||
}
|
||||
<ha-icon-picker
|
||||
.index=${index}
|
||||
.value=${rule.icon}
|
||||
.label=${this.hass.localize("ui.dialogs.entity_state_icons.icon")}
|
||||
@value-changed=${this._ruleIconChanged}
|
||||
></ha-icon-picker>
|
||||
<ha-icon-button
|
||||
.index=${index}
|
||||
.path=${mdiDeleteOutline}
|
||||
.label=${this.hass.localize("ui.common.remove")}
|
||||
@click=${this._removeRule}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this.params) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`
|
||||
<div class="content">
|
||||
<p class="description">
|
||||
${this.hass.localize(
|
||||
this._numeric
|
||||
? "ui.dialogs.entity_state_icons.description_range"
|
||||
: "ui.dialogs.entity_state_icons.description_state"
|
||||
)}
|
||||
</p>
|
||||
${this._rules.map((rule, index) => this._renderRule(rule, index))}
|
||||
<ha-button
|
||||
class="add"
|
||||
appearance="plain"
|
||||
size="s"
|
||||
@click=${this._addRule}
|
||||
>
|
||||
<ha-svg-icon slot="start" .path=${mdiPlus}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
this._numeric
|
||||
? "ui.dialogs.entity_state_icons.add_range"
|
||||
: "ui.dialogs.entity_state_icons.add_state"
|
||||
)}
|
||||
</ha-button>
|
||||
<ha-icon-picker
|
||||
class="default-icon"
|
||||
.value=${this._defaultIcon}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_state_icons.default_icon"
|
||||
)}
|
||||
.helper=${this.hass.localize(
|
||||
"ui.dialogs.entity_state_icons.default_icon_helper"
|
||||
)}
|
||||
.placeholder=${this.params.placeholderIcon}
|
||||
@value-changed=${this._defaultIconChanged}
|
||||
></ha-icon-picker>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles: CSSResultGroup = css`
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 var(--ha-space-6) var(--ha-space-6);
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 0 0 var(--ha-space-4);
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.rule {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--ha-space-2);
|
||||
margin-bottom: var(--ha-space-2);
|
||||
}
|
||||
|
||||
.rule > ha-input,
|
||||
.rule > ha-entity-state-picker,
|
||||
.rule > ha-icon-picker {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.add {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.default-icon {
|
||||
display: block;
|
||||
margin-top: var(--ha-space-6);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-more-info-view-entity-state-icons": HaMoreInfoViewEntityStateIcons;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import type { LocalizeFunc } from "../../../../common/translations/localize";
|
||||
|
||||
export interface EntityStateIconsValue {
|
||||
stateIcons: Record<string, string> | null;
|
||||
rangeIcons: Record<string, string> | null;
|
||||
defaultIcon: string;
|
||||
}
|
||||
|
||||
export interface EntityStateIconsViewParams {
|
||||
entityId: string;
|
||||
stateIcons: Record<string, string> | null;
|
||||
rangeIcons: Record<string, string> | null;
|
||||
defaultIcon: string;
|
||||
placeholderIcon?: string;
|
||||
onChange: (value: EntityStateIconsValue) => void;
|
||||
}
|
||||
|
||||
export const loadEntityStateIconsView = () =>
|
||||
import("./ha-more-info-view-entity-state-icons");
|
||||
|
||||
export const showEntityStateIconsView = (
|
||||
element: HTMLElement,
|
||||
localize: LocalizeFunc,
|
||||
params: EntityStateIconsViewParams
|
||||
): void => {
|
||||
fireEvent(element, "show-child-view", {
|
||||
viewTag: "ha-more-info-view-entity-state-icons",
|
||||
viewImport: loadEntityStateIconsView,
|
||||
viewTitle: localize("ui.dialogs.entity_state_icons.title"),
|
||||
viewParams: params,
|
||||
});
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import { mdiContentCopy, mdiRestore } from "@mdi/js";
|
||||
import { mdiCog, mdiContentCopy, mdiRestore } from "@mdi/js";
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
@@ -25,6 +25,7 @@ import "../../../components/ha-color-picker";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/entity/ha-entity-picker";
|
||||
import "../../../components/ha-icon";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-icon-button-next";
|
||||
import "../../../components/ha-icon-picker";
|
||||
import "../../../components/ha-labels-picker";
|
||||
@@ -95,6 +96,7 @@ import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import { showEntityStateIconsView } from "../../../dialogs/more-info/components/entity/show-view-entity-state-icons";
|
||||
import { showVacuumSegmentMappingView } from "../../../dialogs/more-info/components/vacuum/show-view-vacuum-segment-mapping";
|
||||
import { showVoiceAssistantsView } from "../../../dialogs/more-info/components/voice/show-view-voice-assistants";
|
||||
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||
@@ -168,6 +170,8 @@ export interface EntitySettingsState {
|
||||
windSpeedUnit: string | null | undefined;
|
||||
switchAsDomain: string;
|
||||
switchAsInvert: boolean;
|
||||
stateIcons: Record<string, string> | null;
|
||||
rangeIcons: Record<string, string> | null;
|
||||
}
|
||||
|
||||
@customElement("entity-registry-settings-editor")
|
||||
@@ -195,6 +199,10 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
|
||||
@state() private _icon!: string;
|
||||
|
||||
@state() private _stateIcons?: Record<string, string> | null;
|
||||
|
||||
@state() private _rangeIcons?: Record<string, string> | null;
|
||||
|
||||
@state() private _entityId!: EntitySettingsState["entityId"];
|
||||
|
||||
@state() private _deviceClass?: EntitySettingsState["deviceClass"];
|
||||
@@ -263,6 +271,8 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
|
||||
this._name = this.entry.name || "";
|
||||
this._icon = this.entry.icon || "";
|
||||
this._stateIcons = this.entry.state_icons;
|
||||
this._rangeIcons = this.entry.range_icons;
|
||||
this._deviceClass =
|
||||
this.entry.device_class || this.entry.original_device_class;
|
||||
this._origEntityId = this.entry.entity_id;
|
||||
@@ -405,6 +415,8 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
windSpeedUnit: this._wind_speed_unit,
|
||||
switchAsDomain: this._switchAsDomain,
|
||||
switchAsInvert: this._switchAsInvert,
|
||||
stateIcons: this._stateIcons ?? null,
|
||||
rangeIcons: this._rangeIcons ?? null,
|
||||
},
|
||||
"entity-registry"
|
||||
);
|
||||
@@ -504,39 +516,72 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
this.hideIcon
|
||||
? nothing
|
||||
: html`
|
||||
<ha-icon-picker
|
||||
.value=${this._icon}
|
||||
@value-changed=${this._iconChanged}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.icon"
|
||||
)}
|
||||
.placeholder=${
|
||||
this.entry.original_icon ||
|
||||
stateObj?.attributes.icon ||
|
||||
(stateObj &&
|
||||
until(
|
||||
entityIcon(
|
||||
this.hass.entities,
|
||||
this.hass.config,
|
||||
this.hass.connection,
|
||||
stateObj
|
||||
)
|
||||
)) ||
|
||||
until(entryIcon(this.hass, this.entry))
|
||||
}
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
<div class="icon-row">
|
||||
${
|
||||
!this._icon && !stateObj?.attributes.icon && stateObj
|
||||
this._iconRulesCount > 0
|
||||
? html`
|
||||
<ha-state-icon
|
||||
slot="start"
|
||||
.stateObj=${stateObj}
|
||||
></ha-state-icon>
|
||||
<ha-input
|
||||
inset-label
|
||||
disabled
|
||||
.value=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.dynamic_icon",
|
||||
{ count: this._iconRulesCount }
|
||||
)}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.icon"
|
||||
)}
|
||||
.hint=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.dynamic_icon_hint"
|
||||
)}
|
||||
></ha-input>
|
||||
`
|
||||
: html`
|
||||
<ha-icon-picker
|
||||
.value=${this._icon}
|
||||
@value-changed=${this._iconChanged}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.icon"
|
||||
)}
|
||||
.placeholder=${
|
||||
this.entry.original_icon ||
|
||||
stateObj?.attributes.icon ||
|
||||
(stateObj &&
|
||||
until(
|
||||
entityIcon(
|
||||
this.hass.entities,
|
||||
this.hass.config,
|
||||
this.hass.connection,
|
||||
stateObj
|
||||
)
|
||||
)) ||
|
||||
until(entryIcon(this.hass, this.entry))
|
||||
}
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
${
|
||||
!this._icon &&
|
||||
!stateObj?.attributes.icon &&
|
||||
stateObj
|
||||
? html`
|
||||
<ha-state-icon
|
||||
slot="start"
|
||||
.stateObj=${stateObj}
|
||||
></ha-state-icon>
|
||||
`
|
||||
: nothing
|
||||
}
|
||||
</ha-icon-picker>
|
||||
`
|
||||
: nothing
|
||||
}
|
||||
</ha-icon-picker>
|
||||
<ha-icon-button
|
||||
.path=${mdiCog}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_state_icons.title"
|
||||
)}
|
||||
.disabled=${this.disabled}
|
||||
@click=${this._handleStateIconsClicked}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
${
|
||||
@@ -1247,6 +1292,8 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
const params: Partial<EntityRegistryEntryUpdateParams> = {
|
||||
name: this._name.trim() || null,
|
||||
icon: this._icon.trim() || null,
|
||||
state_icons: this._stateIcons ?? null,
|
||||
range_icons: this._rangeIcons ?? null,
|
||||
area_id: this._areaId || null,
|
||||
labels: this._labels || [],
|
||||
new_entity_id: this._entityId.trim(),
|
||||
@@ -1721,6 +1768,28 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
private get _iconRulesCount(): number {
|
||||
return (
|
||||
Object.keys(this._stateIcons || {}).length +
|
||||
Object.keys(this._rangeIcons || {}).length
|
||||
);
|
||||
}
|
||||
|
||||
private _handleStateIconsClicked() {
|
||||
showEntityStateIconsView(this, this.hass.localize, {
|
||||
entityId: this.entry.entity_id,
|
||||
stateIcons: this._stateIcons ?? null,
|
||||
rangeIcons: this._rangeIcons ?? null,
|
||||
defaultIcon: this._icon,
|
||||
placeholderIcon: this.entry.original_icon,
|
||||
onChange: (value) => {
|
||||
this._stateIcons = value.stateIcons;
|
||||
this._rangeIcons = value.rangeIcons;
|
||||
this._icon = value.defaultIcon;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async _showOptionsFlow() {
|
||||
showOptionsFlowDialog(this, this.helperConfigEntry!, {
|
||||
manifest: await fetchIntegrationManifest(
|
||||
@@ -1821,6 +1890,19 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
margin: var(--ha-space-2) 0;
|
||||
width: 100%;
|
||||
}
|
||||
.icon-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: var(--ha-space-2);
|
||||
}
|
||||
.icon-row > ha-icon-picker,
|
||||
.icon-row > ha-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.icon-row > ha-icon-button {
|
||||
margin-top: var(--ha-space-2);
|
||||
}
|
||||
.menu-item {
|
||||
border-radius: var(--ha-border-radius-sm);
|
||||
margin-top: 3px;
|
||||
|
||||
@@ -263,6 +263,8 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||
has_entity_name: entity.hn,
|
||||
name: entity.en,
|
||||
icon: entity.ic,
|
||||
state_icons: entity.si,
|
||||
range_icons: entity.ri,
|
||||
hidden: entity.hb,
|
||||
display_precision: entity.dp,
|
||||
};
|
||||
|
||||
@@ -1500,6 +1500,18 @@
|
||||
"area_label": "Area",
|
||||
"description": "Configure which areas correspond to each vacuum segment"
|
||||
},
|
||||
"entity_state_icons": {
|
||||
"title": "State icons",
|
||||
"description_range": "Customize the icon for value ranges. Each threshold applies from its value up to the next one.",
|
||||
"description_state": "Customize the icon for specific states.",
|
||||
"from": "From",
|
||||
"state": "State",
|
||||
"icon": "Icon",
|
||||
"add_range": "Add range",
|
||||
"add_state": "Add state",
|
||||
"default_icon": "Default icon",
|
||||
"default_icon_helper": "Used when no rule matches, like the unknown and unavailable states."
|
||||
},
|
||||
"codemirror": {
|
||||
"open_documentation": "Open documentation"
|
||||
},
|
||||
@@ -1897,6 +1909,8 @@
|
||||
"name": "Name",
|
||||
"icon": "Icon",
|
||||
"icon_error": "Icons should be in the format 'prefix:iconname', like 'mdi:home'",
|
||||
"dynamic_icon": "Dynamic icon · {count} {count, plural,\n one {rule}\n other {rules}\n}",
|
||||
"dynamic_icon_hint": "The icon changes with the state",
|
||||
"default_code": "Default code",
|
||||
"default_code_error": "Code does not match code format",
|
||||
"calendar_color": "Calendar color",
|
||||
|
||||
Reference in New Issue
Block a user