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
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
"author": "Paulus Schoutsen <Paulus@PaulusSchoutsen.nl> (http://paulusschoutsen.nl)",
"license": "Apache-2.0",
"dependencies": {
"@material/data-table": "^3.1.1",
"@material/chips": "^3.2.0",
"@material/data-table": "^3.2.0",
"@material/mwc-base": "^0.8.0",
"@material/mwc-button": "^0.8.0",
"@material/mwc-checkbox": "^0.8.0",
"@material/mwc-fab": "^0.8.0",
"@material/mwc-ripple": "0.8.0",
"@material/mwc-ripple": "^0.8.0",
"@material/mwc-switch": "^0.8.0",
"@mdi/svg": "4.4.95",
"@polymer/app-layout": "^3.0.2",
Expand Down
69 changes: 69 additions & 0 deletions src/components/ha-chips.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
css,
CSSResult,
html,
LitElement,
property,
TemplateResult,
customElement,
unsafeCSS,
} from "lit-element";

// @ts-ignore
import chipStyles from "@material/chips/dist/mdc.chips.min.css";
import { fireEvent } from "../common/dom/fire_event";

declare global {
// for fire event
interface HASSDomEvents {
"chip-clicked": { index: string };
}
}

@customElement("ha-chips")
export class HaChips extends LitElement {
@property() public items = [];

protected render(): TemplateResult {
if (this.items.length === 0) {
return html``;
}
return html`
<div class="mdc-chip-set">
${this.items.map(
(item, idx) =>
html`
<button
class="mdc-chip"
.index=${idx}
@click=${this._handleClick}
>
<span class="mdc-chip__text">${item}</span>
</button>
`
)}
</div>
`;
}

private _handleClick(ev) {
fireEvent(
this,
"chip-clicked",
{ index: ev.target.closest("button").index },
{ bubbles: false }
);
}

static get styles(): CSSResult {
return css`
${unsafeCSS(chipStyles)}
`;
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-chips": HaChips;
}
}
17 changes: 17 additions & 0 deletions src/data/automation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
HassEntityAttributeBase,
} from "home-assistant-js-websocket";
import { HomeAssistant } from "../types";
import { navigate } from "../common/navigate";

export interface AutomationEntity extends HassEntityBase {
attributes: HassEntityAttributeBase & {
Expand All @@ -21,3 +22,19 @@ export interface AutomationConfig {

export const deleteAutomation = (hass: HomeAssistant, id: string) =>
hass.callApi("DELETE", `config/automation/config/${id}`);

let inititialAutomationEditorData: Partial<AutomationConfig> | undefined;

export const showAutomationEditor = (
el: HTMLElement,
data?: Partial<AutomationConfig>
) => {
inititialAutomationEditorData = data;
navigate(el, "/config/automation/new");
};

export const getAutomationEditorInitData = () => {
const data = inititialAutomationEditorData;
inititialAutomationEditorData = undefined;
return data;
};
4 changes: 3 additions & 1 deletion src/panels/config/automation/ha-automation-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
AutomationEntity,
AutomationConfig,
deleteAutomation,
getAutomationEditorInitData,
} from "../../../data/automation";
import { navigate } from "../../../common/navigate";
import { computeRTL } from "../../../common/util/compute_rtl";
Expand All @@ -36,7 +37,7 @@ function AutomationEditor(mountEl, props, mergeEl) {
return render(h(Automation, props), mountEl, mergeEl);
}

class HaAutomationEditor extends LitElement {
export class HaAutomationEditor extends LitElement {
public hass!: HomeAssistant;
public automation!: AutomationEntity;
public isWide?: boolean;
Expand Down Expand Up @@ -187,6 +188,7 @@ class HaAutomationEditor extends LitElement {
trigger: [{ platform: "state" }],
condition: [],
action: [{ service: "" }],
...getAutomationEditorInitData(),
};
}

Expand Down
5 changes: 5 additions & 0 deletions src/panels/config/automation/ha-config-automation.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ class HaConfigAutomation extends PolymerElement {
};
}

disconnectedCallback() {
super.disconnectedCallback();
this.route = { path: "", prefix: "" };
}

computeAutomation(automations, edittingAddon, routeData) {
if (!automations || !edittingAddon) {
return null;
Expand Down
26 changes: 26 additions & 0 deletions src/panels/config/devices/device-detail/ha-device-actions-card.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { customElement } from "lit-element";
import {
DeviceAction,
fetchDeviceActions,
localizeDeviceAutomationAction,
} from "../../../../data/device_automation";

import "../../../../components/ha-card";

import { HaDeviceAutomationCard } from "./ha-device-automation-card";

@customElement("ha-device-actions-card")
export class HaDeviceActionsCard extends HaDeviceAutomationCard<DeviceAction> {
protected type = "action";
protected headerKey = "ui.panel.config.devices.automation.actions.caption";

constructor() {
super(localizeDeviceAutomationAction, fetchDeviceActions);
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-device-actions-card": HaDeviceActionsCard;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { LitElement, TemplateResult, html, property } from "lit-element";
import { HomeAssistant } from "../../../../types";
import { DeviceAutomation } from "../../../../data/device_automation";

import "../../../../components/ha-card";
import "../../../../components/ha-chips";
import { showAutomationEditor } from "../../../../data/automation";

export abstract class HaDeviceAutomationCard<
T extends DeviceAutomation
> extends LitElement {
@property() public hass!: HomeAssistant;
@property() public deviceId?: string;

protected headerKey = "";
protected type = "";

@property() private _automations: T[] = [];

private _localizeDeviceAutomation: (
hass: HomeAssistant,
automation: T
) => string;
private _fetchDeviceAutomations: (
hass: HomeAssistant,
deviceId: string
) => Promise<T[]>;

constructor(
localizeDeviceAutomation: HaDeviceAutomationCard<
T
>["_localizeDeviceAutomation"],
fetchDeviceAutomations: HaDeviceAutomationCard<T>["_fetchDeviceAutomations"]
) {
super();
this._localizeDeviceAutomation = localizeDeviceAutomation;
this._fetchDeviceAutomations = fetchDeviceAutomations;
}

protected shouldUpdate(changedProps): boolean {
if (changedProps.has("deviceId") || changedProps.has("_automations")) {
return true;
}
const oldHass = changedProps.get("hass");
if (!oldHass || this.hass.language !== oldHass.language) {
return true;
}
return false;
}

protected async updated(changedProps): Promise<void> {
super.updated(changedProps);

if (changedProps.has("deviceId")) {
this._automations = this.deviceId
? await this._fetchDeviceAutomations(this.hass, this.deviceId)
: [];
}
}

protected render(): TemplateResult {
if (this._automations.length === 0) {
return html``;
}
return html`
<ha-card>
<div class="card-header">
${this.hass.localize(this.headerKey)}
</div>
<div class="card-content">
<ha-chips
@chip-clicked=${this._handleAutomationClicked}
.items=${this._automations.map((automation) =>
this._localizeDeviceAutomation(this.hass, automation)
)}
>
</ha-chips>
</div>
</ha-card>
`;
}

private _handleAutomationClicked(ev: CustomEvent) {
const automation = this._automations[ev.detail.index];
if (!automation) {
return;
}
const data = {};
data[this.type] = [automation];
showAutomationEditor(this, data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ import "@polymer/paper-listbox/paper-listbox";
import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";

import "../../../components/ha-card";
import "../../../layouts/hass-subpage";
import "../../../../components/ha-card";
import "../../../../layouts/hass-subpage";

import { EventsMixin } from "../../../mixins/events-mixin";
import LocalizeMixin from "../../../mixins/localize-mixin";
import { computeStateName } from "../../../common/entity/compute_state_name";
import "../../../components/entity/state-badge";
import { compare } from "../../../common/string/compare";
import { EventsMixin } from "../../../../mixins/events-mixin";
import LocalizeMixin from "../../../../mixins/localize-mixin";
import { computeStateName } from "../../../../common/entity/compute_state_name";
import "../../../../components/entity/state-badge";
import { compare } from "../../../../common/string/compare";
import {
subscribeDeviceRegistry,
updateDeviceRegistryEntry,
} from "../../../data/device_registry";
import { subscribeAreaRegistry } from "../../../data/area_registry";
} from "../../../../data/device_registry";
import { subscribeAreaRegistry } from "../../../../data/area_registry";
import {
loadDeviceRegistryDetailDialog,
showDeviceRegistryDetailDialog,
} from "../../../dialogs/device-registry-detail/show-dialog-device-registry-detail";
} from "../../../../dialogs/device-registry-detail/show-dialog-device-registry-detail";

function computeEntityName(hass, entity) {
if (entity.name) return entity.name;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { customElement } from "lit-element";
import {
DeviceCondition,
fetchDeviceConditions,
localizeDeviceAutomationCondition,
} from "../../../../data/device_automation";

import "../../../../components/ha-card";

import { HaDeviceAutomationCard } from "./ha-device-automation-card";

@customElement("ha-device-conditions-card")
export class HaDeviceConditionsCard extends HaDeviceAutomationCard<
DeviceCondition
> {
protected type = "condition";
protected headerKey = "ui.panel.config.devices.automation.conditions.caption";

constructor() {
super(localizeDeviceAutomationCondition, fetchDeviceConditions);
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-device-conditions-card": HaDeviceConditionsCard;
}
}
26 changes: 26 additions & 0 deletions src/panels/config/devices/device-detail/ha-device-triggers-card.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { customElement } from "lit-element";
import {
DeviceTrigger,
fetchDeviceTriggers,
localizeDeviceAutomationTrigger,
} from "../../../../data/device_automation";

import { HaDeviceAutomationCard } from "./ha-device-automation-card";

@customElement("ha-device-triggers-card")
export class HaDeviceTriggersCard extends HaDeviceAutomationCard<
DeviceTrigger
> {
protected type = "trigger";
protected headerKey = "ui.panel.config.devices.automation.triggers.caption";

constructor() {
super(localizeDeviceAutomationTrigger, fetchDeviceTriggers);
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-device-triggers-card": HaDeviceTriggersCard;
}
}
Loading