mirror of
https://github.com/home-assistant/frontend.git
synced 2025-05-02 01:07:20 +00:00
Generalize filtering in datatable sub page (#8734)
This commit is contained in:
parent
1865e0661f
commit
0393970a80
@ -1,4 +1,5 @@
|
|||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
|
import { mdiFilterVariant } from "@mdi/js";
|
||||||
import "@polymer/paper-tooltip/paper-tooltip";
|
import "@polymer/paper-tooltip/paper-tooltip";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
@ -10,7 +11,7 @@ import {
|
|||||||
query,
|
query,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { navigate } from "../common/navigate";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { computeRTLDirection } from "../common/util/compute_rtl";
|
import { computeRTLDirection } from "../common/util/compute_rtl";
|
||||||
import "../components/data-table/ha-data-table";
|
import "../components/data-table/ha-data-table";
|
||||||
import type {
|
import type {
|
||||||
@ -22,6 +23,14 @@ import type { HomeAssistant, Route } from "../types";
|
|||||||
import "./hass-tabs-subpage";
|
import "./hass-tabs-subpage";
|
||||||
import type { PageNavigation } from "./hass-tabs-subpage";
|
import type { PageNavigation } from "./hass-tabs-subpage";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
// for fire event
|
||||||
|
interface HASSDomEvents {
|
||||||
|
"search-changed": { value: string };
|
||||||
|
"clear-filter": undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@customElement("hass-tabs-subpage-data-table")
|
@customElement("hass-tabs-subpage-data-table")
|
||||||
export class HaTabsSubpageDataTable extends LitElement {
|
export class HaTabsSubpageDataTable extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@ -64,7 +73,7 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
* Add an extra row at the bottom of the data table
|
* Add an extra row at the bottom of the data table
|
||||||
* @type {TemplateResult}
|
* @type {TemplateResult}
|
||||||
*/
|
*/
|
||||||
@property({ attribute: false }) public appendRow?;
|
@property({ attribute: false }) public appendRow?: TemplateResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Field with a unique id per entry in data.
|
* Field with a unique id per entry in data.
|
||||||
@ -78,12 +87,26 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
*/
|
*/
|
||||||
@property({ type: String }) public filter = "";
|
@property({ type: String }) public filter = "";
|
||||||
|
|
||||||
|
@property() public searchLabel?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of strings that show what the data is currently filtered by.
|
* List of strings that show what the data is currently filtered by.
|
||||||
* @type {Array}
|
* @type {Array}
|
||||||
*/
|
*/
|
||||||
@property({ type: Array }) public activeFilters?;
|
@property({ type: Array }) public activeFilters?;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Text to how how many items are hidden.
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
@property() public hiddenLabel?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many items are hidden because of active filters.
|
||||||
|
* @type {Number}
|
||||||
|
*/
|
||||||
|
@property({ type: Number }) public numHidden = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What path to use when the back button is pressed.
|
* What path to use when the back button is pressed.
|
||||||
* @type {String}
|
* @type {String}
|
||||||
@ -118,6 +141,47 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
const hiddenLabel = this.numHidden
|
||||||
|
? this.hiddenLabel ||
|
||||||
|
this.hass.localize(
|
||||||
|
"ui.components.data-table.hidden",
|
||||||
|
"number",
|
||||||
|
this.numHidden
|
||||||
|
) ||
|
||||||
|
this.numHidden
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const filterInfo = this.activeFilters
|
||||||
|
? html`${this.hass.localize("ui.components.data-table.filtering_by")}
|
||||||
|
${this.activeFilters.join(", ")}
|
||||||
|
${hiddenLabel ? `(${hiddenLabel})` : ""}`
|
||||||
|
: hiddenLabel;
|
||||||
|
|
||||||
|
const headerToolbar = html`<search-input
|
||||||
|
.filter=${this.filter}
|
||||||
|
no-label-float
|
||||||
|
no-underline
|
||||||
|
@value-changed=${this._handleSearchChange}
|
||||||
|
.label=${this.searchLabel ||
|
||||||
|
this.hass.localize("ui.components.data-table.search")}
|
||||||
|
>
|
||||||
|
</search-input
|
||||||
|
>${filterInfo
|
||||||
|
? html`<div class="active-filters">
|
||||||
|
${this.narrow
|
||||||
|
? html`<div>
|
||||||
|
<ha-svg-icon .path="${mdiFilterVariant}"></ha-svg-icon>
|
||||||
|
<paper-tooltip animation-delay="0" position="left">
|
||||||
|
${filterInfo}
|
||||||
|
</paper-tooltip>
|
||||||
|
</div>`
|
||||||
|
: filterInfo}
|
||||||
|
<mwc-button @click=${this._clearFilter}>
|
||||||
|
${this.hass.localize("ui.components.data-table.clear")}
|
||||||
|
</mwc-button>
|
||||||
|
</div>`
|
||||||
|
: ""}<slot name="filter-menu"></slot>`;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage
|
<hass-tabs-subpage
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -134,34 +198,7 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
<div slot="header">
|
<div slot="header">
|
||||||
<slot name="header">
|
<slot name="header">
|
||||||
<div class="search-toolbar">
|
<div class="search-toolbar">
|
||||||
<search-input
|
${headerToolbar}
|
||||||
.filter=${this.filter}
|
|
||||||
class="header"
|
|
||||||
no-label-float
|
|
||||||
no-underline
|
|
||||||
@value-changed=${this._handleSearchChange}
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.components.data-table.search"
|
|
||||||
)}
|
|
||||||
></search-input>
|
|
||||||
${this.activeFilters
|
|
||||||
? html`<div class="active-filters">
|
|
||||||
<div>
|
|
||||||
<ha-icon icon="hass:filter-variant"></ha-icon>
|
|
||||||
<paper-tooltip animation-delay="0" position="left">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.filtering_by"
|
|
||||||
)}
|
|
||||||
${this.activeFilters.join(", ")}
|
|
||||||
</paper-tooltip>
|
|
||||||
</div>
|
|
||||||
<mwc-button @click=${this._clearFilter}
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.clear"
|
|
||||||
)}</mwc-button
|
|
||||||
>
|
|
||||||
</div>`
|
|
||||||
: ""}
|
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
@ -184,29 +221,7 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
<div slot="header">
|
<div slot="header">
|
||||||
<slot name="header">
|
<slot name="header">
|
||||||
<div class="table-header">
|
<div class="table-header">
|
||||||
<search-input
|
${headerToolbar}
|
||||||
.filter=${this.filter}
|
|
||||||
no-label-float
|
|
||||||
no-underline
|
|
||||||
@value-changed=${this._handleSearchChange}
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.components.data-table.search"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
</search-input>
|
|
||||||
${this.activeFilters
|
|
||||||
? html`<div class="active-filters">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.filtering_by"
|
|
||||||
)}
|
|
||||||
${this.activeFilters.join(", ")}
|
|
||||||
<mwc-button @click=${this._clearFilter}
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.clear"
|
|
||||||
)}</mwc-button
|
|
||||||
>
|
|
||||||
</div>`
|
|
||||||
: ""}
|
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
@ -220,10 +235,11 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
|
|
||||||
private _handleSearchChange(ev: CustomEvent) {
|
private _handleSearchChange(ev: CustomEvent) {
|
||||||
this.filter = ev.detail.value;
|
this.filter = ev.detail.value;
|
||||||
|
fireEvent(this, "search-changed", { value: this.filter });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _clearFilter() {
|
private _clearFilter() {
|
||||||
navigate(this, window.location.pathname);
|
fireEvent(this, "clear-filter");
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
@ -247,7 +263,6 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
padding: 0 16px;
|
|
||||||
}
|
}
|
||||||
search-input {
|
search-input {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -283,10 +298,6 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
left: 0;
|
left: 0;
|
||||||
content: "";
|
content: "";
|
||||||
}
|
}
|
||||||
.search-toolbar .active-filters {
|
|
||||||
top: -8px;
|
|
||||||
right: -16px;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ class HassTabsSubpage extends LitElement {
|
|||||||
></ha-icon-button-arrow-prev>
|
></ha-icon-button-arrow-prev>
|
||||||
`}
|
`}
|
||||||
${this.narrow
|
${this.narrow
|
||||||
? html` <div class="main-title"><slot name="header"></slot></div> `
|
? html`<div class="main-title"><slot name="header"></slot></div>`
|
||||||
: ""}
|
: ""}
|
||||||
${showTabs
|
${showTabs
|
||||||
? html`
|
? html`
|
||||||
@ -270,9 +270,7 @@ class HassTabsSubpage extends LitElement {
|
|||||||
|
|
||||||
.main-title {
|
.main-title {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
max-height: var(--header-height);
|
||||||
text-overflow: ellipsis;
|
|
||||||
max-height: 58px;
|
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import {
|
|||||||
property,
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||||
@ -357,83 +356,46 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
this.hass.localize
|
this.hass.localize
|
||||||
);
|
);
|
||||||
|
|
||||||
const headerToolbar = html`
|
return html`
|
||||||
<search-input
|
<hass-tabs-subpage-data-table
|
||||||
no-label-float
|
.hass=${this.hass}
|
||||||
no-underline
|
.narrow=${this.narrow}
|
||||||
@value-changed=${this._handleSearchChange}
|
.backPath=${this._searchParms.has("historyBack")
|
||||||
|
? undefined
|
||||||
|
: "/config"}
|
||||||
|
.tabs=${configSections.integrations}
|
||||||
|
.route=${this.route}
|
||||||
|
.activeFilters=${activeFilters}
|
||||||
|
.numHidden=${this._numHiddenDevices}
|
||||||
|
.searchLabel=${this.hass.localize(
|
||||||
|
"ui.panel.config.devices.picker.search"
|
||||||
|
)}
|
||||||
|
.hiddenLabel=${this.hass.localize(
|
||||||
|
"ui.panel.config.devices.picker.filter.hidden_devices",
|
||||||
|
"number",
|
||||||
|
this._numHiddenDevices
|
||||||
|
)}
|
||||||
|
.columns=${this._columns(this.narrow, this._showDisabled)}
|
||||||
|
.data=${devicesOutput}
|
||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
.label=${this.hass.localize("ui.panel.config.devices.picker.search")}
|
@clear-filter=${this._clearFilter}
|
||||||
></search-input
|
@search-changed=${this._handleSearchChange}
|
||||||
>${activeFilters
|
@row-click=${this._handleRowClicked}
|
||||||
? html`<div class="active-filters">
|
clickable
|
||||||
${this.narrow
|
.hasFab=${includeZHAFab}
|
||||||
? html` <div>
|
|
||||||
<ha-icon icon="hass:filter-variant"></ha-icon>
|
|
||||||
<paper-tooltip animation-delay="0" position="left">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.filtering_by"
|
|
||||||
)}
|
|
||||||
${activeFilters.join(", ")}
|
|
||||||
${this._numHiddenDevices
|
|
||||||
? "(" +
|
|
||||||
this.hass.localize(
|
|
||||||
"ui.panel.config.devices.picker.filter.hidden_devices",
|
|
||||||
"number",
|
|
||||||
this._numHiddenDevices
|
|
||||||
) +
|
|
||||||
")"
|
|
||||||
: ""}
|
|
||||||
</paper-tooltip>
|
|
||||||
</div>`
|
|
||||||
: `${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.filtering_by"
|
|
||||||
)} ${activeFilters.join(", ")}
|
|
||||||
${
|
|
||||||
this._numHiddenDevices
|
|
||||||
? "(" +
|
|
||||||
this.hass.localize(
|
|
||||||
"ui.panel.config.devices.picker.filter.hidden_devices",
|
|
||||||
"number",
|
|
||||||
this._numHiddenDevices
|
|
||||||
) +
|
|
||||||
")"
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
<mwc-button @click=${this._clearFilter}
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.clear"
|
|
||||||
)}</mwc-button
|
|
||||||
>
|
>
|
||||||
</div>`
|
${includeZHAFab
|
||||||
: ""}
|
? html`<a href="/config/zha/add" slot="fab">
|
||||||
${this._numHiddenDevices && !activeFilters
|
<ha-fab
|
||||||
? html`<div class="active-filters">
|
.label=${this.hass.localize("ui.panel.config.zha.add_device")}
|
||||||
${this.narrow
|
extended
|
||||||
? html` <div>
|
?rtl=${computeRTL(this.hass)}
|
||||||
<ha-icon icon="hass:filter-variant"></ha-icon>
|
|
||||||
<paper-tooltip animation-delay="0" position="left">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.devices.picker.filter.hidden_devices",
|
|
||||||
"number",
|
|
||||||
this._numHiddenDevices
|
|
||||||
)}
|
|
||||||
</paper-tooltip>
|
|
||||||
</div>`
|
|
||||||
: `${this.hass.localize(
|
|
||||||
"ui.panel.config.devices.picker.filter.hidden_devices",
|
|
||||||
"number",
|
|
||||||
this._numHiddenDevices
|
|
||||||
)}`}
|
|
||||||
<mwc-button @click=${this._showAll}
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.config.devices.picker.filter.show_all"
|
|
||||||
)}</mwc-button
|
|
||||||
>
|
>
|
||||||
</div>`
|
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
||||||
: ""}
|
</ha-fab>
|
||||||
<ha-button-menu corner="BOTTOM_START" multi>
|
</a>`
|
||||||
|
: html``}
|
||||||
|
<ha-button-menu slot="filter-menu" corner="BOTTOM_START" multi>
|
||||||
<mwc-icon-button
|
<mwc-icon-button
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
.label=${this.hass!.localize(
|
.label=${this.hass!.localize(
|
||||||
@ -459,44 +421,6 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
</ha-button-menu>
|
</ha-button-menu>
|
||||||
`;
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<hass-tabs-subpage-data-table
|
|
||||||
.hass=${this.hass}
|
|
||||||
.narrow=${this.narrow}
|
|
||||||
.backPath=${this._searchParms.has("historyBack")
|
|
||||||
? undefined
|
|
||||||
: "/config"}
|
|
||||||
.tabs=${configSections.integrations}
|
|
||||||
.route=${this.route}
|
|
||||||
.columns=${this._columns(this.narrow, this._showDisabled)}
|
|
||||||
.data=${devicesOutput}
|
|
||||||
.filter=${this._filter}
|
|
||||||
@row-click=${this._handleRowClicked}
|
|
||||||
clickable
|
|
||||||
.hasFab=${includeZHAFab}
|
|
||||||
>
|
|
||||||
${includeZHAFab
|
|
||||||
? html`<a href="/config/zha/add" slot="fab">
|
|
||||||
<ha-fab
|
|
||||||
.label=${this.hass.localize("ui.panel.config.zha.add_device")}
|
|
||||||
extended
|
|
||||||
?rtl=${computeRTL(this.hass)}
|
|
||||||
>
|
|
||||||
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
|
||||||
</ha-fab>
|
|
||||||
</a>`
|
|
||||||
: html``}
|
|
||||||
<div
|
|
||||||
class=${classMap({
|
|
||||||
"search-toolbar": this.narrow,
|
|
||||||
"table-header": !this.narrow,
|
|
||||||
})}
|
|
||||||
slot="header"
|
|
||||||
>
|
|
||||||
${headerToolbar}
|
|
||||||
</div>
|
|
||||||
</hass-tabs-subpage-data-table>
|
</hass-tabs-subpage-data-table>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -540,121 +464,22 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _clearFilter() {
|
private _clearFilter() {
|
||||||
|
if (
|
||||||
|
this._activeFilters(this.entries, this._searchParms, this.hass.localize)
|
||||||
|
) {
|
||||||
navigate(this, window.location.pathname, true);
|
navigate(this, window.location.pathname, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showAll() {
|
|
||||||
this._showDisabled = true;
|
this._showDisabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
|
||||||
css`
|
css`
|
||||||
hass-loading-screen {
|
|
||||||
--app-header-background-color: var(--sidebar-background-color);
|
|
||||||
--app-header-text-color: var(--sidebar-text-color);
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
margin-top: 0;
|
|
||||||
font-family: var(--paper-font-headline_-_font-family);
|
|
||||||
-webkit-font-smoothing: var(
|
|
||||||
--paper-font-headline_-_-webkit-font-smoothing
|
|
||||||
);
|
|
||||||
font-size: var(--paper-font-headline_-_font-size);
|
|
||||||
font-weight: var(--paper-font-headline_-_font-weight);
|
|
||||||
letter-spacing: var(--paper-font-headline_-_letter-spacing);
|
|
||||||
line-height: var(--paper-font-headline_-_line-height);
|
|
||||||
opacity: var(--dark-primary-opacity);
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
font-family: var(--paper-font-subhead_-_font-family);
|
|
||||||
-webkit-font-smoothing: var(
|
|
||||||
--paper-font-subhead_-_-webkit-font-smoothing
|
|
||||||
);
|
|
||||||
font-weight: var(--paper-font-subhead_-_font-weight);
|
|
||||||
line-height: var(--paper-font-subhead_-_line-height);
|
|
||||||
}
|
|
||||||
ha-data-table {
|
|
||||||
width: 100%;
|
|
||||||
--data-table-border-width: 0;
|
|
||||||
}
|
|
||||||
:host(:not([narrow])) ha-data-table {
|
|
||||||
height: calc(100vh - 1px - var(--header-height));
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
ha-button-menu {
|
ha-button-menu {
|
||||||
margin-right: 8px;
|
margin: 0 -8px 0 8px;
|
||||||
}
|
|
||||||
.table-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12);
|
|
||||||
}
|
|
||||||
search-input {
|
|
||||||
margin-left: 16px;
|
|
||||||
flex-grow: 1;
|
|
||||||
position: relative;
|
|
||||||
top: 2px;
|
|
||||||
}
|
|
||||||
.search-toolbar search-input {
|
|
||||||
margin-left: 8px;
|
|
||||||
top: 1px;
|
|
||||||
}
|
|
||||||
.search-toolbar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
.search-toolbar ha-button-menu {
|
|
||||||
position: static;
|
|
||||||
}
|
|
||||||
.selected-txt {
|
|
||||||
font-weight: bold;
|
|
||||||
padding-left: 16px;
|
|
||||||
}
|
|
||||||
.table-header .selected-txt {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
.search-toolbar .selected-txt {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.header-btns > mwc-button,
|
|
||||||
.header-btns > ha-icon-button {
|
|
||||||
margin: 8px;
|
|
||||||
}
|
|
||||||
.active-filters {
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 2px 2px 2px 8px;
|
|
||||||
margin-left: 4px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.active-filters ha-icon {
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
.active-filters mwc-button {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
.active-filters::before {
|
|
||||||
background-color: var(--primary-color);
|
|
||||||
opacity: 0.12;
|
|
||||||
border-radius: 4px;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
content: "";
|
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
haStyle,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
import "@material/mwc-list/mwc-list-item";
|
import "@material/mwc-list/mwc-list-item";
|
||||||
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
|
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
|
||||||
import { mdiFilterVariant, mdiPlus } from "@mdi/js";
|
import {
|
||||||
|
mdiCancel,
|
||||||
|
mdiDelete,
|
||||||
|
mdiFilterVariant,
|
||||||
|
mdiPlus,
|
||||||
|
mdiUndo,
|
||||||
|
} from "@mdi/js";
|
||||||
import "@polymer/paper-checkbox/paper-checkbox";
|
import "@polymer/paper-checkbox/paper-checkbox";
|
||||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||||
import "@polymer/paper-item/paper-icon-item";
|
import "@polymer/paper-item/paper-icon-item";
|
||||||
@ -36,7 +42,7 @@ import type {
|
|||||||
SelectionChangedEvent,
|
SelectionChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/ha-button-menu";
|
import "../../../components/ha-button-menu";
|
||||||
import "../../../components/ha-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import {
|
import {
|
||||||
AreaRegistryEntry,
|
AreaRegistryEntry,
|
||||||
subscribeAreaRegistry,
|
subscribeAreaRegistry,
|
||||||
@ -457,8 +463,46 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const includeZHAFab = filteredDomains.includes("zha");
|
const includeZHAFab = filteredDomains.includes("zha");
|
||||||
const headerToolbar = this._selectedEntities.length
|
|
||||||
? html`
|
return html`
|
||||||
|
<hass-tabs-subpage-data-table
|
||||||
|
.hass=${this.hass}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.backPath=${this._searchParms.has("historyBack")
|
||||||
|
? undefined
|
||||||
|
: "/config"}
|
||||||
|
.route=${this.route}
|
||||||
|
.tabs=${configSections.integrations}
|
||||||
|
.columns=${this._columns(this.narrow, this.hass.language)}
|
||||||
|
.data=${filteredEntities}
|
||||||
|
.activeFilters=${activeFilters}
|
||||||
|
.numHidden=${this._numHiddenEntities}
|
||||||
|
.searchLabel=${this.hass.localize(
|
||||||
|
"ui.panel.config.entities.picker.search"
|
||||||
|
)}
|
||||||
|
.hiddenLabel=${this.hass.localize(
|
||||||
|
"ui.panel.config.entities.picker.filter.hidden_entities",
|
||||||
|
"number",
|
||||||
|
this._numHiddenEntities
|
||||||
|
)}
|
||||||
|
.filter=${this._filter}
|
||||||
|
selectable
|
||||||
|
clickable
|
||||||
|
@selection-changed=${this._handleSelectionChanged}
|
||||||
|
@clear-filter=${this._clearFilter}
|
||||||
|
@search-changed=${this._handleSearchChange}
|
||||||
|
@row-click=${this._openEditEntry}
|
||||||
|
id="entity_id"
|
||||||
|
.hasFab=${includeZHAFab}
|
||||||
|
>
|
||||||
|
${this._selectedEntities.length
|
||||||
|
? html`<div
|
||||||
|
class=${classMap({
|
||||||
|
"header-toolbar": this.narrow,
|
||||||
|
"table-header": !this.narrow,
|
||||||
|
})}
|
||||||
|
slot="header"
|
||||||
|
>
|
||||||
<p class="selected-txt">
|
<p class="selected-txt">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.entities.picker.selected",
|
"ui.panel.config.entities.picker.selected",
|
||||||
@ -486,32 +530,32 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
>
|
>
|
||||||
`
|
`
|
||||||
: html`
|
: html`
|
||||||
<ha-icon-button
|
<mwc-icon-button
|
||||||
id="enable-btn"
|
id="enable-btn"
|
||||||
icon="hass:undo"
|
|
||||||
@click=${this._enableSelected}
|
@click=${this._enableSelected}
|
||||||
></ha-icon-button>
|
><ha-svg-icon .path=${mdiUndo}></ha-svg-icon
|
||||||
|
></mwc-icon-button>
|
||||||
<paper-tooltip animation-delay="0" for="enable-btn">
|
<paper-tooltip animation-delay="0" for="enable-btn">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.entities.picker.enable_selected.button"
|
"ui.panel.config.entities.picker.enable_selected.button"
|
||||||
)}
|
)}
|
||||||
</paper-tooltip>
|
</paper-tooltip>
|
||||||
<ha-icon-button
|
<mwc-icon-button
|
||||||
id="disable-btn"
|
id="disable-btn"
|
||||||
icon="hass:cancel"
|
|
||||||
@click=${this._disableSelected}
|
@click=${this._disableSelected}
|
||||||
></ha-icon-button>
|
><ha-svg-icon .path=${mdiCancel}></ha-svg-icon
|
||||||
|
></mwc-icon-button>
|
||||||
<paper-tooltip animation-delay="0" for="disable-btn">
|
<paper-tooltip animation-delay="0" for="disable-btn">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.entities.picker.disable_selected.button"
|
"ui.panel.config.entities.picker.disable_selected.button"
|
||||||
)}
|
)}
|
||||||
</paper-tooltip>
|
</paper-tooltip>
|
||||||
<ha-icon-button
|
<mwc-icon-button
|
||||||
class="warning"
|
class="warning"
|
||||||
id="remove-btn"
|
id="remove-btn"
|
||||||
icon="hass:delete"
|
|
||||||
@click=${this._removeSelected}
|
@click=${this._removeSelected}
|
||||||
></ha-icon-button>
|
><ha-svg-icon .path=${mdiDelete}></ha-svg-icon
|
||||||
|
></mwc-icon-button>
|
||||||
<paper-tooltip animation-delay="0" for="remove-btn">
|
<paper-tooltip animation-delay="0" for="remove-btn">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.entities.picker.remove_selected.button"
|
"ui.panel.config.entities.picker.remove_selected.button"
|
||||||
@ -519,86 +563,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
</paper-tooltip>
|
</paper-tooltip>
|
||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
`
|
</div> `
|
||||||
: html`
|
: html`<ha-button-menu slot="filter-menu" corner="BOTTOM_START" multi>
|
||||||
<search-input
|
|
||||||
no-label-float
|
|
||||||
no-underline
|
|
||||||
@value-changed=${this._handleSearchChange}
|
|
||||||
.filter=${this._filter}
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.entities.picker.search"
|
|
||||||
)}
|
|
||||||
></search-input
|
|
||||||
>${activeFilters
|
|
||||||
? html`<div class="active-filters">
|
|
||||||
${this.narrow
|
|
||||||
? html` <div>
|
|
||||||
<ha-icon icon="hass:filter-variant"></ha-icon>
|
|
||||||
<paper-tooltip animation-delay="0" position="left">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.filtering_by"
|
|
||||||
)}
|
|
||||||
${activeFilters.join(", ")}
|
|
||||||
${this._numHiddenEntities
|
|
||||||
? "(" +
|
|
||||||
this.hass.localize(
|
|
||||||
"ui.panel.config.entities.picker.filter.hidden_entities",
|
|
||||||
"number",
|
|
||||||
this._numHiddenEntities
|
|
||||||
) +
|
|
||||||
")"
|
|
||||||
: ""}
|
|
||||||
</paper-tooltip>
|
|
||||||
</div>`
|
|
||||||
: `${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.filtering_by"
|
|
||||||
)} ${activeFilters.join(", ")}
|
|
||||||
${
|
|
||||||
this._numHiddenEntities
|
|
||||||
? "(" +
|
|
||||||
this.hass.localize(
|
|
||||||
"ui.panel.config.entities.picker.filter.hidden_entities",
|
|
||||||
"number",
|
|
||||||
this._numHiddenEntities
|
|
||||||
) +
|
|
||||||
")"
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
<mwc-button @click=${this._clearFilter}
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.config.filtering.clear"
|
|
||||||
)}</mwc-button
|
|
||||||
>
|
|
||||||
</div>`
|
|
||||||
: ""}
|
|
||||||
${this._numHiddenEntities && !activeFilters
|
|
||||||
? html`<div class="active-filters">
|
|
||||||
${this.narrow
|
|
||||||
? html` <div>
|
|
||||||
<ha-icon icon="hass:filter-variant"></ha-icon>
|
|
||||||
<paper-tooltip animation-delay="0" position="left">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.entities.picker.filter.hidden_entities",
|
|
||||||
"number",
|
|
||||||
this._numHiddenEntities
|
|
||||||
)}
|
|
||||||
</paper-tooltip>
|
|
||||||
</div>`
|
|
||||||
: `${this.hass.localize(
|
|
||||||
"ui.panel.config.entities.picker.filter.hidden_entities",
|
|
||||||
"number",
|
|
||||||
this._numHiddenEntities
|
|
||||||
)}`}
|
|
||||||
<mwc-button @click=${this._showAll}
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.config.entities.picker.filter.show_all"
|
|
||||||
)}</mwc-button
|
|
||||||
>
|
|
||||||
</div>`
|
|
||||||
: ""}
|
|
||||||
<ha-button-menu corner="BOTTOM_START" multi>
|
|
||||||
<mwc-icon-button
|
<mwc-icon-button
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
.label=${this.hass!.localize(
|
.label=${this.hass!.localize(
|
||||||
@ -649,37 +615,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
"ui.panel.config.entities.picker.filter.show_readonly"
|
"ui.panel.config.entities.picker.filter.show_readonly"
|
||||||
)}
|
)}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
</ha-button-menu>
|
</ha-button-menu>`}
|
||||||
`;
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<hass-tabs-subpage-data-table
|
|
||||||
.hass=${this.hass}
|
|
||||||
.narrow=${this.narrow}
|
|
||||||
.backPath=${this._searchParms.has("historyBack")
|
|
||||||
? undefined
|
|
||||||
: "/config"}
|
|
||||||
.route=${this.route}
|
|
||||||
.tabs=${configSections.integrations}
|
|
||||||
.columns=${this._columns(this.narrow, this.hass.language)}
|
|
||||||
.data=${filteredEntities}
|
|
||||||
.filter=${this._filter}
|
|
||||||
selectable
|
|
||||||
clickable
|
|
||||||
@selection-changed=${this._handleSelectionChanged}
|
|
||||||
@row-click=${this._openEditEntry}
|
|
||||||
id="entity_id"
|
|
||||||
.hasFab=${includeZHAFab}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=${classMap({
|
|
||||||
"search-toolbar": this.narrow,
|
|
||||||
"table-header": !this.narrow,
|
|
||||||
})}
|
|
||||||
slot="header"
|
|
||||||
>
|
|
||||||
${headerToolbar}
|
|
||||||
</div>
|
|
||||||
${includeZHAFab
|
${includeZHAFab
|
||||||
? html`<a href="/config/zha/add" slot="fab">
|
? html`<a href="/config/zha/add" slot="fab">
|
||||||
<ha-fab
|
<ha-fab
|
||||||
@ -899,10 +835,11 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _clearFilter() {
|
private _clearFilter() {
|
||||||
|
if (
|
||||||
|
this._activeFilters(this._searchParms, this.hass.localize, this._entries)
|
||||||
|
) {
|
||||||
navigate(this, window.location.pathname, true);
|
navigate(this, window.location.pathname, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showAll() {
|
|
||||||
this._showDisabled = true;
|
this._showDisabled = true;
|
||||||
this._showReadOnly = true;
|
this._showReadOnly = true;
|
||||||
this._showUnavailable = true;
|
this._showUnavailable = true;
|
||||||
@ -916,64 +853,20 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
--app-header-background-color: var(--sidebar-background-color);
|
--app-header-background-color: var(--sidebar-background-color);
|
||||||
--app-header-text-color: var(--sidebar-text-color);
|
--app-header-text-color: var(--sidebar-text-color);
|
||||||
}
|
}
|
||||||
a {
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
margin-top: 0;
|
|
||||||
font-family: var(--paper-font-headline_-_font-family);
|
|
||||||
-webkit-font-smoothing: var(
|
|
||||||
--paper-font-headline_-_-webkit-font-smoothing
|
|
||||||
);
|
|
||||||
font-size: var(--paper-font-headline_-_font-size);
|
|
||||||
font-weight: var(--paper-font-headline_-_font-weight);
|
|
||||||
letter-spacing: var(--paper-font-headline_-_letter-spacing);
|
|
||||||
line-height: var(--paper-font-headline_-_line-height);
|
|
||||||
opacity: var(--dark-primary-opacity);
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
font-family: var(--paper-font-subhead_-_font-family);
|
|
||||||
-webkit-font-smoothing: var(
|
|
||||||
--paper-font-subhead_-_-webkit-font-smoothing
|
|
||||||
);
|
|
||||||
font-weight: var(--paper-font-subhead_-_font-weight);
|
|
||||||
line-height: var(--paper-font-subhead_-_line-height);
|
|
||||||
}
|
|
||||||
ha-data-table {
|
|
||||||
width: 100%;
|
|
||||||
--data-table-border-width: 0;
|
|
||||||
}
|
|
||||||
:host(:not([narrow])) ha-data-table {
|
|
||||||
height: calc(100vh - 1px - var(--header-height));
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
ha-button-menu {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
.table-header {
|
.table-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
height: 58px;
|
||||||
border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12);
|
border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12);
|
||||||
}
|
}
|
||||||
search-input {
|
.header-toolbar {
|
||||||
margin-left: 16px;
|
|
||||||
flex-grow: 1;
|
|
||||||
position: relative;
|
|
||||||
top: 2px;
|
|
||||||
}
|
|
||||||
.search-toolbar search-input {
|
|
||||||
margin-left: 8px;
|
|
||||||
top: 1px;
|
|
||||||
}
|
|
||||||
.search-toolbar {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
}
|
position: relative;
|
||||||
.search-toolbar ha-button-menu {
|
top: -4px;
|
||||||
position: static;
|
|
||||||
}
|
}
|
||||||
.selected-txt {
|
.selected-txt {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -982,38 +875,18 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
.table-header .selected-txt {
|
.table-header .selected-txt {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
.search-toolbar .selected-txt {
|
.header-toolbar .selected-txt {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
.header-toolbar .header-btns {
|
||||||
|
margin-right: -12px;
|
||||||
|
}
|
||||||
.header-btns > mwc-button,
|
.header-btns > mwc-button,
|
||||||
.header-btns > ha-icon-button {
|
.header-btns > mwc-icon-button {
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
}
|
}
|
||||||
.active-filters {
|
ha-button-menu {
|
||||||
color: var(--primary-text-color);
|
margin: 0 -8px 0 8px;
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 2px 2px 2px 8px;
|
|
||||||
margin-left: 4px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.active-filters ha-icon {
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
.active-filters mwc-button {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
.active-filters::before {
|
|
||||||
background-color: var(--primary-color);
|
|
||||||
opacity: 0.12;
|
|
||||||
border-radius: 4px;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
content: "";
|
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
|
@ -348,11 +348,11 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
"number",
|
"number",
|
||||||
disabledConfigEntries.size
|
disabledConfigEntries.size
|
||||||
)}
|
)}
|
||||||
<mwc-button @click=${this._toggleShowDisabled}
|
<mwc-button @click=${this._toggleShowDisabled}>
|
||||||
>${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.filtering.show"
|
"ui.panel.config.integrations.disable.show"
|
||||||
)}</mwc-button
|
)}
|
||||||
>
|
</mwc-button>
|
||||||
</div>`
|
</div>`
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
|
@ -459,7 +459,10 @@
|
|||||||
},
|
},
|
||||||
"data-table": {
|
"data-table": {
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
"no-data": "No data"
|
"no-data": "No data",
|
||||||
|
"filtering_by": "Filtering by",
|
||||||
|
"hidden": "{number} hidden",
|
||||||
|
"clear": "Clear"
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
"pick": "Pick",
|
"pick": "Pick",
|
||||||
@ -848,11 +851,6 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"header": "Configure Home Assistant",
|
"header": "Configure Home Assistant",
|
||||||
"introduction": "In this view it is possible to configure your components and Home Assistant. Not everything is possible to configure from the UI yet, but we're working on it.",
|
"introduction": "In this view it is possible to configure your components and Home Assistant. Not everything is possible to configure from the UI yet, but we're working on it.",
|
||||||
"filtering": {
|
|
||||||
"filtering_by": "Filtering by",
|
|
||||||
"clear": "Clear",
|
|
||||||
"show": "Show"
|
|
||||||
},
|
|
||||||
"advanced_mode": {
|
"advanced_mode": {
|
||||||
"hint_enable": "Missing config options? Enable advanced mode on",
|
"hint_enable": "Missing config options? Enable advanced mode on",
|
||||||
"link_profile_page": "your profile page"
|
"link_profile_page": "your profile page"
|
||||||
@ -2071,7 +2069,8 @@
|
|||||||
"disable": {
|
"disable": {
|
||||||
"show_disabled": "Show disabled integrations",
|
"show_disabled": "Show disabled integrations",
|
||||||
"hide_disabled": "Hide disabled integrations",
|
"hide_disabled": "Hide disabled integrations",
|
||||||
"disabled_integrations": "{number} disabled"
|
"disabled_integrations": "{number} disabled",
|
||||||
|
"show": "Show"
|
||||||
},
|
},
|
||||||
"ignore": {
|
"ignore": {
|
||||||
"ignore": "Ignore",
|
"ignore": "Ignore",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user