mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 03:06:41 +00:00
Add empty page to automation/script/scene config (#19075)
This commit is contained in:
parent
3e7fa66790
commit
45b7ebbe46
@ -124,6 +124,12 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
*/
|
*/
|
||||||
@property({ type: String }) public noDataText?: string;
|
@property({ type: String }) public noDataText?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the data table and show an empty message.
|
||||||
|
* @type {Boolean}
|
||||||
|
*/
|
||||||
|
@property({ type: Boolean }) public empty = false;
|
||||||
|
|
||||||
@property() public route!: Route;
|
@property() public route!: Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,56 +204,61 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
.mainPage=${this.mainPage}
|
.mainPage=${this.mainPage}
|
||||||
.supervisor=${this.supervisor}
|
.supervisor=${this.supervisor}
|
||||||
>
|
>
|
||||||
${!this.hideFilterMenu
|
${this.empty
|
||||||
? html`
|
? html`<div class="center">
|
||||||
<div slot="toolbar-icon">
|
<slot name="empty">${this.noDataText}</slot>
|
||||||
${this.narrow
|
</div>`
|
||||||
|
: html`${!this.hideFilterMenu
|
||||||
|
? html`
|
||||||
|
<div slot="toolbar-icon">
|
||||||
|
${this.narrow
|
||||||
|
? html`
|
||||||
|
<div class="filter-menu">
|
||||||
|
${this.numHidden || this.activeFilters
|
||||||
|
? html`<span class="badge"
|
||||||
|
>${this.numHidden || "!"}</span
|
||||||
|
>`
|
||||||
|
: ""}
|
||||||
|
<slot name="filter-menu"></slot>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""}<slot name="toolbar-icon"></slot>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${this.narrow
|
||||||
|
? html`
|
||||||
|
<div slot="header">
|
||||||
|
<slot name="header">
|
||||||
|
<div class="search-toolbar">${headerToolbar}</div>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
<ha-data-table
|
||||||
|
.hass=${this.hass}
|
||||||
|
.columns=${this.columns}
|
||||||
|
.data=${this.data}
|
||||||
|
.noDataText=${this.noDataText}
|
||||||
|
.filter=${this.filter}
|
||||||
|
.selectable=${this.selectable}
|
||||||
|
.hasFab=${this.hasFab}
|
||||||
|
.id=${this.id}
|
||||||
|
.dir=${computeRTLDirection(this.hass)}
|
||||||
|
.clickable=${this.clickable}
|
||||||
|
.appendRow=${this.appendRow}
|
||||||
|
>
|
||||||
|
${!this.narrow
|
||||||
? html`
|
? html`
|
||||||
<div class="filter-menu">
|
<div slot="header">
|
||||||
${this.numHidden || this.activeFilters
|
<slot name="header">
|
||||||
? html`<span class="badge"
|
<div class="table-header">${headerToolbar}</div>
|
||||||
>${this.numHidden || "!"}</span
|
</slot>
|
||||||
>`
|
|
||||||
: ""}
|
|
||||||
<slot name="filter-menu"></slot>
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}<slot name="toolbar-icon"></slot>
|
: html` <div slot="header"></div> `}
|
||||||
</div>
|
</ha-data-table>`}
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this.narrow
|
|
||||||
? html`
|
|
||||||
<div slot="header">
|
|
||||||
<slot name="header">
|
|
||||||
<div class="search-toolbar">${headerToolbar}</div>
|
|
||||||
</slot>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
<ha-data-table
|
|
||||||
.hass=${this.hass}
|
|
||||||
.columns=${this.columns}
|
|
||||||
.data=${this.data}
|
|
||||||
.filter=${this.filter}
|
|
||||||
.selectable=${this.selectable}
|
|
||||||
.hasFab=${this.hasFab}
|
|
||||||
.id=${this.id}
|
|
||||||
.noDataText=${this.noDataText}
|
|
||||||
.dir=${computeRTLDirection(this.hass)}
|
|
||||||
.clickable=${this.clickable}
|
|
||||||
.appendRow=${this.appendRow}
|
|
||||||
>
|
|
||||||
${!this.narrow
|
|
||||||
? html`
|
|
||||||
<div slot="header">
|
|
||||||
<slot name="header">
|
|
||||||
<div class="table-header">${headerToolbar}</div>
|
|
||||||
</slot>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: html` <div slot="header"></div> `}
|
|
||||||
</ha-data-table>
|
|
||||||
<div slot="fab"><slot name="fab"></slot></div>
|
<div slot="fab"><slot name="fab"></slot></div>
|
||||||
</hass-tabs-subpage>
|
</hass-tabs-subpage>
|
||||||
`;
|
`;
|
||||||
@ -374,6 +385,16 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
.filter-menu {
|
.filter-menu {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,19 @@ import {
|
|||||||
mdiPlay,
|
mdiPlay,
|
||||||
mdiPlayCircleOutline,
|
mdiPlayCircleOutline,
|
||||||
mdiPlus,
|
mdiPlus,
|
||||||
|
mdiRobotHappy,
|
||||||
mdiStopCircleOutline,
|
mdiStopCircleOutline,
|
||||||
mdiTransitConnection,
|
mdiTransitConnection,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
||||||
import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import {
|
||||||
|
css,
|
||||||
|
CSSResultGroup,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
nothing,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { differenceInDays } from "date-fns/esm";
|
import { differenceInDays } from "date-fns/esm";
|
||||||
@ -295,6 +303,7 @@ class HaAutomationPicker extends LitElement {
|
|||||||
.activeFilters=${this._activeFilters}
|
.activeFilters=${this._activeFilters}
|
||||||
.columns=${this._columns(this.narrow, this.hass.locale)}
|
.columns=${this._columns(this.narrow, this.hass.locale)}
|
||||||
.data=${this._automations(this.automations, this._filteredAutomations)}
|
.data=${this._automations(this.automations, this._filteredAutomations)}
|
||||||
|
.empty=${!this.automations.length}
|
||||||
@row-click=${this._handleRowClicked}
|
@row-click=${this._handleRowClicked}
|
||||||
.noDataText=${this.hass.localize(
|
.noDataText=${this.hass.localize(
|
||||||
"ui.panel.config.automation.picker.no_automations"
|
"ui.panel.config.automation.picker.no_automations"
|
||||||
@ -318,6 +327,35 @@ class HaAutomationPicker extends LitElement {
|
|||||||
@related-changed=${this._relatedFilterChanged}
|
@related-changed=${this._relatedFilterChanged}
|
||||||
>
|
>
|
||||||
</ha-button-related-filter-menu>
|
</ha-button-related-filter-menu>
|
||||||
|
${!this.automations.length
|
||||||
|
? html` <div class="empty" slot="empty">
|
||||||
|
<ha-svg-icon .path=${mdiRobotHappy}></ha-svg-icon>
|
||||||
|
<h1>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.empty_header"
|
||||||
|
)}
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.empty_text_1"
|
||||||
|
)}<br />
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.empty_text_2"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href=${documentationUrl(this.hass, "/docs/automation/editor/")}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<ha-button>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.learn_more"
|
||||||
|
)}
|
||||||
|
</ha-button>
|
||||||
|
</a>
|
||||||
|
</div>`
|
||||||
|
: nothing}
|
||||||
<ha-fab
|
<ha-fab
|
||||||
slot="fab"
|
slot="fab"
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
@ -505,7 +543,15 @@ class HaAutomationPicker extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return haStyle;
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
.empty {
|
||||||
|
--paper-font-headline_-_font-size: 28px;
|
||||||
|
--mdc-icon-size: 80px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,12 +3,20 @@ import {
|
|||||||
mdiDelete,
|
mdiDelete,
|
||||||
mdiHelpCircle,
|
mdiHelpCircle,
|
||||||
mdiInformationOutline,
|
mdiInformationOutline,
|
||||||
|
mdiPalette,
|
||||||
mdiPencilOff,
|
mdiPencilOff,
|
||||||
mdiPlay,
|
mdiPlay,
|
||||||
mdiPlus,
|
mdiPlus,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import {
|
||||||
|
css,
|
||||||
|
CSSResultGroup,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
nothing,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { differenceInDays } from "date-fns/esm";
|
import { differenceInDays } from "date-fns/esm";
|
||||||
@ -21,6 +29,7 @@ import {
|
|||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/ha-button-related-filter-menu";
|
import "../../../components/ha-button-related-filter-menu";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
|
import "../../../components/ha-button";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-state-icon";
|
import "../../../components/ha-state-icon";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
@ -214,6 +223,7 @@ class HaSceneDashboard extends LitElement {
|
|||||||
.columns=${this._columns(this.hass.locale, this.narrow)}
|
.columns=${this._columns(this.hass.locale, this.narrow)}
|
||||||
id="entity_id"
|
id="entity_id"
|
||||||
.data=${this._scenes(this.scenes, this._filteredScenes)}
|
.data=${this._scenes(this.scenes, this._filteredScenes)}
|
||||||
|
.empty=${!this.scenes.length}
|
||||||
.activeFilters=${this._activeFilters}
|
.activeFilters=${this._activeFilters}
|
||||||
.noDataText=${this.hass.localize(
|
.noDataText=${this.hass.localize(
|
||||||
"ui.panel.config.scene.picker.no_scenes"
|
"ui.panel.config.scene.picker.no_scenes"
|
||||||
@ -238,6 +248,30 @@ class HaSceneDashboard extends LitElement {
|
|||||||
@related-changed=${this._relatedFilterChanged}
|
@related-changed=${this._relatedFilterChanged}
|
||||||
>
|
>
|
||||||
</ha-button-related-filter-menu>
|
</ha-button-related-filter-menu>
|
||||||
|
${!this.scenes.length
|
||||||
|
? html` <div class="empty" slot="empty">
|
||||||
|
<ha-svg-icon .path=${mdiPalette}></ha-svg-icon>
|
||||||
|
<h1>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.picker.empty_header"
|
||||||
|
)}
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
${this.hass.localize("ui.panel.config.scene.picker.empty_text")}
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href=${documentationUrl(this.hass, "/docs/scene/editor/")}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<ha-button>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.scene.picker.learn_more"
|
||||||
|
)}
|
||||||
|
</ha-button>
|
||||||
|
</a>
|
||||||
|
</div>`
|
||||||
|
: nothing}
|
||||||
<a href="/config/scene/edit/new" slot="fab">
|
<a href="/config/scene/edit/new" slot="fab">
|
||||||
<ha-fab
|
<ha-fab
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
@ -350,6 +384,10 @@ class HaSceneDashboard extends LitElement {
|
|||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
.empty {
|
||||||
|
--paper-font-headline_-_font-size: 28px;
|
||||||
|
--mdc-icon-size: 80px;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,18 @@ import {
|
|||||||
mdiInformationOutline,
|
mdiInformationOutline,
|
||||||
mdiPlay,
|
mdiPlay,
|
||||||
mdiPlus,
|
mdiPlus,
|
||||||
|
mdiScriptText,
|
||||||
mdiTransitConnection,
|
mdiTransitConnection,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import { differenceInDays } from "date-fns/esm";
|
import { differenceInDays } from "date-fns/esm";
|
||||||
import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit";
|
import {
|
||||||
|
CSSResultGroup,
|
||||||
|
LitElement,
|
||||||
|
TemplateResult,
|
||||||
|
css,
|
||||||
|
html,
|
||||||
|
nothing,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
@ -241,6 +249,7 @@ class HaScriptPicker extends LitElement {
|
|||||||
.tabs=${configSections.automations}
|
.tabs=${configSections.automations}
|
||||||
.columns=${this._columns(this.narrow, this.hass.locale)}
|
.columns=${this._columns(this.narrow, this.hass.locale)}
|
||||||
.data=${this._scripts(this.scripts, this._filteredScripts)}
|
.data=${this._scripts(this.scripts, this._filteredScripts)}
|
||||||
|
.empty=${!this.scripts.length}
|
||||||
.activeFilters=${this._activeFilters}
|
.activeFilters=${this._activeFilters}
|
||||||
id="entity_id"
|
id="entity_id"
|
||||||
.noDataText=${this.hass.localize(
|
.noDataText=${this.hass.localize(
|
||||||
@ -266,6 +275,32 @@ class HaScriptPicker extends LitElement {
|
|||||||
@related-changed=${this._relatedFilterChanged}
|
@related-changed=${this._relatedFilterChanged}
|
||||||
>
|
>
|
||||||
</ha-button-related-filter-menu>
|
</ha-button-related-filter-menu>
|
||||||
|
${!this.scripts.length
|
||||||
|
? html` <div class="empty" slot="empty">
|
||||||
|
<ha-svg-icon .path=${mdiScriptText}></ha-svg-icon>
|
||||||
|
<h1>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.script.picker.empty_header"
|
||||||
|
)}
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.script.picker.empty_text"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href=${documentationUrl(this.hass, "/docs/script/editor/")}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<ha-button>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.script.picker.learn_more"
|
||||||
|
)}
|
||||||
|
</ha-button>
|
||||||
|
</a>
|
||||||
|
</div>`
|
||||||
|
: nothing}
|
||||||
<ha-fab
|
<ha-fab
|
||||||
slot="fab"
|
slot="fab"
|
||||||
?is-wide=${this.isWide}
|
?is-wide=${this.isWide}
|
||||||
@ -471,6 +506,10 @@ class HaScriptPicker extends LitElement {
|
|||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
.empty {
|
||||||
|
--paper-font-headline_-_font-size: 28px;
|
||||||
|
--mdc-icon-size: 80px;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -2360,7 +2360,10 @@
|
|||||||
"trigger": "Trigger",
|
"trigger": "Trigger",
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"state": "State"
|
"state": "State"
|
||||||
}
|
},
|
||||||
|
"empty_header": "Start automating",
|
||||||
|
"empty_text_1": "The automation editor is an easy way of creating and editing automations.",
|
||||||
|
"empty_text_2": "Even if you're new to home automation."
|
||||||
},
|
},
|
||||||
"dialog_new": {
|
"dialog_new": {
|
||||||
"header": "Create automation",
|
"header": "Create automation",
|
||||||
@ -3059,7 +3062,9 @@
|
|||||||
"state": "State"
|
"state": "State"
|
||||||
},
|
},
|
||||||
"delete": "[%key:ui::common::delete%]",
|
"delete": "[%key:ui::common::delete%]",
|
||||||
"duplicate": "[%key:ui::common::duplicate%]"
|
"duplicate": "[%key:ui::common::duplicate%]",
|
||||||
|
"empty_header": "Create your first script",
|
||||||
|
"empty_text": "Scripts allow you to perform a sequence of actions."
|
||||||
},
|
},
|
||||||
"dialog_new": {
|
"dialog_new": {
|
||||||
"header": "Create script",
|
"header": "Create script",
|
||||||
@ -3159,7 +3164,9 @@
|
|||||||
"state": "State",
|
"state": "State",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"last_activated": "Last activated"
|
"last_activated": "Last activated"
|
||||||
}
|
},
|
||||||
|
"empty_header": "Create your first scene",
|
||||||
|
"empty_text": "Scenes are an easy way to store and replicate the state of devices."
|
||||||
},
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"default_name": "New scene",
|
"default_name": "New scene",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user