Change automation picker to data table (#5344)

* Change automation picker to data-table

* Update ha-automation-picker.ts

* Update ha-automation-picker.ts

* Update ha-automation-picker.ts

* Add edit button + disabled tooltip

* Fix translation key

* Remove unused

* Comments and fixes

* Update ha-automation-picker.ts
This commit is contained in:
Bram Kragten 2020-03-30 14:21:55 +02:00 committed by GitHub
parent 5a2e08647f
commit fca286d6c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 160 additions and 160 deletions

View File

@ -69,7 +69,7 @@ export interface DataTableSortColumnData {
export interface DataTableColumnData extends DataTableSortColumnData { export interface DataTableColumnData extends DataTableSortColumnData {
title: string; title: string;
type?: "numeric" | "icon"; type?: "numeric" | "icon" | "icon-button";
template?: <T>(data: any, row: T) => TemplateResult | string; template?: <T>(data: any, row: T) => TemplateResult | string;
width?: string; width?: string;
maxWidth?: string; maxWidth?: string;
@ -228,10 +228,13 @@ export class HaDataTable extends LitElement {
const sorted = key === this._sortColumn; const sorted = key === this._sortColumn;
const classes = { const classes = {
"mdc-data-table__header-cell--numeric": Boolean( "mdc-data-table__header-cell--numeric": Boolean(
column.type && column.type === "numeric" column.type === "numeric"
), ),
"mdc-data-table__header-cell--icon": Boolean( "mdc-data-table__header-cell--icon": Boolean(
column.type && column.type === "icon" column.type === "icon"
),
"mdc-data-table__header-cell--icon-button": Boolean(
column.type === "icon-button"
), ),
sortable: Boolean(column.sortable), sortable: Boolean(column.sortable),
"not-sorted": Boolean(column.sortable && !sorted), "not-sorted": Boolean(column.sortable && !sorted),
@ -318,10 +321,13 @@ export class HaDataTable extends LitElement {
<div <div
class="mdc-data-table__cell ${classMap({ class="mdc-data-table__cell ${classMap({
"mdc-data-table__cell--numeric": Boolean( "mdc-data-table__cell--numeric": Boolean(
column.type && column.type === "numeric" column.type === "numeric"
), ),
"mdc-data-table__cell--icon": Boolean( "mdc-data-table__cell--icon": Boolean(
column.type && column.type === "icon" column.type === "icon"
),
"mdc-data-table__cell--icon-button": Boolean(
column.type === "icon-button"
), ),
grows: Boolean(column.grows), grows: Boolean(column.grows),
})}" })}"
@ -614,6 +620,16 @@ export class HaDataTable extends LitElement {
margin-right: -8px; margin-right: -8px;
} }
.mdc-data-table__header-cell--icon-button,
.mdc-data-table__cell--icon-button {
width: 40px;
padding: 4px;
}
.mdc-data-table__cell--icon-button a {
color: var(--primary-text-color);
}
.mdc-data-table__header-cell { .mdc-data-table__header-cell {
font-family: Roboto, sans-serif; font-family: Roboto, sans-serif;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;

View File

@ -7,18 +7,13 @@ import {
property, property,
customElement, customElement,
} from "lit-element"; } from "lit-element";
import { ifDefined } from "lit-html/directives/if-defined";
import "@polymer/paper-icon-button/paper-icon-button"; import "@polymer/paper-icon-button/paper-icon-button";
import "@polymer/paper-item/paper-item-body";
import "@polymer/paper-tooltip/paper-tooltip"; import "@polymer/paper-tooltip/paper-tooltip";
import "../../../layouts/hass-tabs-subpage"; import "../../../layouts/hass-tabs-subpage-data-table";
import "../../../components/ha-card";
import "../../../components/ha-fab"; import "../../../components/ha-fab";
import "../../../components/entity/ha-entity-toggle"; import "../../../components/entity/ha-entity-toggle";
import "../ha-config-section";
import { computeStateName } from "../../../common/entity/compute_state_name"; import { computeStateName } from "../../../common/entity/compute_state_name";
import { computeRTL } from "../../../common/util/compute_rtl"; import { computeRTL } from "../../../common/util/compute_rtl";
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
@ -27,12 +22,16 @@ import {
AutomationEntity, AutomationEntity,
showAutomationEditor, showAutomationEditor,
AutomationConfig, AutomationConfig,
triggerAutomation,
} from "../../../data/automation"; } from "../../../data/automation";
import { formatDateTime } from "../../../common/datetime/format_date_time"; import { formatDateTime } from "../../../common/datetime/format_date_time";
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import { showThingtalkDialog } from "./show-dialog-thingtalk"; import { showThingtalkDialog } from "./show-dialog-thingtalk";
import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { configSections } from "../ha-panel-config"; import { configSections } from "../ha-panel-config";
import { DataTableColumnContainer } from "../../../components/data-table/ha-data-table";
import memoizeOne from "memoize-one";
import { ifDefined } from "lit-html/directives/if-defined";
@customElement("ha-automation-picker") @customElement("ha-automation-picker")
class HaAutomationPicker extends LitElement { class HaAutomationPicker extends LitElement {
@ -42,139 +41,152 @@ class HaAutomationPicker extends LitElement {
@property() public route!: Route; @property() public route!: Route;
@property() public automations!: AutomationEntity[]; @property() public automations!: AutomationEntity[];
private _automations = memoizeOne((automations: AutomationEntity[]) => {
return automations.map((automation) => {
return {
...automation,
name: computeStateName(automation),
};
});
});
private _columns = memoizeOne(
(narrow: boolean, _language): DataTableColumnContainer => {
const columns: DataTableColumnContainer = {
toggle: {
title: "",
type: "icon",
template: (_toggle, automation) =>
html`
<ha-entity-toggle
.hass=${this.hass}
.stateObj=${automation}
></ha-entity-toggle>
`,
},
name: {
title: this.hass.localize(
"ui.panel.config.automation.picker.headers.name"
),
sortable: true,
filterable: true,
direction: "asc",
grows: true,
template: (name, automation: any) => html`
${name}
<div class="secondary">
${this.hass.localize("ui.card.automation.last_triggered")}:
${automation.attributes.last_triggered
? formatDateTime(
new Date(automation.attributes.last_triggered),
this.hass.language
)
: this.hass.localize("ui.components.relative_time.never")}
</div>
`,
},
};
if (!narrow) {
columns.execute = {
title: "",
template: (_info, automation) => html`
<mwc-button .automation=${automation} @click=${this._execute}>
${this.hass.localize("ui.card.automation.trigger")}
</mwc-button>
`,
};
}
columns.info = {
title: "",
type: "icon-button",
template: (_info, automation) => html`
<paper-icon-button
.automation=${automation}
@click=${this._showInfo}
icon="hass:information-outline"
title="${this.hass.localize(
"ui.panel.config.automation.picker.show_info_automation"
)}"
></paper-icon-button>
`,
};
columns.edit = {
title: "",
type: "icon-button",
template: (_info, automation: any) => html`
<a
href=${ifDefined(
automation.attributes.id
? `/config/automation/edit/${automation.attributes.id}`
: undefined
)}
>
<paper-icon-button
.icon=${automation.attributes.id
? "hass:pencil"
: "hass:pencil-off"}
.disabled=${!automation.attributes.id}
title="${this.hass.localize(
"ui.panel.config.automation.picker.show_info_automation"
)}"
></paper-icon-button>
</a>
${!automation.attributes.id
? html`
<paper-tooltip position="left">
${this.hass.localize(
"ui.panel.config.automation.picker.only_editable"
)}
</paper-tooltip>
`
: ""}
`,
};
return columns;
}
);
protected render(): TemplateResult { protected render(): TemplateResult {
return html` return html`
<hass-tabs-subpage <hass-tabs-subpage-data-table
.hass=${this.hass} .hass=${this.hass}
.narrow=${this.narrow} .narrow=${this.narrow}
back-path="/config" back-path="/config"
.route=${this.route} .route=${this.route}
.tabs=${configSections.automation} .tabs=${configSections.automation}
.columns=${this._columns(this.narrow, this.hass.language)}
.data=${this._automations(this.automations)}
id="entity_id"
.noDataText=${this.hass.localize(
"ui.panel.config.automation.picker.no_automations"
)}
> >
<ha-config-section .isWide=${this.isWide}> </hass-tabs-subpage-data-table>
<div slot="header"> <ha-fab
${this.hass.localize("ui.panel.config.automation.picker.header")} slot="fab"
</div> ?is-wide=${this.isWide}
<div slot="introduction"> ?narrow=${this.narrow}
${this.hass.localize( icon="hass:plus"
"ui.panel.config.automation.picker.introduction" title=${this.hass.localize(
)} "ui.panel.config.automation.picker.add_automation"
<p> )}
<a ?rtl=${computeRTL(this.hass)}
href="https://home-assistant.io/docs/automation/editor/" @click=${this._createNew}
target="_blank" ></ha-fab>
rel="noreferrer"
>
${this.hass.localize(
"ui.panel.config.automation.picker.learn_more"
)}
</a>
</p>
</div>
<ha-card
.heading=${this.hass.localize(
"ui.panel.config.automation.picker.pick_automation"
)}
>
${this.automations.length === 0
? html`
<div class="card-content">
<p>
${this.hass.localize(
"ui.panel.config.automation.picker.no_automations"
)}
</p>
</div>
`
: this.automations.map(
(automation) => html`
<div class='automation'>
<ha-entity-toggle
.hass=${this.hass}
.stateObj=${automation}
></ha-entity-toggle>
<paper-item-body two-line>
<div>${computeStateName(automation)}</div>
<div secondary>
${this.hass.localize(
"ui.card.automation.last_triggered"
)}: ${
automation.attributes.last_triggered
? formatDateTime(
new Date(automation.attributes.last_triggered),
this.hass.language
)
: this.hass.localize("ui.components.relative_time.never")
}
</div>
</paper-item-body>
<div class='actions'>
<paper-icon-button
.automation=${automation}
@click=${this._showInfo}
icon="hass:information-outline"
title="${this.hass.localize(
"ui.panel.config.automation.picker.show_info_automation"
)}"
></paper-icon-button>
<a
href=${ifDefined(
automation.attributes.id
? `/config/automation/edit/${automation.attributes.id}`
: undefined
)}
>
<paper-icon-button
title="${this.hass.localize(
"ui.panel.config.automation.picker.edit_automation"
)}"
icon="hass:pencil"
.disabled=${!automation.attributes.id}
></paper-icon-button>
${
!automation.attributes.id
? html`
<paper-tooltip position="left">
${this.hass.localize(
"ui.panel.config.automation.picker.only_editable"
)}
</paper-tooltip>
`
: ""
}
</a>
</div>
</div>
</a>
`
)}
</ha-card>
</ha-config-section>
<div>
<ha-fab
slot="fab"
?is-wide=${this.isWide}
?narrow=${this.narrow}
icon="hass:plus"
title=${this.hass.localize(
"ui.panel.config.automation.picker.add_automation"
)}
?rtl=${computeRTL(this.hass)}
@click=${this._createNew}
></ha-fab>
</div>
</hass-tabs-subpage>
`; `;
} }
private _showInfo(ev) { private _showInfo(ev) {
ev.stopPropagation();
const entityId = ev.currentTarget.automation.entity_id; const entityId = ev.currentTarget.automation.entity_id;
fireEvent(this, "hass-more-info", { entityId }); fireEvent(this, "hass-more-info", { entityId });
} }
private _execute(ev) {
const entityId = ev.currentTarget.automation.entity_id;
triggerAutomation(this.hass, entityId);
}
private _createNew() { private _createNew() {
if (!isComponentLoaded(this.hass, "cloud")) { if (!isComponentLoaded(this.hass, "cloud")) {
showAutomationEditor(this); showAutomationEditor(this);
@ -190,33 +202,6 @@ class HaAutomationPicker extends LitElement {
return [ return [
haStyle, haStyle,
css` css`
:host {
display: block;
}
ha-card {
margin-bottom: 56px;
}
.automation {
display: flex;
flex-direction: horizontal;
align-items: center;
padding: 0 8px 0 16px;
}
.automation a[href] {
color: var(--primary-text-color);
}
ha-entity-toggle {
margin-right: 16px;
}
.actions {
display: flex;
}
ha-fab { ha-fab {
position: fixed; position: fixed;
bottom: 16px; bottom: 16px;
@ -242,10 +227,6 @@ class HaAutomationPicker extends LitElement {
right: auto; right: auto;
left: 24px; left: 24px;
} }
a {
color: var(--primary-color);
}
`, `,
]; ];
} }

View File

@ -1002,7 +1002,10 @@
"edit_automation": "Edit automation", "edit_automation": "Edit automation",
"show_info_automation": "Show info about automation", "show_info_automation": "Show info about automation",
"delete_automation": "Delete automation", "delete_automation": "Delete automation",
"delete_confirm": "Are you sure you want to delete this automation?" "delete_confirm": "Are you sure you want to delete this automation?",
"headers": {
"name": "Name"
}
}, },
"editor": { "editor": {
"enable_disable": "Enable/Disable automation", "enable_disable": "Enable/Disable automation",