20250430.1 (#25244)

This commit is contained in:
Paul Bottein 2025-04-30 16:10:12 +02:00 committed by GitHub
commit d996ba818f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 180 additions and 7 deletions

View File

@ -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"

View File

@ -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<string, unknown>;
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<string, unknown>;
return "condition" in condition && typeof condition.condition === "string";
};
export const subscribeTrigger = (
hass: HomeAssistant,
onChange: (result: {

View File

@ -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;
}

View File

@ -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`
<ha-card
outlined
header=${this.hass.localize("ui.panel.config.network.discovery.dhcp")}
>
<div class="card-content">
<p>
${this.hass.localize("ui.panel.config.network.discovery.dhcp_info")}
</p>
</div>
<div class="card-actions">
<a
href="/config/dhcp"
aria-label=${this.hass.localize(
"ui.panel.config.network.discovery.dhcp_browser"
)}
>
<ha-button>
${this.hass.localize(
"ui.panel.config.network.discovery.dhcp_browser"
)}
</ha-button>
</a>
</div>
</ha-card>
`;
}
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;
}
}

View File

@ -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 {
: ""}
<ha-config-url-form .hass=${this.hass}></ha-config-url-form>
<ha-config-network .hass=${this.hass}></ha-config-network>
${isComponentLoaded(this.hass, "dhcp")
? html`<ha-config-network-dhcp
.hass=${this.hass}
></ha-config-network-dhcp>`
: ""}
${isComponentLoaded(this.hass, "ssdp")
? html`<ha-config-network-ssdp
.hass=${this.hass}
@ -62,6 +68,7 @@ class HaConfigSectionNetwork extends LitElement {
supervisor-network,
ha-config-url-form,
ha-config-network,
ha-config-network-dhcp,
ha-config-network-ssdp,
ha-config-network-zeroconf {
display: block;

View File

@ -24,7 +24,11 @@ import "../../../components/ha-card";
import "../../../components/ha-icon-button";
import "../../../components/ha-markdown";
import type { Action, Fields, ScriptConfig } from "../../../data/script";
import { MODES, normalizeScriptConfig } from "../../../data/script";
import {
getActionType,
MODES,
normalizeScriptConfig,
} from "../../../data/script";
import { haStyle } from "../../../resources/styles";
import type { HomeAssistant } from "../../../types";
import { documentationUrl } from "../../../util/documentation-url";
@ -236,10 +240,31 @@ export class HaManualScriptEditor extends LitElement {
const loaded: any = load(paste);
if (loaded) {
let config = loaded;
if ("script" in config) {
config = config.script;
if (Object.keys(config).length) {
config = config[Object.keys(config)[0]];
}
}
if (Array.isArray(config)) {
if (config.length === 1) {
config = config[0];
} else {
config = { sequence: config };
}
}
if (!["sequence", "unknown"].includes(getActionType(config))) {
config = { sequence: [config] };
}
let normalized: ScriptConfig | undefined;
try {
normalized = normalizeScriptConfig(loaded);
normalized = normalizeScriptConfig(config);
} catch (_err: any) {
return;
}

View File

@ -6392,6 +6392,9 @@
}
},
"discovery": {
"dhcp": "DHCP browser",
"dhcp_info": "The DHCP browser displays devices discovered by Home Assistant via DHCP, ARP+PTR lookups, and router-based device trackers. All detected devices by these methods will appear here.",
"dhcp_browser": "View DHCP browser",
"ssdp": "SSDP browser",
"ssdp_info": "The SSDP browser shows devices discovered by Home Assistant using SSDP/UPnP. Devices that Home Assistant has discovered will appear here.",
"ssdp_browser": "View SSDP browser",