diff --git a/pyproject.toml b/pyproject.toml index 169b86dbe8..bb4fba543b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20250430.0" +version = "20250430.1" license = "Apache-2.0" license-files = ["LICENSE*"] description = "The Home Assistant frontend" diff --git a/src/data/automation.ts b/src/data/automation.ts index 7308e51e34..1e57fde2ff 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -492,6 +492,25 @@ export const getAutomationEditorInitData = () => { return data; }; +export const isTrigger = (config: unknown): boolean => { + if (!config || typeof config !== "object") { + return false; + } + const trigger = config as Record; + return ( + ("trigger" in trigger && typeof trigger.trigger === "string") || + ("platform" in trigger && typeof trigger.platform === "string") + ); +}; + +export const isCondition = (config: unknown): boolean => { + if (!config || typeof config !== "object") { + return false; + } + const condition = config as Record; + return "condition" in condition && typeof condition.condition === "string"; +}; + export const subscribeTrigger = ( hass: HomeAssistant, onChange: (result: { diff --git a/src/panels/config/automation/manual-automation-editor.ts b/src/panels/config/automation/manual-automation-editor.ts index a064b65a8d..8e0ae2209f 100644 --- a/src/panels/config/automation/manual-automation-editor.ts +++ b/src/panels/config/automation/manual-automation-editor.ts @@ -26,8 +26,12 @@ import type { ManualAutomationConfig, Trigger, } from "../../../data/automation"; -import { normalizeAutomationConfig } from "../../../data/automation"; -import type { Action } from "../../../data/script"; +import { + isCondition, + isTrigger, + normalizeAutomationConfig, +} from "../../../data/automation"; +import { getActionType, type Action } from "../../../data/script"; import { haStyle } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; import { documentationUrl } from "../../../util/documentation-url"; @@ -312,10 +316,59 @@ export class HaManualAutomationEditor extends LitElement { const loaded: any = load(paste); if (loaded) { - let normalized: AutomationConfig | undefined; + let config = loaded; + + if ("automation" in config) { + config = config.automation; + if (Array.isArray(config)) { + config = config[0]; + } + } + + if (Array.isArray(config)) { + if (config.length === 1) { + config = config[0]; + } else { + const newConfig: AutomationConfig = { + triggers: [], + conditions: [], + actions: [], + }; + let found = false; + config.forEach((cfg: any) => { + if (isTrigger(cfg)) { + found = true; + (newConfig.triggers as Trigger[]).push(cfg); + } + if (isCondition(cfg)) { + found = true; + (newConfig.conditions as Condition[]).push(cfg); + } + if (getActionType(cfg) !== "unknown") { + found = true; + (newConfig.actions as Action[]).push(cfg); + } + }); + if (found) { + config = newConfig; + } + } + } + + if (isTrigger(config)) { + config = { triggers: [config] }; + } + if (isCondition(config)) { + config = { conditions: [config] }; + } + if (getActionType(config) !== "unknown") { + config = { actions: [config] }; + } + + let normalized: AutomationConfig; try { - normalized = normalizeAutomationConfig(loaded); + normalized = normalizeAutomationConfig(config); } catch (_err: any) { return; } diff --git a/src/panels/config/network/ha-config-network-dhcp.ts b/src/panels/config/network/ha-config-network-dhcp.ts new file mode 100644 index 0000000000..ef70d11903 --- /dev/null +++ b/src/panels/config/network/ha-config-network-dhcp.ts @@ -0,0 +1,66 @@ +import "@material/mwc-button/mwc-button"; +import type { CSSResultGroup } from "lit"; +import { css, html, LitElement } from "lit"; +import { customElement, property } from "lit/decorators"; +import "../../../components/ha-button"; +import "../../../components/ha-card"; +import { haStyle } from "../../../resources/styles"; +import type { HomeAssistant } from "../../../types"; + +@customElement("ha-config-network-dhcp") +class ConfigNetworkDHCP extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + protected render() { + return html` + +
+

+ ${this.hass.localize("ui.panel.config.network.discovery.dhcp_info")} +

+
+ +
+ `; + } + + static get styles(): CSSResultGroup { + return [ + haStyle, + css` + ha-settings-row { + padding: 0; + } + + .card-actions { + display: flex; + flex-direction: row-reverse; + justify-content: space-between; + align-items: center; + } + `, // row-reverse so we tab first to "save" + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-config-network-dhcp": ConfigNetworkDHCP; + } +} diff --git a/src/panels/config/network/ha-config-section-network.ts b/src/panels/config/network/ha-config-section-network.ts index 4b5f6a2808..c9a3df311d 100644 --- a/src/panels/config/network/ha-config-section-network.ts +++ b/src/panels/config/network/ha-config-section-network.ts @@ -5,6 +5,7 @@ import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import "../../../layouts/hass-subpage"; import type { HomeAssistant, Route } from "../../../types"; import "./ha-config-network"; +import "./ha-config-network-dhcp"; import "./ha-config-network-ssdp"; import "./ha-config-network-zeroconf"; import "./ha-config-url-form"; @@ -37,6 +38,11 @@ class HaConfigSectionNetwork extends LitElement { : ""} + ${isComponentLoaded(this.hass, "dhcp") + ? html`` + : ""} ${isComponentLoaded(this.hass, "ssdp") ? html`