Compare commits

..

2 Commits

Author SHA1 Message Date
Wendelin 8af5908682 Fix add T/C/A floor auto open; Target details adaptive dialog. (#52001)
* Auto open single floor

* Use adaptive dialog for target details

* review
2026-05-12 19:28:24 +03:00
George Caliment 60e95b886c Fixed how ha-entity-toggle sets ha-switch styles var (#51984) 2026-05-12 16:46:01 +02:00
7 changed files with 23 additions and 189 deletions
@@ -124,7 +124,6 @@ export class HaAutomationRow extends LitElement {
static styles = css`
:host {
display: block;
position: relative;
}
.row {
display: flex;
+11 -3
View File
@@ -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>
`;
}
-14
View File
@@ -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;
@@ -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];
}
}
-6
View File
@@ -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",