20250430.2 (#25246)

This commit is contained in:
Paul Bottein 2025-04-30 17:52:11 +02:00 committed by GitHub
commit e517175f68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 184 additions and 148 deletions

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
version = "20250430.1"
version = "20250430.2"
license = "Apache-2.0"
license-files = ["LICENSE*"]
description = "The Home Assistant frontend"

View File

@ -71,7 +71,7 @@ const DOMAIN_STYLE = styleMap({
});
const ENTITY_ID_STYLE = styleMap({
fontFamily: "var(--code-font-family, monospace)",
fontFamily: "var(--ha-font-family-code)",
fontSize: "var(--ha-font-size-xs)",
});

View File

@ -48,7 +48,7 @@ interface StatisticItem {
const TYPE_ORDER = ["entity", "external", "no_state"] as StatisticItemType[];
const ENTITY_ID_STYLE = styleMap({
fontFamily: "var(--code-font-family, monospace)",
fontFamily: "var(--ha-font-family-code)",
fontSize: "11px",
});

View File

@ -24,6 +24,10 @@ export class HaToast extends Snackbar {
max-width: 650px;
}
.mdc-snackbar__actions {
color: rgba(255, 255, 255, 0.87);
}
/* Revert the default styles set by mwc-snackbar */
@media (max-width: 480px), (max-width: 344px) {
.mdc-snackbar__surface {

View File

@ -314,104 +314,119 @@ export class HaManualAutomationEditor extends LitElement {
return;
}
const loaded: any = load(paste);
if (loaded) {
let config = loaded;
let loaded: any;
try {
loaded = load(paste);
} catch (_err: any) {
showToast(this, {
message: this.hass.localize(
"ui.panel.config.automation.editor.paste_invalid_yaml"
),
duration: 4000,
dismissable: true,
});
return;
}
if ("automation" in config) {
config = config.automation;
if (Array.isArray(config)) {
config = config[0];
}
}
if (!loaded || typeof loaded !== "object") {
return;
}
let config = loaded;
if ("automation" in config) {
config = config.automation;
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;
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 (isTrigger(config)) {
config = { triggers: [config] };
}
if (isCondition(config)) {
config = { conditions: [config] };
}
if (getActionType(config) !== "unknown") {
config = { actions: [config] };
}
let normalized: AutomationConfig;
try {
normalized = normalizeAutomationConfig(config);
} catch (_err: any) {
return;
}
try {
assert(normalized, automationConfigStruct);
} catch (_err: any) {
showToast(this, {
message: this.hass.localize(
"ui.panel.config.automation.editor.paste_invalid_config"
),
duration: 4000,
dismissable: true,
});
return;
}
if (normalized) {
ev.preventDefault();
if (this.dirty) {
const result = await new Promise<boolean>((resolve) => {
showPasteReplaceDialog(this, {
domain: "automation",
pastedConfig: normalized,
onClose: () => resolve(false),
onAppend: () => {
this._appendToExistingConfig(normalized);
resolve(false);
},
onReplace: () => resolve(true),
});
});
if (!result) {
return;
}
if (found) {
config = newConfig;
}
// replace the config completely
this._replaceExistingConfig(normalized);
}
}
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(config);
} catch (_err: any) {
return;
}
try {
assert(normalized, automationConfigStruct);
} catch (_err: any) {
showToast(this, {
message: this.hass.localize(
"ui.panel.config.automation.editor.paste_invalid_config"
),
duration: 4000,
dismissable: true,
});
return;
}
if (normalized) {
ev.preventDefault();
if (this.dirty) {
const result = await new Promise<boolean>((resolve) => {
showPasteReplaceDialog(this, {
domain: "automation",
pastedConfig: normalized,
onClose: () => resolve(false),
onAppend: () => {
this._appendToExistingConfig(normalized);
resolve(false);
},
onReplace: () => resolve(true),
});
});
if (!result) {
return;
}
}
// replace the config completely
this._replaceExistingConfig(normalized);
}
};
private _appendToExistingConfig(config: ManualAutomationConfig) {

View File

@ -238,75 +238,90 @@ export class HaManualScriptEditor extends LitElement {
return;
}
const loaded: any = load(paste);
if (loaded) {
let config = loaded;
let loaded: any;
try {
loaded = load(paste);
} catch (_err: any) {
showToast(this, {
message: this.hass.localize(
"ui.panel.config.script.editor.paste_invalid_config"
),
duration: 4000,
dismissable: true,
});
return;
}
if ("script" in config) {
config = config.script;
if (Object.keys(config).length) {
config = config[Object.keys(config)[0]];
}
if (!loaded || typeof loaded !== "object") {
return;
}
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 (Array.isArray(config)) {
if (config.length === 1) {
config = config[0];
} else {
config = { sequence: config };
}
}
if (!["sequence", "unknown"].includes(getActionType(config))) {
config = { sequence: [config] };
}
if (!["sequence", "unknown"].includes(getActionType(config))) {
config = { sequence: [config] };
}
let normalized: ScriptConfig | undefined;
let normalized: ScriptConfig | undefined;
try {
normalized = normalizeScriptConfig(config);
} catch (_err: any) {
return;
}
try {
normalized = normalizeScriptConfig(config);
} catch (_err: any) {
return;
}
try {
assert(normalized, scriptConfigStruct);
} catch (_err: any) {
showToast(this, {
message: this.hass.localize(
"ui.panel.config.script.editor.paste_invalid_config"
),
duration: 4000,
dismissable: true,
});
return;
}
try {
assert(normalized, scriptConfigStruct);
} catch (_err: any) {
showToast(this, {
message: this.hass.localize(
"ui.panel.config.script.editor.paste_invalid_config"
),
duration: 4000,
dismissable: true,
});
return;
}
if (normalized) {
ev.preventDefault();
if (normalized) {
ev.preventDefault();
if (this.dirty) {
const result = await new Promise<boolean>((resolve) => {
showPasteReplaceDialog(this, {
domain: "script",
pastedConfig: normalized,
onClose: () => resolve(false),
onAppend: () => {
this._appendToExistingConfig(normalized);
resolve(false);
},
onReplace: () => resolve(true),
});
if (this.dirty) {
const result = await new Promise<boolean>((resolve) => {
showPasteReplaceDialog(this, {
domain: "script",
pastedConfig: normalized,
onClose: () => resolve(false),
onAppend: () => {
this._appendToExistingConfig(normalized);
resolve(false);
},
onReplace: () => resolve(true),
});
});
if (!result) {
return;
}
if (!result) {
return;
}
// replace the config completely
this._replaceExistingConfig(normalized);
}
// replace the config completely
this._replaceExistingConfig(normalized);
}
};

View File

@ -4356,6 +4356,7 @@
"text": "How do you want to paste your automation?"
},
"paste_toast_message": "Pasted automation from clipboard",
"paste_invalid_yaml": "Pasted value is not valid YAML",
"paste_invalid_config": "Pasted automation is not editable in the visual editor"
},
"trace": {
@ -4595,6 +4596,7 @@
"text": "How do you want to paste your script?"
},
"paste_toast_message": "Pasted script from clipboard",
"paste_invalid_yaml": "Pasted value is not valid YAML",
"paste_invalid_config": "Pasted script is not editable in the visual editor"
},
"trace": {