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
20 changes: 16 additions & 4 deletions src/components/ha-yaml-editor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { safeDump, safeLoad } from "js-yaml";
import "./ha-code-editor";
import { LitElement, property, customElement, html } from "lit-element";
import { LitElement, property, customElement, html, query } from "lit-element";
import { fireEvent } from "../common/dom/fire_event";
import { afterNextRender } from "../common/util/render-status";
// tslint:disable-next-line
import { HaCodeEditor } from "./ha-code-editor";

const isEmpty = (obj: object) => {
for (const key in obj) {
Expand All @@ -18,14 +21,23 @@ export class HaYamlEditor extends LitElement {
@property() public isValid = true;
@property() public label?: string;
@property() private _yaml?: string;
@query("ha-code-editor") private _editor?: HaCodeEditor;

protected firstUpdated() {
public setValue(value) {
try {
this._yaml =
this.value && !isEmpty(this.value) ? safeDump(this.value) : "";
this._yaml = value && !isEmpty(value) ? safeDump(value) : "";
} catch (err) {
alert(`There was an error converting to YAML: ${err}`);
}
afterNextRender(() => {
if (this._editor?.codemirror) {
this._editor.codemirror.refresh();
}
});
}

protected firstUpdated() {
this.setValue(this.value);
}

protected render() {
Expand Down
100 changes: 59 additions & 41 deletions src/panels/config/devices/device-detail/ha-device-entities-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { domainIcon } from "../../../../common/entity/domain_icon";
// tslint:disable-next-line
import { HaSwitch } from "../../../../components/ha-switch";
import { EntityRegistryStateEntry } from "../ha-config-device-page";
import { addEntitiesToLovelaceView } from "../../../lovelace/editor/add-entities-to-view";

@customElement("ha-device-entities-card")
export class HaDeviceEntitiesCard extends LitElement {
Expand All @@ -49,51 +50,60 @@ export class HaDeviceEntitiesCard extends LitElement {
</ha-switch>
</paper-item>
${this.entities.length
? this.entities.map((entry: EntityRegistryStateEntry) => {
if (!this._showDisabled && entry.disabled_by) {
return "";
}
const stateObj = this.hass.states[entry.entity_id];
return html`
<paper-icon-item
.entry=${entry}
class=${classMap({ "disabled-entry": !!entry.disabled_by })}
>
${stateObj
? html`
<state-badge
@click=${this._openMoreInfo}
.stateObj=${stateObj}
slot="item-icon"
></state-badge>
`
: html`
<ha-icon
slot="item-icon"
.icon=${domainIcon(computeDomain(entry.entity_id))}
></ha-icon>
`}
<paper-item-body two-line @click=${this._openMoreInfo}>
<div class="name">${entry.stateName}</div>
<div class="secondary entity-id">${entry.entity_id}</div>
</paper-item-body>
<div class="buttons">
? html`
${this.entities.map((entry: EntityRegistryStateEntry) => {
if (!this._showDisabled && entry.disabled_by) {
return "";
}
const stateObj = this.hass.states[entry.entity_id];
return html`
<paper-icon-item
.entry=${entry}
class=${classMap({ "disabled-entry": !!entry.disabled_by })}
>
${stateObj
? html`
<paper-icon-button
<state-badge
@click=${this._openMoreInfo}
icon="hass:information-outline"
></paper-icon-button>
.stateObj=${stateObj}
slot="item-icon"
></state-badge>
`
: ""}
<paper-icon-button
@click=${this._openEditEntry}
icon="hass:settings"
></paper-icon-button>
</div>
</paper-icon-item>
`;
})
: html`
<ha-icon
slot="item-icon"
.icon=${domainIcon(computeDomain(entry.entity_id))}
></ha-icon>
`}
<paper-item-body two-line @click=${this._openMoreInfo}>
<div class="name">${entry.stateName}</div>
<div class="secondary entity-id">${entry.entity_id}</div>
</paper-item-body>
<div class="buttons">
${stateObj
? html`
<paper-icon-button
@click=${this._openMoreInfo}
icon="hass:information-outline"
></paper-icon-button>
`
: ""}
<paper-icon-button
@click=${this._openEditEntry}
icon="hass:settings"
></paper-icon-button>
</div>
</paper-icon-item>
`;
})}
<div class="card-actions">
<mwc-button @click=${this._addToLovelaceView}>
${this.hass.localize(
"ui.panel.config.devices.entities.add_entities_lovelace"
)}
</mwc-button>
</div>
`
: html`
<div class="config-entry-row">
<paper-item-body two-line>
Expand Down Expand Up @@ -125,6 +135,14 @@ export class HaDeviceEntitiesCard extends LitElement {
fireEvent(this, "hass-more-info", { entityId: entry.entity_id });
}

private _addToLovelaceView(): void {
addEntitiesToLovelaceView(
this,
this.hass,
this.entities.map((entity) => entity.entity_id)
);
}

static get styles(): CSSResult {
return css`
ha-icon {
Expand Down
4 changes: 3 additions & 1 deletion src/panels/config/devices/ha-config-device-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ export class HaConfigDevicePage extends LitElement {
${entities.length
? html`
<div class="header">
${this.hass.localize("ui.panel.config.devices.entities")}
${this.hass.localize(
"ui.panel.config.devices.entities.entities"
)}
</div>
<ha-device-entities-card
.hass=${this.hass}
Expand Down
9 changes: 7 additions & 2 deletions src/panels/lovelace/common/generate-lovelace-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ const splitByAreas = (
};
};

const computeCards = (
states: Array<[string, HassEntity]>,
export const computeCards = (
states: Array<[string, HassEntity?]>,
entityCardOptions: Partial<EntitiesCardConfig>
): LovelaceCardConfig[] => {
const cards: LovelaceCardConfig[] = [];
Expand Down Expand Up @@ -132,6 +132,11 @@ const computeCards = (
title: stateObj.attributes.friendly_name,
refresh_interval: stateObj.attributes.refresh,
});
} else if (domain === "light") {
cards.push({
type: "light",
entity: entityId,
});
} else if (domain === "media_player") {
cards.push({
type: "media-control",
Expand Down
3 changes: 2 additions & 1 deletion src/panels/lovelace/components/hui-card-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ export class HuiCardOptions extends LitElement {

private _editCard(): void {
showEditCardDialog(this, {
lovelace: this.lovelace!,
lovelaceConfig: this.lovelace!.config,
saveConfig: this.lovelace!.saveConfig,
path: this.path!,
});
}
Expand Down
60 changes: 60 additions & 0 deletions src/panels/lovelace/editor/add-entities-to-view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { HomeAssistant } from "../../../types";
import {
LovelaceConfig,
fetchConfig,
saveConfig,
} from "../../../data/lovelace";
import { showSelectViewDialog } from "./select-view/show-select-view-dialog";
import { showSuggestCardDialog } from "./card-editor/show-suggest-card-dialog";

export const addEntitiesToLovelaceView = async (
element: HTMLElement,
hass: HomeAssistant,
entities: string[],
lovelaceConfig?: LovelaceConfig,
saveConfigFunc?: (newConfig: LovelaceConfig) => void
) => {
if ((hass!.panels.lovelace?.config as any)?.mode === "yaml") {
showSuggestCardDialog(element, {
entities,
});
return;
}
if (!lovelaceConfig) {
try {
lovelaceConfig = await fetchConfig(hass.connection, false);
} catch {
alert(
hass.localize(
"ui.panel.lovelace.editor.add_entities.generated_unsupported"
)
);
return;
}
}
showSelectViewDialog(element, {
lovelaceConfig,
viewSelectedCallback: (view) => {
if (!saveConfigFunc) {
saveConfigFunc = async (newConfig: LovelaceConfig): Promise<void> => {
try {
await saveConfig(hass!, newConfig);
} catch {
alert(
hass.localize(
"ui.panel.config.devices.add_entities.saving_failed"
)
);
}
};
}

showSuggestCardDialog(element, {
lovelaceConfig: lovelaceConfig!,
saveConfig: saveConfigFunc,
path: [view],
entities,
});
},
});
};
13 changes: 7 additions & 6 deletions src/panels/lovelace/editor/card-editor/hui-dialog-edit-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { addCard, replaceCard } from "../config-util";

import "../../../../components/dialog/ha-paper-dialog";
import { haStyleDialog } from "../../../../resources/styles";
import { showSaveSuccessToast } from "../../../../util/toast-saved-success";

declare global {
// for fire event
Expand All @@ -38,7 +39,7 @@ declare global {

@customElement("hui-dialog-edit-card")
export class HuiDialogEditCard extends LitElement {
@property() protected hass?: HomeAssistant;
@property() protected hass!: HomeAssistant;

@property() private _params?: EditCardDialogParams;

Expand All @@ -51,7 +52,7 @@ export class HuiDialogEditCard extends LitElement {
public async showDialog(params: EditCardDialogParams): Promise<void> {
this._params = params;
const [view, card] = params.path;
this._viewConfig = params.lovelace.config.views[view];
this._viewConfig = params.lovelaceConfig.views[view];
this._cardConfig =
card !== undefined ? this._viewConfig.cards![card] : undefined;
}
Expand Down Expand Up @@ -283,22 +284,22 @@ export class HuiDialogEditCard extends LitElement {
}

private async _save(): Promise<void> {
const lovelace = this._params!.lovelace;
this._saving = true;
await lovelace.saveConfig(
await this._params!.saveConfig(
this._params!.path.length === 1
? addCard(
lovelace.config,
this._params!.lovelaceConfig,
this._params!.path as [number],
this._cardConfig!
)
: replaceCard(
lovelace.config,
this._params!.lovelaceConfig,
this._params!.path as [number, number],
this._cardConfig!
)
);
this._saving = false;
showSaveSuccessToast(this, this.hass);
this._close();
}
}
Expand Down
Loading