Move condition handlers to their own files
This commit is contained in:
parent
52fdbfe44c
commit
c632204939
|
@ -5,8 +5,9 @@ import { Statistic, StatisticType } from "../../../data/recorder";
|
|||
import { ForecastType } from "../../../data/weather";
|
||||
import { FullCalendarView, TranslationDict } from "../../../types";
|
||||
import { LovelaceCardFeatureConfig } from "../card-features/types";
|
||||
import { LovelaceCondition } from "../common/conditions/types";
|
||||
import { LegacyStateFilter } from "../common/evaluate-filter";
|
||||
import { Condition, LegacyCondition } from "../common/validate-condition";
|
||||
import { LegacyCondition } from "../common/validate-condition";
|
||||
import { HuiImage } from "../components/hui-image";
|
||||
import { TimestampRenderingFormat } from "../components/types";
|
||||
import { LovelaceElementConfig } from "../elements/types";
|
||||
|
@ -40,7 +41,7 @@ export interface CalendarCardConfig extends LovelaceCardConfig {
|
|||
|
||||
export interface ConditionalCardConfig extends LovelaceCardConfig {
|
||||
card: LovelaceCardConfig;
|
||||
conditions: (Condition | LegacyCondition)[];
|
||||
conditions: (LovelaceCondition | LegacyCondition)[];
|
||||
}
|
||||
|
||||
export interface EmptyStateCardConfig extends LovelaceCardConfig {
|
||||
|
@ -203,7 +204,7 @@ export interface EntityFilterCardConfig extends LovelaceCardConfig {
|
|||
type: "entity-filter";
|
||||
entities: Array<EntityFilterEntityConfig | string>;
|
||||
state_filter?: Array<LegacyStateFilter>;
|
||||
conditions: Array<Condition>;
|
||||
conditions: Array<LovelaceCondition>;
|
||||
card?: Partial<LovelaceCardConfig>;
|
||||
show_empty?: boolean;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { HomeAssistant } from "../../../../types";
|
||||
import { ConditionHandler, checkCondition } from "./handle-condition";
|
||||
import { LovelaceBaseCondition, LovelaceCondition } from "./types";
|
||||
|
||||
export type LovelaceAndCondition = LovelaceBaseCondition & {
|
||||
condition: "and";
|
||||
conditions?: LovelaceCondition[];
|
||||
};
|
||||
|
||||
export class AndConditionHandler
|
||||
implements ConditionHandler<LovelaceAndCondition>
|
||||
{
|
||||
validate(condition: LovelaceAndCondition): boolean {
|
||||
return condition.conditions != null;
|
||||
}
|
||||
|
||||
check(condition: LovelaceAndCondition, hass: HomeAssistant): boolean {
|
||||
if (!condition.conditions) return true;
|
||||
return condition.conditions.every((c) => checkCondition(c, hass));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
import { isValidEntityId } from "../../../../common/entity/valid_entity_id";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import { ConditionHandler } from "./handle-condition";
|
||||
import { LovelaceBaseCondition } from "./types";
|
||||
|
||||
function getValueFromEntityId(hass: HomeAssistant, value: string): string {
|
||||
if (isValidEntityId(value) && hass.states[value]) {
|
||||
return hass.states[value]?.state;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export type LovelaceNumericStateCondition = LovelaceBaseCondition & {
|
||||
condition: "numeric_state";
|
||||
entity?: string;
|
||||
below?: string | number;
|
||||
above?: string | number;
|
||||
};
|
||||
|
||||
export class NumericStateConditionHandler
|
||||
implements ConditionHandler<LovelaceNumericStateCondition>
|
||||
{
|
||||
validate(condition: LovelaceNumericStateCondition): boolean {
|
||||
return (
|
||||
condition.entity != null &&
|
||||
(condition.above != null || condition.below != null)
|
||||
);
|
||||
}
|
||||
|
||||
check(
|
||||
condition: LovelaceNumericStateCondition,
|
||||
hass: HomeAssistant
|
||||
): boolean {
|
||||
const state = (condition.entity ? hass.states[condition.entity] : undefined)
|
||||
?.state;
|
||||
let above = condition.above;
|
||||
let below = condition.below;
|
||||
|
||||
// Handle entity_id, UI should be updated for conditionnal card (filters does not have UI for now)
|
||||
if (typeof above === "string") {
|
||||
above = getValueFromEntityId(hass, above) as string;
|
||||
}
|
||||
if (typeof below === "string") {
|
||||
below = getValueFromEntityId(hass, below) as string;
|
||||
}
|
||||
|
||||
const numericState = Number(state);
|
||||
const numericAbove = Number(above);
|
||||
const numericBelow = Number(below);
|
||||
|
||||
if (isNaN(numericState)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
(condition.above == null ||
|
||||
isNaN(numericAbove) ||
|
||||
numericAbove < numericState) &&
|
||||
(condition.below == null ||
|
||||
isNaN(numericBelow) ||
|
||||
numericBelow > numericState)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import { HomeAssistant } from "../../../../types";
|
||||
import { ConditionHandler, checkCondition } from "./handle-condition";
|
||||
import { LovelaceBaseCondition, LovelaceCondition } from "./types";
|
||||
|
||||
export type LovelaceOrCondition = LovelaceBaseCondition & {
|
||||
condition: "or";
|
||||
conditions?: LovelaceCondition[];
|
||||
};
|
||||
|
||||
export class OrConditionHandler
|
||||
implements ConditionHandler<LovelaceOrCondition>
|
||||
{
|
||||
validate(condition: LovelaceOrCondition): boolean {
|
||||
return condition.conditions != null;
|
||||
}
|
||||
|
||||
check(condition: LovelaceOrCondition, hass: HomeAssistant): boolean {
|
||||
if (!condition.conditions) return true;
|
||||
return condition.conditions.some((c) => checkCondition(c, hass));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import { HomeAssistant } from "../../../../types";
|
||||
import { ConditionHandler } from "./handle-condition";
|
||||
import { LovelaceBaseCondition } from "./types";
|
||||
|
||||
export type LovelaceScreenCondition = LovelaceBaseCondition & {
|
||||
condition: "screen";
|
||||
media_query?: string;
|
||||
};
|
||||
|
||||
export class ScreenConditionHandler
|
||||
implements ConditionHandler<LovelaceScreenCondition>
|
||||
{
|
||||
validate(condition: LovelaceScreenCondition): boolean {
|
||||
return condition.media_query != null;
|
||||
}
|
||||
|
||||
check(condition: LovelaceScreenCondition, _hass: HomeAssistant): boolean {
|
||||
return condition.media_query
|
||||
? window.matchMedia(condition.media_query).matches
|
||||
: false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import { ensureArray } from "../../../../common/array/ensure-array";
|
||||
import { isValidEntityId } from "../../../../common/entity/valid_entity_id";
|
||||
import { UNAVAILABLE } from "../../../../data/entity";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import { ConditionHandler } from "./handle-condition";
|
||||
import { LovelaceBaseCondition } from "./types";
|
||||
|
||||
function getValueFromEntityId(hass: HomeAssistant, value: string): string {
|
||||
if (isValidEntityId(value) && hass.states[value]) {
|
||||
return hass.states[value]?.state;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export type LovelaceStateCondition = LovelaceBaseCondition & {
|
||||
condition: "state";
|
||||
entity?: string;
|
||||
state?: string | string[];
|
||||
state_not?: string | string[];
|
||||
};
|
||||
|
||||
export class StateConditionHandler
|
||||
implements ConditionHandler<LovelaceStateCondition>
|
||||
{
|
||||
validate(condition: LovelaceStateCondition): boolean {
|
||||
return (
|
||||
condition.entity != null &&
|
||||
(condition.state != null || condition.state_not != null)
|
||||
);
|
||||
}
|
||||
|
||||
check(condition: LovelaceStateCondition, hass: HomeAssistant): boolean {
|
||||
const state =
|
||||
condition.entity && hass.states[condition.entity]
|
||||
? hass.states[condition.entity].state
|
||||
: UNAVAILABLE;
|
||||
let value = condition.state ?? condition.state_not;
|
||||
|
||||
if (typeof value === "string") {
|
||||
value = getValueFromEntityId(hass, value);
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
value = value.map((val) => getValueFromEntityId(hass, val));
|
||||
}
|
||||
|
||||
return condition.state != null
|
||||
? ensureArray(value).includes(state)
|
||||
: !ensureArray(value).includes(state);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import { HomeAssistant } from "../../../../types";
|
||||
import { ConditionHandler } from "./handle-condition";
|
||||
import { LovelaceBaseCondition } from "./types";
|
||||
|
||||
export type LovelaceUserCondition = LovelaceBaseCondition & {
|
||||
condition: "user";
|
||||
users?: string[];
|
||||
};
|
||||
|
||||
export class UserConditionHandler
|
||||
implements ConditionHandler<LovelaceUserCondition>
|
||||
{
|
||||
validate(condition: LovelaceUserCondition): boolean {
|
||||
return condition.users != null;
|
||||
}
|
||||
|
||||
check(condition: LovelaceUserCondition, hass: HomeAssistant): boolean {
|
||||
return condition.users && hass.user?.id
|
||||
? condition.users.includes(hass.user.id)
|
||||
: false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
import { HomeAssistant } from "../../../../types";
|
||||
import { AndConditionHandler } from "./condition-and";
|
||||
import { NumericStateConditionHandler } from "./condition-numeric-state";
|
||||
import { OrConditionHandler } from "./condition-or";
|
||||
import { ScreenConditionHandler } from "./condition-screen";
|
||||
import { StateConditionHandler } from "./condition-state";
|
||||
import { UserConditionHandler } from "./condition-user";
|
||||
import { LovelaceBaseCondition, LovelaceCondition } from "./types";
|
||||
|
||||
export interface ConditionHandler<
|
||||
T extends LovelaceBaseCondition = LovelaceBaseCondition,
|
||||
> {
|
||||
validate(condition: T): boolean;
|
||||
check(condition: T, hass: HomeAssistant): boolean;
|
||||
}
|
||||
|
||||
const HANDLER: Record<LovelaceCondition["condition"], ConditionHandler> = {
|
||||
state: new StateConditionHandler(),
|
||||
numeric_state: new NumericStateConditionHandler(),
|
||||
screen: new ScreenConditionHandler(),
|
||||
and: new AndConditionHandler(),
|
||||
or: new OrConditionHandler(),
|
||||
user: new UserConditionHandler(),
|
||||
};
|
||||
|
||||
export function checkCondition(
|
||||
condition: LovelaceCondition,
|
||||
hass: HomeAssistant
|
||||
): boolean {
|
||||
return HANDLER[condition.condition].check(condition, hass);
|
||||
}
|
||||
|
||||
export function validateCondition(condition: LovelaceCondition): boolean {
|
||||
return HANDLER[condition.condition].validate(condition);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
export type LovelaceCondition =
|
||||
| LovelaceNumericStateCondition
|
||||
| LovelaceStateCondition
|
||||
| LovelaceScreenCondition
|
||||
| LovelaceOrCondition
|
||||
| LovelaceAndCondition
|
||||
| LovelaceUserCondition;
|
||||
|
||||
export type LovelaceBaseCondition = {
|
||||
condition: string;
|
||||
};
|
||||
|
||||
export type LovelaceNumericStateCondition = LovelaceBaseCondition & {
|
||||
condition: "numeric_state";
|
||||
entity?: string;
|
||||
below?: string | number;
|
||||
above?: string | number;
|
||||
};
|
||||
|
||||
export type LovelaceStateCondition = LovelaceBaseCondition & {
|
||||
condition: "state";
|
||||
entity?: string;
|
||||
state?: string | string[];
|
||||
state_not?: string | string[];
|
||||
};
|
||||
|
||||
export type LovelaceScreenCondition = LovelaceBaseCondition & {
|
||||
condition: "screen";
|
||||
media_query?: string;
|
||||
};
|
||||
|
||||
export type LovelaceUserCondition = LovelaceBaseCondition & {
|
||||
condition: "user";
|
||||
users?: string[];
|
||||
};
|
||||
|
||||
export type LovelaceOrCondition = LovelaceBaseCondition & {
|
||||
condition: "or";
|
||||
conditions?: LovelaceCondition[];
|
||||
};
|
||||
|
||||
export type LovelaceAndCondition = LovelaceBaseCondition & {
|
||||
condition: "and";
|
||||
conditions?: LovelaceCondition[];
|
||||
};
|
|
@ -1,15 +1,11 @@
|
|||
import { ensureArray } from "../../../common/array/ensure-array";
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
|
||||
export type Condition =
|
||||
| NumericStateCondition
|
||||
| StateCondition
|
||||
| ScreenCondition
|
||||
| UserCondition
|
||||
| OrCondition
|
||||
| AndCondition;
|
||||
import {
|
||||
checkCondition,
|
||||
validateCondition,
|
||||
} from "./conditions/handle-condition";
|
||||
import { LovelaceCondition } from "./conditions/types";
|
||||
|
||||
// Legacy conditional card condition
|
||||
export interface LegacyCondition {
|
||||
|
@ -18,131 +14,6 @@ export interface LegacyCondition {
|
|||
state_not?: string | string[];
|
||||
}
|
||||
|
||||
interface BaseCondition {
|
||||
condition: string;
|
||||
}
|
||||
|
||||
export interface NumericStateCondition extends BaseCondition {
|
||||
condition: "numeric_state";
|
||||
entity?: string;
|
||||
below?: string | number;
|
||||
above?: string | number;
|
||||
}
|
||||
|
||||
export interface StateCondition extends BaseCondition {
|
||||
condition: "state";
|
||||
entity?: string;
|
||||
state?: string | string[];
|
||||
state_not?: string | string[];
|
||||
}
|
||||
|
||||
export interface ScreenCondition extends BaseCondition {
|
||||
condition: "screen";
|
||||
media_query?: string;
|
||||
}
|
||||
|
||||
export interface UserCondition extends BaseCondition {
|
||||
condition: "user";
|
||||
users?: string[];
|
||||
}
|
||||
|
||||
export interface OrCondition extends BaseCondition {
|
||||
condition: "or";
|
||||
conditions?: Condition[];
|
||||
}
|
||||
|
||||
export interface AndCondition extends BaseCondition {
|
||||
condition: "and";
|
||||
conditions?: Condition[];
|
||||
}
|
||||
|
||||
function getValueFromEntityId(hass: HomeAssistant, value: string): string {
|
||||
if (isValidEntityId(value) && hass.states[value]) {
|
||||
return hass.states[value]?.state;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function checkStateCondition(
|
||||
condition: StateCondition | LegacyCondition,
|
||||
hass: HomeAssistant
|
||||
) {
|
||||
const state =
|
||||
condition.entity && hass.states[condition.entity]
|
||||
? hass.states[condition.entity].state
|
||||
: UNAVAILABLE;
|
||||
let value = condition.state ?? condition.state_not;
|
||||
|
||||
// Handle entity_id, UI should be updated for conditionnal card (filters does not have UI for now)
|
||||
if (typeof value === "string") {
|
||||
value = getValueFromEntityId(hass, value);
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
value = value.map((val) => getValueFromEntityId(hass, val));
|
||||
}
|
||||
|
||||
return condition.state != null
|
||||
? ensureArray(value).includes(state)
|
||||
: !ensureArray(value).includes(state);
|
||||
}
|
||||
|
||||
function checkStateNumericCondition(
|
||||
condition: NumericStateCondition,
|
||||
hass: HomeAssistant
|
||||
) {
|
||||
const state = (condition.entity ? hass.states[condition.entity] : undefined)
|
||||
?.state;
|
||||
let above = condition.above;
|
||||
let below = condition.below;
|
||||
|
||||
// Handle entity_id, UI should be updated for conditionnal card (filters does not have UI for now)
|
||||
if (typeof above === "string") {
|
||||
above = getValueFromEntityId(hass, above) as string;
|
||||
}
|
||||
if (typeof below === "string") {
|
||||
below = getValueFromEntityId(hass, below) as string;
|
||||
}
|
||||
|
||||
const numericState = Number(state);
|
||||
const numericAbove = Number(above);
|
||||
const numericBelow = Number(below);
|
||||
|
||||
if (isNaN(numericState)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
(condition.above == null ||
|
||||
isNaN(numericAbove) ||
|
||||
numericAbove < numericState) &&
|
||||
(condition.below == null ||
|
||||
isNaN(numericBelow) ||
|
||||
numericBelow > numericState)
|
||||
);
|
||||
}
|
||||
|
||||
function checkScreenCondition(condition: ScreenCondition, _: HomeAssistant) {
|
||||
return condition.media_query
|
||||
? matchMedia(condition.media_query).matches
|
||||
: false;
|
||||
}
|
||||
|
||||
function checkUserCondition(condition: UserCondition, hass: HomeAssistant) {
|
||||
return condition.users && hass.user?.id
|
||||
? condition.users.includes(hass.user.id)
|
||||
: false;
|
||||
}
|
||||
|
||||
function checkAndCondition(condition: AndCondition, hass: HomeAssistant) {
|
||||
if (!condition.conditions) return true;
|
||||
return checkConditionsMet(condition.conditions, hass);
|
||||
}
|
||||
|
||||
function checkOrCondition(condition: OrCondition, hass: HomeAssistant) {
|
||||
if (!condition.conditions) return true;
|
||||
return condition.conditions.some((c) => checkConditionsMet([c], hass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result of applying conditions
|
||||
* @param conditions conditions to apply
|
||||
|
@ -150,32 +21,25 @@ function checkOrCondition(condition: OrCondition, hass: HomeAssistant) {
|
|||
* @returns true if conditions are respected
|
||||
*/
|
||||
export function checkConditionsMet(
|
||||
conditions: (Condition | LegacyCondition)[],
|
||||
conditions: (LovelaceCondition | LegacyCondition)[],
|
||||
hass: HomeAssistant
|
||||
): boolean {
|
||||
return conditions.every((c) => {
|
||||
if ("condition" in c) {
|
||||
switch (c.condition) {
|
||||
case "screen":
|
||||
return checkScreenCondition(c, hass);
|
||||
case "user":
|
||||
return checkUserCondition(c, hass);
|
||||
case "numeric_state":
|
||||
return checkStateNumericCondition(c, hass);
|
||||
case "and":
|
||||
return checkAndCondition(c, hass);
|
||||
case "or":
|
||||
return checkOrCondition(c, hass);
|
||||
default:
|
||||
return checkStateCondition(c, hass);
|
||||
return checkCondition(c, hass);
|
||||
}
|
||||
}
|
||||
return checkStateCondition(c, hass);
|
||||
return checkCondition(
|
||||
{
|
||||
condition: "state",
|
||||
...c,
|
||||
},
|
||||
hass
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function extractConditionEntityIds(
|
||||
conditions: Condition[]
|
||||
conditions: LovelaceCondition[]
|
||||
): Set<string> {
|
||||
const entityIds: Set<string> = new Set();
|
||||
for (const condition of conditions) {
|
||||
|
@ -211,61 +75,22 @@ export function extractConditionEntityIds(
|
|||
return entityIds;
|
||||
}
|
||||
|
||||
function validateStateCondition(condition: StateCondition | LegacyCondition) {
|
||||
return (
|
||||
condition.entity != null &&
|
||||
(condition.state != null || condition.state_not != null)
|
||||
);
|
||||
}
|
||||
|
||||
function validateScreenCondition(condition: ScreenCondition) {
|
||||
return condition.media_query != null;
|
||||
}
|
||||
|
||||
function validateUserCondition(condition: UserCondition) {
|
||||
return condition.users != null;
|
||||
}
|
||||
|
||||
function validateAndCondition(condition: AndCondition) {
|
||||
return condition.conditions != null;
|
||||
}
|
||||
|
||||
function validateOrCondition(condition: OrCondition) {
|
||||
return condition.conditions != null;
|
||||
}
|
||||
|
||||
function validateNumericStateCondition(condition: NumericStateCondition) {
|
||||
return (
|
||||
condition.entity != null &&
|
||||
(condition.above != null || condition.below != null)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Validate the conditions config for the UI
|
||||
* @param conditions conditions to apply
|
||||
* @returns true if conditions are validated
|
||||
*/
|
||||
export function validateConditionalConfig(
|
||||
conditions: (Condition | LegacyCondition)[]
|
||||
conditions: (LovelaceCondition | LegacyCondition)[]
|
||||
): boolean {
|
||||
return conditions.every((c) => {
|
||||
if ("condition" in c) {
|
||||
switch (c.condition) {
|
||||
case "screen":
|
||||
return validateScreenCondition(c);
|
||||
case "user":
|
||||
return validateUserCondition(c);
|
||||
case "numeric_state":
|
||||
return validateNumericStateCondition(c);
|
||||
case "and":
|
||||
return validateAndCondition(c);
|
||||
case "or":
|
||||
return validateOrCondition(c);
|
||||
default:
|
||||
return validateStateCondition(c);
|
||||
return validateCondition(c);
|
||||
}
|
||||
}
|
||||
return validateStateCondition(c);
|
||||
return validateCondition({
|
||||
condition: "state",
|
||||
...c,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -276,9 +101,9 @@ export function validateConditionalConfig(
|
|||
* @returns a new condition with entity id
|
||||
*/
|
||||
export function addEntityToCondition(
|
||||
condition: Condition,
|
||||
condition: LovelaceCondition,
|
||||
entityId: string
|
||||
): Condition {
|
||||
): LovelaceCondition {
|
||||
if ("conditions" in condition && condition.conditions) {
|
||||
return {
|
||||
...condition,
|
||||
|
|
|
@ -19,9 +19,9 @@ import "../../../../components/ha-yaml-editor";
|
|||
import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||
import { haStyle } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { LovelaceCondition } from "../../common/conditions/types";
|
||||
import { ICON_CONDITION } from "../../common/icon-condition";
|
||||
import {
|
||||
Condition,
|
||||
LegacyCondition,
|
||||
checkConditionsMet,
|
||||
validateConditionalConfig,
|
||||
|
@ -32,7 +32,9 @@ import type { LovelaceConditionEditorConstructor } from "./types";
|
|||
export class HaCardConditionEditor extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) condition!: Condition | LegacyCondition;
|
||||
@property({ attribute: false }) condition!:
|
||||
| LovelaceCondition
|
||||
| LegacyCondition;
|
||||
|
||||
@state() public _yamlMode = false;
|
||||
|
||||
|
@ -40,7 +42,7 @@ export class HaCardConditionEditor extends LitElement {
|
|||
|
||||
@state() public _uiWarnings: string[] = [];
|
||||
|
||||
@state() _condition?: Condition;
|
||||
@state() _condition?: LovelaceCondition;
|
||||
|
||||
@state() private _testingResult?: boolean;
|
||||
|
||||
|
|
|
@ -16,17 +16,18 @@ import "../../../../components/ha-list-item";
|
|||
import type { HaSelect } from "../../../../components/ha-select";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { LovelaceCondition } from "../../common/conditions/types";
|
||||
import { ICON_CONDITION } from "../../common/icon-condition";
|
||||
import { Condition, LegacyCondition } from "../../common/validate-condition";
|
||||
import { LegacyCondition } from "../../common/validate-condition";
|
||||
import "./ha-card-condition-editor";
|
||||
import type { HaCardConditionEditor } from "./ha-card-condition-editor";
|
||||
import { LovelaceConditionEditorConstructor } from "./types";
|
||||
import "./types/ha-card-condition-and";
|
||||
import "./types/ha-card-condition-numeric_state";
|
||||
import "./types/ha-card-condition-or";
|
||||
import "./types/ha-card-condition-screen";
|
||||
import "./types/ha-card-condition-state";
|
||||
import "./types/ha-card-condition-user";
|
||||
import "./types/ha-card-condition-or";
|
||||
import "./types/ha-card-condition-and";
|
||||
|
||||
const UI_CONDITION = [
|
||||
"numeric_state",
|
||||
|
@ -35,14 +36,14 @@ const UI_CONDITION = [
|
|||
"user",
|
||||
"and",
|
||||
"or",
|
||||
] as const satisfies readonly Condition["condition"][];
|
||||
] as const satisfies readonly LovelaceCondition["condition"][];
|
||||
|
||||
@customElement("ha-card-conditions-editor")
|
||||
export class HaCardConditionsEditor extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public conditions!: (
|
||||
| Condition
|
||||
| LovelaceCondition
|
||||
| LegacyCondition
|
||||
)[];
|
||||
|
||||
|
@ -138,7 +139,7 @@ export class HaCardConditionsEditor extends LitElement {
|
|||
|
||||
private _addCondition(ev: CustomEvent): void {
|
||||
const condition = (ev.currentTarget as HaSelect).items[ev.detail.index]
|
||||
.value as Condition["condition"];
|
||||
.value as LovelaceCondition["condition"];
|
||||
const conditions = [...this.conditions];
|
||||
|
||||
const elClass = customElements.get(`ha-card-condition-${condition}`) as
|
||||
|
|
|
@ -5,10 +5,9 @@ import { fireEvent } from "../../../../../common/dom/fire_event";
|
|||
import "../../../../../components/ha-form/ha-form";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import {
|
||||
AndCondition,
|
||||
Condition,
|
||||
StateCondition,
|
||||
} from "../../../common/validate-condition";
|
||||
LovelaceAndCondition,
|
||||
LovelaceCondition,
|
||||
} from "../../../common/conditions/types";
|
||||
import "../ha-card-conditions-editor";
|
||||
|
||||
const andConditionStruct = object({
|
||||
|
@ -20,15 +19,15 @@ const andConditionStruct = object({
|
|||
export class HaCardConditionNumericAnd extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public condition!: AndCondition;
|
||||
@property({ attribute: false }) public condition!: LovelaceAndCondition;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
public static get defaultConfig(): AndCondition {
|
||||
public static get defaultConfig(): LovelaceAndCondition {
|
||||
return { condition: "and", conditions: [] };
|
||||
}
|
||||
|
||||
protected static validateUIConfig(condition: StateCondition) {
|
||||
protected static validateUIConfig(condition: LovelaceAndCondition) {
|
||||
return assert(condition, andConditionStruct);
|
||||
}
|
||||
|
||||
|
@ -46,7 +45,7 @@ export class HaCardConditionNumericAnd extends LitElement {
|
|||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
ev.stopPropagation();
|
||||
const conditions = ev.detail.value as Condition[];
|
||||
const conditions = ev.detail.value as LovelaceCondition[];
|
||||
const condition = {
|
||||
...this.condition,
|
||||
conditions,
|
||||
|
|
|
@ -8,10 +8,7 @@ import "../../../../../components/ha-form/ha-form";
|
|||
import type { SchemaUnion } from "../../../../../components/ha-form/types";
|
||||
import { HaFormSchema } from "../../../../../components/ha-form/types";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import {
|
||||
NumericStateCondition,
|
||||
StateCondition,
|
||||
} from "../../../common/validate-condition";
|
||||
import { LovelaceNumericStateCondition } from "../../../common/conditions/types";
|
||||
|
||||
const numericStateConditionStruct = object({
|
||||
condition: literal("numeric_state"),
|
||||
|
@ -24,15 +21,16 @@ const numericStateConditionStruct = object({
|
|||
export class HaCardConditionNumericState extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public condition!: NumericStateCondition;
|
||||
@property({ attribute: false })
|
||||
public condition!: LovelaceNumericStateCondition;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
public static get defaultConfig(): NumericStateCondition {
|
||||
public static get defaultConfig(): LovelaceNumericStateCondition {
|
||||
return { condition: "numeric_state", entity: "" };
|
||||
}
|
||||
|
||||
protected static validateUIConfig(condition: StateCondition) {
|
||||
protected static validateUIConfig(condition: LovelaceNumericStateCondition) {
|
||||
return assert(condition, numericStateConditionStruct);
|
||||
}
|
||||
|
||||
|
@ -88,7 +86,7 @@ export class HaCardConditionNumericState extends LitElement {
|
|||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
ev.stopPropagation();
|
||||
const condition = ev.detail.value as NumericStateCondition;
|
||||
const condition = ev.detail.value as LovelaceNumericStateCondition;
|
||||
fireEvent(this, "value-changed", { value: condition });
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,9 @@ import { fireEvent } from "../../../../../common/dom/fire_event";
|
|||
import "../../../../../components/ha-form/ha-form";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import {
|
||||
Condition,
|
||||
OrCondition,
|
||||
StateCondition,
|
||||
} from "../../../common/validate-condition";
|
||||
LovelaceCondition,
|
||||
LovelaceOrCondition,
|
||||
} from "../../../common/conditions/types";
|
||||
import "../ha-card-conditions-editor";
|
||||
|
||||
const orConditionStruct = object({
|
||||
|
@ -20,15 +19,15 @@ const orConditionStruct = object({
|
|||
export class HaCardConditionOr extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public condition!: OrCondition;
|
||||
@property({ attribute: false }) public condition!: LovelaceOrCondition;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
public static get defaultConfig(): OrCondition {
|
||||
public static get defaultConfig(): LovelaceOrCondition {
|
||||
return { condition: "or", conditions: [] };
|
||||
}
|
||||
|
||||
protected static validateUIConfig(condition: StateCondition) {
|
||||
protected static validateUIConfig(condition: LovelaceOrCondition) {
|
||||
return assert(condition, orConditionStruct);
|
||||
}
|
||||
|
||||
|
@ -46,7 +45,7 @@ export class HaCardConditionOr extends LitElement {
|
|||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
ev.stopPropagation();
|
||||
const conditions = ev.detail.value as Condition[];
|
||||
const conditions = ev.detail.value as LovelaceCondition[];
|
||||
const condition = {
|
||||
...this.condition,
|
||||
conditions,
|
||||
|
|
|
@ -8,7 +8,7 @@ import "../../../../../components/ha-form/ha-form";
|
|||
import type { SchemaUnion } from "../../../../../components/ha-form/types";
|
||||
import { HaFormSchema } from "../../../../../components/ha-form/types";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import { ScreenCondition } from "../../../common/validate-condition";
|
||||
import { LovelaceScreenCondition } from "../../../common/conditions/types";
|
||||
|
||||
const BREAKPOINT_VALUES = [0, 768, 1024, 1280, Infinity];
|
||||
const BREAKPOINTS = ["mobile", "tablet", "desktop", "wide"] as const;
|
||||
|
@ -95,16 +95,16 @@ type ScreenConditionData = {
|
|||
export class HaCardConditionScreen extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public condition!: ScreenCondition;
|
||||
@property({ attribute: false }) public condition!: LovelaceScreenCondition;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
public static get defaultConfig(): ScreenCondition {
|
||||
public static get defaultConfig(): LovelaceScreenCondition {
|
||||
return { condition: "screen", media_query: "" };
|
||||
}
|
||||
|
||||
protected static validateUIConfig(
|
||||
condition: ScreenCondition,
|
||||
condition: LovelaceScreenCondition,
|
||||
hass: HomeAssistant
|
||||
) {
|
||||
const valid =
|
||||
|
@ -174,7 +174,7 @@ export class HaCardConditionScreen extends LitElement {
|
|||
|
||||
const { breakpoints } = data;
|
||||
|
||||
const condition: ScreenCondition = {
|
||||
const condition: LovelaceScreenCondition = {
|
||||
condition: "screen",
|
||||
media_query: mediaQueryMap.get(computeBreakpointsKey(breakpoints)) ?? "",
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ import "../../../../../components/ha-form/ha-form";
|
|||
import type { SchemaUnion } from "../../../../../components/ha-form/types";
|
||||
import { HaFormSchema } from "../../../../../components/ha-form/types";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import { StateCondition } from "../../../common/validate-condition";
|
||||
import { LovelaceStateCondition } from "../../../common/conditions/types";
|
||||
|
||||
const stateConditionStruct = object({
|
||||
condition: literal("state"),
|
||||
|
@ -28,15 +28,15 @@ type StateConditionData = {
|
|||
export class HaCardConditionState extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public condition!: StateCondition;
|
||||
@property({ attribute: false }) public condition!: LovelaceStateCondition;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
public static get defaultConfig(): StateCondition {
|
||||
public static get defaultConfig(): LovelaceStateCondition {
|
||||
return { condition: "state", entity: "", state: "" };
|
||||
}
|
||||
|
||||
protected static validateUIConfig(condition: StateCondition) {
|
||||
protected static validateUIConfig(condition: LovelaceStateCondition) {
|
||||
return assert(condition, stateConditionStruct);
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ export class HaCardConditionState extends LitElement {
|
|||
|
||||
const { invert, state, condition: _, ...content } = data;
|
||||
|
||||
const condition: StateCondition = {
|
||||
const condition: LovelaceStateCondition = {
|
||||
condition: "state",
|
||||
...content,
|
||||
state: invert === "false" ? state ?? "" : undefined,
|
||||
|
|
|
@ -10,7 +10,7 @@ import "../../../../../components/ha-switch";
|
|||
import "../../../../../components/user/ha-user-badge";
|
||||
import { User, fetchUsers } from "../../../../../data/user";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import { UserCondition } from "../../../common/validate-condition";
|
||||
import { LovelaceUserCondition } from "../../../common/conditions/types";
|
||||
|
||||
const userConditionStruct = object({
|
||||
condition: literal("user"),
|
||||
|
@ -21,17 +21,17 @@ const userConditionStruct = object({
|
|||
export class HaCardConditionUser extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public condition!: UserCondition;
|
||||
@property({ attribute: false }) public condition!: LovelaceUserCondition;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
public static get defaultConfig(): UserCondition {
|
||||
public static get defaultConfig(): LovelaceUserCondition {
|
||||
return { condition: "user", users: [] };
|
||||
}
|
||||
|
||||
@state() private _users: User[] = [];
|
||||
|
||||
protected static validateUIConfig(condition: UserCondition) {
|
||||
protected static validateUIConfig(condition: LovelaceUserCondition) {
|
||||
return assert(condition, userConditionStruct);
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ export class HaCardConditionUser extends LitElement {
|
|||
users = users.filter((user) => user !== userId);
|
||||
}
|
||||
|
||||
const condition: UserCondition = {
|
||||
const condition: LovelaceUserCondition = {
|
||||
...this.condition,
|
||||
users,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue