mirror of
https://github.com/home-assistant/frontend.git
synced 2026-05-13 04:36:53 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8af5908682 | |||
| 60e95b886c |
@@ -124,7 +124,6 @@ export class HaAutomationRow extends LitElement {
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
|
||||
@@ -22,6 +22,14 @@ const isOn = (stateObj?: HassEntity) =>
|
||||
!STATES_OFF.includes(stateObj.state) &&
|
||||
!isUnavailableState(stateObj.state);
|
||||
|
||||
/**
|
||||
* @element ha-entity-toggle
|
||||
*
|
||||
* @cssprop --ha-entity-toggle-switch-width - Width of the switch track. Defaults to `38px`.
|
||||
* @cssprop --ha-entity-toggle-switch-size - Height of the switch track. Defaults to `20px`.
|
||||
* @cssprop --ha-entity-toggle-switch-thumb-size - Size of the switch thumb. Defaults to `14px`.
|
||||
*/
|
||||
|
||||
@customElement("ha-entity-toggle")
|
||||
export class HaEntityToggle extends LitElement {
|
||||
// hass is not a property so that we only re-render on stateObj changes
|
||||
@@ -165,9 +173,9 @@ export class HaEntityToggle extends LitElement {
|
||||
white-space: nowrap;
|
||||
}
|
||||
ha-switch {
|
||||
--ha-switch-width: 38px;
|
||||
--ha-switch-size: 20px;
|
||||
--ha-switch-thumb-size: 14px;
|
||||
--ha-switch-width: var(--ha-entity-toggle-switch-width, 38px);
|
||||
--ha-switch-size: var(--ha-entity-toggle-switch-size, 20px);
|
||||
--ha-switch-thumb-size: var(--ha-entity-toggle-switch-thumb-size, 14px);
|
||||
}
|
||||
ha-icon-button {
|
||||
--ha-icon-button-size: 40px;
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
import type { HassDialog } from "../../../dialogs/make-dialog-manager";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { HaDevicePickerDeviceFilterFunc } from "../../device/ha-device-picker";
|
||||
import "../../ha-dialog";
|
||||
import "../../ha-adaptive-dialog";
|
||||
import "../../ha-dialog-header";
|
||||
import "../../ha-icon-button";
|
||||
import "../../ha-icon-next";
|
||||
@@ -153,7 +153,7 @@ class DialogTargetDetails extends LitElement implements HassDialog {
|
||||
!this._entitySourcesLoaded;
|
||||
|
||||
return html`
|
||||
<ha-dialog
|
||||
<ha-adaptive-dialog
|
||||
.open=${this._opened}
|
||||
header-title=${this.hass.localize(
|
||||
"ui.components.target-picker.target_details"
|
||||
@@ -187,7 +187,7 @@ class DialogTargetDetails extends LitElement implements HassDialog {
|
||||
`}
|
||||
</ha-list-base>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
</ha-adaptive-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type {
|
||||
Connection,
|
||||
HassEntityAttributeBase,
|
||||
HassEntityBase,
|
||||
HassServiceTarget,
|
||||
@@ -585,19 +584,6 @@ export const testCondition = (
|
||||
variables,
|
||||
});
|
||||
|
||||
export const subscribeCondition = (
|
||||
connection: Connection,
|
||||
onChange: (result: {
|
||||
result?: boolean;
|
||||
error?: string | { code: string; message: string };
|
||||
}) => void,
|
||||
condition: Condition
|
||||
) =>
|
||||
connection.subscribeMessage(onChange, {
|
||||
type: "subscribe_condition",
|
||||
condition,
|
||||
});
|
||||
|
||||
export interface AutomationClipboard {
|
||||
trigger?: Trigger;
|
||||
condition?: Condition;
|
||||
|
||||
+4
-1
@@ -866,10 +866,13 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
undefined
|
||||
);
|
||||
|
||||
const filteredFloors = this._floorAreas.filter(
|
||||
({ id, areas }) => id !== undefined && areas.length
|
||||
);
|
||||
this._floorAreas.forEach((floor) => {
|
||||
this._entries[floor.id || `floor${TARGET_SEPARATOR}`] = {
|
||||
// auto expand if only one floor is present
|
||||
open: this._floorAreas.length === 1,
|
||||
open: filteredFloors.length === 1 && filteredFloors[0].id === floor.id,
|
||||
areas: {},
|
||||
};
|
||||
|
||||
|
||||
@@ -17,13 +17,10 @@ import {
|
||||
mdiStopCircleOutline,
|
||||
} from "@mdi/js";
|
||||
import deepClone from "deep-clone-simple";
|
||||
import type {
|
||||
HassServiceTarget,
|
||||
UnsubscribeFunc,
|
||||
} from "home-assistant-js-websocket";
|
||||
import type { HassServiceTarget } from "home-assistant-js-websocket";
|
||||
import { dump } from "js-yaml";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { LitElement, html, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
@@ -35,7 +32,6 @@ import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
||||
import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter";
|
||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||
import { copyToClipboard } from "../../../../common/util/copy-clipboard";
|
||||
import { debounce } from "../../../../common/util/debounce";
|
||||
import "../../../../components/automation/ha-automation-row";
|
||||
import type { HaAutomationRow } from "../../../../components/automation/ha-automation-row";
|
||||
import "../../../../components/automation/ha-automation-row-event-chip";
|
||||
@@ -46,18 +42,13 @@ import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
import "../../../../components/ha-dropdown-item";
|
||||
import "../../../../components/ha-expansion-panel";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-tooltip";
|
||||
import type {
|
||||
AutomationClipboard,
|
||||
Condition,
|
||||
ConditionSidebarConfig,
|
||||
PlatformCondition,
|
||||
} from "../../../../data/automation";
|
||||
import {
|
||||
isCondition,
|
||||
subscribeCondition,
|
||||
testCondition,
|
||||
} from "../../../../data/automation";
|
||||
import { isCondition, testCondition } from "../../../../data/automation";
|
||||
import { describeCondition } from "../../../../data/automation_i18n";
|
||||
import type { ConditionDescriptions } from "../../../../data/condition";
|
||||
import { CONDITION_BUILDING_BLOCKS } from "../../../../data/condition";
|
||||
@@ -149,11 +140,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
|
||||
@state() private _selected = false;
|
||||
|
||||
@state() private _liveTestResult: {
|
||||
state: "pass" | "fail" | "invalid" | "unknown";
|
||||
message?: string;
|
||||
} = { state: "unknown" };
|
||||
|
||||
@state()
|
||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||
_entityReg: EntityRegistryEntry[] = [];
|
||||
@@ -166,8 +152,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
|
||||
private _testingTimeout?: number;
|
||||
|
||||
private _conditionUnsub?: Promise<UnsubscribeFunc>;
|
||||
|
||||
get selected() {
|
||||
return this._selected;
|
||||
}
|
||||
@@ -497,23 +481,7 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
.dim=${this._testing}
|
||||
@click=${this._toggleSidebar}
|
||||
@toggle-collapsed=${this._toggleCollapse}
|
||||
>${this._renderRow()}
|
||||
<div
|
||||
slot="icons"
|
||||
id="live-test"
|
||||
class=${this._liveTestResult.state}
|
||||
role="status"
|
||||
tabindex="0"
|
||||
aria-label=${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.conditions.live_test_state.${this._liveTestResult.state}`
|
||||
)}
|
||||
>
|
||||
${this._liveTestResult.message
|
||||
? html`<ha-tooltip for="live-test">
|
||||
${this._liveTestResult.message}
|
||||
</ha-tooltip>`
|
||||
: nothing}
|
||||
</div></ha-automation-row
|
||||
>${this._renderRow()}</ha-automation-row
|
||||
>`
|
||||
: html`
|
||||
<ha-expansion-panel
|
||||
@@ -558,11 +526,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
></ha-automation-row-targets>`
|
||||
);
|
||||
|
||||
public connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this._subscribeCondition();
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProperties: PropertyValues<this>): void {
|
||||
super.firstUpdated(changedProperties);
|
||||
|
||||
@@ -578,85 +541,11 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
protected override updated(changedProps: PropertyValues<this>): void {
|
||||
super.updated(changedProps);
|
||||
if (
|
||||
changedProps.has("condition") &&
|
||||
changedProps.get("condition") !== undefined
|
||||
) {
|
||||
this._resetSubscription();
|
||||
this._debounceSubscribeCondition();
|
||||
}
|
||||
}
|
||||
|
||||
public disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
if (this._testingTimeout !== undefined) {
|
||||
clearTimeout(this._testingTimeout);
|
||||
}
|
||||
this._resetSubscription();
|
||||
}
|
||||
|
||||
private _resetSubscription() {
|
||||
this._liveTestResult = {
|
||||
state: "unknown",
|
||||
message: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.live_test_state.unknown"
|
||||
),
|
||||
};
|
||||
if (this._conditionUnsub) {
|
||||
this._conditionUnsub.then((unsub) => unsub());
|
||||
this._conditionUnsub = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private _debounceSubscribeCondition = debounce(
|
||||
() => this._subscribeCondition(),
|
||||
500
|
||||
);
|
||||
|
||||
private async _subscribeCondition() {
|
||||
const condition = this.condition;
|
||||
|
||||
this._resetSubscription();
|
||||
|
||||
// Don't do anything if condition changed.
|
||||
if (this.condition !== condition) {
|
||||
return;
|
||||
}
|
||||
|
||||
const conditionUnsub = subscribeCondition(
|
||||
this.hass.connection,
|
||||
(result) => {
|
||||
if (result.error) {
|
||||
this._handleLiveTestError(result.error);
|
||||
} else {
|
||||
this._liveTestResult = {
|
||||
state: result.result ? "pass" : "fail",
|
||||
message: this.hass.localize(
|
||||
`ui.panel.config.automation.editor.conditions.testing_${result.result ? "pass" : "error"}`
|
||||
),
|
||||
};
|
||||
}
|
||||
},
|
||||
condition
|
||||
);
|
||||
conditionUnsub.catch((err: any) => {
|
||||
this._handleLiveTestError(err);
|
||||
if (this._conditionUnsub === conditionUnsub) {
|
||||
this._conditionUnsub = undefined;
|
||||
}
|
||||
});
|
||||
this._conditionUnsub = conditionUnsub;
|
||||
}
|
||||
|
||||
private _handleLiveTestError(error: any) {
|
||||
const invalid =
|
||||
typeof error !== "string" && error.code === "invalid_format";
|
||||
this._liveTestResult = {
|
||||
state: invalid ? "invalid" : "unknown",
|
||||
message: typeof error === "string" ? error : error.message,
|
||||
};
|
||||
}
|
||||
|
||||
private _onValueChange(event: CustomEvent) {
|
||||
@@ -1066,52 +955,7 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
rowStyles,
|
||||
overflowStyles,
|
||||
css`
|
||||
#live-test {
|
||||
position: absolute;
|
||||
inset-inline-end: -6px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: var(--ha-border-radius-circle);
|
||||
border: 3px solid;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--card-background-color);
|
||||
transition: all var(--ha-animation-duration-normal) ease-in-out;
|
||||
}
|
||||
#live-test.pass {
|
||||
background-color: var(--ha-color-fill-success-loud-resting);
|
||||
border-color: var(--ha-color-fill-success-loud-resting);
|
||||
}
|
||||
#live-test.pass:hover {
|
||||
background-color: var(--ha-color-fill-success-loud-hover);
|
||||
border-color: var(--ha-color-fill-success-loud-hover);
|
||||
}
|
||||
#live-test.fail {
|
||||
border-color: var(--ha-color-fill-warning-loud-resting);
|
||||
}
|
||||
#live-test.fail:hover {
|
||||
background-color: var(--ha-color-fill-warning-loud-hover);
|
||||
border-color: var(--ha-color-fill-warning-loud-hover);
|
||||
}
|
||||
#live-test.invalid {
|
||||
border-color: var(--ha-color-fill-danger-loud-resting);
|
||||
}
|
||||
#live-test.invalid:hover {
|
||||
background-color: var(--ha-color-fill-danger-loud-hover);
|
||||
border-color: var(--ha-color-fill-danger-loud-hover);
|
||||
}
|
||||
#live-test.unknown {
|
||||
border-color: var(--ha-color-fill-neutral-loud-resting);
|
||||
}
|
||||
#live-test.unknown:hover {
|
||||
background-color: var(--ha-color-fill-neutral-loud-hover);
|
||||
border-color: var(--ha-color-fill-neutral-loud-hover);
|
||||
}
|
||||
`,
|
||||
];
|
||||
return [rowStyles, overflowStyles];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5405,12 +5405,6 @@
|
||||
"test": "Test",
|
||||
"testing_error": "Condition did not pass",
|
||||
"testing_pass": "Condition passes",
|
||||
"live_test_state": {
|
||||
"pass": "[%key:ui::panel::config::automation::editor::conditions::testing_pass%]",
|
||||
"fail": "[%key:ui::panel::config::automation::editor::conditions::testing_error%]",
|
||||
"invalid": "Condition is invalid",
|
||||
"unknown": "Condition state unknown"
|
||||
},
|
||||
"invalid_condition": "Invalid condition configuration",
|
||||
"validation_failed": "Condition validation failed",
|
||||
"test_failed": "Error occurred while testing condition",
|
||||
|
||||
Reference in New Issue
Block a user