Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Attribute Picker as a selector - add to state trigger #11641

Merged
merged 6 commits into from
Feb 10, 2022
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.
Jump to
Jump to file
Failed to load files.
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
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
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
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
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
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
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
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
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
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";
zsarnett marked this conversation as resolved.
Show resolved Hide resolved
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
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