From 029029c9066454162b713d75bf9cf72102277097 Mon Sep 17 00:00:00 2001 From: RFDarter Date: Mon, 7 Oct 2024 04:53:34 +0200 Subject: [PATCH] V3 grouping (#102) --- packages/v3/src/css/tab.ts | 4 +- packages/v3/src/esp-entity-table.ts | 69 ++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/packages/v3/src/css/tab.ts b/packages/v3/src/css/tab.ts index ef03a9b..7e837d5 100644 --- a/packages/v3/src/css/tab.ts +++ b/packages/v3/src/css/tab.ts @@ -3,9 +3,11 @@ import { css } from "lit"; export default css` .tab-header { display: inline-flex; - min-height: 40px; + max-width:90%; font-weight: 400; padding-inline: 1.5em; + padding-top: 0.5em; + padding-bottom: 0.5em; align-items: center; border-radius: 12px 12px 0px 0px; background-color: rgba(127, 127, 127, 0.3); diff --git a/packages/v3/src/esp-entity-table.ts b/packages/v3/src/esp-entity-table.ts index 4b9822e..3195a20 100644 --- a/packages/v3/src/esp-entity-table.ts +++ b/packages/v3/src/esp-entity-table.ts @@ -11,6 +11,7 @@ import "iconify-icon"; interface entityConfig { unique_id: string; sorting_weight: number; + sorting_group?: string; domain: string; id: string; state: string; @@ -50,6 +51,11 @@ interface entityConfig { is_disabled_by_default?: boolean; } +interface groupConfig { + name: string; + sorting_weight: number; +} + export const stateOn = "ON"; export const stateOff = "OFF"; @@ -70,6 +76,7 @@ export class EntityTable extends LitElement implements RestAction { private _actionRenderer = new ActionRenderer(); private _basePath = getBasePath(); + private groups: groupConfig[] = [] private static ENTITY_UNDEFINED = "States"; private static ENTITY_CATEGORIES = [ "Sensor and Control", @@ -92,6 +99,7 @@ export class EntityTable extends LitElement implements RestAction { unique_id: data.id, id: parts.slice(1).join("-"), entity_category: data.entity_category, + sorting_group: data.sorting_group ?? (EntityTable.ENTITY_CATEGORIES[parseInt(data.entity_category)] || EntityTable.ENTITY_UNDEFINED), value_numeric_history: [data.value], } as entityConfig; entity.has_action = this.hasAction(entity); @@ -102,18 +110,18 @@ export class EntityTable extends LitElement implements RestAction { this.entities.sort((a, b) => { const sortA = a.sorting_weight ?? a.name; const sortB = b.sorting_weight ?? b.name; - return a.entity_category < b.entity_category + return a.sorting_group < b.sorting_group ? -1 - : a.entity_category == b.entity_category - ? sortA === sortB + : a.sorting_group === b.sorting_group + ? sortA === sortB ? a.name.toLowerCase() < b.name.toLowerCase() ? -1 - : 1 + : 1 : sortA < sortB ? -1 - : 1 - : 1 - }); + : 1 + : 1 + }); this.requestUpdate(); } else { if (typeof data.value === "number") { @@ -129,6 +137,33 @@ export class EntityTable extends LitElement implements RestAction { this.requestUpdate(); } }); + + window.source?.addEventListener("sorting_group", (e: Event) => { + const messageEvent = e as MessageEvent; + const data = JSON.parse(messageEvent.data); + const groupIndex = this.groups.findIndex((x) => x.name === data.name); + if (groupIndex === -1) { + let group = { + ...data, + } as groupConfig; + this.groups.push(group); + this.groups.sort((a, b) => { + return a.sorting_weight < b.sorting_weight + ? -1 + : 1 + }); + } + }); + + this.groups = EntityTable.ENTITY_CATEGORIES.map((category, index) => ({ + name: category, + sorting_weight: index + })); + + this.groups.push({ + name: EntityTable.ENTITY_UNDEFINED, + sorting_weight: -1 + }); } hasAction(entity: entityConfig): boolean { @@ -169,24 +204,34 @@ export class EntityTable extends LitElement implements RestAction { } render() { - function groupBy(xs: Array, key: string): Map> { - return xs.reduce(function (rv, x) { + const groupBy = (xs: Array, key: string): Map> => { + const groupedMap = xs.reduce(function (rv, x) { ( rv.get(x[key]) || (() => { - let tmp: Array = []; + let tmp: Array = []; rv.set(x[key], tmp); return tmp; })() ).push(x); return rv; }, new Map>()); + + const sortedGroupedMap = new Map>(); + for (const group of this.groups) { + const groupName = group.name; + if (groupedMap.has(groupName)) { + sortedGroupedMap.set(groupName, groupedMap.get(groupName) || []); + } + } + + return sortedGroupedMap; } const entities = this.show_all ? this.entities : this.entities.filter((elem) => !elem.is_disabled_by_default); - const grouped = groupBy(entities, "entity_category"); + const grouped = groupBy(entities, "sorting_group"); const elems = Array.from(grouped, ([name, value]) => ({ name, value })); return html`
@@ -196,7 +241,7 @@ export class EntityTable extends LitElement implements RestAction { class="tab-header" @dblclick="${this._handleTabHeaderDblClick}" > - ${EntityTable.ENTITY_CATEGORIES[parseInt(group.name)] || + ${group.name || EntityTable.ENTITY_UNDEFINED}