diff --git a/src/panels/light/strategies/light-view-strategy.ts b/src/panels/light/strategies/light-view-strategy.ts index c499920ce7..e5a4d9b08d 100644 --- a/src/panels/light/strategies/light-view-strategy.ts +++ b/src/panels/light/strategies/light-view-strategy.ts @@ -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 diff --git a/src/panels/lovelace/strategies/areas/area-view-strategy.ts b/src/panels/lovelace/strategies/areas/area-view-strategy.ts index 4fce04d82f..b6919a1176 100644 --- a/src/panels/lovelace/strategies/areas/area-view-strategy.ts +++ b/src/panels/lovelace/strategies/areas/area-view-strategy.ts @@ -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", diff --git a/src/panels/lovelace/strategies/helpers/light-toggle-badges.ts b/src/panels/lovelace/strategies/helpers/light-toggle-badges.ts new file mode 100644 index 0000000000..7bad4d09de --- /dev/null +++ b/src/panels/lovelace/strategies/helpers/light-toggle-badges.ts @@ -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], + }, + ]; +};