Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion gallery/src/pages/components/ha-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ const SCHEMAS: {
schema: [
{ name: "addon", selector: { addon: {} } },
{ name: "entity", selector: { entity: {} } },
{ name: "device", selector: { device: {} } },
{
name: "Attribute",
selector: { attribute: { entity_id: "" } },
},
{ name: "Device", selector: { device: {} } },
{ name: "Duration", selector: { duration: {} } },
{ name: "area", selector: { area: {} } },
{ name: "target", selector: { target: {} } },
{ name: "number", selector: { number: { min: 0, max: 10 } } },
Expand Down
5 changes: 5 additions & 0 deletions gallery/src/pages/components/ha-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ const SCHEMAS: {
name: "One of each",
input: {
entity: { name: "Entity", selector: { entity: {} } },
attribute: {
name: "Attribute",
selector: { attribute: { entity_id: "" } },
},
device: { name: "Device", selector: { device: {} } },
duration: { name: "Duration", selector: { duration: {} } },
addon: { name: "Addon", selector: { addon: {} } },
area: { name: "Area", selector: { area: {} } },
target: { name: "Target", selector: { target: {} } },
Expand Down
1 change: 1 addition & 0 deletions src/components/ha-form/ha-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export class HaForm extends LitElement implements HaFormElement {
: ""}
${"selector" in item
? html`<ha-selector
.schema=${item}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary? The selector value is the schema in this case.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding features outside of the selector definition will break compatibility when selectors are used in services.yaml or blueprints.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed for the value changed event
I removed it and now all selectors are broken

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All selectors work here https://design.home-assistant.io/#components/ha-form

Why does it fix it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the value is changed and sent to the ha-form. Ha-form uses schema to find the name of the value

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

root.addEventListener("value-changed", (ev) => {
      ev.stopPropagation();
      const schema = (ev.target as HaFormElement).schema as HaFormSchema;
      fireEvent(this, "value-changed", {
        value: { ...this.data, [schema.name]: ev.detail.value },
      });
    });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then how does the selectors card on https://design.home-assistant.io/#components/ha-form work?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it the latest dev?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I broke it today

.hass=${this.hass}
.selector=${item.selector}
.value=${getValue(this.data, item)}
Expand Down
38 changes: 38 additions & 0 deletions src/components/ha-selector/ha-selector-attribute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import "../entity/ha-entity-attribute-picker";
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { AttributeSelector } from "../../data/selector";
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../types";

@customElement("ha-selector-attribute")
export class HaSelectorAttribute extends SubscribeMixin(LitElement) {
@property() public hass!: HomeAssistant;

@property() public selector!: AttributeSelector;

@property() public value?: any;

@property() public label?: string;

@property({ type: Boolean }) public disabled = false;

protected render() {
return html`
<ha-entity-attribute-picker
.hass=${this.hass}
.entityId=${this.selector.attribute.entity_id}
.value=${this.value}
.label=${this.label}
.disabled=${this.disabled}
allow-custom-value
></ha-entity-attribute-picker>
`;
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-selector-attribute": HaSelectorAttribute;
}
}
3 changes: 2 additions & 1 deletion src/components/ha-selector/ha-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ import { HomeAssistant } from "../../types";
import "./ha-selector-action";
import "./ha-selector-addon";
import "./ha-selector-area";
import "./ha-selector-attribute";
import "./ha-selector-boolean";
import "./ha-selector-device";
import "./ha-selector-duration";
import "./ha-selector-entity";
import "./ha-selector-number";
import "./ha-selector-object";
import "./ha-selector-select";
import "./ha-selector-target";
import "./ha-selector-text";
import "./ha-selector-time";
import "./ha-selector-duration";

@customElement("ha-selector")
export class HaSelector extends LitElement {
Expand Down
9 changes: 9 additions & 0 deletions src/data/selector.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export type Selector =
| AddonSelector
| AttributeSelector
| EntitySelector
| DeviceSelector
| DurationSelector
| AreaSelector
| TargetSelector
| NumberSelector
Expand All @@ -11,6 +13,7 @@ export type Selector =
| StringSelector
| ObjectSelector
| SelectSelector;

export interface EntitySelector {
entity: {
integration?: string;
Expand All @@ -19,6 +22,12 @@ export interface EntitySelector {
};
}

export interface AttributeSelector {
attribute: {
entity_id: string;
};
}

export interface DeviceSelector {
device: {
integration?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
string,
union,
} from "superstruct";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { hasTemplate } from "../../../../../common/string/has-template";
import { StateTrigger } from "../../../../../data/automation";
Expand All @@ -33,6 +34,7 @@ const stateTriggerStruct = assign(

const SCHEMA = [
{ name: "entity_id", selector: { entity: {} } },
{ name: "attribute", selector: { attribute: { entity_id: "" } } },
{ name: "from", required: false, selector: { text: {} } },
{ name: "to", required: false, selector: { text: {} } },
{ name: "for", required: false, selector: { duration: {} } },
Expand All @@ -48,6 +50,15 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
return { entity_id: "" };
}

private _schema = memoizeOne((entityId) => {
const schema = [...SCHEMA];
schema[1] = {
name: "attribute",
selector: { attribute: { entity_id: entityId } },
};
return schema;
});

public shouldUpdate(changedProperties: PropertyValues) {
if (!changedProperties.has("trigger")) {
return true;
Expand Down Expand Up @@ -81,12 +92,13 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
const trgFor = createDurationData(this.trigger.for);

const data = { ...this.trigger, ...{ for: trgFor } };
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{ ...this.trigger, for: trgFor }

const schema = this._schema(this.trigger.entity_id);

return html`
<ha-form
.hass=${this.hass}
.data=${data}
.schema=${SCHEMA}
.schema=${schema}
@value-changed=${this._valueChanged}
.computeLabel=${this._computeLabelCallback}
></ha-form>
Expand Down