mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-18 23:06:40 +00:00
Handle errrors/wrong values on paste (#25245)
This commit is contained in:
parent
46cc254f77
commit
efd7b380a9
@ -24,6 +24,10 @@ export class HaToast extends Snackbar {
|
|||||||
max-width: 650px;
|
max-width: 650px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mdc-snackbar__actions {
|
||||||
|
color: rgba(255, 255, 255, 0.87);
|
||||||
|
}
|
||||||
|
|
||||||
/* Revert the default styles set by mwc-snackbar */
|
/* Revert the default styles set by mwc-snackbar */
|
||||||
@media (max-width: 480px), (max-width: 344px) {
|
@media (max-width: 480px), (max-width: 344px) {
|
||||||
.mdc-snackbar__surface {
|
.mdc-snackbar__surface {
|
||||||
|
@ -314,104 +314,119 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loaded: any = load(paste);
|
let loaded: any;
|
||||||
if (loaded) {
|
try {
|
||||||
let config = loaded;
|
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) {
|
if (!loaded || typeof loaded !== "object") {
|
||||||
config = config.automation;
|
return;
|
||||||
if (Array.isArray(config)) {
|
}
|
||||||
config = config[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let config = loaded;
|
||||||
|
|
||||||
|
if ("automation" in config) {
|
||||||
|
config = config.automation;
|
||||||
if (Array.isArray(config)) {
|
if (Array.isArray(config)) {
|
||||||
if (config.length === 1) {
|
config = config[0];
|
||||||
config = config[0];
|
}
|
||||||
} else {
|
}
|
||||||
const newConfig: AutomationConfig = {
|
|
||||||
triggers: [],
|
if (Array.isArray(config)) {
|
||||||
conditions: [],
|
if (config.length === 1) {
|
||||||
actions: [],
|
config = config[0];
|
||||||
};
|
} else {
|
||||||
let found = false;
|
const newConfig: AutomationConfig = {
|
||||||
config.forEach((cfg: any) => {
|
triggers: [],
|
||||||
if (isTrigger(cfg)) {
|
conditions: [],
|
||||||
found = true;
|
actions: [],
|
||||||
(newConfig.triggers as Trigger[]).push(cfg);
|
};
|
||||||
}
|
let found = false;
|
||||||
if (isCondition(cfg)) {
|
config.forEach((cfg: any) => {
|
||||||
found = true;
|
if (isTrigger(cfg)) {
|
||||||
(newConfig.conditions as Condition[]).push(cfg);
|
found = true;
|
||||||
}
|
(newConfig.triggers as Trigger[]).push(cfg);
|
||||||
if (getActionType(cfg) !== "unknown") {
|
}
|
||||||
found = true;
|
if (isCondition(cfg)) {
|
||||||
(newConfig.actions as Action[]).push(cfg);
|
found = true;
|
||||||
}
|
(newConfig.conditions as Condition[]).push(cfg);
|
||||||
});
|
}
|
||||||
if (found) {
|
if (getActionType(cfg) !== "unknown") {
|
||||||
config = newConfig;
|
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 (found) {
|
||||||
}
|
config = newConfig;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
private _appendToExistingConfig(config: ManualAutomationConfig) {
|
||||||
|
@ -238,75 +238,90 @@ export class HaManualScriptEditor extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loaded: any = load(paste);
|
let loaded: any;
|
||||||
if (loaded) {
|
try {
|
||||||
let config = loaded;
|
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) {
|
if (!loaded || typeof loaded !== "object") {
|
||||||
config = config.script;
|
return;
|
||||||
if (Object.keys(config).length) {
|
}
|
||||||
config = config[Object.keys(config)[0]];
|
|
||||||
}
|
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 (Array.isArray(config)) {
|
||||||
if (config.length === 1) {
|
if (config.length === 1) {
|
||||||
config = config[0];
|
config = config[0];
|
||||||
} else {
|
} else {
|
||||||
config = { sequence: config };
|
config = { sequence: config };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!["sequence", "unknown"].includes(getActionType(config))) {
|
if (!["sequence", "unknown"].includes(getActionType(config))) {
|
||||||
config = { sequence: [config] };
|
config = { sequence: [config] };
|
||||||
}
|
}
|
||||||
|
|
||||||
let normalized: ScriptConfig | undefined;
|
let normalized: ScriptConfig | undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
normalized = normalizeScriptConfig(config);
|
normalized = normalizeScriptConfig(config);
|
||||||
} catch (_err: any) {
|
} catch (_err: any) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assert(normalized, scriptConfigStruct);
|
assert(normalized, scriptConfigStruct);
|
||||||
} catch (_err: any) {
|
} catch (_err: any) {
|
||||||
showToast(this, {
|
showToast(this, {
|
||||||
message: this.hass.localize(
|
message: this.hass.localize(
|
||||||
"ui.panel.config.script.editor.paste_invalid_config"
|
"ui.panel.config.script.editor.paste_invalid_config"
|
||||||
),
|
),
|
||||||
duration: 4000,
|
duration: 4000,
|
||||||
dismissable: true,
|
dismissable: true,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalized) {
|
if (normalized) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
if (this.dirty) {
|
if (this.dirty) {
|
||||||
const result = await new Promise<boolean>((resolve) => {
|
const result = await new Promise<boolean>((resolve) => {
|
||||||
showPasteReplaceDialog(this, {
|
showPasteReplaceDialog(this, {
|
||||||
domain: "script",
|
domain: "script",
|
||||||
pastedConfig: normalized,
|
pastedConfig: normalized,
|
||||||
onClose: () => resolve(false),
|
onClose: () => resolve(false),
|
||||||
onAppend: () => {
|
onAppend: () => {
|
||||||
this._appendToExistingConfig(normalized);
|
this._appendToExistingConfig(normalized);
|
||||||
resolve(false);
|
resolve(false);
|
||||||
},
|
},
|
||||||
onReplace: () => resolve(true),
|
onReplace: () => resolve(true),
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace the config completely
|
|
||||||
this._replaceExistingConfig(normalized);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// replace the config completely
|
||||||
|
this._replaceExistingConfig(normalized);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4356,6 +4356,7 @@
|
|||||||
"text": "How do you want to paste your automation?"
|
"text": "How do you want to paste your automation?"
|
||||||
},
|
},
|
||||||
"paste_toast_message": "Pasted automation from clipboard",
|
"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"
|
"paste_invalid_config": "Pasted automation is not editable in the visual editor"
|
||||||
},
|
},
|
||||||
"trace": {
|
"trace": {
|
||||||
@ -4595,6 +4596,7 @@
|
|||||||
"text": "How do you want to paste your script?"
|
"text": "How do you want to paste your script?"
|
||||||
},
|
},
|
||||||
"paste_toast_message": "Pasted script from clipboard",
|
"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"
|
"paste_invalid_config": "Pasted script is not editable in the visual editor"
|
||||||
},
|
},
|
||||||
"trace": {
|
"trace": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user