Skip to content

Commit

Permalink
Add picker for badges (#21436)
Browse files Browse the repository at this point in the history
  • Loading branch information
piitaya authored Jul 19, 2024
1 parent 345000a commit 179245e
Show file tree
Hide file tree
Showing 24 changed files with 1,300 additions and 40 deletions.
23 changes: 18 additions & 5 deletions src/data/lovelace/config/badge.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import { Condition } from "../../../panels/lovelace/common/validate-condition";

export interface LovelaceBadgeConfig {
type?: string;
type: string;
[key: string]: any;
visibility?: Condition[];
}

export const defaultBadgeConfig = (entity_id: string): LovelaceBadgeConfig => ({
type: "entity",
entity: entity_id,
});
export const ensureBadgeConfig = (
config: Partial<LovelaceBadgeConfig> | string
): LovelaceBadgeConfig => {
if (typeof config === "string") {
return {
type: "entity",
entity: config,
};
}
if ("type" in config && config.type) {
return config as LovelaceBadgeConfig;
}
return {
type: "entity",
...config,
};
};
2 changes: 1 addition & 1 deletion src/data/lovelace/config/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface LovelaceBaseViewConfig {

export interface LovelaceViewConfig extends LovelaceBaseViewConfig {
type?: string;
badges?: (string | LovelaceBadgeConfig)[]; // Badge can be just an entity_id
badges?: (string | Partial<LovelaceBadgeConfig>)[]; // Badge can be just an entity_id or without type
cards?: LovelaceCardConfig[];
sections?: LovelaceSectionRawConfig[];
}
Expand Down
5 changes: 4 additions & 1 deletion src/panels/lovelace/badges/hui-entity-filter-badge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,10 @@ export class HuiEntityFilterBadge
const element = document.createElement("hui-badge");
element.hass = this.hass;
element.preview = this.preview;
element.config = badgeConfig;
element.config = {
type: "entity",
...badgeConfig,
};
element.load();
this._elements.push(element);
}
Expand Down
19 changes: 19 additions & 0 deletions src/panels/lovelace/common/generate-lovelace-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import {
} from "../cards/types";
import { EntityConfig } from "../entity-rows/types";
import { ButtonsHeaderFooterConfig } from "../header-footer/types";
import { LovelaceBadgeConfig } from "../../../data/lovelace/config/badge";
import { EntityBadgeConfig } from "../badges/types";

const HIDE_DOMAIN = new Set([
"automation",
Expand Down Expand Up @@ -310,6 +312,23 @@ export const computeCards = (
];
};

export const computeBadges = (
_states: HassEntities,
entityIds: string[]
): LovelaceBadgeConfig[] => {
const badges: LovelaceBadgeConfig[] = [];

for (const entityId of entityIds) {
const config: EntityBadgeConfig = {
type: "entity",
entity: entityId,
};

badges.push(config);
}
return badges;
};

const computeDefaultViewStates = (
entities: HassEntities,
entityEntries: HomeAssistant["entities"]
Expand Down
41 changes: 35 additions & 6 deletions src/panels/lovelace/components/hui-badge-edit-mode.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
import {
mdiContentCopy,
mdiContentCut,
mdiContentDuplicate,
mdiDelete,
mdiDotsVertical,
mdiPencil,
} from "@mdi/js";
import deepClone from "deep-clone-simple";
import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
Expand All @@ -25,6 +28,7 @@ import {
parseLovelaceCardPath,
} from "../editor/lovelace-path";
import { Lovelace } from "../types";
import { ensureBadgeConfig } from "../../../data/lovelace/config/badge";

@customElement("hui-badge-edit-mode")
export class HuiBadgeEditMode extends LitElement {
Expand All @@ -46,7 +50,7 @@ export class HuiBadgeEditMode extends LitElement {
public _focused: boolean = false;

@storage({
key: "lovelaceClipboard",
key: "dashboardBadgeClipboard",
state: false,
subscribe: false,
storage: "sessionStorage",
Expand Down Expand Up @@ -134,6 +138,14 @@ export class HuiBadgeEditMode extends LitElement {
"ui.panel.lovelace.editor.edit_card.duplicate"
)}
</ha-list-item>
<ha-list-item graphic="icon">
<ha-svg-icon slot="graphic" .path=${mdiContentCopy}></ha-svg-icon>
${this.hass.localize("ui.panel.lovelace.editor.edit_card.copy")}
</ha-list-item>
<ha-list-item graphic="icon">
<ha-svg-icon slot="graphic" .path=${mdiContentCut}></ha-svg-icon>
${this.hass.localize("ui.panel.lovelace.editor.edit_card.cut")}
</ha-list-item>
<li divider role="separator"></li>
<ha-list-item graphic="icon" class="warning">
${this.hass.localize("ui.panel.lovelace.editor.edit_card.delete")}
Expand All @@ -159,18 +171,35 @@ export class HuiBadgeEditMode extends LitElement {
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._duplicateCard();
this._duplicateBadge();
break;
case 1:
this._deleteCard();
this._copyBadge();
break;
case 2:
this._cutBadge();
break;
case 3:
this._deleteBadge();
break;
}
}

private _duplicateCard(): void {
private _cutBadge(): void {
this._copyBadge();
this._deleteBadge();
}

private _copyBadge(): void {
const { cardIndex } = parseLovelaceCardPath(this.path!);
const cardConfig = this._badges[cardIndex];
this._clipboard = deepClone(cardConfig);
}

private _duplicateBadge(): void {
const { cardIndex } = parseLovelaceCardPath(this.path!);
const containerPath = getLovelaceContainerPath(this.path!);
const badgeConfig = this._badges![cardIndex];
const badgeConfig = ensureBadgeConfig(this._badges![cardIndex]);
showEditBadgeDialog(this, {
lovelaceConfig: this.lovelace!.config,
saveConfig: this.lovelace!.saveConfig,
Expand All @@ -191,7 +220,7 @@ export class HuiBadgeEditMode extends LitElement {
fireEvent(this, "ll-edit-badge", { path: this.path! });
}

private _deleteCard(): void {
private _deleteBadge(): void {
fireEvent(this, "ll-delete-badge", { path: this.path! });
}

Expand Down
2 changes: 1 addition & 1 deletion src/panels/lovelace/components/hui-card-edit-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class HuiCardEditMode extends LitElement {
public _focused: boolean = false;

@storage({
key: "lovelaceClipboard",
key: "dashboardCardClipboard",
state: false,
subscribe: false,
storage: "sessionStorage",
Expand Down
2 changes: 1 addition & 1 deletion src/panels/lovelace/components/hui-card-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class HuiCardOptions extends LitElement {
@property({ type: Boolean }) public hidePosition = false;

@storage({
key: "lovelaceClipboard",
key: "dashboardCardClipboard",
state: false,
subscribe: false,
storage: "sessionStorage",
Expand Down
12 changes: 12 additions & 0 deletions src/panels/lovelace/create-element/create-badge-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@ import "../badges/hui-state-label-badge";
import {
createLovelaceElement,
getLovelaceElementClass,
tryCreateLovelaceElement,
} from "./create-element-base";

const ALWAYS_LOADED_TYPES = new Set(["error", "state-label", "entity"]);
const LAZY_LOAD_TYPES = {
"entity-filter": () => import("../badges/hui-entity-filter-badge"),
};

// This will not return an error card but will throw the error
export const tryCreateBadgeElement = (config: LovelaceBadgeConfig) =>
tryCreateLovelaceElement(
"badge",
config,
ALWAYS_LOADED_TYPES,
LAZY_LOAD_TYPES,
undefined,
undefined
);

export const createBadgeElement = (config: LovelaceBadgeConfig) =>
createLovelaceElement(
"badge",
Expand Down
Loading

0 comments on commit 179245e

Please sign in to comment.