mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-18 07:56:44 +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,
|
SMALL_SCREEN_CONDITION,
|
||||||
} from "../../lovelace/strategies/helpers/screen-conditions";
|
} from "../../lovelace/strategies/helpers/screen-conditions";
|
||||||
import type { ToggleGroupCardConfig } from "../../lovelace/cards/types";
|
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 {
|
export interface LightViewStrategyConfig {
|
||||||
type: "light";
|
type: "light";
|
||||||
@@ -51,15 +51,21 @@ const processAreasForLight = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (areaCards.length > 0) {
|
if (areaCards.length > 0) {
|
||||||
// Visibility condition: any light is on
|
const lightToggleBadges = computeLightToggleHeadingBadges(
|
||||||
const anyOnCondition = {
|
areaLights,
|
||||||
condition: "or" as const,
|
{ area_id: area.area_id },
|
||||||
conditions: areaLights.map((entityId) => ({
|
{
|
||||||
condition: "state" as const,
|
icon: "mdi:power",
|
||||||
entity: entityId,
|
turnOnText: hass.localize(
|
||||||
state: "on",
|
"ui.panel.lovelace.strategy.light.off"
|
||||||
})),
|
),
|
||||||
};
|
turnOffText: hass.localize(
|
||||||
|
"ui.panel.lovelace.strategy.light.on"
|
||||||
|
),
|
||||||
|
turnOffColor: "orange",
|
||||||
|
extraVisibility: [SMALL_SCREEN_CONDITION],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
cards.push({
|
cards.push({
|
||||||
heading_style: "subtitle",
|
heading_style: "subtitle",
|
||||||
@@ -71,42 +77,7 @@ const processAreasForLight = (
|
|||||||
navigation_path: `/home/areas-${area.area_id}`,
|
navigation_path: `/home/areas-${area.area_id}`,
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
badges: [
|
badges: lightToggleBadges satisfies LovelaceCardConfig[],
|
||||||
// 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[],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Toggle group card for desktop
|
// 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 { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import type { HeadingCardConfig } from "../../cards/types";
|
import type { HeadingCardConfig } from "../../cards/types";
|
||||||
import type { ButtonHeadingBadgeConfig } from "../../heading-badges/types";
|
import { computeLightToggleHeadingBadges } from "../helpers/light-toggle-badges";
|
||||||
import {
|
import {
|
||||||
AREA_STRATEGY_GROUP_ICONS,
|
AREA_STRATEGY_GROUP_ICONS,
|
||||||
computeAreaTileCardConfig,
|
computeAreaTileCardConfig,
|
||||||
@@ -97,50 +97,12 @@ export class AreaViewStrategy extends ReactiveElement {
|
|||||||
hass
|
hass
|
||||||
);
|
);
|
||||||
|
|
||||||
const lightBadges: ButtonHeadingBadgeConfig[] = [];
|
const lightBadges =
|
||||||
|
lightControlEntities.light.length > 0
|
||||||
if (lightControlEntities.light.length > 0) {
|
? computeLightToggleHeadingBadges(lightControlEntities.light, {
|
||||||
const anyOnCondition = {
|
entity_id: lightControlEntities.light,
|
||||||
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],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sections.push({
|
sections.push({
|
||||||
type: "grid",
|
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