Fix input select more info (#3132)

* Fix input select more info

* Lint
This commit is contained in:
Paulus Schoutsen 2019-04-27 22:02:26 -07:00 committed by GitHub
parent 8ca70ace4c
commit 1e72ffc0c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 160 additions and 122 deletions

View File

@ -0,0 +1 @@
export const stopPropagation = (ev) => ev.stopPropagation();

View File

@ -1,6 +1,6 @@
import { HomeAssistant } from "../types";
export const setOption = (
export const setInputSelectOption = (
hass: HomeAssistant,
entity: string,
option: string

View File

@ -8,7 +8,6 @@ import {
customElement,
PropertyValues,
} from "lit-element";
import { repeat } from "lit-html/directives/repeat";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
@ -18,11 +17,12 @@ import "../components/hui-warning";
import computeStateName from "../../../common/entity/compute_state_name";
import { HomeAssistant } from "../../../types";
import { HomeAssistant, InputSelectEntity } from "../../../types";
import { EntityRow, EntityConfig } from "./types";
import { setOption } from "../../../data/input-select";
import { setInputSelectOption } from "../../../data/input-select";
import { hasConfigOrEntityChanged } from "../common/has-changed";
import { forwardHaptic } from "../../../util/haptics";
import { stopPropagation } from "../../../common/dom/stop_propagation";
@customElement("hui-input-select-entity-row")
class HuiInputSelectEntityRow extends LitElement implements EntityRow {
@ -47,7 +47,9 @@ class HuiInputSelectEntityRow extends LitElement implements EntityRow {
return html``;
}
const stateObj = this.hass.states[this._config.entity];
const stateObj = this.hass.states[this._config.entity] as
| InputSelectEntity
| undefined;
if (!stateObj) {
return html`
@ -64,26 +66,43 @@ class HuiInputSelectEntityRow extends LitElement implements EntityRow {
return html`
<state-badge .stateObj="${stateObj}"></state-badge>
<ha-paper-dropdown-menu
selected-item-label="${stateObj.state}"
@selected-item-label-changed="${this._selectedChanged}"
label="${this._config.name || computeStateName(stateObj)}"
.label=${this._config.name || computeStateName(stateObj)}
.value=${stateObj.state}
@iron-select=${this._selectedChanged}
@click=${stopPropagation}
>
<paper-listbox
slot="dropdown-content"
selected="${stateObj.attributes.options.indexOf(stateObj.state)}"
>
${repeat(
stateObj.attributes.options,
(option) =>
html`
<paper-item>${option}</paper-item>
`
<paper-listbox slot="dropdown-content">
${stateObj.attributes.options.map(
(option) => html`
<paper-item>${option}</paper-item>
`
)}
</paper-listbox>
</ha-paper-dropdown-menu>
`;
}
protected updated(changedProps: PropertyValues) {
super.updated(changedProps);
if (!this.hass || !this._config) {
return;
}
const stateObj = this.hass.states[this._config.entity] as
| InputSelectEntity
| undefined;
if (!stateObj) {
return;
}
// Update selected after rendering the items or else it won't work in Firefox
this.shadowRoot!.querySelector(
"paper-listbox"
)!.selected = stateObj.attributes.options.indexOf(stateObj.state);
}
static get styles(): CSSResult {
return css`
:host {
@ -94,22 +113,28 @@ class HuiInputSelectEntityRow extends LitElement implements EntityRow {
margin-left: 16px;
flex: 1;
}
paper-item {
cursor: pointer;
min-width: 200px;
}
`;
}
private _selectedChanged(ev): void {
forwardHaptic(this, "light");
// Selected Option will transition to '' before transitioning to new value
const stateObj = this.hass!.states[this._config!.entity];
if (
!ev.target.selectedItem ||
ev.target.selectedItem.innerText === "" ||
ev.target.selectedItem.innerText === stateObj.state
) {
const option = ev.detail.item.innerText;
if (option === stateObj.state) {
return;
}
setOption(this.hass!, stateObj.entity_id, ev.target.selectedItem.innerText);
forwardHaptic(this, "light");
setInputSelectOption(
this.hass!,
stateObj.entity_id,
ev.target.selectedItem.innerText
);
}
}

View File

@ -18,6 +18,12 @@ export interface PolymerChangedEvent<T> extends Event {
};
}
export interface PolymerIronSelectEvent<T> extends Event {
detail: {
item: T;
};
}
declare global {
// for fire event
interface HASSDomEvents {

View File

@ -1,96 +0,0 @@
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../components/entity/state-badge";
import computeStateName from "../common/entity/compute_state_name";
class StateCardInputSelect extends PolymerElement {
static get template() {
return html`
<style>
:host {
display: block;
}
state-badge {
float: left;
margin-top: 10px;
}
paper-dropdown-menu {
display: block;
margin-left: 53px;
}
paper-item {
cursor: pointer;
}
</style>
${this.stateBadgeTemplate}
<paper-dropdown-menu
on-click="stopPropagation"
selected-item-label="{{selectedOption}}"
label="[[_computeStateName(stateObj)]]"
>
<paper-listbox
slot="dropdown-content"
selected="[[computeSelected(stateObj)]]"
>
<template is="dom-repeat" items="[[stateObj.attributes.options]]">
<paper-item>[[item]]</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>
`;
}
static get stateBadgeTemplate() {
return html`
<state-badge state-obj="[[stateObj]]"></state-badge>
`;
}
static get properties() {
return {
hass: Object,
stateObj: Object,
inDialog: {
type: Boolean,
value: false,
},
selectedOption: {
type: String,
observer: "selectedOptionChanged",
},
};
}
_computeStateName(stateObj) {
return computeStateName(stateObj);
}
computeSelected(stateObj) {
return stateObj.attributes.options.indexOf(stateObj.state);
}
selectedOptionChanged(option) {
// Selected Option will transition to '' before transitioning to new value
if (option === "" || option === this.stateObj.state) {
return;
}
this.hass.callService("input_select", "select_option", {
option: option,
entity_id: this.stateObj.entity_id,
});
}
stopPropagation(ev) {
ev.stopPropagation();
}
}
customElements.define("state-card-input_select", StateCardInputSelect);

View File

@ -0,0 +1,96 @@
import {
LitElement,
customElement,
TemplateResult,
html,
CSSResult,
css,
property,
PropertyValues,
} from "lit-element";
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
import "@polymer/paper-item/paper-item";
// tslint:disable-next-line: no-duplicate-imports
import { PaperItemElement } from "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import "../components/entity/state-badge";
import computeStateName from "../common/entity/compute_state_name";
import { HomeAssistant, InputSelectEntity } from "../types";
import { setInputSelectOption } from "../data/input-select";
import { PolymerIronSelectEvent } from "../polymer-types";
import { stopPropagation } from "../common/dom/stop_propagation";
@customElement("state-card-input_select")
class StateCardInputSelect extends LitElement {
@property() public hass!: HomeAssistant;
@property() public stateObj!: InputSelectEntity;
protected render(): TemplateResult | void {
return html`
<state-badge .stateObj=${this.stateObj}></state-badge>
<paper-dropdown-menu-light
.label=${computeStateName(this.stateObj)}
.value="${this.stateObj.state}"
@iron-select=${this._selectedOptionChanged}
@click=${stopPropagation}
>
<paper-listbox slot="dropdown-content">
${this.stateObj.attributes.options.map(
(option) => html`
<paper-item>${option}</paper-item>
`
)}
</paper-listbox>
</paper-dropdown-menu-light>
`;
}
protected updated(changedProps: PropertyValues) {
super.updated(changedProps);
// Update selected after rendering the items or else it won't work in Firefox
this.shadowRoot!.querySelector(
"paper-listbox"
)!.selected = this.stateObj.attributes.options.indexOf(this.stateObj.state);
}
private async _selectedOptionChanged(
ev: PolymerIronSelectEvent<PaperItemElement>
) {
const option = ev.detail.item.innerText;
if (option === this.stateObj.state) {
return;
}
await setInputSelectOption(this.hass, this.stateObj.entity_id, option);
}
static get styles(): CSSResult {
return css`
:host {
display: block;
}
state-badge {
float: left;
margin-top: 10px;
}
paper-dropdown-menu-light {
display: block;
margin-left: 53px;
}
paper-item {
cursor: pointer;
min-width: 200px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"state-card-input_select": StateCardInputSelect;
}
}

View File

@ -219,6 +219,12 @@ export type CameraEntity = HassEntityBase & {
};
};
export type InputSelectEntity = HassEntityBase & {
attributes: HassEntityAttributeBase & {
options: string[];
};
};
export interface Route {
prefix: string;
path: string;