mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-10 10:56:34 +00:00
Updating Entities Card to TS+lit
This commit is contained in:
parent
1feb9f6a27
commit
18be134ad8
@ -1,150 +0,0 @@
|
|||||||
import "@polymer/iron-flex-layout/iron-flex-layout-classes.js";
|
|
||||||
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
|
||||||
|
|
||||||
import "../../../components/ha-card.js";
|
|
||||||
import "../components/hui-entities-toggle.js";
|
|
||||||
|
|
||||||
import createRowElement from "../common/create-row-element.js";
|
|
||||||
import computeDomain from "../../../common/entity/compute_domain.js";
|
|
||||||
import { DOMAINS_HIDE_MORE_INFO } from "../../../common/const.js";
|
|
||||||
|
|
||||||
import EventsMixin from "../../../mixins/events-mixin.js";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @appliesMixin EventsMixin
|
|
||||||
*/
|
|
||||||
class HuiEntitiesCard extends EventsMixin(PolymerElement) {
|
|
||||||
static get template() {
|
|
||||||
return html`
|
|
||||||
<style>
|
|
||||||
ha-card {
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
#states {
|
|
||||||
margin: -4px 0;
|
|
||||||
}
|
|
||||||
#states > div {
|
|
||||||
margin: 4px 0;
|
|
||||||
}
|
|
||||||
#states > div > * {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.header {
|
|
||||||
@apply --paper-font-headline;
|
|
||||||
/* overwriting line-height +8 because entity-toggle can be 40px height,
|
|
||||||
compensating this with reduced padding */
|
|
||||||
line-height: 40px;
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
padding: 4px 0 12px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.header .name {
|
|
||||||
@apply --paper-font-common-nowrap;
|
|
||||||
}
|
|
||||||
.state-card-dialog {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<ha-card>
|
|
||||||
<template is='dom-if' if='[[_showHeader(_config)]]'>
|
|
||||||
<div class='header'>
|
|
||||||
<div class="name">[[_config.title]]</div>
|
|
||||||
<template is="dom-if" if="[[_showHeaderToggle(_config.show_header_toggle)]]">
|
|
||||||
<hui-entities-toggle hass="[[hass]]" entities="[[_filterEntities(_config.entities)]]"></hui-entities-toggle>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div id="states"></div>
|
|
||||||
</ha-card>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
observer: "_hassChanged",
|
|
||||||
},
|
|
||||||
_config: Object,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this._elements = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
ready() {
|
|
||||||
super.ready();
|
|
||||||
if (this._config) this._buildConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
getCardSize() {
|
|
||||||
// +1 for the header
|
|
||||||
return 1 + (this._config ? this._config.entities.length : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
_showHeaderToggle(show) {
|
|
||||||
// If show is undefined, we treat it as true
|
|
||||||
return show !== false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_showHeader(config) {
|
|
||||||
// Show header if either title or toggle configured to show in it
|
|
||||||
return config.title || config.show_header_toggle;
|
|
||||||
}
|
|
||||||
|
|
||||||
setConfig(config) {
|
|
||||||
this._config = config;
|
|
||||||
this._rows = config.entities.map(
|
|
||||||
(item) => (typeof item === "string" ? { entity: item } : item)
|
|
||||||
);
|
|
||||||
if (this.$) this._buildConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
_buildConfig() {
|
|
||||||
const root = this.$.states;
|
|
||||||
|
|
||||||
while (root.lastChild) {
|
|
||||||
root.removeChild(root.lastChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._elements = [];
|
|
||||||
|
|
||||||
for (const row of this._rows) {
|
|
||||||
const entityId = row.entity;
|
|
||||||
const element = createRowElement(row);
|
|
||||||
if (
|
|
||||||
entityId &&
|
|
||||||
!DOMAINS_HIDE_MORE_INFO.includes(computeDomain(entityId))
|
|
||||||
) {
|
|
||||||
element.classList.add("state-card-dialog");
|
|
||||||
element.addEventListener("click", () =>
|
|
||||||
this.fire("hass-more-info", { entityId })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
element.hass = this.hass;
|
|
||||||
this._elements.push(element);
|
|
||||||
const container = document.createElement("div");
|
|
||||||
container.appendChild(element);
|
|
||||||
root.appendChild(container);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_hassChanged(hass) {
|
|
||||||
this._elements.forEach((element) => {
|
|
||||||
element.hass = hass;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_filterEntities(items) {
|
|
||||||
return items
|
|
||||||
.filter((item) => typeof item === "string" || item.entity)
|
|
||||||
.map((item) => (typeof item === "string" ? item : item.entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("hui-entities-card", HuiEntitiesCard);
|
|
194
src/panels/lovelace/cards/hui-entities-card.ts
Normal file
194
src/panels/lovelace/cards/hui-entities-card.ts
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element";
|
||||||
|
import { repeat } from "lit-html/directives/repeat";
|
||||||
|
|
||||||
|
import "../../../components/ha-card.js";
|
||||||
|
import "../components/hui-entities-toggle.js";
|
||||||
|
|
||||||
|
import { fireEvent } from "../../../common/dom/fire_event.js";
|
||||||
|
import { DOMAINS_HIDE_MORE_INFO } from "../../../common/const.js";
|
||||||
|
import { HassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin";
|
||||||
|
import { LovelaceCard, LovelaceConfig } from "../types.js";
|
||||||
|
import { HomeAssistant } from "../../../types.js";
|
||||||
|
import createRowElement from "../common/create-row-element.js";
|
||||||
|
import computeDomain from "../../../common/entity/compute_domain.js";
|
||||||
|
import processConfigEntities from "../common/process-config-entities";
|
||||||
|
|
||||||
|
interface EntityConfig {
|
||||||
|
name?: string;
|
||||||
|
icon?: string;
|
||||||
|
entity: string;
|
||||||
|
type?: string;
|
||||||
|
secondary_info: "entity-id" | "last-changed";
|
||||||
|
action_name?: string;
|
||||||
|
service?: string;
|
||||||
|
service_data?: object;
|
||||||
|
url?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Config extends LovelaceConfig {
|
||||||
|
show_header_toggle?: boolean;
|
||||||
|
title?: string;
|
||||||
|
entities: EntityConfig[];
|
||||||
|
}
|
||||||
|
|
||||||
|
class HuiEntitiesCard extends HassLocalizeLitMixin(LitElement)
|
||||||
|
implements LovelaceCard {
|
||||||
|
protected hass?: HomeAssistant;
|
||||||
|
protected config?: Config;
|
||||||
|
protected configEntities?: EntityConfig[];
|
||||||
|
|
||||||
|
static get properties(): PropertyDeclarations {
|
||||||
|
return {
|
||||||
|
hass: {},
|
||||||
|
config: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCardSize() {
|
||||||
|
// +1 for the header
|
||||||
|
return 1 + (this.config ? this.config.entities.length : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setConfig(config: Config) {
|
||||||
|
this.config = { show_header_toggle: true, ...config };
|
||||||
|
const entities = processConfigEntities(config.entities);
|
||||||
|
|
||||||
|
for (const entity of entities) {
|
||||||
|
if (
|
||||||
|
entity.type === "call-service" &&
|
||||||
|
!entity.service &&
|
||||||
|
!entity.name &&
|
||||||
|
!entity.icon &&
|
||||||
|
!entity.service_data &&
|
||||||
|
!entity.action_name
|
||||||
|
) {
|
||||||
|
throw new Error("Missing required property when type is call-service");
|
||||||
|
} else if (
|
||||||
|
entity.type === "weblink" &&
|
||||||
|
!entity.name &&
|
||||||
|
!entity.icon &&
|
||||||
|
!entity.url
|
||||||
|
) {
|
||||||
|
throw new Error("Missing required property when type is weblink");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.configEntities = entities;
|
||||||
|
if (this.hass) {
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.config || !this.hass) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
const { show_header_toggle, title } = this.config;
|
||||||
|
const states = this.hass.states;
|
||||||
|
|
||||||
|
const stateEntities = this.configEntities!.filter(
|
||||||
|
(conf) => conf.entity in states
|
||||||
|
);
|
||||||
|
|
||||||
|
const rowEntities = this.configEntities!.filter(
|
||||||
|
(item) => typeof item === "string" || item.entity
|
||||||
|
).map((item) => (typeof item === "string" ? item : item.entity));
|
||||||
|
|
||||||
|
return html`
|
||||||
|
${this.renderStyle()}
|
||||||
|
<ha-card>
|
||||||
|
${
|
||||||
|
!title && !show_header_toggle
|
||||||
|
? html``
|
||||||
|
: html`
|
||||||
|
<div class='header'>
|
||||||
|
${!title ? html`` : html`<div class="name">${title}</div>`}
|
||||||
|
${
|
||||||
|
!show_header_toggle
|
||||||
|
? html``
|
||||||
|
: html`
|
||||||
|
<hui-entities-toggle
|
||||||
|
.hass="${this.hass}"
|
||||||
|
.entities="${rowEntities}"
|
||||||
|
>
|
||||||
|
</hui-entities-toggle>`
|
||||||
|
}
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
|
<div id="states">
|
||||||
|
${repeat<EntityConfig>(
|
||||||
|
stateEntities,
|
||||||
|
(entityConf) => entityConf.entity,
|
||||||
|
(entityConf) => this.renderEntity(entityConf)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderStyle() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
ha-card {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
#states {
|
||||||
|
margin: -4px 0;
|
||||||
|
}
|
||||||
|
#states > div {
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
#states > div > * {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
@apply --paper-font-headline;
|
||||||
|
/* overwriting line-height +8 because entity-toggle can be 40px height,
|
||||||
|
compensating this with reduced padding */
|
||||||
|
line-height: 40px;
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
padding: 4px 0 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.header .name {
|
||||||
|
@apply --paper-font-common-nowrap;
|
||||||
|
}
|
||||||
|
.state-card-dialog {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderEntity(entityConf) {
|
||||||
|
const element = createRowElement(entityConf);
|
||||||
|
element.hass = this.hass;
|
||||||
|
element.entityConf = entityConf;
|
||||||
|
if (!DOMAINS_HIDE_MORE_INFO.includes(computeDomain(entityConf.entity))) {
|
||||||
|
element.classList.add("state-card-dialog");
|
||||||
|
element.onclick = this.handleClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div>
|
||||||
|
${element}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleClick(ev: MouseEvent) {
|
||||||
|
const config = (ev.currentTarget as any).entityConf as EntityConfig;
|
||||||
|
const entityId = config.entity;
|
||||||
|
|
||||||
|
fireEvent(this, "hass-more-info", { entityId });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hui-entities-card": HuiEntitiesCard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("hui-entities-card", HuiEntitiesCard);
|
@ -2,7 +2,7 @@ import { fireEvent } from "../../../common/dom/fire_event.js";
|
|||||||
|
|
||||||
import "../cards/hui-alarm-panel-card.js";
|
import "../cards/hui-alarm-panel-card.js";
|
||||||
import "../cards/hui-conditional-card.ts";
|
import "../cards/hui-conditional-card.ts";
|
||||||
import "../cards/hui-entities-card.js";
|
import "../cards/hui-entities-card.ts";
|
||||||
import "../cards/hui-entity-button-card.ts";
|
import "../cards/hui-entity-button-card.ts";
|
||||||
import "../cards/hui-entity-filter-card.js";
|
import "../cards/hui-entity-filter-card.js";
|
||||||
import "../cards/hui-error-card.js";
|
import "../cards/hui-error-card.js";
|
||||||
|
@ -4,7 +4,7 @@ import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
|||||||
import computeUnusedEntities from "./common/compute-unused-entities.js";
|
import computeUnusedEntities from "./common/compute-unused-entities.js";
|
||||||
import createCardElement from "./common/create-card-element.js";
|
import createCardElement from "./common/create-card-element.js";
|
||||||
|
|
||||||
import "./cards/hui-entities-card.js";
|
import "./cards/hui-entities-card.ts";
|
||||||
|
|
||||||
class HuiUnusedEntities extends PolymerElement {
|
class HuiUnusedEntities extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user