mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 01:06:35 +00:00
Add icon to scenes (#6379)
This commit is contained in:
parent
f291ea6647
commit
05d7b98ba0
@ -40,6 +40,7 @@ export interface SceneEntity extends HassEntityBase {
|
|||||||
|
|
||||||
export interface SceneConfig {
|
export interface SceneConfig {
|
||||||
name: string;
|
name: string;
|
||||||
|
icon?: string;
|
||||||
entities: SceneEntities;
|
entities: SceneEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,10 @@ import { haStyle } from "../../../resources/styles";
|
|||||||
import { HomeAssistant, Route } from "../../../types";
|
import { HomeAssistant, Route } from "../../../types";
|
||||||
import { showToast } from "../../../util/toast";
|
import { showToast } from "../../../util/toast";
|
||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
|
import "../../../components/ha-icon";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import { mdiPlus } from "@mdi/js";
|
import { mdiPlus } from "@mdi/js";
|
||||||
|
import { stateIcon } from "../../../common/entity/state_icon";
|
||||||
|
|
||||||
@customElement("ha-scene-dashboard")
|
@customElement("ha-scene-dashboard")
|
||||||
class HaSceneDashboard extends LitElement {
|
class HaSceneDashboard extends LitElement {
|
||||||
@ -44,6 +46,7 @@ class HaSceneDashboard extends LitElement {
|
|||||||
return {
|
return {
|
||||||
...scene,
|
...scene,
|
||||||
name: computeStateName(scene),
|
name: computeStateName(scene),
|
||||||
|
icon: stateIcon(scene),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -66,6 +69,11 @@ class HaSceneDashboard extends LitElement {
|
|||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
icon: {
|
||||||
|
title: "",
|
||||||
|
type: "icon",
|
||||||
|
template: (icon) => html` <ha-icon .icon=${icon}></ha-icon> `,
|
||||||
|
},
|
||||||
name: {
|
name: {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
"ui.panel.config.scene.picker.headers.name"
|
"ui.panel.config.scene.picker.headers.name"
|
||||||
|
@ -23,6 +23,7 @@ import { computeRTL } from "../../../common/util/compute_rtl";
|
|||||||
import "../../../components/device/ha-device-picker";
|
import "../../../components/device/ha-device-picker";
|
||||||
import "../../../components/entity/ha-entities-picker";
|
import "../../../components/entity/ha-entities-picker";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
|
import "../../../components/ha-icon-input";
|
||||||
import "@material/mwc-fab";
|
import "@material/mwc-fab";
|
||||||
import {
|
import {
|
||||||
computeDeviceName,
|
computeDeviceName,
|
||||||
@ -87,7 +88,7 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@property() private _errors?: string;
|
@property() private _errors?: string;
|
||||||
|
|
||||||
@property() private _config!: SceneConfig;
|
@property() private _config?: SceneConfig;
|
||||||
|
|
||||||
@property() private _entities: string[] = [];
|
@property() private _entities: string[] = [];
|
||||||
|
|
||||||
@ -210,115 +211,68 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
|||||||
rtl: computeRTL(this.hass),
|
rtl: computeRTL(this.hass),
|
||||||
})}"
|
})}"
|
||||||
>
|
>
|
||||||
<ha-config-section .isWide=${this.isWide}>
|
${this._config
|
||||||
${!this.narrow ? html` <span slot="header">${name}</span> ` : ""}
|
|
||||||
<div slot="introduction">
|
|
||||||
${this.hass.localize("ui.panel.config.scene.editor.introduction")}
|
|
||||||
</div>
|
|
||||||
<ha-card>
|
|
||||||
<div class="card-content">
|
|
||||||
<paper-input
|
|
||||||
.value=${this._scene ? computeStateName(this._scene) : ""}
|
|
||||||
@value-changed=${this._nameChanged}
|
|
||||||
label=${this.hass.localize(
|
|
||||||
"ui.panel.config.scene.editor.name"
|
|
||||||
)}
|
|
||||||
></paper-input>
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
</ha-config-section>
|
|
||||||
|
|
||||||
<ha-config-section .isWide=${this.isWide}>
|
|
||||||
<div slot="header">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.scene.editor.devices.header"
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div slot="introduction">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.scene.editor.devices.introduction"
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
${devices.map(
|
|
||||||
(device) =>
|
|
||||||
html`
|
|
||||||
<ha-card>
|
|
||||||
<div class="card-header">
|
|
||||||
${device.name}
|
|
||||||
<ha-icon-button
|
|
||||||
icon="hass:delete"
|
|
||||||
title="${this.hass.localize(
|
|
||||||
"ui.panel.config.scene.editor.devices.delete"
|
|
||||||
)}"
|
|
||||||
.device=${device.id}
|
|
||||||
@click=${this._deleteDevice}
|
|
||||||
></ha-icon-button>
|
|
||||||
</div>
|
|
||||||
${device.entities.map((entityId) => {
|
|
||||||
const entityStateObj = this.hass.states[entityId];
|
|
||||||
if (!entityStateObj) {
|
|
||||||
return html``;
|
|
||||||
}
|
|
||||||
return html`
|
|
||||||
<paper-icon-item
|
|
||||||
.entityId=${entityId}
|
|
||||||
@click=${this._showMoreInfo}
|
|
||||||
class="device-entity"
|
|
||||||
>
|
|
||||||
<state-badge
|
|
||||||
.stateObj=${entityStateObj}
|
|
||||||
slot="item-icon"
|
|
||||||
></state-badge>
|
|
||||||
<paper-item-body>
|
|
||||||
${computeStateName(entityStateObj)}
|
|
||||||
</paper-item-body>
|
|
||||||
</paper-icon-item>
|
|
||||||
`;
|
|
||||||
})}
|
|
||||||
</ha-card>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
|
|
||||||
<ha-card
|
|
||||||
.header=${this.hass.localize(
|
|
||||||
"ui.panel.config.scene.editor.devices.add"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div class="card-content">
|
|
||||||
<ha-device-picker
|
|
||||||
@value-changed=${this._devicePicked}
|
|
||||||
.hass=${this.hass}
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.scene.editor.devices.add"
|
|
||||||
)}
|
|
||||||
></ha-device-picker>
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
</ha-config-section>
|
|
||||||
|
|
||||||
${this.showAdvanced
|
|
||||||
? html`
|
? html`
|
||||||
|
<ha-config-section .isWide=${this.isWide}>
|
||||||
|
${!this.narrow
|
||||||
|
? html` <span slot="header">${name}</span> `
|
||||||
|
: ""}
|
||||||
|
<div slot="introduction">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.introduction"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-content">
|
||||||
|
<paper-input
|
||||||
|
.value=${this._config.name}
|
||||||
|
.name=${"name"}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
label=${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.name"
|
||||||
|
)}
|
||||||
|
></paper-input>
|
||||||
|
<ha-icon-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.icon"
|
||||||
|
)}
|
||||||
|
.name=${"icon"}
|
||||||
|
.value=${this._config.icon}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
>
|
||||||
|
</ha-icon-input>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
</ha-config-section>
|
||||||
|
|
||||||
<ha-config-section .isWide=${this.isWide}>
|
<ha-config-section .isWide=${this.isWide}>
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.scene.editor.entities.header"
|
"ui.panel.config.scene.editor.devices.header"
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div slot="introduction">
|
<div slot="introduction">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.scene.editor.entities.introduction"
|
"ui.panel.config.scene.editor.devices.introduction"
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
${entities.length
|
|
||||||
? html`
|
${devices.map(
|
||||||
<ha-card
|
(device) =>
|
||||||
class="entities"
|
html`
|
||||||
.header=${this.hass.localize(
|
<ha-card>
|
||||||
"ui.panel.config.scene.editor.entities.without_device"
|
<div class="card-header">
|
||||||
)}
|
${device.name}
|
||||||
>
|
<ha-icon-button
|
||||||
${entities.map((entityId) => {
|
icon="hass:delete"
|
||||||
|
title="${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.devices.delete"
|
||||||
|
)}"
|
||||||
|
.device=${device.id}
|
||||||
|
@click=${this._deleteDevice}
|
||||||
|
></ha-icon-button>
|
||||||
|
</div>
|
||||||
|
${device.entities.map((entityId) => {
|
||||||
const entityStateObj = this.hass.states[entityId];
|
const entityStateObj = this.hass.states[entityId];
|
||||||
if (!entityStateObj) {
|
if (!entityStateObj) {
|
||||||
return html``;
|
return html``;
|
||||||
@ -336,41 +290,108 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
|||||||
<paper-item-body>
|
<paper-item-body>
|
||||||
${computeStateName(entityStateObj)}
|
${computeStateName(entityStateObj)}
|
||||||
</paper-item-body>
|
</paper-item-body>
|
||||||
<ha-icon-button
|
|
||||||
icon="hass:delete"
|
|
||||||
.entityId=${entityId}
|
|
||||||
.title="${this.hass.localize(
|
|
||||||
"ui.panel.config.scene.editor.entities.delete"
|
|
||||||
)}"
|
|
||||||
@click=${this._deleteEntity}
|
|
||||||
></ha-icon-button>
|
|
||||||
</paper-icon-item>
|
</paper-icon-item>
|
||||||
`;
|
`;
|
||||||
})}
|
})}
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`
|
`
|
||||||
: ""}
|
)}
|
||||||
|
|
||||||
<ha-card
|
<ha-card
|
||||||
header=${this.hass.localize(
|
.header=${this.hass.localize(
|
||||||
"ui.panel.config.scene.editor.entities.add"
|
"ui.panel.config.scene.editor.devices.add"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
${this.hass.localize(
|
<ha-device-picker
|
||||||
"ui.panel.config.scene.editor.entities.device_entities"
|
@value-changed=${this._devicePicked}
|
||||||
)}
|
|
||||||
<ha-entity-picker
|
|
||||||
@value-changed=${this._entityPicked}
|
|
||||||
.excludeDomains=${SCENE_IGNORED_DOMAINS}
|
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.scene.editor.entities.add"
|
"ui.panel.config.scene.editor.devices.add"
|
||||||
)}
|
)}
|
||||||
></ha-entity-picker>
|
></ha-device-picker>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
</ha-config-section>
|
</ha-config-section>
|
||||||
|
|
||||||
|
${this.showAdvanced
|
||||||
|
? html`
|
||||||
|
<ha-config-section .isWide=${this.isWide}>
|
||||||
|
<div slot="header">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.entities.header"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div slot="introduction">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.entities.introduction"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
${entities.length
|
||||||
|
? html`
|
||||||
|
<ha-card
|
||||||
|
class="entities"
|
||||||
|
.header=${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.entities.without_device"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
${entities.map((entityId) => {
|
||||||
|
const entityStateObj = this.hass.states[
|
||||||
|
entityId
|
||||||
|
];
|
||||||
|
if (!entityStateObj) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<paper-icon-item
|
||||||
|
.entityId=${entityId}
|
||||||
|
@click=${this._showMoreInfo}
|
||||||
|
class="device-entity"
|
||||||
|
>
|
||||||
|
<state-badge
|
||||||
|
.stateObj=${entityStateObj}
|
||||||
|
slot="item-icon"
|
||||||
|
></state-badge>
|
||||||
|
<paper-item-body>
|
||||||
|
${computeStateName(entityStateObj)}
|
||||||
|
</paper-item-body>
|
||||||
|
<ha-icon-button
|
||||||
|
icon="hass:delete"
|
||||||
|
.entityId=${entityId}
|
||||||
|
.title="${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.entities.delete"
|
||||||
|
)}"
|
||||||
|
@click=${this._deleteEntity}
|
||||||
|
></ha-icon-button>
|
||||||
|
</paper-icon-item>
|
||||||
|
`;
|
||||||
|
})}
|
||||||
|
</ha-card>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
|
||||||
|
<ha-card
|
||||||
|
header=${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.entities.add"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div class="card-content">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.entities.device_entities"
|
||||||
|
)}
|
||||||
|
<ha-entity-picker
|
||||||
|
@value-changed=${this._entityPicked}
|
||||||
|
.excludeDomains=${SCENE_IGNORED_DOMAINS}
|
||||||
|
.hass=${this.hass}
|
||||||
|
label=${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.editor.entities.add"
|
||||||
|
)}
|
||||||
|
></ha-entity-picker>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
</ha-config-section>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
@ -587,11 +608,21 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
|||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _nameChanged(ev: CustomEvent) {
|
private _valueChanged(ev: CustomEvent) {
|
||||||
if (!this._config || this._config.name === ev.detail.value) {
|
ev.stopPropagation();
|
||||||
|
const target = ev.target as any;
|
||||||
|
const name = target.name;
|
||||||
|
if (!name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._config.name = ev.detail.value;
|
let newVal = ev.detail.value;
|
||||||
|
if (target.type === "number") {
|
||||||
|
newVal = Number(newVal);
|
||||||
|
}
|
||||||
|
if ((this._config![name] || "") === newVal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._config = { ...this._config!, [name]: newVal };
|
||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,7 +702,7 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
private async _saveScene(): Promise<void> {
|
private async _saveScene(): Promise<void> {
|
||||||
const id = !this.sceneId ? "" + Date.now() : this.sceneId!;
|
const id = !this.sceneId ? "" + Date.now() : this.sceneId!;
|
||||||
this._config = { ...this._config, entities: this._calculateStates() };
|
this._config = { ...this._config!, entities: this._calculateStates() };
|
||||||
try {
|
try {
|
||||||
await saveScene(this.hass, id, this._config);
|
await saveScene(this.hass, id, this._config);
|
||||||
this._dirty = false;
|
this._dirty = false;
|
||||||
|
@ -1130,6 +1130,7 @@
|
|||||||
"save": "Save",
|
"save": "Save",
|
||||||
"unsaved_confirm": "You have unsaved changes. Are you sure you want to leave?",
|
"unsaved_confirm": "You have unsaved changes. Are you sure you want to leave?",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
"icon": "Icon",
|
||||||
"devices": {
|
"devices": {
|
||||||
"header": "Devices",
|
"header": "Devices",
|
||||||
"introduction": "Add the devices that you want to be included in your scene. Set all the devices to the state you want for this scene.",
|
"introduction": "Add the devices that you want to be included in your scene. Set all the devices to the state you want for this scene.",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user