mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-20 02:38:53 +00:00
Use entity picker for heading card entities editor (#28463)
* Use entity picker for heading card entities editor * Use space tokens * Pass index * Lint * Set undefined * Iterate * Spread * Fixes * Fixes
This commit is contained in:
@@ -5,14 +5,17 @@ import { customElement, property } from "lit/decorators";
|
|||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { preventDefault } from "../../../../common/dom/prevent_default";
|
import { preventDefault } from "../../../../common/dom/prevent_default";
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
|
||||||
import "../../../../components/entity/ha-entity-picker";
|
import "../../../../components/entity/ha-entity-picker";
|
||||||
|
import type { HaEntityPicker } from "../../../../components/entity/ha-entity-picker";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-icon-button";
|
import "../../../../components/ha-icon-button";
|
||||||
import "../../../../components/ha-sortable";
|
import "../../../../components/ha-sortable";
|
||||||
import "../../../../components/ha-svg-icon";
|
import "../../../../components/ha-svg-icon";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import type { LovelaceHeadingBadgeConfig } from "../../heading-badges/types";
|
import type {
|
||||||
|
EntityHeadingBadgeConfig,
|
||||||
|
LovelaceHeadingBadgeConfig,
|
||||||
|
} from "../../heading-badges/types";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
@@ -38,20 +41,8 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
return this._badgesKeys.get(badge)!;
|
return this._badgesKeys.get(badge)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _computeBadgeLabel(badge: LovelaceHeadingBadgeConfig) {
|
private _createValueChangedHandler(index: number) {
|
||||||
const type = badge.type ?? "entity";
|
return (ev: CustomEvent) => this._valueChanged(ev, index);
|
||||||
|
|
||||||
if (type === "entity") {
|
|
||||||
const entityId = "entity" in badge ? (badge.entity as string) : undefined;
|
|
||||||
const stateObj = entityId ? this.hass.states[entityId] : undefined;
|
|
||||||
return (
|
|
||||||
(stateObj && computeStateName(stateObj)) ||
|
|
||||||
entityId ||
|
|
||||||
type ||
|
|
||||||
"Unknown badge"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
@@ -71,7 +62,12 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
this.badges,
|
this.badges,
|
||||||
(badge) => this._getKey(badge),
|
(badge) => this._getKey(badge),
|
||||||
(badge, index) => {
|
(badge, index) => {
|
||||||
const label = this._computeBadgeLabel(badge);
|
const type = badge.type ?? "entity";
|
||||||
|
const isEntityBadge =
|
||||||
|
type === "entity" && "entity" in badge;
|
||||||
|
const entityBadge = isEntityBadge
|
||||||
|
? (badge as EntityHeadingBadgeConfig)
|
||||||
|
: undefined;
|
||||||
return html`
|
return html`
|
||||||
<div class="badge">
|
<div class="badge">
|
||||||
<div class="handle">
|
<div class="handle">
|
||||||
@@ -79,9 +75,23 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
.path=${mdiDragHorizontalVariant}
|
.path=${mdiDragHorizontalVariant}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</div>
|
</div>
|
||||||
|
${isEntityBadge && entityBadge
|
||||||
|
? html`
|
||||||
|
<ha-entity-picker
|
||||||
|
allow-custom-entity
|
||||||
|
hide-clear-icon
|
||||||
|
.hass=${this.hass}
|
||||||
|
.value=${entityBadge.entity ?? ""}
|
||||||
|
@value-changed=${this._createValueChangedHandler(
|
||||||
|
index
|
||||||
|
)}
|
||||||
|
></ha-entity-picker>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
<div class="badge-content">
|
<div class="badge-content">
|
||||||
<span>${label}</span>
|
<span>${type}</span>
|
||||||
</div>
|
</div>
|
||||||
|
`}
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.label=${this.hass!.localize(
|
.label=${this.hass!.localize(
|
||||||
`ui.panel.lovelace.editor.entities.edit`
|
`ui.panel.lovelace.editor.entities.edit`
|
||||||
@@ -128,7 +138,7 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _entityPicked(ev) {
|
private _entityPicked(ev: CustomEvent): void {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
if (!ev.detail.value) {
|
if (!ev.detail.value) {
|
||||||
return;
|
return;
|
||||||
@@ -137,15 +147,32 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
type: "entity",
|
type: "entity",
|
||||||
entity: ev.detail.value,
|
entity: ev.detail.value,
|
||||||
};
|
};
|
||||||
const newBadges = (this.badges || []).concat(newEntity);
|
const newBadges = [...(this.badges || []), newEntity];
|
||||||
|
(ev.target as HaEntityPicker).value = undefined;
|
||||||
|
fireEvent(this, "heading-badges-changed", { badges: newBadges });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent, index: number): void {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const value = ev.detail.value;
|
||||||
|
const newBadges = [...(this.badges || [])];
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
newBadges.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
newBadges[index] = {
|
||||||
|
...newBadges[index],
|
||||||
|
entity: value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fireEvent(this, "heading-badges-changed", { badges: newBadges });
|
fireEvent(this, "heading-badges-changed", { badges: newBadges });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _badgeMoved(ev: CustomEvent): void {
|
private _badgeMoved(ev: CustomEvent): void {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const { oldIndex, newIndex } = ev.detail;
|
const { oldIndex, newIndex } = ev.detail;
|
||||||
|
const newBadges = [...(this.badges || [])];
|
||||||
const newBadges = (this.badges || []).concat();
|
|
||||||
|
|
||||||
newBadges.splice(newIndex, 0, newBadges.splice(oldIndex, 1)[0]);
|
newBadges.splice(newIndex, 0, newBadges.splice(oldIndex, 1)[0]);
|
||||||
|
|
||||||
@@ -154,7 +181,7 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
|
|
||||||
private _removeEntity(ev: CustomEvent): void {
|
private _removeEntity(ev: CustomEvent): void {
|
||||||
const index = (ev.currentTarget as any).index;
|
const index = (ev.currentTarget as any).index;
|
||||||
const newBadges = (this.badges || []).concat();
|
const newBadges = [...(this.badges || [])];
|
||||||
|
|
||||||
newBadges.splice(index, 1);
|
newBadges.splice(index, 1);
|
||||||
|
|
||||||
@@ -174,8 +201,15 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
ha-button {
|
ha-button {
|
||||||
margin-top: 8px;
|
margin-top: var(--ha-space-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entities {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--ha-space-2);
|
||||||
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -183,8 +217,8 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
.badge .handle {
|
.badge .handle {
|
||||||
cursor: move; /* fallback if grab cursor is unsupported */
|
cursor: move; /* fallback if grab cursor is unsupported */
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
padding-right: 8px;
|
padding-right: var(--ha-space-2);
|
||||||
padding-inline-end: 8px;
|
padding-inline-end: var(--ha-space-2);
|
||||||
padding-inline-start: initial;
|
padding-inline-start: initial;
|
||||||
direction: var(--direction);
|
direction: var(--direction);
|
||||||
}
|
}
|
||||||
@@ -206,6 +240,12 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.badge ha-entity-picker {
|
||||||
|
flex-grow: 1;
|
||||||
|
min-width: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.remove-icon,
|
.remove-icon,
|
||||||
.edit-icon {
|
.edit-icon {
|
||||||
--mdc-icon-button-size: 36px;
|
--mdc-icon-button-size: 36px;
|
||||||
@@ -224,6 +264,7 @@ export class HuiHeadingBadgesEditor extends LitElement {
|
|||||||
.add-container {
|
.add-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin-top: var(--ha-space-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
mwc-menu-surface {
|
mwc-menu-surface {
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ export class HuiHeadingCardEditor
|
|||||||
}
|
}
|
||||||
ha-form {
|
ha-form {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 24px;
|
margin-bottom: var(--ha-space-6);
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user