UI Editor for picture-entity card (#3708)

* UI Editor for picture-entity card

Closes https://github.com/home-assistant/home-assistant-polymer/issues/3699

* address review comments

* translations
This commit is contained in:
Ian Richardson 2019-09-21 22:15:30 -05:00 committed by GitHub
parent ec52e71c71
commit 37129adfab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 257 additions and 1 deletions

View File

@ -20,7 +20,7 @@ import computeStateName from "../../../common/entity/compute_state_name";
import { longPress } from "../common/directives/long-press-directive";
import { HomeAssistant } from "../../../types";
import { LovelaceCard } from "../types";
import { LovelaceCard, LovelaceCardEditor } from "../types";
import { handleClick } from "../common/handle-click";
import { UNAVAILABLE } from "../../../data/entity";
import { hasConfigOrEntityChanged } from "../common/has-changed";
@ -28,6 +28,18 @@ import { PictureEntityCardConfig } from "./types";
@customElement("hui-picture-entity-card")
class HuiPictureEntityCard extends LitElement implements LovelaceCard {
public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import(/* webpackChunkName: "hui-picture-entity-card-editor" */ "../editor/config-elements/hui-picture-entity-card-editor");
return document.createElement("hui-picture-entity-card-editor");
}
public static getStubConfig(): object {
return {
entity: "",
image:
"https://www.home-assistant.io/images/merchandise/shirt-frontpage.png",
};
}
@property() public hass?: HomeAssistant;
@property() private _config?: PictureEntityCardConfig;

View File

@ -0,0 +1,238 @@
import {
html,
LitElement,
TemplateResult,
customElement,
property,
} from "lit-element";
import "@polymer/paper-input/paper-input";
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-toggle-button/paper-toggle-button";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import { struct } from "../../common/structs/struct";
import {
EntitiesEditorEvent,
EditorTarget,
actionConfigStruct,
} from "../types";
import { HomeAssistant } from "../../../../types";
import { LovelaceCardEditor } from "../../types";
import { fireEvent } from "../../../../common/dom/fire_event";
import { configElementStyle } from "./config-elements-style";
import { ActionConfig } from "../../../../data/lovelace";
import { PictureEntityCardConfig } from "../../cards/types";
const cardConfigStruct = struct({
type: "string",
entity: "string",
image: "string?",
camera_image: "string?",
camera_view: "string?",
aspect_ratio: "string?",
tap_action: struct.optional(actionConfigStruct),
hold_action: struct.optional(actionConfigStruct),
show_name: "boolean?",
show_state: "boolean?",
});
@customElement("hui-picture-entity-card-editor")
export class HuiPictureEntityCardEditor extends LitElement
implements LovelaceCardEditor {
@property() public hass?: HomeAssistant;
@property() private _config?: PictureEntityCardConfig;
public setConfig(config: PictureEntityCardConfig): void {
config = cardConfigStruct(config);
this._config = config;
}
get _entity(): string {
return this._config!.entity || "";
}
get _name(): string {
return this._config!.name || "";
}
get _image(): string {
return this._config!.image || "";
}
get _camera_image(): string {
return this._config!.camera_image || "";
}
get _camera_view(): string {
return this._config!.camera_view || "auto";
}
get _aspect_ratio(): string {
return this._config!.aspect_ratio || "50";
}
get _tap_action(): ActionConfig {
return this._config!.tap_action || { action: "more-info" };
}
get _hold_action(): ActionConfig {
return this._config!.hold_action || { action: "more-info" };
}
get _show_name(): boolean {
return this._config!.show_name || true;
}
get _show_state(): boolean {
return this._config!.show_state || true;
}
protected render(): TemplateResult | void {
if (!this.hass) {
return html``;
}
const actions = ["more-info", "toggle", "navigate", "call-service", "none"];
const views = ["auto", "live"];
return html`
${configElementStyle}
<div class="card-config">
<ha-entity-picker
label="${this.hass.localize(
"ui.panel.lovelace.editor.card.entity_required"
)}"
.hass="${this.hass}"
.value="${this._entity}"
.configValue=${"entity"}
@change="${this._valueChanged}"
allow-custom-entity
></ha-entity-picker>
<paper-input
label="Name (Optional)"
.value="${this._name}"
.configValue="${"name"}"
@value-changed="${this._valueChanged}"
></paper-input>
<paper-input
label="Image Url (Optional)"
.value="${this._image}"
.configValue="${"image"}"
@value-changed="${this._valueChanged}"
></paper-input>
<ha-entity-picker
label="Camera Image (Optional)"
.hass="${this.hass}"
.value="${this._camera_image}"
.configValue=${"camera_image"}
@change="${this._valueChanged}"
domain-filter="camera"
allow-custom-entity
></ha-entity-picker>
<div class="side-by-side">
<paper-dropdown-menu
label="Camera View (Optional)"
.configValue="${"camera_view"}"
@value-changed="${this._valueChanged}"
>
<paper-listbox
slot="dropdown-content"
.selected="${views.indexOf(this._camera_view)}"
>
${views.map((view) => {
return html`
<paper-item>${view}</paper-item>
`;
})}
</paper-listbox>
</paper-dropdown-menu>
<paper-input
label="Aspect Ratio (Optional)"
type="number"
.value="${Number(this._aspect_ratio.replace("%", ""))}"
.configValue="${"aspect_ratio"}"
@value-changed="${this._valueChanged}"
></paper-input>
</div>
<div class="side-by-side">
<paper-toggle-button
?checked="${this._show_name !== false}"
.configValue="${"show_name"}"
@change="${this._valueChanged}"
>Show Name?</paper-toggle-button
>
<paper-toggle-button
?checked="${this._show_state !== false}"
.configValue="${"show_state"}"
@change="${this._valueChanged}"
>Show State?</paper-toggle-button
>
</div>
<div class="side-by-side">
<hui-action-editor
label="Tap Action (Optional)"
.hass="${this.hass}"
.config="${this._tap_action}"
.actions="${actions}"
.configValue="${"tap_action"}"
@action-changed="${this._valueChanged}"
></hui-action-editor>
<hui-action-editor
label="Hold Action (Optional)"
.hass="${this.hass}"
.config="${this._hold_action}"
.actions="${actions}"
.configValue="${"hold_action"}"
@action-changed="${this._valueChanged}"
></hui-action-editor>
</div>
</div>
`;
}
private _valueChanged(ev: EntitiesEditorEvent): void {
if (!this._config || !this.hass) {
return;
}
const target = ev.target! as EditorTarget;
let value = target.value;
if (target.configValue! === "aspect_ratio" && target.value) {
value += "%";
}
if (
this[`_${target.configValue}`] === value ||
this[`_${target.configValue}`] === target.config
) {
return;
}
if (target.configValue) {
if (value === "") {
delete this._config[target.configValue!];
} else {
this._config = {
...this._config,
[target.configValue!]:
target.checked !== undefined
? target.checked
: value
? value
: target.config,
};
}
}
fireEvent(this, "config-changed", { config: this._config });
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-picture-entity-card-editor": HuiPictureEntityCardEditor;
}
}

View File

@ -1113,6 +1113,12 @@
},
"theme": {
"theme": "Theme (Optional)"
},
"card": {
"entity": {
"required": "Entity (Required)",
"optitional": "Entity (Optional)"
}
}
},
"warning": {