mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 03:06:41 +00:00
Allow to hide and sort columns in data tables (#21168)
* Allow to hide and sort columns in data tables * fix unused * store
This commit is contained in:
parent
adea384f40
commit
7d28f3f585
280
src/components/data-table/dialog-data-table-settings.ts
Normal file
280
src/components/data-table/dialog-data-table-settings.ts
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
import "@material/mwc-list";
|
||||||
|
import { mdiDrag, mdiEye, mdiEyeOff } from "@mdi/js";
|
||||||
|
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { classMap } from "lit/directives/class-map";
|
||||||
|
import { repeat } from "lit/directives/repeat";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
|
import { haStyleDialog } from "../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
import { createCloseHeading } from "../ha-dialog";
|
||||||
|
import "../ha-list-item";
|
||||||
|
import "../ha-sortable";
|
||||||
|
import "../ha-button";
|
||||||
|
import { DataTableColumnContainer, DataTableColumnData } from "./ha-data-table";
|
||||||
|
import { DataTableSettingsDialogParams } from "./show-dialog-data-table-settings";
|
||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
|
||||||
|
@customElement("dialog-data-table-settings")
|
||||||
|
export class DialogDataTableSettings extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private _params?: DataTableSettingsDialogParams;
|
||||||
|
|
||||||
|
@state() private _columnOrder?: string[];
|
||||||
|
|
||||||
|
@state() private _hiddenColumns?: string[];
|
||||||
|
|
||||||
|
public showDialog(params: DataTableSettingsDialogParams) {
|
||||||
|
this._params = params;
|
||||||
|
this._columnOrder = params.columnOrder;
|
||||||
|
this._hiddenColumns = params.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog() {
|
||||||
|
this._params = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _sortedColumns = memoizeOne(
|
||||||
|
(
|
||||||
|
columns: DataTableColumnContainer,
|
||||||
|
columnOrder: string[] | undefined,
|
||||||
|
hiddenColumns: string[] | undefined
|
||||||
|
) =>
|
||||||
|
Object.keys(columns)
|
||||||
|
.filter((col) => !columns[col].hidden)
|
||||||
|
.sort((a, b) => {
|
||||||
|
const orderA = columnOrder?.indexOf(a) ?? -1;
|
||||||
|
const orderB = columnOrder?.indexOf(b) ?? -1;
|
||||||
|
const hiddenA =
|
||||||
|
hiddenColumns?.includes(a) ?? Boolean(columns[a].defaultHidden);
|
||||||
|
const hiddenB =
|
||||||
|
hiddenColumns?.includes(b) ?? Boolean(columns[b].defaultHidden);
|
||||||
|
if (hiddenA !== hiddenB) {
|
||||||
|
return hiddenA ? 1 : -1;
|
||||||
|
}
|
||||||
|
if (orderA !== orderB) {
|
||||||
|
if (orderA === -1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (orderB === -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orderA - orderB;
|
||||||
|
})
|
||||||
|
.reduce(
|
||||||
|
(arr, key) => {
|
||||||
|
arr.push({ key, ...columns[key] });
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
[] as (DataTableColumnData & { key: string })[]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this._params) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = this._sortedColumns(
|
||||||
|
this._params.columns,
|
||||||
|
this._columnOrder,
|
||||||
|
this._hiddenColumns
|
||||||
|
);
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-dialog
|
||||||
|
open
|
||||||
|
@closed=${this.closeDialog}
|
||||||
|
.heading=${createCloseHeading(
|
||||||
|
this.hass,
|
||||||
|
this.hass.localize("ui.components.data-table.settings.header")
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-sortable
|
||||||
|
@item-moved=${this._columnMoved}
|
||||||
|
draggable-selector=".draggable"
|
||||||
|
handle-selector=".handle"
|
||||||
|
>
|
||||||
|
<mwc-list>
|
||||||
|
${repeat(
|
||||||
|
columns,
|
||||||
|
(col) => col.key,
|
||||||
|
(col, _idx) => {
|
||||||
|
const canMove = !col.main && col.moveable !== false;
|
||||||
|
const canHide = !col.main && col.hideable !== false;
|
||||||
|
const isVisible = !(this._columnOrder &&
|
||||||
|
this._columnOrder.includes(col.key)
|
||||||
|
? this._hiddenColumns?.includes(col.key) ?? col.defaultHidden
|
||||||
|
: col.defaultHidden);
|
||||||
|
|
||||||
|
return html`<ha-list-item
|
||||||
|
hasMeta
|
||||||
|
class=${classMap({
|
||||||
|
hidden: !isVisible,
|
||||||
|
draggable: canMove && isVisible,
|
||||||
|
})}
|
||||||
|
graphic="icon"
|
||||||
|
noninteractive
|
||||||
|
>${col.title || col.label || col.key}
|
||||||
|
${canMove && isVisible
|
||||||
|
? html`<ha-svg-icon
|
||||||
|
class="handle"
|
||||||
|
.path=${mdiDrag}
|
||||||
|
slot="graphic"
|
||||||
|
></ha-svg-icon>`
|
||||||
|
: nothing}
|
||||||
|
<ha-icon-button
|
||||||
|
tabindex="0"
|
||||||
|
class="action"
|
||||||
|
.disabled=${!canHide}
|
||||||
|
.hidden=${!isVisible}
|
||||||
|
.path=${isVisible ? mdiEye : mdiEyeOff}
|
||||||
|
slot="meta"
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
`ui.components.data-table.settings.${isVisible ? "hide" : "show"}`,
|
||||||
|
{ title: typeof col.title === "string" ? col.title : "" }
|
||||||
|
)}
|
||||||
|
.column=${col.key}
|
||||||
|
@click=${this._toggle}
|
||||||
|
></ha-icon-button>
|
||||||
|
</ha-list-item>`;
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</mwc-list>
|
||||||
|
</ha-sortable>
|
||||||
|
<ha-button slot="secondaryAction" @click=${this._reset}
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.components.data-table.settings.restore"
|
||||||
|
)}</ha-button
|
||||||
|
>
|
||||||
|
<ha-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.components.data-table.settings.done")}
|
||||||
|
</ha-button>
|
||||||
|
</ha-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _columnMoved(ev: CustomEvent): void {
|
||||||
|
ev.stopPropagation();
|
||||||
|
if (!this._params) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { oldIndex, newIndex } = ev.detail;
|
||||||
|
|
||||||
|
const columns = this._sortedColumns(
|
||||||
|
this._params.columns,
|
||||||
|
this._columnOrder,
|
||||||
|
this._hiddenColumns
|
||||||
|
);
|
||||||
|
|
||||||
|
const columnOrder = columns.map((column) => column.key);
|
||||||
|
|
||||||
|
const option = columnOrder.splice(oldIndex, 1)[0];
|
||||||
|
columnOrder.splice(newIndex, 0, option);
|
||||||
|
|
||||||
|
this._columnOrder = columnOrder;
|
||||||
|
|
||||||
|
this._params!.onUpdate(this._columnOrder, this._hiddenColumns);
|
||||||
|
}
|
||||||
|
|
||||||
|
_toggle(ev) {
|
||||||
|
if (!this._params) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const column = ev.target.column;
|
||||||
|
const wasHidden = ev.target.hidden;
|
||||||
|
|
||||||
|
const hidden = [
|
||||||
|
...(this._hiddenColumns ??
|
||||||
|
Object.entries(this._params.columns)
|
||||||
|
.filter(([_key, col]) => col.defaultHidden)
|
||||||
|
.map(([key]) => key)),
|
||||||
|
];
|
||||||
|
if (wasHidden && hidden.includes(column)) {
|
||||||
|
hidden.splice(hidden.indexOf(column), 1);
|
||||||
|
} else if (!wasHidden) {
|
||||||
|
hidden.push(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = this._sortedColumns(
|
||||||
|
this._params.columns,
|
||||||
|
this._columnOrder,
|
||||||
|
this._hiddenColumns
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!this._columnOrder) {
|
||||||
|
this._columnOrder = columns.map((col) => col.key);
|
||||||
|
} else {
|
||||||
|
columns.forEach((col) => {
|
||||||
|
if (!this._columnOrder!.includes(col.key)) {
|
||||||
|
this._columnOrder!.push(col.key);
|
||||||
|
if (col.defaultHidden) {
|
||||||
|
hidden.push(col.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this._hiddenColumns = hidden;
|
||||||
|
|
||||||
|
this._params!.onUpdate(this._columnOrder, this._hiddenColumns);
|
||||||
|
}
|
||||||
|
|
||||||
|
_reset() {
|
||||||
|
this._columnOrder = undefined;
|
||||||
|
this._hiddenColumns = undefined;
|
||||||
|
|
||||||
|
this._params!.onUpdate(this._columnOrder, this._hiddenColumns);
|
||||||
|
this.closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
|
ha-dialog {
|
||||||
|
--mdc-dialog-max-width: 500px;
|
||||||
|
--dialog-z-index: 10;
|
||||||
|
--dialog-content-padding: 0 8px;
|
||||||
|
}
|
||||||
|
@media all and (max-width: 451px) {
|
||||||
|
ha-dialog {
|
||||||
|
--vertical-align-dialog: flex-start;
|
||||||
|
--dialog-surface-margin-top: 250px;
|
||||||
|
--ha-dialog-border-radius: 28px 28px 0 0;
|
||||||
|
--mdc-dialog-min-height: calc(100% - 250px);
|
||||||
|
--mdc-dialog-max-height: calc(100% - 250px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ha-list-item {
|
||||||
|
--mdc-list-side-padding: 12px;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
.hidden {
|
||||||
|
color: var(--disabled-text-color);
|
||||||
|
}
|
||||||
|
.handle {
|
||||||
|
cursor: move; /* fallback if grab cursor is unsupported */
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
ha-icon-button {
|
||||||
|
display: block;
|
||||||
|
margin: -12px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-data-table-settings": DialogDataTableSettings;
|
||||||
|
}
|
||||||
|
}
|
@ -65,6 +65,10 @@ export interface DataTableSortColumnData {
|
|||||||
valueColumn?: string;
|
valueColumn?: string;
|
||||||
direction?: SortingDirection;
|
direction?: SortingDirection;
|
||||||
groupable?: boolean;
|
groupable?: boolean;
|
||||||
|
moveable?: boolean;
|
||||||
|
hideable?: boolean;
|
||||||
|
defaultHidden?: boolean;
|
||||||
|
showNarrow?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataTableColumnData<T = any> extends DataTableSortColumnData {
|
export interface DataTableColumnData<T = any> extends DataTableSortColumnData {
|
||||||
@ -79,6 +83,7 @@ export interface DataTableColumnData<T = any> extends DataTableSortColumnData {
|
|||||||
| "overflow-menu"
|
| "overflow-menu"
|
||||||
| "flex";
|
| "flex";
|
||||||
template?: (row: T) => TemplateResult | string | typeof nothing;
|
template?: (row: T) => TemplateResult | string | typeof nothing;
|
||||||
|
extraTemplate?: (row: T) => TemplateResult | string | typeof nothing;
|
||||||
width?: string;
|
width?: string;
|
||||||
maxWidth?: string;
|
maxWidth?: string;
|
||||||
grows?: boolean;
|
grows?: boolean;
|
||||||
@ -105,6 +110,8 @@ const UNDEFINED_GROUP_KEY = "zzzzz_undefined";
|
|||||||
export class HaDataTable extends LitElement {
|
export class HaDataTable extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
@property({ type: Object }) public columns: DataTableColumnContainer = {};
|
@property({ type: Object }) public columns: DataTableColumnContainer = {};
|
||||||
|
|
||||||
@property({ type: Array }) public data: DataTableRowData[] = [];
|
@property({ type: Array }) public data: DataTableRowData[] = [];
|
||||||
@ -145,6 +152,10 @@ export class HaDataTable extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public initialCollapsedGroups?: string[];
|
@property({ attribute: false }) public initialCollapsedGroups?: string[];
|
||||||
|
|
||||||
|
@property({ attribute: false }) public hiddenColumns?: string[];
|
||||||
|
|
||||||
|
@property({ attribute: false }) public columnOrder?: string[];
|
||||||
|
|
||||||
@state() private _filterable = false;
|
@state() private _filterable = false;
|
||||||
|
|
||||||
@state() private _filter = "";
|
@state() private _filter = "";
|
||||||
@ -235,6 +246,7 @@ export class HaDataTable extends LitElement {
|
|||||||
(column: ClonedDataTableColumnData) => {
|
(column: ClonedDataTableColumnData) => {
|
||||||
delete column.title;
|
delete column.title;
|
||||||
delete column.template;
|
delete column.template;
|
||||||
|
delete column.extraTemplate;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -272,12 +284,44 @@ export class HaDataTable extends LitElement {
|
|||||||
this._sortFilterData();
|
this._sortFilterData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties.has("selectable")) {
|
if (properties.has("selectable") || properties.has("hiddenColumns")) {
|
||||||
this._items = [...this._items];
|
this._items = [...this._items];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _sortedColumns = memoizeOne(
|
||||||
|
(columns: DataTableColumnContainer, columnOrder?: string[]) => {
|
||||||
|
if (!columnOrder || !columnOrder.length) {
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.keys(columns)
|
||||||
|
.sort((a, b) => {
|
||||||
|
const orderA = columnOrder!.indexOf(a);
|
||||||
|
const orderB = columnOrder!.indexOf(b);
|
||||||
|
if (orderA !== orderB) {
|
||||||
|
if (orderA === -1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (orderB === -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orderA - orderB;
|
||||||
|
})
|
||||||
|
.reduce((obj, key) => {
|
||||||
|
obj[key] = columns[key];
|
||||||
|
return obj;
|
||||||
|
}, {}) as DataTableColumnContainer;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
|
const columns = this._sortedColumns(this.columns, this.columnOrder);
|
||||||
|
|
||||||
|
const renderRow = (row: DataTableRowData, index: number) =>
|
||||||
|
this._renderRow(columns, this.narrow, row, index);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="mdc-data-table">
|
<div class="mdc-data-table">
|
||||||
<slot name="header" @slotchange=${this._calcTableHeight}>
|
<slot name="header" @slotchange=${this._calcTableHeight}>
|
||||||
@ -326,9 +370,14 @@ export class HaDataTable extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${Object.entries(this.columns).map(([key, column]) => {
|
${Object.entries(columns).map(([key, column]) => {
|
||||||
if (column.hidden) {
|
if (
|
||||||
return "";
|
column.hidden ||
|
||||||
|
(this.columnOrder && this.columnOrder.includes(key)
|
||||||
|
? this.hiddenColumns?.includes(key) ?? column.defaultHidden
|
||||||
|
: column.defaultHidden)
|
||||||
|
) {
|
||||||
|
return nothing;
|
||||||
}
|
}
|
||||||
const sorted = key === this.sortColumn;
|
const sorted = key === this.sortColumn;
|
||||||
const classes = {
|
const classes = {
|
||||||
@ -399,7 +448,7 @@ export class HaDataTable extends LitElement {
|
|||||||
@scroll=${this._saveScrollPos}
|
@scroll=${this._saveScrollPos}
|
||||||
.items=${this._items}
|
.items=${this._items}
|
||||||
.keyFunction=${this._keyFunction}
|
.keyFunction=${this._keyFunction}
|
||||||
.renderItem=${this._renderRow}
|
.renderItem=${renderRow}
|
||||||
></lit-virtualizer>
|
></lit-virtualizer>
|
||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
@ -409,7 +458,12 @@ export class HaDataTable extends LitElement {
|
|||||||
|
|
||||||
private _keyFunction = (row: DataTableRowData) => row?.[this.id] || row;
|
private _keyFunction = (row: DataTableRowData) => row?.[this.id] || row;
|
||||||
|
|
||||||
private _renderRow = (row: DataTableRowData, index: number) => {
|
private _renderRow = (
|
||||||
|
columns: DataTableColumnContainer,
|
||||||
|
narrow: boolean,
|
||||||
|
row: DataTableRowData,
|
||||||
|
index: number
|
||||||
|
) => {
|
||||||
// not sure how this happens...
|
// not sure how this happens...
|
||||||
if (!row) {
|
if (!row) {
|
||||||
return nothing;
|
return nothing;
|
||||||
@ -454,8 +508,14 @@ export class HaDataTable extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${Object.entries(this.columns).map(([key, column]) => {
|
${Object.entries(columns).map(([key, column]) => {
|
||||||
if (column.hidden) {
|
if (
|
||||||
|
(narrow && !column.main && !column.showNarrow) ||
|
||||||
|
column.hidden ||
|
||||||
|
(this.columnOrder && this.columnOrder.includes(key)
|
||||||
|
? this.hiddenColumns?.includes(key) ?? column.defaultHidden
|
||||||
|
: column.defaultHidden)
|
||||||
|
) {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
return html`
|
return html`
|
||||||
@ -482,7 +542,38 @@ export class HaDataTable extends LitElement {
|
|||||||
})
|
})
|
||||||
: ""}
|
: ""}
|
||||||
>
|
>
|
||||||
${column.template ? column.template(row) : row[key]}
|
${column.template
|
||||||
|
? column.template(row)
|
||||||
|
: narrow && column.main
|
||||||
|
? html`<div class="primary">${row[key]}</div>
|
||||||
|
<div class="secondary">
|
||||||
|
${Object.entries(columns)
|
||||||
|
.filter(
|
||||||
|
([key2, column2]) =>
|
||||||
|
!column2.hidden &&
|
||||||
|
!column2.main &&
|
||||||
|
!column2.showNarrow &&
|
||||||
|
!(this.columnOrder &&
|
||||||
|
this.columnOrder.includes(key2)
|
||||||
|
? this.hiddenColumns?.includes(key2) ??
|
||||||
|
column2.defaultHidden
|
||||||
|
: column2.defaultHidden)
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
([key2, column2], i) =>
|
||||||
|
html`${i !== 0
|
||||||
|
? " ⸱ "
|
||||||
|
: nothing}${column2.template
|
||||||
|
? column2.template(row)
|
||||||
|
: row[key2]}`
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
${column.extraTemplate
|
||||||
|
? column.extraTemplate(row)
|
||||||
|
: nothing}`
|
||||||
|
: html`${row[key]}${column.extraTemplate
|
||||||
|
? column.extraTemplate(row)
|
||||||
|
: nothing}`}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
})}
|
})}
|
||||||
@ -861,6 +952,7 @@ export class HaDataTable extends LitElement {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
border: 0;
|
border: 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mdc-data-table__cell {
|
.mdc-data-table__cell {
|
||||||
|
26
src/components/data-table/show-dialog-data-table-settings.ts
Normal file
26
src/components/data-table/show-dialog-data-table-settings.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
import { DataTableColumnContainer } from "./ha-data-table";
|
||||||
|
|
||||||
|
export interface DataTableSettingsDialogParams {
|
||||||
|
columns: DataTableColumnContainer;
|
||||||
|
onUpdate: (
|
||||||
|
columnOrder: string[] | undefined,
|
||||||
|
hiddenColumns: string[] | undefined
|
||||||
|
) => void;
|
||||||
|
hiddenColumns?: string[];
|
||||||
|
columnOrder?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loadDataTableSettingsDialog = () =>
|
||||||
|
import("./dialog-data-table-settings");
|
||||||
|
|
||||||
|
export const showDataTableSettingsDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
dialogParams: DataTableSettingsDialogParams
|
||||||
|
): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-data-table-settings",
|
||||||
|
dialogImport: loadDataTableSettingsDialog,
|
||||||
|
dialogParams,
|
||||||
|
});
|
||||||
|
};
|
@ -6,6 +6,7 @@ import {
|
|||||||
mdiArrowDown,
|
mdiArrowDown,
|
||||||
mdiArrowUp,
|
mdiArrowUp,
|
||||||
mdiClose,
|
mdiClose,
|
||||||
|
mdiCog,
|
||||||
mdiFilterVariant,
|
mdiFilterVariant,
|
||||||
mdiFilterVariantRemove,
|
mdiFilterVariantRemove,
|
||||||
mdiFormatListChecks,
|
mdiFormatListChecks,
|
||||||
@ -42,6 +43,7 @@ import "../components/search-input-outlined";
|
|||||||
import type { HomeAssistant, Route } from "../types";
|
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";
|
||||||
|
import { showDataTableSettingsDialog } from "../components/data-table/show-dialog-data-table-settings";
|
||||||
|
|
||||||
@customElement("hass-tabs-subpage-data-table")
|
@customElement("hass-tabs-subpage-data-table")
|
||||||
export class HaTabsSubpageDataTable extends LitElement {
|
export class HaTabsSubpageDataTable extends LitElement {
|
||||||
@ -171,6 +173,10 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public groupOrder?: string[];
|
@property({ attribute: false }) public groupOrder?: string[];
|
||||||
|
|
||||||
|
@property({ attribute: false }) public columnOrder?: string[];
|
||||||
|
|
||||||
|
@property({ attribute: false }) public hiddenColumns?: string[];
|
||||||
|
|
||||||
@state() private _sortColumn?: string;
|
@state() private _sortColumn?: string;
|
||||||
|
|
||||||
@state() private _sortDirection: SortingDirection = null;
|
@state() private _sortDirection: SortingDirection = null;
|
||||||
@ -290,6 +296,14 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
`
|
`
|
||||||
: nothing;
|
: nothing;
|
||||||
|
|
||||||
|
const settingsButton = html`<ha-assist-chip
|
||||||
|
class="has-dropdown select-mode-chip"
|
||||||
|
@click=${this._openSettings}
|
||||||
|
.title=${localize("ui.components.subpage-data-table.settings")}
|
||||||
|
>
|
||||||
|
<ha-svg-icon slot="icon" .path=${mdiCog}></ha-svg-icon>
|
||||||
|
</ha-assist-chip>`;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage
|
<hass-tabs-subpage
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -416,6 +430,7 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
: ""}
|
: ""}
|
||||||
<ha-data-table
|
<ha-data-table
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
.narrow=${this.narrow}
|
||||||
.columns=${this.columns}
|
.columns=${this.columns}
|
||||||
.data=${this.data}
|
.data=${this.data}
|
||||||
.noDataText=${this.noDataText}
|
.noDataText=${this.noDataText}
|
||||||
@ -430,6 +445,8 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
.groupColumn=${this._groupColumn}
|
.groupColumn=${this._groupColumn}
|
||||||
.groupOrder=${this.groupOrder}
|
.groupOrder=${this.groupOrder}
|
||||||
.initialCollapsedGroups=${this.initialCollapsedGroups}
|
.initialCollapsedGroups=${this.initialCollapsedGroups}
|
||||||
|
.columnOrder=${this.columnOrder}
|
||||||
|
.hiddenColumns=${this.hiddenColumns}
|
||||||
>
|
>
|
||||||
${!this.narrow
|
${!this.narrow
|
||||||
? html`
|
? html`
|
||||||
@ -438,7 +455,7 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
<div class="table-header">
|
<div class="table-header">
|
||||||
${this.hasFilters && !this.showFilters
|
${this.hasFilters && !this.showFilters
|
||||||
? html`${filterButton}`
|
? html`${filterButton}`
|
||||||
: nothing}${selectModeBtn}${searchBar}${groupByMenu}${sortByMenu}
|
: nothing}${selectModeBtn}${searchBar}${groupByMenu}${sortByMenu}${settingsButton}
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
@ -448,7 +465,7 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
${this.hasFilters && !this.showFilters
|
${this.hasFilters && !this.showFilters
|
||||||
? html`${filterButton}`
|
? html`${filterButton}`
|
||||||
: nothing}
|
: nothing}
|
||||||
${selectModeBtn}${groupByMenu}${sortByMenu}
|
${selectModeBtn}${groupByMenu}${sortByMenu}${settingsButton}
|
||||||
</div>`}
|
</div>`}
|
||||||
</ha-data-table>`}
|
</ha-data-table>`}
|
||||||
<div slot="fab"><slot name="fab"></slot></div>
|
<div slot="fab"><slot name="fab"></slot></div>
|
||||||
@ -608,6 +625,22 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
fireEvent(this, "grouping-changed", { value: columnId });
|
fireEvent(this, "grouping-changed", { value: columnId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _openSettings() {
|
||||||
|
showDataTableSettingsDialog(this, {
|
||||||
|
columns: this.columns,
|
||||||
|
hiddenColumns: this.hiddenColumns,
|
||||||
|
columnOrder: this.columnOrder,
|
||||||
|
onUpdate: (
|
||||||
|
columnOrder: string[] | undefined,
|
||||||
|
hiddenColumns: string[] | undefined
|
||||||
|
) => {
|
||||||
|
this.columnOrder = columnOrder;
|
||||||
|
this.hiddenColumns = hiddenColumns;
|
||||||
|
fireEvent(this, "columns-changed", { columnOrder, hiddenColumns });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private _collapseAllGroups() {
|
private _collapseAllGroups() {
|
||||||
this._dataTable.collapseAllGroups();
|
this._dataTable.collapseAllGroups();
|
||||||
}
|
}
|
||||||
@ -874,6 +907,10 @@ declare global {
|
|||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"search-changed": { value: string };
|
"search-changed": { value: string };
|
||||||
"grouping-changed": { value: string };
|
"grouping-changed": { value: string };
|
||||||
|
"columns-changed": {
|
||||||
|
columnOrder: string[] | undefined;
|
||||||
|
hiddenColumns: string[] | undefined;
|
||||||
|
};
|
||||||
"clear-filter": undefined;
|
"clear-filter": undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,6 +192,20 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
})
|
})
|
||||||
private _activeCollapsed?: string;
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "automation-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "automation-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
@query("#overflow-menu") private _overflowMenu!: HaMenu;
|
@query("#overflow-menu") private _overflowMenu!: HaMenu;
|
||||||
|
|
||||||
private _sizeController = new ResizeController(this, {
|
private _sizeController = new ResizeController(this, {
|
||||||
@ -253,6 +267,8 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
title: "",
|
title: "",
|
||||||
label: localize("ui.panel.config.automation.picker.headers.state"),
|
label: localize("ui.panel.config.automation.picker.headers.state"),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
|
moveable: false,
|
||||||
|
showNarrow: true,
|
||||||
template: (automation) =>
|
template: (automation) =>
|
||||||
html`<ha-state-icon
|
html`<ha-state-icon
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -272,30 +288,13 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
filterable: true,
|
filterable: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (automation) => {
|
extraTemplate: (automation) =>
|
||||||
const date = new Date(automation.attributes.last_triggered);
|
automation.labels.length
|
||||||
const now = new Date();
|
|
||||||
const dayDifference = differenceInDays(now, date);
|
|
||||||
return html`
|
|
||||||
<div style="font-size: 14px;">${automation.name}</div>
|
|
||||||
${narrow
|
|
||||||
? html`<div class="secondary">
|
|
||||||
${this.hass.localize("ui.card.automation.last_triggered")}:
|
|
||||||
${automation.attributes.last_triggered
|
|
||||||
? dayDifference > 3
|
|
||||||
? formatShortDateTime(date, locale, this.hass.config)
|
|
||||||
: relativeTime(date, locale)
|
|
||||||
: localize("ui.components.relative_time.never")}
|
|
||||||
</div>`
|
|
||||||
: nothing}
|
|
||||||
${automation.labels.length
|
|
||||||
? html`<ha-data-table-labels
|
? html`<ha-data-table-labels
|
||||||
@label-clicked=${this._labelClicked}
|
@label-clicked=${this._labelClicked}
|
||||||
.labels=${automation.labels}
|
.labels=${automation.labels}
|
||||||
></ha-data-table-labels>`
|
></ha-data-table-labels>`
|
||||||
: nothing}
|
: nothing,
|
||||||
`;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
area: {
|
area: {
|
||||||
title: localize("ui.panel.config.automation.picker.headers.area"),
|
title: localize("ui.panel.config.automation.picker.headers.area"),
|
||||||
@ -322,7 +321,6 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
sortable: true,
|
sortable: true,
|
||||||
width: "130px",
|
width: "130px",
|
||||||
title: localize("ui.card.automation.last_triggered"),
|
title: localize("ui.card.automation.last_triggered"),
|
||||||
hidden: narrow,
|
|
||||||
template: (automation) => {
|
template: (automation) => {
|
||||||
if (!automation.last_triggered) {
|
if (!automation.last_triggered) {
|
||||||
return this.hass.localize("ui.components.relative_time.never");
|
return this.hass.localize("ui.components.relative_time.never");
|
||||||
@ -341,9 +339,9 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
width: "82px",
|
width: "82px",
|
||||||
sortable: true,
|
sortable: true,
|
||||||
groupable: true,
|
groupable: true,
|
||||||
|
hidden: narrow,
|
||||||
title: "",
|
title: "",
|
||||||
type: "overflow",
|
type: "overflow",
|
||||||
hidden: narrow,
|
|
||||||
label: this.hass.localize("ui.panel.config.automation.picker.state"),
|
label: this.hass.localize("ui.panel.config.automation.picker.state"),
|
||||||
template: (automation) => html`
|
template: (automation) => html`
|
||||||
<ha-entity-toggle
|
<ha-entity-toggle
|
||||||
@ -356,6 +354,9 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
title: "",
|
title: "",
|
||||||
width: "64px",
|
width: "64px",
|
||||||
type: "icon-button",
|
type: "icon-button",
|
||||||
|
showNarrow: true,
|
||||||
|
moveable: false,
|
||||||
|
hideable: false,
|
||||||
template: (automation) => html`
|
template: (automation) => html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.automation=${automation}
|
.automation=${automation}
|
||||||
@ -545,6 +546,9 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
.initialGroupColumn=${this._activeGrouping || "category"}
|
.initialGroupColumn=${this._activeGrouping || "category"}
|
||||||
.initialCollapsedGroups=${this._activeCollapsed}
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@grouping-changed=${this._handleGroupingChanged}
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
@collapsed-changed=${this._handleCollapseChanged}
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
@ -1415,6 +1419,11 @@ ${rejected
|
|||||||
this._activeCollapsed = ev.detail.value;
|
this._activeCollapsed = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -60,14 +60,19 @@ class HaConfigBackup extends LitElement {
|
|||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (backup) =>
|
template: narrow
|
||||||
|
? undefined
|
||||||
|
: (backup) =>
|
||||||
html`${backup.name}
|
html`${backup.name}
|
||||||
<div class="secondary">${backup.path}</div>`,
|
<div class="secondary">${backup.path}</div>`,
|
||||||
},
|
},
|
||||||
|
path: {
|
||||||
|
title: localize("ui.panel.config.backup.path"),
|
||||||
|
hidden: !narrow,
|
||||||
|
},
|
||||||
size: {
|
size: {
|
||||||
title: localize("ui.panel.config.backup.size"),
|
title: localize("ui.panel.config.backup.size"),
|
||||||
width: "15%",
|
width: "15%",
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
filterable: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
template: (backup) => Math.ceil(backup.size * 10) / 10 + " MB",
|
template: (backup) => Math.ceil(backup.size * 10) / 10 + " MB",
|
||||||
@ -76,7 +81,6 @@ class HaConfigBackup extends LitElement {
|
|||||||
title: localize("ui.panel.config.backup.created"),
|
title: localize("ui.panel.config.backup.created"),
|
||||||
width: "15%",
|
width: "15%",
|
||||||
direction: "desc",
|
direction: "desc",
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
filterable: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
template: (backup) =>
|
template: (backup) =>
|
||||||
@ -87,6 +91,9 @@ class HaConfigBackup extends LitElement {
|
|||||||
title: "",
|
title: "",
|
||||||
width: "15%",
|
width: "15%",
|
||||||
type: "overflow-menu",
|
type: "overflow-menu",
|
||||||
|
showNarrow: true,
|
||||||
|
hideable: false,
|
||||||
|
moveable: false,
|
||||||
template: (backup) =>
|
template: (backup) =>
|
||||||
html`<ha-icon-overflow-menu
|
html`<ha-icon-overflow-menu
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
@ -107,6 +107,20 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
})
|
})
|
||||||
private _activeCollapsed?: string;
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "blueprint-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "blueprint-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
@storage({
|
@storage({
|
||||||
storage: "sessionStorage",
|
storage: "sessionStorage",
|
||||||
key: "blueprint-table-search",
|
key: "blueprint-table-search",
|
||||||
@ -154,8 +168,6 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
|
|
||||||
private _columns = memoizeOne(
|
private _columns = memoizeOne(
|
||||||
(
|
(
|
||||||
narrow,
|
|
||||||
_language,
|
|
||||||
localize: LocalizeFunc
|
localize: LocalizeFunc
|
||||||
): DataTableColumnContainer<BlueprintMetaDataPath> => ({
|
): DataTableColumnContainer<BlueprintMetaDataPath> => ({
|
||||||
name: {
|
name: {
|
||||||
@ -165,19 +177,12 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
filterable: true,
|
filterable: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
grows: true,
|
grows: true,
|
||||||
template: narrow
|
|
||||||
? (blueprint) => html`
|
|
||||||
${blueprint.name}<br />
|
|
||||||
<div class="secondary">${blueprint.path}</div>
|
|
||||||
`
|
|
||||||
: undefined,
|
|
||||||
},
|
},
|
||||||
translated_type: {
|
translated_type: {
|
||||||
title: localize("ui.panel.config.blueprint.overview.headers.type"),
|
title: localize("ui.panel.config.blueprint.overview.headers.type"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
groupable: true,
|
groupable: true,
|
||||||
hidden: narrow,
|
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
width: "10%",
|
width: "10%",
|
||||||
},
|
},
|
||||||
@ -185,7 +190,6 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
title: localize("ui.panel.config.blueprint.overview.headers.file_name"),
|
title: localize("ui.panel.config.blueprint.overview.headers.file_name"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
hidden: narrow,
|
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
width: "25%",
|
width: "25%",
|
||||||
},
|
},
|
||||||
@ -197,6 +201,9 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
title: "",
|
title: "",
|
||||||
width: this.narrow ? undefined : "10%",
|
width: this.narrow ? undefined : "10%",
|
||||||
type: "overflow-menu",
|
type: "overflow-menu",
|
||||||
|
showNarrow: true,
|
||||||
|
moveable: false,
|
||||||
|
hideable: false,
|
||||||
template: (blueprint) =>
|
template: (blueprint) =>
|
||||||
blueprint.error
|
blueprint.error
|
||||||
? html`<ha-svg-icon
|
? html`<ha-svg-icon
|
||||||
@ -280,11 +287,7 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
back-path="/config"
|
back-path="/config"
|
||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
.tabs=${configSections.automations}
|
.tabs=${configSections.automations}
|
||||||
.columns=${this._columns(
|
.columns=${this._columns(this.hass.localize)}
|
||||||
this.narrow,
|
|
||||||
this.hass.language,
|
|
||||||
this.hass.localize
|
|
||||||
)}
|
|
||||||
.data=${this._processedBlueprints(this.blueprints, this.hass.localize)}
|
.data=${this._processedBlueprints(this.blueprints, this.hass.localize)}
|
||||||
id="fullpath"
|
id="fullpath"
|
||||||
.noDataText=${this.hass.localize(
|
.noDataText=${this.hass.localize(
|
||||||
@ -313,6 +316,9 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
.initialGroupColumn=${this._activeGrouping}
|
.initialGroupColumn=${this._activeGrouping}
|
||||||
.initialCollapsedGroups=${this._activeCollapsed}
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@grouping-changed=${this._handleGroupingChanged}
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
@collapsed-changed=${this._handleCollapseChanged}
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
@ -556,6 +562,11 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
this._filter = ev.detail.value;
|
this._filter = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return haStyle;
|
return haStyle;
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,20 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
@storage({ key: "devices-table-collapsed", state: false, subscribe: false })
|
@storage({ key: "devices-table-collapsed", state: false, subscribe: false })
|
||||||
private _activeCollapsed?: string;
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "devices-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "devices-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
private _sizeController = new ResizeController(this, {
|
private _sizeController = new ResizeController(this, {
|
||||||
callback: (entries) => entries[0]?.contentRect.width,
|
callback: (entries) => entries[0]?.contentRect.width,
|
||||||
});
|
});
|
||||||
@ -434,10 +448,13 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
typeof this._devicesAndFilterDomains
|
typeof this._devicesAndFilterDomains
|
||||||
>["devicesOutput"][number];
|
>["devicesOutput"][number];
|
||||||
|
|
||||||
const columns: DataTableColumnContainer<DeviceItem> = {
|
return {
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
|
label: localize("ui.panel.config.devices.data_table.icon"),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
|
moveable: false,
|
||||||
|
showNarrow: true,
|
||||||
template: (device) =>
|
template: (device) =>
|
||||||
device.domains.length
|
device.domains.length
|
||||||
? html`<img
|
? html`<img
|
||||||
@ -452,19 +469,14 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
/>`
|
/>`
|
||||||
: "",
|
: "",
|
||||||
},
|
},
|
||||||
};
|
name: {
|
||||||
|
|
||||||
if (narrow) {
|
|
||||||
columns.name = {
|
|
||||||
title: localize("ui.panel.config.devices.data_table.device"),
|
title: localize("ui.panel.config.devices.data_table.device"),
|
||||||
main: true,
|
main: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (device) => html`
|
extraTemplate: (device) => html`
|
||||||
<div style="font-size: 14px;">${device.name}</div>
|
|
||||||
<div class="secondary">${device.area} | ${device.integration}</div>
|
|
||||||
${device.label_entries.length
|
${device.label_entries.length
|
||||||
? html`
|
? html`
|
||||||
<ha-data-table-labels
|
<ha-data-table-labels
|
||||||
@ -473,61 +485,37 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
`
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
`,
|
`,
|
||||||
};
|
},
|
||||||
} else {
|
manufacturer: {
|
||||||
columns.name = {
|
|
||||||
title: localize("ui.panel.config.devices.data_table.device"),
|
|
||||||
main: true,
|
|
||||||
sortable: true,
|
|
||||||
filterable: true,
|
|
||||||
direction: "asc",
|
|
||||||
grows: true,
|
|
||||||
template: (device) => html`
|
|
||||||
<div style="font-size: 14px;">${device.name}</div>
|
|
||||||
${device.label_entries.length
|
|
||||||
? html`
|
|
||||||
<ha-data-table-labels
|
|
||||||
.labels=${device.label_entries}
|
|
||||||
></ha-data-table-labels>
|
|
||||||
`
|
|
||||||
: nothing}
|
|
||||||
`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
columns.manufacturer = {
|
|
||||||
title: localize("ui.panel.config.devices.data_table.manufacturer"),
|
title: localize("ui.panel.config.devices.data_table.manufacturer"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
filterable: true,
|
||||||
groupable: true,
|
groupable: true,
|
||||||
width: "15%",
|
width: "15%",
|
||||||
};
|
},
|
||||||
columns.model = {
|
model: {
|
||||||
title: localize("ui.panel.config.devices.data_table.model"),
|
title: localize("ui.panel.config.devices.data_table.model"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
filterable: true,
|
||||||
width: "15%",
|
width: "15%",
|
||||||
};
|
},
|
||||||
columns.area = {
|
area: {
|
||||||
title: localize("ui.panel.config.devices.data_table.area"),
|
title: localize("ui.panel.config.devices.data_table.area"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
filterable: true,
|
||||||
groupable: true,
|
groupable: true,
|
||||||
width: "15%",
|
width: "15%",
|
||||||
};
|
},
|
||||||
columns.integration = {
|
integration: {
|
||||||
title: localize("ui.panel.config.devices.data_table.integration"),
|
title: localize("ui.panel.config.devices.data_table.integration"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
filterable: true,
|
||||||
groupable: true,
|
groupable: true,
|
||||||
width: "15%",
|
width: "15%",
|
||||||
};
|
},
|
||||||
columns.battery_entity = {
|
battery_entity: {
|
||||||
title: localize("ui.panel.config.devices.data_table.battery"),
|
title: localize("ui.panel.config.devices.data_table.battery"),
|
||||||
|
showNarrow: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
type: "numeric",
|
type: "numeric",
|
||||||
@ -540,7 +528,9 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
batteryEntityPair && batteryEntityPair[0]
|
batteryEntityPair && batteryEntityPair[0]
|
||||||
? this.hass.states[batteryEntityPair[0]]
|
? this.hass.states[batteryEntityPair[0]]
|
||||||
: undefined;
|
: undefined;
|
||||||
const batteryDomain = battery ? computeStateDomain(battery) : undefined;
|
const batteryDomain = battery
|
||||||
|
? computeStateDomain(battery)
|
||||||
|
: undefined;
|
||||||
const batteryCharging =
|
const batteryCharging =
|
||||||
batteryEntityPair && batteryEntityPair[1]
|
batteryEntityPair && batteryEntityPair[1]
|
||||||
? this.hass.states[batteryEntityPair[1]]
|
? this.hass.states[batteryEntityPair[1]]
|
||||||
@ -560,8 +550,8 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
`
|
`
|
||||||
: html`—`;
|
: html`—`;
|
||||||
},
|
},
|
||||||
};
|
},
|
||||||
columns.disabled_by = {
|
disabled_by: {
|
||||||
title: "",
|
title: "",
|
||||||
label: localize("ui.panel.config.devices.data_table.disabled_by"),
|
label: localize("ui.panel.config.devices.data_table.disabled_by"),
|
||||||
hidden: true,
|
hidden: true,
|
||||||
@ -569,16 +559,15 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
device.disabled_by
|
device.disabled_by
|
||||||
? this.hass.localize("ui.panel.config.devices.disabled")
|
? this.hass.localize("ui.panel.config.devices.disabled")
|
||||||
: "",
|
: "",
|
||||||
};
|
},
|
||||||
columns.labels = {
|
labels: {
|
||||||
title: "",
|
title: "",
|
||||||
hidden: true,
|
hidden: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
template: (device) =>
|
template: (device) =>
|
||||||
device.label_entries.map((lbl) => lbl.name).join(" "),
|
device.label_entries.map((lbl) => lbl.name).join(" "),
|
||||||
};
|
},
|
||||||
|
} as DataTableColumnContainer<DeviceItem>;
|
||||||
return columns;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
||||||
@ -704,6 +693,9 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
.initialGroupColumn=${this._activeGrouping}
|
.initialGroupColumn=${this._activeGrouping}
|
||||||
.initialCollapsedGroups=${this._activeCollapsed}
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@clear-filter=${this._clearFilter}
|
@clear-filter=${this._clearFilter}
|
||||||
@search-changed=${this._handleSearchChange}
|
@search-changed=${this._handleSearchChange}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@ -1043,6 +1035,11 @@ ${rejected
|
|||||||
this._activeCollapsed = ev.detail.value;
|
this._activeCollapsed = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
css`
|
css`
|
||||||
|
@ -186,6 +186,20 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
})
|
})
|
||||||
private _activeCollapsed?: string;
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "entities-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "entities-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
@query("hass-tabs-subpage-data-table", true)
|
@query("hass-tabs-subpage-data-table", true)
|
||||||
private _dataTable!: HaTabsSubpageDataTable;
|
private _dataTable!: HaTabsSubpageDataTable;
|
||||||
|
|
||||||
@ -251,15 +265,13 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
private _columns = memoize(
|
private _columns = memoize(
|
||||||
(
|
(localize: LocalizeFunc): DataTableColumnContainer<EntityRow> => ({
|
||||||
localize: LocalizeFunc,
|
|
||||||
narrow,
|
|
||||||
_language
|
|
||||||
): DataTableColumnContainer<EntityRow> => ({
|
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
label: localize("ui.panel.config.entities.picker.headers.state_icon"),
|
label: localize("ui.panel.config.entities.picker.headers.state_icon"),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
|
showNarrow: true,
|
||||||
|
moveable: false,
|
||||||
template: (entry) =>
|
template: (entry) =>
|
||||||
entry.icon
|
entry.icon
|
||||||
? html`<ha-icon .icon=${entry.icon}></ha-icon>`
|
? html`<ha-icon .icon=${entry.icon}></ha-icon>`
|
||||||
@ -283,32 +295,23 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
filterable: true,
|
filterable: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (entry) => html`
|
extraTemplate: (entry) =>
|
||||||
<div style="font-size: 14px;">${entry.name}</div>
|
entry.label_entries.length
|
||||||
${narrow
|
|
||||||
? html`<div class="secondary">
|
|
||||||
${entry.entity_id} | ${entry.localized_platform}
|
|
||||||
</div>`
|
|
||||||
: nothing}
|
|
||||||
${entry.label_entries.length
|
|
||||||
? html`
|
? html`
|
||||||
<ha-data-table-labels
|
<ha-data-table-labels
|
||||||
.labels=${entry.label_entries}
|
.labels=${entry.label_entries}
|
||||||
></ha-data-table-labels>
|
></ha-data-table-labels>
|
||||||
`
|
`
|
||||||
: nothing}
|
: nothing,
|
||||||
`,
|
|
||||||
},
|
},
|
||||||
entity_id: {
|
entity_id: {
|
||||||
title: localize("ui.panel.config.entities.picker.headers.entity_id"),
|
title: localize("ui.panel.config.entities.picker.headers.entity_id"),
|
||||||
hidden: narrow,
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
width: "25%",
|
width: "25%",
|
||||||
},
|
},
|
||||||
localized_platform: {
|
localized_platform: {
|
||||||
title: localize("ui.panel.config.entities.picker.headers.integration"),
|
title: localize("ui.panel.config.entities.picker.headers.integration"),
|
||||||
hidden: narrow,
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
groupable: true,
|
groupable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
@ -324,7 +327,6 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
area: {
|
area: {
|
||||||
title: localize("ui.panel.config.entities.picker.headers.area"),
|
title: localize("ui.panel.config.entities.picker.headers.area"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
filterable: true,
|
||||||
groupable: true,
|
groupable: true,
|
||||||
width: "15%",
|
width: "15%",
|
||||||
@ -343,6 +345,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
status: {
|
status: {
|
||||||
title: localize("ui.panel.config.entities.picker.headers.status"),
|
title: localize("ui.panel.config.entities.picker.headers.status"),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
|
showNarrow: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
width: "68px",
|
width: "68px",
|
||||||
@ -688,11 +691,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
.tabs=${configSections.devices}
|
.tabs=${configSections.devices}
|
||||||
.columns=${this._columns(
|
.columns=${this._columns(this.hass.localize)}
|
||||||
this.hass.localize,
|
|
||||||
this.narrow,
|
|
||||||
this.hass.language
|
|
||||||
)}
|
|
||||||
.data=${filteredEntities}
|
.data=${filteredEntities}
|
||||||
.searchLabel=${this.hass.localize(
|
.searchLabel=${this.hass.localize(
|
||||||
"ui.panel.config.entities.picker.search",
|
"ui.panel.config.entities.picker.search",
|
||||||
@ -714,6 +713,9 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
.initialGroupColumn=${this._activeGrouping}
|
.initialGroupColumn=${this._activeGrouping}
|
||||||
.initialCollapsedGroups=${this._activeCollapsed}
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@grouping-changed=${this._handleGroupingChanged}
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
@collapsed-changed=${this._handleCollapseChanged}
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
@ -1335,6 +1337,11 @@ ${rejected
|
|||||||
this._activeCollapsed = ev.detail.value;
|
this._activeCollapsed = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -167,6 +167,20 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
})
|
})
|
||||||
private _filter = "";
|
private _filter = "";
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "helpers-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "helpers-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
@state() private _stateItems: HassEntity[] = [];
|
@state() private _stateItems: HassEntity[] = [];
|
||||||
|
|
||||||
@state() private _entityEntries?: Record<string, EntityRegistryEntry>;
|
@state() private _entityEntries?: Record<string, EntityRegistryEntry>;
|
||||||
@ -243,14 +257,13 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _columns = memoizeOne(
|
private _columns = memoizeOne(
|
||||||
(
|
(localize: LocalizeFunc): DataTableColumnContainer<HelperItem> => ({
|
||||||
narrow: boolean,
|
|
||||||
localize: LocalizeFunc
|
|
||||||
): DataTableColumnContainer<HelperItem> => ({
|
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
label: localize("ui.panel.config.helpers.picker.headers.icon"),
|
label: localize("ui.panel.config.helpers.picker.headers.icon"),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
|
showNarrow: true,
|
||||||
|
moveable: false,
|
||||||
template: (helper) =>
|
template: (helper) =>
|
||||||
helper.entity
|
helper.entity
|
||||||
? html`<ha-state-icon
|
? html`<ha-state-icon
|
||||||
@ -269,23 +282,17 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
filterable: true,
|
filterable: true,
|
||||||
grows: true,
|
grows: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
template: (helper) => html`
|
extraTemplate: (helper) =>
|
||||||
<div style="font-size: 14px;">${helper.name}</div>
|
helper.label_entries.length
|
||||||
${narrow
|
|
||||||
? html`<div class="secondary">${helper.entity_id}</div> `
|
|
||||||
: nothing}
|
|
||||||
${helper.label_entries.length
|
|
||||||
? html`
|
? html`
|
||||||
<ha-data-table-labels
|
<ha-data-table-labels
|
||||||
.labels=${helper.label_entries}
|
.labels=${helper.label_entries}
|
||||||
></ha-data-table-labels>
|
></ha-data-table-labels>
|
||||||
`
|
`
|
||||||
: nothing}
|
: nothing,
|
||||||
`,
|
|
||||||
},
|
},
|
||||||
entity_id: {
|
entity_id: {
|
||||||
title: localize("ui.panel.config.helpers.picker.headers.entity_id"),
|
title: localize("ui.panel.config.helpers.picker.headers.entity_id"),
|
||||||
hidden: this.narrow,
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
width: "25%",
|
width: "25%",
|
||||||
@ -313,10 +320,9 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
},
|
},
|
||||||
editable: {
|
editable: {
|
||||||
title: "",
|
title: "",
|
||||||
label: this.hass.localize(
|
label: localize("ui.panel.config.helpers.picker.headers.editable"),
|
||||||
"ui.panel.config.helpers.picker.headers.editable"
|
|
||||||
),
|
|
||||||
type: "icon",
|
type: "icon",
|
||||||
|
showNarrow: true,
|
||||||
template: (helper) => html`
|
template: (helper) => html`
|
||||||
${!helper.editable
|
${!helper.editable
|
||||||
? html`
|
? html`
|
||||||
@ -337,8 +343,12 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
title: "",
|
title: "",
|
||||||
|
label: "Actions",
|
||||||
width: "64px",
|
width: "64px",
|
||||||
type: "overflow-menu",
|
type: "overflow-menu",
|
||||||
|
hideable: false,
|
||||||
|
moveable: false,
|
||||||
|
showNarrow: true,
|
||||||
template: (helper) => html`
|
template: (helper) => html`
|
||||||
<ha-icon-overflow-menu
|
<ha-icon-overflow-menu
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -556,11 +566,14 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
Array.isArray(val) ? val.length : val
|
Array.isArray(val) ? val.length : val
|
||||||
)
|
)
|
||||||
).length}
|
).length}
|
||||||
.columns=${this._columns(this.narrow, this.hass.localize)}
|
.columns=${this._columns(this.hass.localize)}
|
||||||
.data=${helpers}
|
.data=${helpers}
|
||||||
.initialGroupColumn=${this._activeGrouping || "category"}
|
.initialGroupColumn=${this._activeGrouping || "category"}
|
||||||
.initialCollapsedGroups=${this._activeCollapsed}
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@grouping-changed=${this._handleGroupingChanged}
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
@collapsed-changed=${this._handleCollapseChanged}
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
@ -1084,6 +1097,11 @@ ${rejected
|
|||||||
this._filter = ev.detail.value;
|
this._filter = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -66,10 +66,26 @@ export class HaConfigLabels extends LitElement {
|
|||||||
})
|
})
|
||||||
private _activeSorting?: SortingChangedEvent;
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "labels-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "labels-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
private _columns = memoizeOne((localize: LocalizeFunc) => {
|
private _columns = memoizeOne((localize: LocalizeFunc) => {
|
||||||
const columns: DataTableColumnContainer<LabelRegistryEntry> = {
|
const columns: DataTableColumnContainer<LabelRegistryEntry> = {
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
|
moveable: false,
|
||||||
|
showNarrow: true,
|
||||||
label: localize("ui.panel.config.labels.headers.icon"),
|
label: localize("ui.panel.config.labels.headers.icon"),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
template: (label) =>
|
template: (label) =>
|
||||||
@ -77,6 +93,7 @@ export class HaConfigLabels extends LitElement {
|
|||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
title: "",
|
title: "",
|
||||||
|
showNarrow: true,
|
||||||
label: localize("ui.panel.config.labels.headers.color"),
|
label: localize("ui.panel.config.labels.headers.color"),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
template: (label) =>
|
template: (label) =>
|
||||||
@ -105,6 +122,9 @@ export class HaConfigLabels extends LitElement {
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
title: "",
|
title: "",
|
||||||
|
showNarrow: true,
|
||||||
|
moveable: false,
|
||||||
|
hideable: false,
|
||||||
width: "64px",
|
width: "64px",
|
||||||
type: "overflow-menu",
|
type: "overflow-menu",
|
||||||
template: (label) => html`
|
template: (label) => html`
|
||||||
@ -167,6 +187,9 @@ export class HaConfigLabels extends LitElement {
|
|||||||
.noDataText=${this.hass.localize("ui.panel.config.labels.no_labels")}
|
.noDataText=${this.hass.localize("ui.panel.config.labels.no_labels")}
|
||||||
hasFab
|
hasFab
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
@search-changed=${this._handleSearchChange}
|
@search-changed=${this._handleSearchChange}
|
||||||
@ -297,6 +320,11 @@ export class HaConfigLabels extends LitElement {
|
|||||||
private _handleSearchChange(ev: CustomEvent) {
|
private _handleSearchChange(ev: CustomEvent) {
|
||||||
this._filter = ev.detail.value;
|
this._filter = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -85,6 +85,20 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
})
|
})
|
||||||
private _activeSorting?: SortingChangedEvent;
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "lovelace-dashboards-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "lovelace-dashboards-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
public willUpdate() {
|
public willUpdate() {
|
||||||
if (!this.hasUpdated) {
|
if (!this.hasUpdated) {
|
||||||
this.hass.loadFragmentTranslation("lovelace");
|
this.hass.loadFragmentTranslation("lovelace");
|
||||||
@ -101,6 +115,8 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
const columns: DataTableColumnContainer<DataTableItem> = {
|
const columns: DataTableColumnContainer<DataTableItem> = {
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
|
moveable: false,
|
||||||
|
showNarrow: true,
|
||||||
label: localize(
|
label: localize(
|
||||||
"ui.panel.config.lovelace.dashboards.picker.headers.icon"
|
"ui.panel.config.lovelace.dashboards.picker.headers.icon"
|
||||||
),
|
),
|
||||||
@ -128,8 +144,9 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (dashboard) => {
|
template: narrow
|
||||||
const titleTemplate = html`
|
? undefined
|
||||||
|
: (dashboard) => html`
|
||||||
${dashboard.title}
|
${dashboard.title}
|
||||||
${dashboard.default
|
${dashboard.default
|
||||||
? html`
|
? html`
|
||||||
@ -144,24 +161,10 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
</simple-tooltip>
|
</simple-tooltip>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
`;
|
`,
|
||||||
return narrow
|
|
||||||
? html`
|
|
||||||
${titleTemplate}
|
|
||||||
<div class="secondary">
|
|
||||||
${this.hass.localize(
|
|
||||||
`ui.panel.config.lovelace.dashboards.conf_mode.${dashboard.mode}`
|
|
||||||
)}${dashboard.filename
|
|
||||||
? html` – ${dashboard.filename} `
|
|
||||||
: ""}
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: titleTemplate;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!narrow) {
|
|
||||||
columns.mode = {
|
columns.mode = {
|
||||||
title: localize(
|
title: localize(
|
||||||
"ui.panel.config.lovelace.dashboards.picker.headers.conf_mode"
|
"ui.panel.config.lovelace.dashboards.picker.headers.conf_mode"
|
||||||
@ -191,6 +194,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
),
|
),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
type: "icon",
|
type: "icon",
|
||||||
|
hidden: narrow,
|
||||||
width: "100px",
|
width: "100px",
|
||||||
template: (dashboard) =>
|
template: (dashboard) =>
|
||||||
dashboard.require_admin
|
dashboard.require_admin
|
||||||
@ -202,13 +206,13 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
"ui.panel.config.lovelace.dashboards.picker.headers.sidebar"
|
"ui.panel.config.lovelace.dashboards.picker.headers.sidebar"
|
||||||
),
|
),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
|
hidden: narrow,
|
||||||
width: "121px",
|
width: "121px",
|
||||||
template: (dashboard) =>
|
template: (dashboard) =>
|
||||||
dashboard.show_in_sidebar
|
dashboard.show_in_sidebar
|
||||||
? html`<ha-svg-icon .path=${mdiCheck}></ha-svg-icon>`
|
? html`<ha-svg-icon .path=${mdiCheck}></ha-svg-icon>`
|
||||||
: html`—`,
|
: html`—`,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
columns.url_path = {
|
columns.url_path = {
|
||||||
title: "",
|
title: "",
|
||||||
@ -216,6 +220,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
"ui.panel.config.lovelace.dashboards.picker.headers.url"
|
"ui.panel.config.lovelace.dashboards.picker.headers.url"
|
||||||
),
|
),
|
||||||
filterable: true,
|
filterable: true,
|
||||||
|
showNarrow: true,
|
||||||
width: "100px",
|
width: "100px",
|
||||||
template: (dashboard) =>
|
template: (dashboard) =>
|
||||||
narrow
|
narrow
|
||||||
@ -311,6 +316,9 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
)}
|
)}
|
||||||
.data=${this._getItems(this._dashboards)}
|
.data=${this._getItems(this._dashboards)}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
@search-changed=${this._handleSearchChange}
|
@search-changed=${this._handleSearchChange}
|
||||||
@ -467,6 +475,11 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
private _handleSearchChange(ev: CustomEvent) {
|
private _handleSearchChange(ev: CustomEvent) {
|
||||||
this._filter = ev.detail.value;
|
this._filter = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -67,12 +67,27 @@ export class HaConfigLovelaceRescources extends LitElement {
|
|||||||
})
|
})
|
||||||
private _activeSorting?: SortingChangedEvent;
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "lovelace-resources-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "lovelace-resources-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
private _columns = memoize(
|
private _columns = memoize(
|
||||||
(
|
(
|
||||||
_language,
|
_language,
|
||||||
localize: LocalizeFunc
|
localize: LocalizeFunc
|
||||||
): DataTableColumnContainer<LovelaceResource> => ({
|
): DataTableColumnContainer<LovelaceResource> => ({
|
||||||
url: {
|
url: {
|
||||||
|
main: true,
|
||||||
title: localize(
|
title: localize(
|
||||||
"ui.panel.config.lovelace.resources.picker.headers.url"
|
"ui.panel.config.lovelace.resources.picker.headers.url"
|
||||||
),
|
),
|
||||||
@ -145,6 +160,9 @@ export class HaConfigLovelaceRescources extends LitElement {
|
|||||||
"ui.panel.config.lovelace.resources.picker.no_resources"
|
"ui.panel.config.lovelace.resources.picker.no_resources"
|
||||||
)}
|
)}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
@search-changed=${this._handleSearchChange}
|
@search-changed=${this._handleSearchChange}
|
||||||
@ -266,6 +284,11 @@ export class HaConfigLovelaceRescources extends LitElement {
|
|||||||
this._filter = ev.detail.value;
|
this._filter = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -180,6 +180,20 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
})
|
})
|
||||||
private _activeCollapsed?: string;
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "scene-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "scene-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
private _sizeController = new ResizeController(this, {
|
private _sizeController = new ResizeController(this, {
|
||||||
callback: (entries) => entries[0]?.contentRect.width,
|
callback: (entries) => entries[0]?.contentRect.width,
|
||||||
});
|
});
|
||||||
@ -225,11 +239,13 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private _columns = memoizeOne(
|
private _columns = memoizeOne(
|
||||||
(narrow, localize: LocalizeFunc): DataTableColumnContainer => {
|
(localize: LocalizeFunc): DataTableColumnContainer => {
|
||||||
const columns: DataTableColumnContainer<SceneItem> = {
|
const columns: DataTableColumnContainer<SceneItem> = {
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
label: localize("ui.panel.config.scene.picker.headers.state"),
|
label: localize("ui.panel.config.scene.picker.headers.state"),
|
||||||
|
moveable: false,
|
||||||
|
showNarrow: true,
|
||||||
type: "icon",
|
type: "icon",
|
||||||
template: (scene) => html`
|
template: (scene) => html`
|
||||||
<ha-state-icon
|
<ha-state-icon
|
||||||
@ -245,15 +261,13 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
filterable: true,
|
filterable: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (scene) => html`
|
extraTemplate: (scene) =>
|
||||||
<div style="font-size: 14px;">${scene.name}</div>
|
scene.labels.length
|
||||||
${scene.labels.length
|
|
||||||
? html`<ha-data-table-labels
|
? html`<ha-data-table-labels
|
||||||
@label-clicked=${this._labelClicked}
|
@label-clicked=${this._labelClicked}
|
||||||
.labels=${scene.labels}
|
.labels=${scene.labels}
|
||||||
></ha-data-table-labels>`
|
></ha-data-table-labels>`
|
||||||
: nothing}
|
: nothing,
|
||||||
`,
|
|
||||||
},
|
},
|
||||||
area: {
|
area: {
|
||||||
title: localize("ui.panel.config.scene.picker.headers.area"),
|
title: localize("ui.panel.config.scene.picker.headers.area"),
|
||||||
@ -281,7 +295,6 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
),
|
),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
width: "30%",
|
width: "30%",
|
||||||
hidden: narrow,
|
|
||||||
template: (scene) => {
|
template: (scene) => {
|
||||||
const lastActivated = scene.state;
|
const lastActivated = scene.state;
|
||||||
if (!lastActivated || isUnavailableState(lastActivated)) {
|
if (!lastActivated || isUnavailableState(lastActivated)) {
|
||||||
@ -300,6 +313,7 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
only_editable: {
|
only_editable: {
|
||||||
title: "",
|
title: "",
|
||||||
width: "56px",
|
width: "56px",
|
||||||
|
showNarrow: true,
|
||||||
template: (scene) =>
|
template: (scene) =>
|
||||||
!scene.attributes.id
|
!scene.attributes.id
|
||||||
? html`
|
? html`
|
||||||
@ -319,6 +333,9 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
title: "",
|
title: "",
|
||||||
width: "64px",
|
width: "64px",
|
||||||
type: "overflow-menu",
|
type: "overflow-menu",
|
||||||
|
showNarrow: true,
|
||||||
|
moveable: false,
|
||||||
|
hideable: false,
|
||||||
template: (scene) => html`
|
template: (scene) => html`
|
||||||
<ha-icon-overflow-menu
|
<ha-icon-overflow-menu
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -536,11 +553,14 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
Array.isArray(val) ? val.length : val
|
Array.isArray(val) ? val.length : val
|
||||||
)
|
)
|
||||||
).length}
|
).length}
|
||||||
.columns=${this._columns(this.narrow, this.hass.localize)}
|
.columns=${this._columns(this.hass.localize)}
|
||||||
id="entity_id"
|
id="entity_id"
|
||||||
.initialGroupColumn=${this._activeGrouping || "category"}
|
.initialGroupColumn=${this._activeGrouping || "category"}
|
||||||
.initialCollapsedGroups=${this._activeCollapsed}
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@grouping-changed=${this._handleGroupingChanged}
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
@collapsed-changed=${this._handleCollapseChanged}
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
@ -1155,6 +1175,11 @@ ${rejected
|
|||||||
this._filter = ev.detail.value;
|
this._filter = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -184,6 +184,20 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
})
|
})
|
||||||
private _activeCollapsed?: string;
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "script-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "script-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
private _sizeController = new ResizeController(this, {
|
private _sizeController = new ResizeController(this, {
|
||||||
callback: (entries) => entries[0]?.contentRect.width,
|
callback: (entries) => entries[0]?.contentRect.width,
|
||||||
});
|
});
|
||||||
@ -232,14 +246,12 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private _columns = memoizeOne(
|
private _columns = memoizeOne(
|
||||||
(
|
(localize: LocalizeFunc): DataTableColumnContainer<ScriptItem> => {
|
||||||
narrow,
|
|
||||||
localize: LocalizeFunc,
|
|
||||||
locale: HomeAssistant["locale"]
|
|
||||||
): DataTableColumnContainer<ScriptItem> => {
|
|
||||||
const columns: DataTableColumnContainer = {
|
const columns: DataTableColumnContainer = {
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
|
showNarrow: true,
|
||||||
|
moveable: false,
|
||||||
label: localize("ui.panel.config.script.picker.headers.state"),
|
label: localize("ui.panel.config.script.picker.headers.state"),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
template: (script) =>
|
template: (script) =>
|
||||||
@ -259,30 +271,13 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
filterable: true,
|
filterable: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (script) => {
|
extraTemplate: (script) =>
|
||||||
const date = new Date(script.last_triggered);
|
script.labels.length
|
||||||
const now = new Date();
|
|
||||||
const dayDifference = differenceInDays(now, date);
|
|
||||||
return html`
|
|
||||||
<div style="font-size: 14px;">${script.name}</div>
|
|
||||||
${narrow
|
|
||||||
? html`<div class="secondary">
|
|
||||||
${this.hass.localize("ui.card.automation.last_triggered")}:
|
|
||||||
${script.attributes.last_triggered
|
|
||||||
? dayDifference > 3
|
|
||||||
? formatShortDateTime(date, locale, this.hass.config)
|
|
||||||
: relativeTime(date, locale)
|
|
||||||
: localize("ui.components.relative_time.never")}
|
|
||||||
</div>`
|
|
||||||
: nothing}
|
|
||||||
${script.labels.length
|
|
||||||
? html`<ha-data-table-labels
|
? html`<ha-data-table-labels
|
||||||
@label-clicked=${this._labelClicked}
|
@label-clicked=${this._labelClicked}
|
||||||
.labels=${script.labels}
|
.labels=${script.labels}
|
||||||
></ha-data-table-labels>`
|
></ha-data-table-labels>`
|
||||||
: nothing}
|
: nothing,
|
||||||
`;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
area: {
|
area: {
|
||||||
title: localize("ui.panel.config.script.picker.headers.area"),
|
title: localize("ui.panel.config.script.picker.headers.area"),
|
||||||
@ -305,7 +300,6 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
template: (script) => script.labels.map((lbl) => lbl.name).join(" "),
|
template: (script) => script.labels.map((lbl) => lbl.name).join(" "),
|
||||||
},
|
},
|
||||||
last_triggered: {
|
last_triggered: {
|
||||||
hidden: narrow,
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
width: "40%",
|
width: "40%",
|
||||||
title: localize("ui.card.automation.last_triggered"),
|
title: localize("ui.card.automation.last_triggered"),
|
||||||
@ -330,6 +324,9 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
title: "",
|
title: "",
|
||||||
width: "64px",
|
width: "64px",
|
||||||
type: "overflow-menu",
|
type: "overflow-menu",
|
||||||
|
showNarrow: true,
|
||||||
|
moveable: false,
|
||||||
|
hideable: false,
|
||||||
template: (script) => html`
|
template: (script) => html`
|
||||||
<ha-icon-overflow-menu
|
<ha-icon-overflow-menu
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -539,6 +536,9 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
.initialGroupColumn=${this._activeGrouping || "category"}
|
.initialGroupColumn=${this._activeGrouping || "category"}
|
||||||
.initialCollapsedGroups=${this._activeCollapsed}
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@grouping-changed=${this._handleGroupingChanged}
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
@collapsed-changed=${this._handleCollapseChanged}
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
@ -553,11 +553,7 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
Array.isArray(val) ? val.length : val
|
Array.isArray(val) ? val.length : val
|
||||||
)
|
)
|
||||||
).length}
|
).length}
|
||||||
.columns=${this._columns(
|
.columns=${this._columns(this.hass.localize)}
|
||||||
this.narrow,
|
|
||||||
this.hass.localize,
|
|
||||||
this.hass.locale
|
|
||||||
)}
|
|
||||||
.data=${scripts}
|
.data=${scripts}
|
||||||
.empty=${!this.scripts.length}
|
.empty=${!this.scripts.length}
|
||||||
.activeFilters=${this._activeFilters}
|
.activeFilters=${this._activeFilters}
|
||||||
@ -1270,6 +1266,11 @@ ${rejected
|
|||||||
this._activeCollapsed = ev.detail.value;
|
this._activeCollapsed = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -66,11 +66,12 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
})
|
})
|
||||||
private _filter = "";
|
private _filter = "";
|
||||||
|
|
||||||
private _columns = memoizeOne(
|
private _columns = memoizeOne((localize: LocalizeFunc) => {
|
||||||
(narrow: boolean, _language, localize: LocalizeFunc) => {
|
|
||||||
const columns: DataTableColumnContainer<TagRowData> = {
|
const columns: DataTableColumnContainer<TagRowData> = {
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
|
moveable: false,
|
||||||
|
showNarrow: true,
|
||||||
label: localize("ui.panel.config.tag.headers.icon"),
|
label: localize("ui.panel.config.tag.headers.icon"),
|
||||||
type: "icon",
|
type: "icon",
|
||||||
template: (tag) => html`<tag-image .tag=${tag}></tag-image>`,
|
template: (tag) => html`<tag-image .tag=${tag}></tag-image>`,
|
||||||
@ -81,24 +82,10 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (tag) =>
|
|
||||||
html`${tag.display_name}
|
|
||||||
${narrow
|
|
||||||
? html`<div class="secondary">
|
|
||||||
${tag.last_scanned_datetime
|
|
||||||
? html`<ha-relative-time
|
|
||||||
.hass=${this.hass}
|
|
||||||
.datetime=${tag.last_scanned_datetime}
|
|
||||||
capitalize
|
|
||||||
></ha-relative-time>`
|
|
||||||
: this.hass.localize("ui.panel.config.tag.never_scanned")}
|
|
||||||
</div>`
|
|
||||||
: ""}`,
|
|
||||||
},
|
},
|
||||||
last_scanned_datetime: {
|
last_scanned_datetime: {
|
||||||
title: localize("ui.panel.config.tag.headers.last_scanned"),
|
title: localize("ui.panel.config.tag.headers.last_scanned"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
hidden: narrow,
|
|
||||||
direction: "desc",
|
direction: "desc",
|
||||||
width: "20%",
|
width: "20%",
|
||||||
template: (tag) => html`
|
template: (tag) => html`
|
||||||
@ -117,8 +104,9 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
title: "",
|
title: "",
|
||||||
label: localize("ui.panel.config.tag.headers.write"),
|
label: localize("ui.panel.config.tag.headers.write"),
|
||||||
type: "icon-button",
|
type: "icon-button",
|
||||||
|
showNarrow: true,
|
||||||
template: (tag) =>
|
template: (tag) =>
|
||||||
html` <ha-icon-button
|
html`<ha-icon-button
|
||||||
.tag=${tag}
|
.tag=${tag}
|
||||||
@click=${this._handleWriteClick}
|
@click=${this._handleWriteClick}
|
||||||
.label=${this.hass.localize("ui.panel.config.tag.write")}
|
.label=${this.hass.localize("ui.panel.config.tag.write")}
|
||||||
@ -129,21 +117,23 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
columns.automation = {
|
columns.automation = {
|
||||||
title: "",
|
title: "",
|
||||||
type: "icon-button",
|
type: "icon-button",
|
||||||
|
showNarrow: true,
|
||||||
template: (tag) =>
|
template: (tag) =>
|
||||||
html` <ha-icon-button
|
html`<ha-icon-button
|
||||||
.tag=${tag}
|
.tag=${tag}
|
||||||
@click=${this._handleAutomationClick}
|
@click=${this._handleAutomationClick}
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize("ui.panel.config.tag.create_automation")}
|
||||||
"ui.panel.config.tag.create_automation"
|
|
||||||
)}
|
|
||||||
.path=${mdiRobot}
|
.path=${mdiRobot}
|
||||||
></ha-icon-button>`,
|
></ha-icon-button>`,
|
||||||
};
|
};
|
||||||
columns.edit = {
|
columns.edit = {
|
||||||
title: "",
|
title: "",
|
||||||
type: "icon-button",
|
type: "icon-button",
|
||||||
|
showNarrow: true,
|
||||||
|
hideable: false,
|
||||||
|
moveable: false,
|
||||||
template: (tag) =>
|
template: (tag) =>
|
||||||
html` <ha-icon-button
|
html`<ha-icon-button
|
||||||
.tag=${tag}
|
.tag=${tag}
|
||||||
@click=${this._handleEditClick}
|
@click=${this._handleEditClick}
|
||||||
.label=${this.hass.localize("ui.panel.config.tag.edit")}
|
.label=${this.hass.localize("ui.panel.config.tag.edit")}
|
||||||
@ -151,8 +141,7 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
></ha-icon-button>`,
|
></ha-icon-button>`,
|
||||||
};
|
};
|
||||||
return columns;
|
return columns;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
private _data = memoizeOne((tags: Tag[]): TagRowData[] =>
|
private _data = memoizeOne((tags: Tag[]): TagRowData[] =>
|
||||||
tags.map((tag) => ({
|
tags.map((tag) => ({
|
||||||
@ -191,11 +180,7 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
back-path="/config"
|
back-path="/config"
|
||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
.tabs=${configSections.tags}
|
.tabs=${configSections.tags}
|
||||||
.columns=${this._columns(
|
.columns=${this._columns(this.hass.localize)}
|
||||||
this.narrow,
|
|
||||||
this.hass.language,
|
|
||||||
this.hass.localize
|
|
||||||
)}
|
|
||||||
.data=${this._data(this._tags)}
|
.data=${this._data(this._tags)}
|
||||||
.noDataText=${this.hass.localize("ui.panel.config.tag.no_tags")}
|
.noDataText=${this.hass.localize("ui.panel.config.tag.no_tags")}
|
||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
|
@ -46,6 +46,20 @@ export class HaConfigUsers extends LitElement {
|
|||||||
@storage({ key: "users-table-grouping", state: false, subscribe: false })
|
@storage({ key: "users-table-grouping", state: false, subscribe: false })
|
||||||
private _activeGrouping?: string;
|
private _activeGrouping?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "users-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "users-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
@storage({
|
@storage({
|
||||||
storage: "sessionStorage",
|
storage: "sessionStorage",
|
||||||
key: "users-table-search",
|
key: "users-table-search",
|
||||||
@ -72,17 +86,6 @@ export class HaConfigUsers extends LitElement {
|
|||||||
width: "25%",
|
width: "25%",
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (user) =>
|
|
||||||
narrow
|
|
||||||
? html` ${user.name}<br />
|
|
||||||
<div class="secondary">
|
|
||||||
${user.username ? `${user.username} |` : ""}
|
|
||||||
${localize(`groups.${user.group_ids[0]}`)}
|
|
||||||
</div>`
|
|
||||||
: html` ${user.name ||
|
|
||||||
this.hass!.localize(
|
|
||||||
"ui.panel.config.users.editor.unnamed_user"
|
|
||||||
)}`,
|
|
||||||
},
|
},
|
||||||
username: {
|
username: {
|
||||||
title: localize("ui.panel.config.users.picker.headers.username"),
|
title: localize("ui.panel.config.users.picker.headers.username"),
|
||||||
@ -90,7 +93,6 @@ export class HaConfigUsers extends LitElement {
|
|||||||
filterable: true,
|
filterable: true,
|
||||||
width: "20%",
|
width: "20%",
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
hidden: narrow,
|
|
||||||
template: (user) => html`${user.username || "—"}`,
|
template: (user) => html`${user.username || "—"}`,
|
||||||
},
|
},
|
||||||
group: {
|
group: {
|
||||||
@ -100,7 +102,6 @@ export class HaConfigUsers extends LitElement {
|
|||||||
groupable: true,
|
groupable: true,
|
||||||
width: "20%",
|
width: "20%",
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
hidden: narrow,
|
|
||||||
},
|
},
|
||||||
is_active: {
|
is_active: {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
@ -154,6 +155,7 @@ export class HaConfigUsers extends LitElement {
|
|||||||
filterable: false,
|
filterable: false,
|
||||||
width: "104px",
|
width: "104px",
|
||||||
hidden: !narrow,
|
hidden: !narrow,
|
||||||
|
showNarrow: true,
|
||||||
template: (user) => {
|
template: (user) => {
|
||||||
const badges = computeUserBadges(this.hass, user, false);
|
const badges = computeUserBadges(this.hass, user, false);
|
||||||
return html`${badges.map(
|
return html`${badges.map(
|
||||||
@ -186,6 +188,9 @@ export class HaConfigUsers extends LitElement {
|
|||||||
.tabs=${configSections.persons}
|
.tabs=${configSections.persons}
|
||||||
.columns=${this._columns(this.narrow, this.hass.localize)}
|
.columns=${this._columns(this.narrow, this.hass.localize)}
|
||||||
.data=${this._userData(this._users, this.hass.localize)}
|
.data=${this._userData(this._users, this.hass.localize)}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
.initialGroupColumn=${this._activeGrouping}
|
.initialGroupColumn=${this._activeGrouping}
|
||||||
.initialCollapsedGroups=${this._activeCollapsed}
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
@ -213,6 +218,7 @@ export class HaConfigUsers extends LitElement {
|
|||||||
private _userData = memoizeOne((users: User[], localize: LocalizeFunc) =>
|
private _userData = memoizeOne((users: User[], localize: LocalizeFunc) =>
|
||||||
users.map((user) => ({
|
users.map((user) => ({
|
||||||
...user,
|
...user,
|
||||||
|
name: user.name || localize("ui.panel.config.users.editor.unnamed_user"),
|
||||||
group: localize(`groups.${user.group_ids[0]}`),
|
group: localize(`groups.${user.group_ids[0]}`),
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
@ -302,6 +308,11 @@ export class HaConfigUsers extends LitElement {
|
|||||||
private _handleSearchChange(ev: CustomEvent) {
|
private _handleSearchChange(ev: CustomEvent) {
|
||||||
this._filter = ev.detail.value;
|
this._filter = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -118,6 +118,20 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
})
|
})
|
||||||
private _activeCollapsed?: string;
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "voice-expose-table-column-order",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeColumnOrder?: string[];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "voice-expose-table-hidden-columns",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeHiddenColumns?: string[];
|
||||||
|
|
||||||
@query("hass-tabs-subpage-data-table", true)
|
@query("hass-tabs-subpage-data-table", true)
|
||||||
private _dataTable!: HaTabsSubpageDataTable;
|
private _dataTable!: HaTabsSubpageDataTable;
|
||||||
|
|
||||||
@ -137,6 +151,7 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
type: "icon",
|
type: "icon",
|
||||||
|
moveable: false,
|
||||||
hidden: narrow,
|
hidden: narrow,
|
||||||
template: (entry) => html`
|
template: (entry) => html`
|
||||||
<ha-state-icon
|
<ha-state-icon
|
||||||
@ -153,11 +168,21 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
filterable: true,
|
filterable: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
grows: true,
|
grows: true,
|
||||||
template: (entry) => html`
|
template: narrow
|
||||||
|
? undefined
|
||||||
|
: (entry) => html`
|
||||||
${entry.name}<br />
|
${entry.name}<br />
|
||||||
<div class="secondary">${entry.entity_id}</div>
|
<div class="secondary">${entry.entity_id}</div>
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
// For search & narrow
|
||||||
|
entity_id: {
|
||||||
|
title: localize(
|
||||||
|
"ui.panel.config.voice_assistants.expose.headers.entity_id"
|
||||||
|
),
|
||||||
|
hidden: !narrow,
|
||||||
|
filterable: true,
|
||||||
|
},
|
||||||
domain: {
|
domain: {
|
||||||
title: localize(
|
title: localize(
|
||||||
"ui.panel.config.voice_assistants.expose.headers.domain"
|
"ui.panel.config.voice_assistants.expose.headers.domain"
|
||||||
@ -171,7 +196,6 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
title: localize("ui.panel.config.voice_assistants.expose.headers.area"),
|
title: localize("ui.panel.config.voice_assistants.expose.headers.area"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
groupable: true,
|
groupable: true,
|
||||||
hidden: narrow,
|
|
||||||
filterable: true,
|
filterable: true,
|
||||||
width: "15%",
|
width: "15%",
|
||||||
},
|
},
|
||||||
@ -179,6 +203,7 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
title: localize(
|
title: localize(
|
||||||
"ui.panel.config.voice_assistants.expose.headers.assistants"
|
"ui.panel.config.voice_assistants.expose.headers.assistants"
|
||||||
),
|
),
|
||||||
|
showNarrow: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
width: "160px",
|
width: "160px",
|
||||||
@ -208,7 +233,6 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
),
|
),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
hidden: narrow,
|
|
||||||
width: "15%",
|
width: "15%",
|
||||||
template: (entry) =>
|
template: (entry) =>
|
||||||
entry.aliases.length === 0
|
entry.aliases.length === 0
|
||||||
@ -230,12 +254,6 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
.path=${mdiCloseCircleOutline}
|
.path=${mdiCloseCircleOutline}
|
||||||
></ha-icon-button>`,
|
></ha-icon-button>`,
|
||||||
},
|
},
|
||||||
// For search
|
|
||||||
entity_id: {
|
|
||||||
title: "",
|
|
||||||
hidden: true,
|
|
||||||
filterable: true,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -552,6 +570,9 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
.initialSorting=${this._activeSorting}
|
.initialSorting=${this._activeSorting}
|
||||||
.initialGroupColumn=${this._activeGrouping}
|
.initialGroupColumn=${this._activeGrouping}
|
||||||
.initialCollapsedGroups=${this._activeCollapsed}
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
|
.columnOrder=${this._activeColumnOrder}
|
||||||
|
.hiddenColumns=${this._activeHiddenColumns}
|
||||||
|
@columns-changed=${this._handleColumnsChanged}
|
||||||
@sorting-changed=${this._handleSortingChanged}
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@selection-changed=${this._handleSelectionChanged}
|
@selection-changed=${this._handleSelectionChanged}
|
||||||
@grouping-changed=${this._handleGroupingChanged}
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
@ -757,6 +778,11 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
this._activeCollapsed = ev.detail.value;
|
this._activeCollapsed = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleColumnsChanged(ev: CustomEvent) {
|
||||||
|
this._activeColumnOrder = ev.detail.columnOrder;
|
||||||
|
this._activeHiddenColumns = ev.detail.hiddenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -530,7 +530,8 @@
|
|||||||
"selected": "Selected {selected}",
|
"selected": "Selected {selected}",
|
||||||
"close_select_mode": "Close selection mode",
|
"close_select_mode": "Close selection mode",
|
||||||
"select_all": "Select all",
|
"select_all": "Select all",
|
||||||
"select_none": "Select none"
|
"select_none": "Select none",
|
||||||
|
"settings": "Customize table"
|
||||||
},
|
},
|
||||||
"config-entry-picker": {
|
"config-entry-picker": {
|
||||||
"config_entry": "Integration"
|
"config_entry": "Integration"
|
||||||
@ -799,7 +800,14 @@
|
|||||||
"filtering_by": "Filtering by",
|
"filtering_by": "Filtering by",
|
||||||
"hidden": "{number} hidden",
|
"hidden": "{number} hidden",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
"ungrouped": "Ungrouped"
|
"ungrouped": "Ungrouped",
|
||||||
|
"settings": {
|
||||||
|
"header": "Customize",
|
||||||
|
"hide": "Hide column {title}",
|
||||||
|
"show": "Show column {title}",
|
||||||
|
"done": "Done",
|
||||||
|
"restore": "Restore defaults"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
"tts": {
|
"tts": {
|
||||||
@ -2071,6 +2079,7 @@
|
|||||||
"download_backup": "[%key:supervisor::backup::download_backup%]",
|
"download_backup": "[%key:supervisor::backup::download_backup%]",
|
||||||
"remove_backup": "[%key:supervisor::backup::delete_backup_title%]",
|
"remove_backup": "[%key:supervisor::backup::delete_backup_title%]",
|
||||||
"name": "[%key:supervisor::backup::name%]",
|
"name": "[%key:supervisor::backup::name%]",
|
||||||
|
"path": "Path",
|
||||||
"size": "[%key:supervisor::backup::size%]",
|
"size": "[%key:supervisor::backup::size%]",
|
||||||
"created": "[%key:supervisor::backup::created%]",
|
"created": "[%key:supervisor::backup::created%]",
|
||||||
"no_backups": "[%key:supervisor::backup::no_backups%]",
|
"no_backups": "[%key:supervisor::backup::no_backups%]",
|
||||||
@ -2665,6 +2674,7 @@
|
|||||||
"caption": "Expose",
|
"caption": "Expose",
|
||||||
"headers": {
|
"headers": {
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
"entity_id": "Entity ID",
|
||||||
"area": "Area",
|
"area": "Area",
|
||||||
"domain": "Domain",
|
"domain": "Domain",
|
||||||
"assistants": "Assistants",
|
"assistants": "Assistants",
|
||||||
@ -4040,6 +4050,7 @@
|
|||||||
"update_device_error": "Updating the device failed",
|
"update_device_error": "Updating the device failed",
|
||||||
"disabled": "Disabled",
|
"disabled": "Disabled",
|
||||||
"data_table": {
|
"data_table": {
|
||||||
|
"icon": "Icon",
|
||||||
"device": "Device",
|
"device": "Device",
|
||||||
"manufacturer": "Manufacturer",
|
"manufacturer": "Manufacturer",
|
||||||
"model": "Model",
|
"model": "Model",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user