mirror of
https://github.com/home-assistant/frontend.git
synced 2026-09-09 13:19:57 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec77f78f55 | ||
|
|
765fd29b19 | ||
|
|
f2a7cde101 | ||
|
|
ceb4090760 |
@@ -1,8 +1,8 @@
|
||||
import memoizeOne from "memoize-one";
|
||||
import { mdiChartBellCurveCumulative } from "@mdi/js";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { mdiChartBellCurveCumulative } from "@mdi/js";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import type {
|
||||
NumericThresholdSelector,
|
||||
@@ -28,14 +28,14 @@ const iconThresholdOutside =
|
||||
|
||||
type ThresholdType = "above" | "below" | "between" | "outside" | "any";
|
||||
|
||||
interface ThresholdValueEntry {
|
||||
export interface ThresholdValueEntry {
|
||||
active_choice?: string;
|
||||
number?: number;
|
||||
entity?: string;
|
||||
unit_of_measurement?: string;
|
||||
}
|
||||
|
||||
interface NumericThresholdValue {
|
||||
export interface NumericThresholdValue {
|
||||
type: ThresholdType;
|
||||
value?: ThresholdValueEntry;
|
||||
value_min?: ThresholdValueEntry;
|
||||
|
||||
@@ -65,6 +65,7 @@ import {
|
||||
import { fullEntitiesContext } from "../../../../data/context";
|
||||
import type { EntityRegistryEntry } from "../../../../data/entity/entity_registry";
|
||||
import type { TargetSelector } from "../../../../data/selector";
|
||||
import { getTargetEntityCount } from "../../../../data/target";
|
||||
import {
|
||||
showAlertDialog,
|
||||
showPromptDialog,
|
||||
@@ -75,6 +76,7 @@ import { showEditorToast } from "../editor-toast";
|
||||
import "../ha-automation-editor-warning";
|
||||
import "../ha-automation-row-behavior";
|
||||
import "../ha-automation-row-options";
|
||||
import "../ha-automation-row-threshold";
|
||||
import { overflowStyles, rowStyles } from "../styles";
|
||||
import { getDeviceTarget } from "../target/get_device_target";
|
||||
import { getEntityTarget } from "../target/get_entity_target";
|
||||
@@ -232,10 +234,10 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
)}
|
||||
${
|
||||
this._getType(this.condition, this.conditionDescriptions) ===
|
||||
"platform"
|
||||
"platform" && targetRequired
|
||||
? html`<ha-automation-row-behavior
|
||||
mode="condition"
|
||||
.config=${this.condition}
|
||||
.config=${getTargetEntityCount(target) > 1 ? this.condition : undefined}
|
||||
></ha-automation-row-behavior>`
|
||||
: nothing
|
||||
}
|
||||
@@ -249,6 +251,17 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
)
|
||||
: nothing
|
||||
}
|
||||
${
|
||||
this._getType(this.condition, this.conditionDescriptions) ===
|
||||
"platform"
|
||||
? html`<ha-automation-row-threshold
|
||||
.config=${this.condition}
|
||||
.description=${
|
||||
this.conditionDescriptions[this.condition.condition]
|
||||
}
|
||||
></ha-automation-row-threshold>`
|
||||
: nothing
|
||||
}
|
||||
${
|
||||
this._getType(this.condition, this.conditionDescriptions) ===
|
||||
"platform"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { html, LitElement, nothing, type PropertyValues } from "lit";
|
||||
import { html, LitElement, type PropertyValues } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { internationalizationContext } from "../../../data/context";
|
||||
import type {
|
||||
@@ -16,7 +16,7 @@ interface HaAutomationRowBehaviorConfig {
|
||||
|
||||
@customElement("ha-automation-row-behavior")
|
||||
export class HaAutomationRowBehavior extends LitElement {
|
||||
@property({ attribute: false }) public config!: HaAutomationRowBehaviorConfig;
|
||||
@property({ attribute: false }) public config?: HaAutomationRowBehaviorConfig;
|
||||
|
||||
@property() public mode: "trigger" | "condition" = "trigger";
|
||||
|
||||
@@ -40,22 +40,18 @@ export class HaAutomationRowBehavior extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const label = this._label;
|
||||
|
||||
if (!label) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`<span class="dot-separator"></span>${label}`;
|
||||
}
|
||||
|
||||
protected updated(changedProperties: PropertyValues): void {
|
||||
super.updated(changedProperties);
|
||||
// Collapse the host when empty so the parent flex gap is not reserved.
|
||||
this.toggleAttribute("hidden", !this._label);
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const label = this._label;
|
||||
|
||||
return html`<span class="dot-separator"></span>${label}`;
|
||||
}
|
||||
|
||||
static styles = rowSummaryStyles;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { html, LitElement, nothing, type PropertyValues } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { formatNumber } from "../../../common/number/format_number";
|
||||
import { blankBeforeUnit } from "../../../common/translations/blank_before_unit";
|
||||
import type {
|
||||
NumericThresholdValue,
|
||||
ThresholdValueEntry,
|
||||
} from "../../../components/ha-selector/ha-selector-numeric-threshold";
|
||||
import type {
|
||||
PlatformCondition,
|
||||
PlatformTrigger,
|
||||
} from "../../../data/automation";
|
||||
import type { ConditionDescription } from "../../../data/condition";
|
||||
import { internationalizationContext } from "../../../data/context";
|
||||
import type { NumericThresholdSelector } from "../../../data/selector";
|
||||
import type { TriggerDescription } from "../../../data/trigger";
|
||||
import { rowSummaryStyles } from "./styles";
|
||||
|
||||
@customElement("ha-automation-row-threshold")
|
||||
export class HaAutomationRowThreshold extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public config!: PlatformTrigger | PlatformCondition;
|
||||
|
||||
@property({ attribute: false })
|
||||
public description?: TriggerDescription | ConditionDescription;
|
||||
|
||||
@state()
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
protected updated(changedProperties: PropertyValues): void {
|
||||
super.updated(changedProperties);
|
||||
// Collapse the host when empty so the parent flex gap is not reserved.
|
||||
this.toggleAttribute(
|
||||
"hidden",
|
||||
!this._getLabel(
|
||||
this._getThreshold(this.config, this.description),
|
||||
this._i18n
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const label = this._getLabel(
|
||||
this._getThreshold(this.config, this.description),
|
||||
this._i18n
|
||||
);
|
||||
|
||||
if (!label) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`<span class="dot-separator"></span>${label}`;
|
||||
}
|
||||
|
||||
private _getThreshold = memoizeOne(
|
||||
(
|
||||
config: PlatformTrigger | PlatformCondition,
|
||||
description: TriggerDescription | ConditionDescription | undefined
|
||||
) => {
|
||||
const fields = description?.fields;
|
||||
if (!fields || !config.options) {
|
||||
return undefined;
|
||||
}
|
||||
const entry = Object.entries(fields).find(
|
||||
([, field]) => field.selector && "numeric_threshold" in field.selector
|
||||
);
|
||||
if (!entry) {
|
||||
return undefined;
|
||||
}
|
||||
const value = config.options[entry[0]] as
|
||||
NumericThresholdValue | undefined;
|
||||
if (!value?.type) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const threshold = (entry[1].selector as NumericThresholdSelector)
|
||||
.numeric_threshold;
|
||||
const fallbackUnit =
|
||||
threshold?.unit_of_measurement?.[0] ??
|
||||
threshold?.number?.unit_of_measurement;
|
||||
const withUnit = (bound?: ThresholdValueEntry) =>
|
||||
bound
|
||||
? {
|
||||
...bound,
|
||||
unit_of_measurement: bound.unit_of_measurement ?? fallbackUnit,
|
||||
}
|
||||
: bound;
|
||||
|
||||
return {
|
||||
...value,
|
||||
value: withUnit(value.value),
|
||||
value_min: withUnit(value.value_min),
|
||||
value_max: withUnit(value.value_max),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
private _getLabel = memoizeOne(
|
||||
(threshold: NumericThresholdValue | undefined, i18n: typeof this._i18n) => {
|
||||
if (
|
||||
!threshold ||
|
||||
!threshold?.type ||
|
||||
threshold.type === "any" ||
|
||||
threshold.value?.active_choice === "entity" ||
|
||||
threshold.value_min?.active_choice === "entity" ||
|
||||
threshold.value_max?.active_choice === "entity"
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (threshold.type === "between" || threshold.type === "outside") {
|
||||
const min = threshold.value_min?.number;
|
||||
const max = threshold.value_max?.number;
|
||||
if (min === undefined || max === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const separateUnits =
|
||||
threshold.value_min?.unit_of_measurement !==
|
||||
threshold.value_max?.unit_of_measurement;
|
||||
|
||||
const range = `${formatNumber(min, this._i18n.locale)}${separateUnits ? this._unit(threshold.value_min?.unit_of_measurement) : ""}-${formatNumber(max, this._i18n.locale)}${this._unit(threshold.value_max?.unit_of_measurement)}`;
|
||||
|
||||
return i18n.localize(
|
||||
`ui.components.selectors.numeric_threshold.row_label.${threshold.type}`,
|
||||
{ value: range }
|
||||
);
|
||||
}
|
||||
|
||||
if (isNaN(Number(threshold.value?.number))) {
|
||||
return undefined;
|
||||
}
|
||||
return i18n.localize(
|
||||
`ui.components.selectors.numeric_threshold.row_label.${threshold.type}`,
|
||||
{
|
||||
value: `${formatNumber(threshold.value!.number!, this._i18n.locale)}${this._unit(threshold.value!.unit_of_measurement ?? "")}`,
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
private _unit(unit?: string): string {
|
||||
if (!unit) {
|
||||
return "";
|
||||
}
|
||||
return `${blankBeforeUnit(unit, this._i18n.locale)}${unit}`;
|
||||
}
|
||||
|
||||
static styles = rowSummaryStyles;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-automation-row-threshold": HaAutomationRowThreshold;
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ import { validateConfig } from "../../../../data/config";
|
||||
import { fullEntitiesContext } from "../../../../data/context";
|
||||
import type { EntityRegistryEntry } from "../../../../data/entity/entity_registry";
|
||||
import type { TargetSelector } from "../../../../data/selector";
|
||||
import { getTargetEntityCount } from "../../../../data/target";
|
||||
import type { TriggerDescriptions } from "../../../../data/trigger";
|
||||
import { isTriggerList } from "../../../../data/trigger";
|
||||
import {
|
||||
@@ -74,6 +75,7 @@ import { showEditorToast } from "../editor-toast";
|
||||
import "../ha-automation-editor-warning";
|
||||
import "../ha-automation-row-behavior";
|
||||
import "../ha-automation-row-options";
|
||||
import "../ha-automation-row-threshold";
|
||||
import { overflowStyles, rowStyles } from "../styles";
|
||||
import { getDeviceTarget } from "../target/get_device_target";
|
||||
import { getEntityTarget } from "../target/get_entity_target";
|
||||
@@ -256,9 +258,9 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
describeTrigger(this.trigger, this.hass, this._entityReg)
|
||||
)}
|
||||
${
|
||||
type === "platform"
|
||||
type === "platform" && targetRequired
|
||||
? html`<ha-automation-row-behavior
|
||||
.config=${this.trigger}
|
||||
.config=${getTargetEntityCount(target) > 1 ? this.trigger : undefined}
|
||||
></ha-automation-row-behavior>`
|
||||
: nothing
|
||||
}
|
||||
@@ -272,6 +274,18 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
)
|
||||
: nothing
|
||||
}
|
||||
${
|
||||
type === "platform"
|
||||
? html`<ha-automation-row-threshold
|
||||
.config=${this.trigger}
|
||||
.description=${
|
||||
this.triggerDescriptions[
|
||||
(this.trigger as PlatformTrigger).trigger
|
||||
]
|
||||
}
|
||||
></ha-automation-row-threshold>`
|
||||
: nothing
|
||||
}
|
||||
${
|
||||
type === "platform"
|
||||
? html`<ha-automation-row-options
|
||||
|
||||
@@ -637,6 +637,12 @@
|
||||
"entity": "Entity",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"row_label": {
|
||||
"above": "above {value}",
|
||||
"below": "below {value}",
|
||||
"between": "in range {value}",
|
||||
"outside": "outside {value}"
|
||||
},
|
||||
"crossed": {
|
||||
"type": "Fire when the value goes",
|
||||
"above": "Above",
|
||||
|
||||
Reference in New Issue
Block a user