test condition (#11925)

This commit is contained in:
Paulus Schoutsen 2022-03-16 14:13:13 -07:00 committed by GitHub
parent d5010dda9e
commit ab5df0fe6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 120 additions and 20 deletions

View File

@ -1,8 +1,9 @@
import "@material/mwc-button"; import "@material/mwc-button";
import type { Button } from "@material/mwc-button"; import { mdiAlertOctagram, mdiCheckBold } from "@mdi/js";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, query } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import "../ha-circular-progress"; import "../ha-circular-progress";
import "../ha-svg-icon";
@customElement("ha-progress-button") @customElement("ha-progress-button")
export class HaProgressButton extends LitElement { export class HaProgressButton extends LitElement {
@ -12,38 +13,53 @@ export class HaProgressButton extends LitElement {
@property({ type: Boolean }) public raised = false; @property({ type: Boolean }) public raised = false;
@query("mwc-button", true) private _button?: Button; @state() private _result?: "success" | "error";
public render(): TemplateResult { public render(): TemplateResult {
const overlay = this._result || this.progress;
return html` return html`
<mwc-button <mwc-button
?raised=${this.raised} ?raised=${this.raised}
.disabled=${this.disabled || this.progress} .disabled=${this.disabled || this.progress}
@click=${this._buttonTapped} @click=${this._buttonTapped}
class=${this._result || ""}
> >
<slot></slot> <slot></slot>
</mwc-button> </mwc-button>
${this.progress ${!overlay
? html`<div class="progress"> ? ""
<ha-circular-progress size="small" active></ha-circular-progress> : html`
</div>` <div class="progress">
${this._result === "success"
? html`<ha-svg-icon .path=${mdiCheckBold}></ha-svg-icon>`
: this._result === "error"
? html`<ha-svg-icon .path=${mdiAlertOctagram}></ha-svg-icon>`
: this.progress
? html`
<ha-circular-progress
size="small"
active
></ha-circular-progress>
`
: ""} : ""}
</div>
`}
`; `;
} }
public actionSuccess(): void { public actionSuccess(): void {
this._tempClass("success"); this._setResult("success");
} }
public actionError(): void { public actionError(): void {
this._tempClass("error"); this._setResult("error");
} }
private _tempClass(className: string): void { private _setResult(result: "success" | "error"): void {
this._button!.classList.add(className); this._result = result;
setTimeout(() => { setTimeout(() => {
this._button!.classList.remove(className); this._result = undefined;
}, 1000); }, 2000);
} }
private _buttonTapped(ev: Event): void { private _buttonTapped(ev: Event): void {
@ -69,6 +85,7 @@ export class HaProgressButton extends LitElement {
background-color: var(--success-color); background-color: var(--success-color);
transition: none; transition: none;
border-radius: 4px; border-radius: 4px;
pointer-events: none;
} }
mwc-button[raised].success { mwc-button[raised].success {
@ -81,6 +98,7 @@ export class HaProgressButton extends LitElement {
background-color: var(--error-color); background-color: var(--error-color);
transition: none; transition: none;
border-radius: 4px; border-radius: 4px;
pointer-events: none;
} }
mwc-button[raised].error { mwc-button[raised].error {
@ -89,13 +107,21 @@ export class HaProgressButton extends LitElement {
} }
.progress { .progress {
bottom: 0; bottom: 4px;
margin-top: 4px;
position: absolute; position: absolute;
text-align: center; text-align: center;
top: 0; top: 4px;
width: 100%; width: 100%;
} }
ha-svg-icon {
color: white;
}
mwc-button.success slot,
mwc-button.error slot {
visibility: hidden;
}
`; `;
} }
} }

View File

@ -7,12 +7,18 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { handleStructError } from "../../../../common/structs/handle-errors"; import { handleStructError } from "../../../../common/structs/handle-errors";
import "../../../../components/ha-button-menu"; import "../../../../components/ha-button-menu";
import "../../../../components/ha-card"; import "../../../../components/ha-card";
import "../../../../components/buttons/ha-progress-button";
import type { HaProgressButton } from "../../../../components/buttons/ha-progress-button";
import "../../../../components/ha-icon-button"; import "../../../../components/ha-icon-button";
import { Condition } from "../../../../data/automation"; import { Condition, testCondition } from "../../../../data/automation";
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box"; import {
showAlertDialog,
showConfirmationDialog,
} from "../../../../dialogs/generic/show-dialog-box";
import { haStyle } from "../../../../resources/styles"; import { haStyle } from "../../../../resources/styles";
import { HomeAssistant } from "../../../../types"; import { HomeAssistant } from "../../../../types";
import "./ha-automation-condition-editor"; import "./ha-automation-condition-editor";
import { validateConfig } from "../../../../data/config";
export interface ConditionElement extends LitElement { export interface ConditionElement extends LitElement {
condition: Condition; condition: Condition;
@ -61,6 +67,11 @@ export default class HaAutomationConditionRow extends LitElement {
<ha-card> <ha-card>
<div class="card-content"> <div class="card-content">
<div class="card-menu"> <div class="card-menu">
<ha-progress-button @click=${this._testCondition}>
${this.hass.localize(
"ui.panel.config.automation.editor.conditions.test"
)}
</ha-progress-button>
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}> <ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
<ha-icon-button <ha-icon-button
slot="trigger" slot="trigger"
@ -165,6 +176,64 @@ export default class HaAutomationConditionRow extends LitElement {
this._yamlMode = !this._yamlMode; this._yamlMode = !this._yamlMode;
} }
private async _testCondition(ev) {
const condition = this.condition;
const button = ev.target as HaProgressButton;
if (button.progress) {
return;
}
button.progress = true;
try {
const validateResult = await validateConfig(this.hass, {
condition,
});
// Abort if condition changed.
if (this.condition !== condition) {
return;
}
if (!validateResult.condition.valid) {
showAlertDialog(this, {
title: this.hass.localize(
"ui.panel.config.automation.editor.conditions.invalid_condition"
),
text: validateResult.condition.error,
});
return;
}
let result: { result: boolean };
try {
result = await testCondition(this.hass, condition);
} catch (err: any) {
if (this.condition !== condition) {
return;
}
showAlertDialog(this, {
title: this.hass.localize(
"ui.panel.config.automation.editor.conditions.test_failed"
),
text: err.message,
});
return;
}
if (this.condition !== condition) {
return;
}
if (result.result) {
button.actionSuccess();
} else {
button.actionError();
}
} finally {
button.progress = false;
}
}
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
haStyle, haStyle,
@ -173,6 +242,8 @@ export default class HaAutomationConditionRow extends LitElement {
float: right; float: right;
z-index: 3; z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color); --mdc-theme-text-primary-on-background: var(--primary-text-color);
display: flex;
align-items: center;
} }
.rtl .card-menu { .rtl .card-menu {
float: left; float: left;

View File

@ -293,7 +293,7 @@ export default class HaAutomationTriggerRow extends LitElement {
} }
const validateResult = await validateConfig(this.hass, { const validateResult = await validateConfig(this.hass, {
trigger: this.trigger, trigger,
}); });
// Don't do anything if trigger not valid or if trigger changed. // Don't do anything if trigger not valid or if trigger changed.

View File

@ -1746,6 +1746,9 @@
"introduction": "Conditions are optional and will prevent the automation from running unless all conditions are satisfied.", "introduction": "Conditions are optional and will prevent the automation from running unless all conditions are satisfied.",
"learn_more": "Learn more about conditions", "learn_more": "Learn more about conditions",
"add": "Add condition", "add": "Add condition",
"test": "Test",
"invalid_condition": "Invalid condition configuration",
"test_failed": "Error occurred while testing condition",
"duplicate": "[%key:ui::panel::config::automation::editor::triggers::duplicate%]", "duplicate": "[%key:ui::panel::config::automation::editor::triggers::duplicate%]",
"delete": "[%key:ui::panel::mailbox::delete_button%]", "delete": "[%key:ui::panel::mailbox::delete_button%]",
"delete_confirm": "[%key:ui::panel::config::automation::editor::triggers::delete_confirm%]", "delete_confirm": "[%key:ui::panel::config::automation::editor::triggers::delete_confirm%]",