mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-02 00:27:49 +01:00
Extract shared light toggle heading badges helper
Move the dual turn_on/turn_off badge pattern into a shared computeLightToggleHeadingBadges helper used by both area-view-strategy and light-view-strategy. https://claude.ai/code/session_01QYArBydHUEkFt5K2SwVZfY
This commit is contained in:
@@ -17,7 +17,7 @@ import {
|
||||
SMALL_SCREEN_CONDITION,
|
||||
} from "../../lovelace/strategies/helpers/screen-conditions";
|
||||
import type { ToggleGroupCardConfig } from "../../lovelace/cards/types";
|
||||
import type { ButtonHeadingBadgeConfig } from "../../lovelace/heading-badges/types";
|
||||
import { computeLightToggleHeadingBadges } from "../../lovelace/strategies/helpers/light-toggle-badges";
|
||||
|
||||
export interface LightViewStrategyConfig {
|
||||
type: "light";
|
||||
@@ -51,15 +51,21 @@ const processAreasForLight = (
|
||||
}
|
||||
|
||||
if (areaCards.length > 0) {
|
||||
// Visibility condition: any light is on
|
||||
const anyOnCondition = {
|
||||
condition: "or" as const,
|
||||
conditions: areaLights.map((entityId) => ({
|
||||
condition: "state" as const,
|
||||
entity: entityId,
|
||||
state: "on",
|
||||
})),
|
||||
};
|
||||
const lightToggleBadges = computeLightToggleHeadingBadges(
|
||||
areaLights,
|
||||
{ area_id: area.area_id },
|
||||
{
|
||||
icon: "mdi:power",
|
||||
turnOnText: hass.localize(
|
||||
"ui.panel.lovelace.strategy.light.off"
|
||||
),
|
||||
turnOffText: hass.localize(
|
||||
"ui.panel.lovelace.strategy.light.on"
|
||||
),
|
||||
turnOffColor: "orange",
|
||||
extraVisibility: [SMALL_SCREEN_CONDITION],
|
||||
}
|
||||
);
|
||||
|
||||
cards.push({
|
||||
heading_style: "subtitle",
|
||||
@@ -71,42 +77,7 @@ const processAreasForLight = (
|
||||
navigation_path: `/home/areas-${area.area_id}`,
|
||||
}
|
||||
: undefined,
|
||||
badges: [
|
||||
// Toggle buttons for mobile
|
||||
{
|
||||
type: "button",
|
||||
icon: "mdi:power",
|
||||
text: hass.localize("ui.panel.lovelace.strategy.light.off"),
|
||||
tap_action: {
|
||||
action: "perform-action",
|
||||
perform_action: "light.turn_on",
|
||||
target: {
|
||||
area_id: area.area_id,
|
||||
},
|
||||
},
|
||||
visibility: [
|
||||
SMALL_SCREEN_CONDITION,
|
||||
{
|
||||
condition: "not",
|
||||
conditions: [anyOnCondition],
|
||||
},
|
||||
],
|
||||
} satisfies ButtonHeadingBadgeConfig,
|
||||
{
|
||||
type: "button",
|
||||
icon: "mdi:power",
|
||||
color: "orange",
|
||||
text: hass.localize("ui.panel.lovelace.strategy.light.on"),
|
||||
tap_action: {
|
||||
action: "perform-action",
|
||||
perform_action: "light.turn_off",
|
||||
target: {
|
||||
area_id: area.area_id,
|
||||
},
|
||||
},
|
||||
visibility: [SMALL_SCREEN_CONDITION, anyOnCondition],
|
||||
} satisfies ButtonHeadingBadgeConfig,
|
||||
] satisfies LovelaceCardConfig[],
|
||||
badges: lightToggleBadges satisfies LovelaceCardConfig[],
|
||||
});
|
||||
|
||||
// Toggle group card for desktop
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { LovelaceSectionRawConfig } from "../../../../data/lovelace/config/
|
||||
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { HeadingCardConfig } from "../../cards/types";
|
||||
import type { ButtonHeadingBadgeConfig } from "../../heading-badges/types";
|
||||
import { computeLightToggleHeadingBadges } from "../helpers/light-toggle-badges";
|
||||
import {
|
||||
AREA_STRATEGY_GROUP_ICONS,
|
||||
computeAreaTileCardConfig,
|
||||
@@ -97,50 +97,12 @@ export class AreaViewStrategy extends ReactiveElement {
|
||||
hass
|
||||
);
|
||||
|
||||
const lightBadges: ButtonHeadingBadgeConfig[] = [];
|
||||
|
||||
if (lightControlEntities.light.length > 0) {
|
||||
const anyOnCondition = {
|
||||
condition: "or" as const,
|
||||
conditions: lightControlEntities.light.map((entityId) => ({
|
||||
condition: "state" as const,
|
||||
entity: entityId,
|
||||
state: "on",
|
||||
})),
|
||||
};
|
||||
|
||||
lightBadges.push(
|
||||
{
|
||||
type: "button",
|
||||
icon: "mdi:lightbulb",
|
||||
tap_action: {
|
||||
action: "perform-action",
|
||||
perform_action: "light.turn_on",
|
||||
target: {
|
||||
entity_id: lightControlEntities.light,
|
||||
},
|
||||
},
|
||||
visibility: [
|
||||
{
|
||||
condition: "not",
|
||||
conditions: [anyOnCondition],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "button",
|
||||
icon: "mdi:lightbulb",
|
||||
tap_action: {
|
||||
action: "perform-action",
|
||||
perform_action: "light.turn_off",
|
||||
target: {
|
||||
entity_id: lightControlEntities.light,
|
||||
},
|
||||
},
|
||||
visibility: [anyOnCondition],
|
||||
}
|
||||
);
|
||||
}
|
||||
const lightBadges =
|
||||
lightControlEntities.light.length > 0
|
||||
? computeLightToggleHeadingBadges(lightControlEntities.light, {
|
||||
entity_id: lightControlEntities.light,
|
||||
})
|
||||
: [];
|
||||
|
||||
sections.push({
|
||||
type: "grid",
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import type { HassServiceTarget } from "home-assistant-js-websocket";
|
||||
import type { ButtonHeadingBadgeConfig } from "../../heading-badges/types";
|
||||
import type { Condition } from "../../common/validate-condition";
|
||||
|
||||
/**
|
||||
* Creates two heading badges for toggling lights: one visible when all lights
|
||||
* are off (calls turn_on), another when any light is on (calls turn_off).
|
||||
*/
|
||||
export const computeLightToggleHeadingBadges = (
|
||||
entityIds: string[],
|
||||
target: HassServiceTarget,
|
||||
options?: {
|
||||
icon?: string;
|
||||
turnOnText?: string;
|
||||
turnOffText?: string;
|
||||
turnOffColor?: string;
|
||||
extraVisibility?: Condition[];
|
||||
}
|
||||
): ButtonHeadingBadgeConfig[] => {
|
||||
const icon = options?.icon ?? "mdi:lightbulb";
|
||||
|
||||
const anyOnCondition: Condition = {
|
||||
condition: "or",
|
||||
conditions: entityIds.map((entityId) => ({
|
||||
condition: "state" as const,
|
||||
entity: entityId,
|
||||
state: "on",
|
||||
})),
|
||||
};
|
||||
|
||||
const extraVisibility = options?.extraVisibility ?? [];
|
||||
|
||||
return [
|
||||
{
|
||||
type: "button",
|
||||
icon: icon,
|
||||
...(options?.turnOnText ? { text: options.turnOnText } : {}),
|
||||
tap_action: {
|
||||
action: "perform-action",
|
||||
perform_action: "light.turn_on",
|
||||
target: target,
|
||||
},
|
||||
visibility: [
|
||||
...extraVisibility,
|
||||
{
|
||||
condition: "not",
|
||||
conditions: [anyOnCondition],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "button",
|
||||
icon: icon,
|
||||
...(options?.turnOffText ? { text: options.turnOffText } : {}),
|
||||
...(options?.turnOffColor ? { color: options.turnOffColor } : {}),
|
||||
tap_action: {
|
||||
action: "perform-action",
|
||||
perform_action: "light.turn_off",
|
||||
target: target,
|
||||
},
|
||||
visibility: [...extraVisibility, anyOnCondition],
|
||||
},
|
||||
];
|
||||
};
|
||||
Reference in New Issue
Block a user