Add created/modified to registry tables (#21494)
parent
a85dda3365
commit
4ade39543d
|
@ -82,6 +82,8 @@ export class HaDemo extends HomeAssistantAppEl {
|
|||
has_entity_name: false,
|
||||
unique_id: "co2_intensity",
|
||||
options: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
config_entry_id: "co2signal",
|
||||
|
@ -100,6 +102,8 @@ export class HaDemo extends HomeAssistantAppEl {
|
|||
has_entity_name: false,
|
||||
unique_id: "grid_fossil_fuel_percentage",
|
||||
options: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import { getEntity } from "../../../../src/fake_data/entity";
|
|||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||
import { HomeAssistant } from "../../../../src/types";
|
||||
import "../../components/demo-black-white-row";
|
||||
import { DeviceRegistryEntry } from "../../../../src/data/device_registry";
|
||||
|
||||
const ENTITIES = [
|
||||
getEntity("alarm_control_panel", "alarm", "disarmed", {
|
||||
|
@ -41,7 +42,7 @@ const ENTITIES = [
|
|||
}),
|
||||
];
|
||||
|
||||
const DEVICES = [
|
||||
const DEVICES: DeviceRegistryEntry[] = [
|
||||
{
|
||||
area_id: "bedroom",
|
||||
configuration_url: null,
|
||||
|
@ -61,6 +62,8 @@ const DEVICES = [
|
|||
via_device_id: null,
|
||||
serial_number: null,
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
area_id: "backyard",
|
||||
|
@ -81,6 +84,8 @@ const DEVICES = [
|
|||
via_device_id: null,
|
||||
serial_number: null,
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
area_id: null,
|
||||
|
@ -101,6 +106,8 @@ const DEVICES = [
|
|||
via_device_id: null,
|
||||
serial_number: null,
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -113,6 +120,8 @@ const AREAS: AreaRegistryEntry[] = [
|
|||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
area_id: "bedroom",
|
||||
|
@ -122,6 +131,8 @@ const AREAS: AreaRegistryEntry[] = [
|
|||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
area_id: "livingroom",
|
||||
|
@ -131,6 +142,8 @@ const AREAS: AreaRegistryEntry[] = [
|
|||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import { FloorRegistryEntry } from "../../../../src/data/floor_registry";
|
|||
import { LabelRegistryEntry } from "../../../../src/data/label_registry";
|
||||
import { mockFloorRegistry } from "../../../../demo/src/stubs/floor_registry";
|
||||
import { mockLabelRegistry } from "../../../../demo/src/stubs/label_registry";
|
||||
import { DeviceRegistryEntry } from "../../../../src/data/device_registry";
|
||||
|
||||
const ENTITIES = [
|
||||
getEntity("alarm_control_panel", "alarm", "disarmed", {
|
||||
|
@ -41,7 +42,7 @@ const ENTITIES = [
|
|||
}),
|
||||
];
|
||||
|
||||
const DEVICES = [
|
||||
const DEVICES: DeviceRegistryEntry[] = [
|
||||
{
|
||||
area_id: "bedroom",
|
||||
configuration_url: null,
|
||||
|
@ -61,6 +62,8 @@ const DEVICES = [
|
|||
via_device_id: null,
|
||||
serial_number: null,
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
area_id: "backyard",
|
||||
|
@ -81,6 +84,8 @@ const DEVICES = [
|
|||
via_device_id: null,
|
||||
serial_number: null,
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
area_id: null,
|
||||
|
@ -101,6 +106,8 @@ const DEVICES = [
|
|||
via_device_id: null,
|
||||
serial_number: null,
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -113,6 +120,8 @@ const AREAS: AreaRegistryEntry[] = [
|
|||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
area_id: "bedroom",
|
||||
|
@ -122,6 +131,8 @@ const AREAS: AreaRegistryEntry[] = [
|
|||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
area_id: "livingroom",
|
||||
|
@ -131,6 +142,8 @@ const AREAS: AreaRegistryEntry[] = [
|
|||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -141,6 +154,8 @@ const FLOORS: FloorRegistryEntry[] = [
|
|||
level: 0,
|
||||
icon: null,
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
floor_id: "first",
|
||||
|
@ -148,6 +163,8 @@ const FLOORS: FloorRegistryEntry[] = [
|
|||
level: 1,
|
||||
icon: "mdi:numeric-1",
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
floor_id: "second",
|
||||
|
@ -155,6 +172,8 @@ const FLOORS: FloorRegistryEntry[] = [
|
|||
level: 2,
|
||||
icon: "mdi:numeric-2",
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -165,6 +184,8 @@ const LABELS: LabelRegistryEntry[] = [
|
|||
icon: null,
|
||||
color: "yellow",
|
||||
description: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
{
|
||||
label_id: "entertainment",
|
||||
|
@ -172,6 +193,8 @@ const LABELS: LabelRegistryEntry[] = [
|
|||
icon: "mdi:popcorn",
|
||||
color: "blue",
|
||||
description: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -358,13 +358,11 @@ export class DemoEntityState extends LitElement {
|
|||
},
|
||||
entity_id: {
|
||||
title: "Entity ID",
|
||||
width: "30%",
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
},
|
||||
state: {
|
||||
title: "State",
|
||||
width: "20%",
|
||||
sortable: true,
|
||||
template: (entry) =>
|
||||
html`${computeStateDisplay(
|
||||
|
@ -379,14 +377,12 @@ export class DemoEntityState extends LitElement {
|
|||
device_class: {
|
||||
title: "Device class",
|
||||
template: (entry) => html`${entry.device_class ?? "-"}`,
|
||||
width: "20%",
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
},
|
||||
domain: {
|
||||
title: "Domain",
|
||||
template: (entry) => html`${computeDomain(entry.entity_id)}`,
|
||||
width: "20%",
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
},
|
||||
|
|
|
@ -203,6 +203,8 @@ const createEntityRegistryEntries = (
|
|||
options: null,
|
||||
labels: [],
|
||||
categories: {},
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -228,6 +230,8 @@ const createDeviceRegistryEntries = (
|
|||
disabled_by: null,
|
||||
configuration_url: null,
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -127,14 +127,13 @@ export class HassioBackups extends LitElement {
|
|||
main: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
flex: 2,
|
||||
template: (backup) =>
|
||||
html`${backup.name || backup.slug}
|
||||
<div class="secondary">${backup.secondary}</div>`,
|
||||
},
|
||||
size: {
|
||||
title: this.supervisor.localize("backup.size"),
|
||||
width: "15%",
|
||||
hidden: narrow,
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
|
@ -142,7 +141,6 @@ export class HassioBackups extends LitElement {
|
|||
},
|
||||
location: {
|
||||
title: this.supervisor.localize("backup.location"),
|
||||
width: "15%",
|
||||
hidden: narrow,
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
|
@ -151,7 +149,6 @@ export class HassioBackups extends LitElement {
|
|||
},
|
||||
date: {
|
||||
title: this.supervisor.localize("backup.created"),
|
||||
width: "15%",
|
||||
direction: "desc",
|
||||
hidden: narrow,
|
||||
filterable: true,
|
||||
|
|
|
@ -85,9 +85,9 @@ export interface DataTableColumnData<T = any> extends DataTableSortColumnData {
|
|||
| "flex";
|
||||
template?: (row: T) => TemplateResult | string | typeof nothing;
|
||||
extraTemplate?: (row: T) => TemplateResult | string | typeof nothing;
|
||||
width?: string;
|
||||
minWidth?: string;
|
||||
maxWidth?: string;
|
||||
grows?: boolean;
|
||||
flex?: number;
|
||||
forceLTR?: boolean;
|
||||
hidden?: boolean;
|
||||
}
|
||||
|
@ -216,6 +216,18 @@ export class HaDataTable extends LitElement {
|
|||
this.updateComplete.then(() => this._calcTableHeight());
|
||||
}
|
||||
|
||||
protected updated() {
|
||||
const header = this.renderRoot.querySelector(".mdc-data-table__header-row");
|
||||
if (!header) {
|
||||
return;
|
||||
}
|
||||
if (header.scrollWidth > header.clientWidth) {
|
||||
this.style.setProperty("--table-row-width", `${header.scrollWidth}px`);
|
||||
} else {
|
||||
this.style.removeProperty("--table-row-width");
|
||||
}
|
||||
}
|
||||
|
||||
public willUpdate(properties: PropertyValues) {
|
||||
super.willUpdate(properties);
|
||||
|
||||
|
@ -355,7 +367,12 @@ export class HaDataTable extends LitElement {
|
|||
: `calc(100% - ${this._headerHeight}px)`,
|
||||
})}
|
||||
>
|
||||
<div class="mdc-data-table__header-row" role="row" aria-rowindex="1">
|
||||
<div
|
||||
class="mdc-data-table__header-row"
|
||||
role="row"
|
||||
aria-rowindex="1"
|
||||
@scroll=${this._scrollContent}
|
||||
>
|
||||
<slot name="header-row">
|
||||
${this.selectable
|
||||
? html`
|
||||
|
@ -398,18 +415,16 @@ export class HaDataTable extends LitElement {
|
|||
column.type === "overflow",
|
||||
sortable: Boolean(column.sortable),
|
||||
"not-sorted": Boolean(column.sortable && !sorted),
|
||||
grows: Boolean(column.grows),
|
||||
};
|
||||
return html`
|
||||
<div
|
||||
aria-label=${ifDefined(column.label)}
|
||||
class="mdc-data-table__header-cell ${classMap(classes)}"
|
||||
style=${column.width
|
||||
? styleMap({
|
||||
[column.grows ? "minWidth" : "width"]: column.width,
|
||||
maxWidth: column.maxWidth || "",
|
||||
})
|
||||
: ""}
|
||||
style=${styleMap({
|
||||
minWidth: column.minWidth,
|
||||
maxWidth: column.maxWidth,
|
||||
flex: column.flex || 1,
|
||||
})}
|
||||
role="columnheader"
|
||||
aria-sort=${ifDefined(
|
||||
sorted
|
||||
|
@ -538,15 +553,13 @@ export class HaDataTable extends LitElement {
|
|||
"mdc-data-table__cell--overflow-menu":
|
||||
column.type === "overflow-menu",
|
||||
"mdc-data-table__cell--overflow": column.type === "overflow",
|
||||
grows: Boolean(column.grows),
|
||||
forceLTR: Boolean(column.forceLTR),
|
||||
})}"
|
||||
style=${column.width
|
||||
? styleMap({
|
||||
[column.grows ? "minWidth" : "width"]: column.width,
|
||||
maxWidth: column.maxWidth ? column.maxWidth : "",
|
||||
})
|
||||
: ""}
|
||||
style=${styleMap({
|
||||
minWidth: column.minWidth,
|
||||
maxWidth: column.maxWidth,
|
||||
flex: column.flex || 1,
|
||||
})}
|
||||
>
|
||||
${column.template
|
||||
? column.template(row)
|
||||
|
@ -815,6 +828,17 @@ export class HaDataTable extends LitElement {
|
|||
@eventOptions({ passive: true })
|
||||
private _saveScrollPos(e: Event) {
|
||||
this._savedScrollPos = (e.target as HTMLDivElement).scrollTop;
|
||||
|
||||
this.renderRoot.querySelector(".mdc-data-table__header-row")!.scrollLeft = (
|
||||
e.target as HTMLDivElement
|
||||
).scrollLeft;
|
||||
}
|
||||
|
||||
@eventOptions({ passive: true })
|
||||
private _scrollContent(e: Event) {
|
||||
this.renderRoot.querySelector("lit-virtualizer")!.scrollLeft = (
|
||||
e.target as HTMLDivElement
|
||||
).scrollLeft;
|
||||
}
|
||||
|
||||
private _collapseGroup = (ev: Event) => {
|
||||
|
@ -889,8 +913,8 @@ export class HaDataTable extends LitElement {
|
|||
|
||||
.mdc-data-table__row {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: var(--data-table-row-height, 52px);
|
||||
width: var(--table-row-width, 100%);
|
||||
}
|
||||
|
||||
.mdc-data-table__row ~ .mdc-data-table__row {
|
||||
|
@ -914,18 +938,26 @@ export class HaDataTable extends LitElement {
|
|||
.mdc-data-table__header-row {
|
||||
height: 56px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.mdc-data-table__header-row::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for IE, Edge and Firefox */
|
||||
.mdc-data-table__header-row {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
.mdc-data-table__cell,
|
||||
.mdc-data-table__header-cell {
|
||||
padding-right: 16px;
|
||||
padding-left: 16px;
|
||||
min-width: 150px;
|
||||
align-self: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
@ -973,6 +1005,8 @@ export class HaDataTable extends LitElement {
|
|||
letter-spacing: 0.0178571429em;
|
||||
text-decoration: inherit;
|
||||
text-transform: inherit;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mdc-data-table__cell a {
|
||||
|
@ -991,7 +1025,8 @@ export class HaDataTable extends LitElement {
|
|||
|
||||
.mdc-data-table__header-cell--icon,
|
||||
.mdc-data-table__cell--icon {
|
||||
width: 54px;
|
||||
min-width: 64px;
|
||||
flex: 0 0 64px !important;
|
||||
}
|
||||
|
||||
.mdc-data-table__cell--icon img {
|
||||
|
@ -1031,11 +1066,14 @@ export class HaDataTable extends LitElement {
|
|||
.mdc-data-table__header-cell--overflow-menu,
|
||||
.mdc-data-table__header-cell--icon-button,
|
||||
.mdc-data-table__cell--icon-button {
|
||||
min-width: 64px;
|
||||
flex: 0 0 64px !important;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.mdc-data-table__header-cell--icon-button,
|
||||
.mdc-data-table__cell--icon-button {
|
||||
min-width: 56px;
|
||||
width: 56px;
|
||||
}
|
||||
|
||||
|
|
|
@ -279,6 +279,8 @@ export class HaAreaPicker extends LitElement {
|
|||
icon: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -295,6 +297,8 @@ export class HaAreaPicker extends LitElement {
|
|||
icon: "mdi:plus",
|
||||
aliases: [],
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -377,6 +381,8 @@ export class HaAreaPicker extends LitElement {
|
|||
picture: null,
|
||||
labels: [],
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
] as AreaRegistryEntry[];
|
||||
} else {
|
||||
|
@ -393,6 +399,8 @@ export class HaAreaPicker extends LitElement {
|
|||
picture: null,
|
||||
labels: [],
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
] as AreaRegistryEntry[];
|
||||
}
|
||||
|
|
|
@ -295,6 +295,8 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
icon: null,
|
||||
level: null,
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -309,6 +311,8 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
icon: "mdi:plus",
|
||||
level: null,
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -391,6 +395,8 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
icon: null,
|
||||
level: null,
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
] as FloorRegistryEntry[];
|
||||
} else {
|
||||
|
@ -405,6 +411,8 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
icon: "mdi:plus",
|
||||
level: null,
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
] as FloorRegistryEntry[];
|
||||
}
|
||||
|
|
|
@ -303,6 +303,8 @@ export class HaLabelPicker extends SubscribeMixin(LitElement) {
|
|||
icon: null,
|
||||
color: null,
|
||||
description: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -317,6 +319,8 @@ export class HaLabelPicker extends SubscribeMixin(LitElement) {
|
|||
icon: "mdi:plus",
|
||||
color: null,
|
||||
description: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@ import { stringCompare } from "../common/string/compare";
|
|||
import { HomeAssistant } from "../types";
|
||||
import { DeviceRegistryEntry } from "./device_registry";
|
||||
import { EntityRegistryEntry } from "./entity_registry";
|
||||
import { RegistryEntry } from "./registry";
|
||||
|
||||
export { subscribeAreaRegistry } from "./ws-area_registry";
|
||||
|
||||
export interface AreaRegistryEntry {
|
||||
export interface AreaRegistryEntry extends RegistryEntry {
|
||||
area_id: string;
|
||||
floor_id: string | null;
|
||||
name: string;
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
import { computeStateName } from "../common/entity/compute_state_name";
|
||||
import { caseInsensitiveStringCompare } from "../common/string/compare";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import { ConfigEntry } from "./config_entries";
|
||||
import type {
|
||||
EntityRegistryDisplayEntry,
|
||||
EntityRegistryEntry,
|
||||
} from "./entity_registry";
|
||||
import { ConfigEntry } from "./config_entries";
|
||||
import type { EntitySources } from "./entity_sources";
|
||||
import { RegistryEntry } from "./registry";
|
||||
|
||||
export {
|
||||
fetchDeviceRegistry,
|
||||
subscribeDeviceRegistry,
|
||||
} from "./ws-device_registry";
|
||||
|
||||
export interface DeviceRegistryEntry {
|
||||
export interface DeviceRegistryEntry extends RegistryEntry {
|
||||
id: string;
|
||||
config_entries: string[];
|
||||
connections: Array<[string, string]>;
|
||||
|
|
|
@ -7,6 +7,7 @@ import { debounce } from "../common/util/debounce";
|
|||
import { HomeAssistant } from "../types";
|
||||
import { LightColor } from "./light";
|
||||
import { computeDomain } from "../common/entity/compute_domain";
|
||||
import { RegistryEntry } from "./registry";
|
||||
|
||||
export { subscribeEntityRegistryDisplay } from "./ws-entity_registry_display";
|
||||
|
||||
|
@ -43,7 +44,7 @@ export interface EntityRegistryDisplayEntryResponse {
|
|||
entity_categories: Record<number, EntityCategory>;
|
||||
}
|
||||
|
||||
export interface EntityRegistryEntry {
|
||||
export interface EntityRegistryEntry extends RegistryEntry {
|
||||
id: string;
|
||||
entity_id: string;
|
||||
name: string | null;
|
||||
|
|
|
@ -4,10 +4,11 @@ import { stringCompare } from "../common/string/compare";
|
|||
import { debounce } from "../common/util/debounce";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { AreaRegistryEntry } from "./area_registry";
|
||||
import { RegistryEntry } from "./registry";
|
||||
|
||||
export { subscribeAreaRegistry } from "./ws-area_registry";
|
||||
|
||||
export interface FloorRegistryEntry {
|
||||
export interface FloorRegistryEntry extends RegistryEntry {
|
||||
floor_id: string;
|
||||
name: string;
|
||||
level: number | null;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { Connection, createCollection } from "home-assistant-js-websocket";
|
||||
import { Store } from "home-assistant-js-websocket/dist/store";
|
||||
import { stringCompare } from "../common/string/compare";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { debounce } from "../common/util/debounce";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { RegistryEntry } from "./registry";
|
||||
|
||||
export interface LabelRegistryEntry {
|
||||
export interface LabelRegistryEntry extends RegistryEntry {
|
||||
label_id: string;
|
||||
name: string;
|
||||
icon: string | null;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export interface RegistryEntry {
|
||||
created_at: number;
|
||||
modified_at: number;
|
||||
}
|
|
@ -87,14 +87,13 @@ export class HaConfigApplicationCredentials extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
client_id: {
|
||||
title: localize(
|
||||
"ui.panel.config.application_credentials.picker.headers.client_id"
|
||||
),
|
||||
filterable: true,
|
||||
width: "30%",
|
||||
},
|
||||
localizedDomain: {
|
||||
title: localize(
|
||||
|
@ -102,12 +101,10 @@ export class HaConfigApplicationCredentials extends LitElement {
|
|||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "30%",
|
||||
direction: "asc",
|
||||
},
|
||||
actions: {
|
||||
title: "",
|
||||
width: "64px",
|
||||
type: "overflow-menu",
|
||||
showNarrow: true,
|
||||
hideable: false,
|
||||
|
|
|
@ -288,7 +288,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
extraTemplate: (automation) =>
|
||||
automation.labels.length
|
||||
? html`<ha-data-table-labels
|
||||
|
@ -320,7 +320,6 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||
},
|
||||
last_triggered: {
|
||||
sortable: true,
|
||||
width: "130px",
|
||||
title: localize("ui.card.automation.last_triggered"),
|
||||
template: (automation) => {
|
||||
if (!automation.last_triggered) {
|
||||
|
@ -337,7 +336,8 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||
},
|
||||
},
|
||||
formatted_state: {
|
||||
width: "82px",
|
||||
minWidth: "82px",
|
||||
maxWidth: "82px",
|
||||
sortable: true,
|
||||
groupable: true,
|
||||
hidden: narrow,
|
||||
|
@ -353,7 +353,6 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||
},
|
||||
actions: {
|
||||
title: "",
|
||||
width: "64px",
|
||||
type: "icon-button",
|
||||
showNarrow: true,
|
||||
moveable: false,
|
||||
|
|
|
@ -59,7 +59,7 @@ class HaConfigBackup extends LitElement {
|
|||
main: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
flex: 2,
|
||||
template: narrow
|
||||
? undefined
|
||||
: (backup) =>
|
||||
|
@ -72,14 +72,12 @@ class HaConfigBackup extends LitElement {
|
|||
},
|
||||
size: {
|
||||
title: localize("ui.panel.config.backup.size"),
|
||||
width: "15%",
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
template: (backup) => Math.ceil(backup.size * 10) / 10 + " MB",
|
||||
},
|
||||
date: {
|
||||
title: localize("ui.panel.config.backup.created"),
|
||||
width: "15%",
|
||||
direction: "desc",
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
|
@ -89,7 +87,6 @@ class HaConfigBackup extends LitElement {
|
|||
|
||||
actions: {
|
||||
title: "",
|
||||
width: "15%",
|
||||
type: "overflow-menu",
|
||||
showNarrow: true,
|
||||
hideable: false,
|
||||
|
|
|
@ -176,7 +176,7 @@ class HaBlueprintOverview extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
translated_type: {
|
||||
title: localize("ui.panel.config.blueprint.overview.headers.type"),
|
||||
|
@ -184,14 +184,13 @@ class HaBlueprintOverview extends LitElement {
|
|||
filterable: true,
|
||||
groupable: true,
|
||||
direction: "asc",
|
||||
width: "10%",
|
||||
},
|
||||
path: {
|
||||
title: localize("ui.panel.config.blueprint.overview.headers.file_name"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
width: "25%",
|
||||
flex: 2,
|
||||
},
|
||||
fullpath: {
|
||||
title: "fullpath",
|
||||
|
@ -199,7 +198,6 @@ class HaBlueprintOverview extends LitElement {
|
|||
},
|
||||
actions: {
|
||||
title: "",
|
||||
width: this.narrow ? undefined : "10%",
|
||||
type: "overflow-menu",
|
||||
showNarrow: true,
|
||||
moveable: false,
|
||||
|
|
|
@ -22,6 +22,7 @@ import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
|||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { computeCssColor } from "../../../common/color/compute-color";
|
||||
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
|
@ -58,6 +59,11 @@ import "../../../components/ha-sub-menu";
|
|||
import { createAreaRegistryEntry } from "../../../data/area_registry";
|
||||
import { ConfigEntry, sortConfigEntries } from "../../../data/config_entries";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import {
|
||||
DataTableFilters,
|
||||
deserializeFilters,
|
||||
serializeFilters,
|
||||
} from "../../../data/data_table_filters";
|
||||
import {
|
||||
DeviceEntityLookup,
|
||||
DeviceRegistryEntry,
|
||||
|
@ -75,6 +81,7 @@ import {
|
|||
createLabelRegistryEntry,
|
||||
subscribeLabelRegistry,
|
||||
} from "../../../data/label_registry";
|
||||
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
|
@ -85,12 +92,6 @@ import { configSections } from "../ha-panel-config";
|
|||
import "../integrations/ha-integration-overflow-menu";
|
||||
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
|
||||
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
||||
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import {
|
||||
serializeFilters,
|
||||
deserializeFilters,
|
||||
DataTableFilters,
|
||||
} from "../../../data/data_table_filters";
|
||||
|
||||
interface DeviceRowData extends DeviceRegistryEntry {
|
||||
device?: DeviceRowData;
|
||||
|
@ -443,7 +444,7 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||
}
|
||||
);
|
||||
|
||||
private _columns = memoizeOne((localize: LocalizeFunc, narrow: boolean) => {
|
||||
private _columns = memoizeOne((localize: LocalizeFunc) => {
|
||||
type DeviceItem = ReturnType<
|
||||
typeof this._devicesAndFilterDomains
|
||||
>["devicesOutput"][number];
|
||||
|
@ -476,6 +477,8 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
minWidth: "150px",
|
||||
extraTemplate: (device) => html`
|
||||
${device.label_entries.length
|
||||
? html`
|
||||
|
@ -491,27 +494,27 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
groupable: true,
|
||||
width: "15%",
|
||||
minWidth: "120px",
|
||||
},
|
||||
model: {
|
||||
title: localize("ui.panel.config.devices.data_table.model"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "15%",
|
||||
minWidth: "120px",
|
||||
},
|
||||
area: {
|
||||
title: localize("ui.panel.config.devices.data_table.area"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
groupable: true,
|
||||
width: "15%",
|
||||
minWidth: "120px",
|
||||
},
|
||||
integration: {
|
||||
title: localize("ui.panel.config.devices.data_table.integration"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
groupable: true,
|
||||
width: "15%",
|
||||
minWidth: "120px",
|
||||
},
|
||||
battery_entity: {
|
||||
title: localize("ui.panel.config.devices.data_table.battery"),
|
||||
|
@ -519,8 +522,8 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
type: "numeric",
|
||||
width: narrow ? "105px" : "15%",
|
||||
maxWidth: "105px",
|
||||
maxWidth: "101px",
|
||||
minWidth: "101px",
|
||||
valueColumn: "battery_level",
|
||||
template: (device) => {
|
||||
const batteryEntityPair = device.battery_entity;
|
||||
|
@ -548,9 +551,39 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||
.batteryChargingStateObj=${batteryCharging}
|
||||
></ha-battery-icon>
|
||||
`
|
||||
: html`—`;
|
||||
: "—";
|
||||
},
|
||||
},
|
||||
created_at: {
|
||||
title: localize("ui.panel.config.generic.headers.created_at"),
|
||||
defaultHidden: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
minWidth: "128px",
|
||||
template: (entry) =>
|
||||
entry.created_at
|
||||
? formatShortDateTime(
|
||||
new Date(entry.created_at * 1000),
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)
|
||||
: "—",
|
||||
},
|
||||
modified_at: {
|
||||
title: localize("ui.panel.config.generic.headers.modified_at"),
|
||||
defaultHidden: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
minWidth: "128px",
|
||||
template: (entry) =>
|
||||
entry.modified_at
|
||||
? formatShortDateTime(
|
||||
new Date(entry.modified_at * 1000),
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)
|
||||
: "—",
|
||||
},
|
||||
disabled_by: {
|
||||
title: "",
|
||||
label: localize("ui.panel.config.devices.data_table.disabled_by"),
|
||||
|
@ -675,7 +708,7 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||
"ui.panel.config.devices.picker.search",
|
||||
{ number: devicesOutput.length }
|
||||
)}
|
||||
.columns=${this._columns(this.hass.localize, this.narrow)}
|
||||
.columns=${this._columns(this.hass.localize)}
|
||||
.data=${devicesOutput}
|
||||
selectable
|
||||
.selected=${this._selected.length}
|
||||
|
|
|
@ -103,6 +103,7 @@ import {
|
|||
deserializeFilters,
|
||||
DataTableFilters,
|
||||
} from "../../../data/data_table_filters";
|
||||
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
||||
|
||||
export interface StateEntity
|
||||
extends Omit<EntityRegistryEntry, "id" | "unique_id"> {
|
||||
|
@ -294,7 +295,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
extraTemplate: (entry) =>
|
||||
entry.label_entries.length
|
||||
? html`
|
||||
|
@ -308,14 +309,12 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||
title: localize("ui.panel.config.entities.picker.headers.entity_id"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "25%",
|
||||
},
|
||||
localized_platform: {
|
||||
title: localize("ui.panel.config.entities.picker.headers.integration"),
|
||||
sortable: true,
|
||||
groupable: true,
|
||||
filterable: true,
|
||||
width: "20%",
|
||||
},
|
||||
domain: {
|
||||
title: localize("ui.panel.config.entities.picker.headers.domain"),
|
||||
|
@ -329,7 +328,6 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
groupable: true,
|
||||
width: "15%",
|
||||
},
|
||||
disabled_by: {
|
||||
title: localize("ui.panel.config.entities.picker.headers.disabled_by"),
|
||||
|
@ -348,7 +346,6 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||
showNarrow: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "68px",
|
||||
template: (entry) =>
|
||||
entry.unavailable ||
|
||||
entry.disabled_by ||
|
||||
|
@ -398,6 +395,36 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||
`
|
||||
: "—",
|
||||
},
|
||||
created_at: {
|
||||
title: localize("ui.panel.config.generic.headers.created_at"),
|
||||
defaultHidden: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
minWidth: "128px",
|
||||
template: (entry) =>
|
||||
entry.created_at
|
||||
? formatShortDateTime(
|
||||
new Date(entry.created_at * 1000),
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)
|
||||
: "—",
|
||||
},
|
||||
modified_at: {
|
||||
title: localize("ui.panel.config.generic.headers.modified_at"),
|
||||
defaultHidden: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
minWidth: "128px",
|
||||
template: (entry) =>
|
||||
entry.modified_at
|
||||
? formatShortDateTime(
|
||||
new Date(entry.modified_at * 1000),
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)
|
||||
: "—",
|
||||
},
|
||||
available: {
|
||||
title: localize("ui.panel.config.entities.picker.headers.availability"),
|
||||
sortable: true,
|
||||
|
@ -1081,6 +1108,8 @@ ${
|
|||
options: null,
|
||||
labels: [],
|
||||
categories: {},
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
});
|
||||
}
|
||||
if (changed) {
|
||||
|
|
|
@ -280,7 +280,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||
main: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
flex: 2,
|
||||
direction: "asc",
|
||||
extraTemplate: (helper) =>
|
||||
helper.label_entries.length
|
||||
|
@ -295,7 +295,6 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||
title: localize("ui.panel.config.helpers.picker.headers.entity_id"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "25%",
|
||||
},
|
||||
category: {
|
||||
title: localize("ui.panel.config.helpers.picker.headers.category"),
|
||||
|
@ -314,7 +313,6 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||
localized_type: {
|
||||
title: localize("ui.panel.config.helpers.picker.headers.type"),
|
||||
sortable: true,
|
||||
width: "25%",
|
||||
filterable: true,
|
||||
groupable: true,
|
||||
},
|
||||
|
@ -344,7 +342,6 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||
actions: {
|
||||
title: "",
|
||||
label: "Actions",
|
||||
width: "64px",
|
||||
type: "overflow-menu",
|
||||
hideable: false,
|
||||
moveable: false,
|
||||
|
|
|
@ -44,7 +44,7 @@ export class ZHAClustersDataTable extends LitElement {
|
|||
title: "Name",
|
||||
sortable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
}
|
||||
: {
|
||||
|
@ -52,18 +52,16 @@ export class ZHAClustersDataTable extends LitElement {
|
|||
title: "Name",
|
||||
sortable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
id: {
|
||||
title: "ID",
|
||||
template: (cluster) => html` ${formatAsPaddedHex(cluster.id)} `,
|
||||
sortable: true,
|
||||
width: "25%",
|
||||
},
|
||||
endpoint_id: {
|
||||
title: "Endpoint ID",
|
||||
sortable: true,
|
||||
width: "15%",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -65,7 +65,7 @@ export class ZHADeviceEndpointDataTable extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
template: (device) => html`
|
||||
<a href=${`/config/devices/device/${device.dev_id}`}>
|
||||
${device.name}
|
||||
|
@ -84,7 +84,7 @@ export class ZHADeviceEndpointDataTable extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
template: (device) => html`
|
||||
<a href=${`/config/devices/device/${device.dev_id}`}>
|
||||
${device.name}
|
||||
|
@ -100,7 +100,7 @@ export class ZHADeviceEndpointDataTable extends LitElement {
|
|||
title: "Associated Entities",
|
||||
sortable: false,
|
||||
filterable: false,
|
||||
width: "50%",
|
||||
flex: 2,
|
||||
template: (device) => html`
|
||||
${device.entities.length
|
||||
? device.entities.length > 3
|
||||
|
|
|
@ -69,14 +69,13 @@ class ZHADeviceNeighbors extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
lqi: {
|
||||
title: this.hass.localize("ui.panel.config.zha.neighbors.lqi"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
type: "numeric",
|
||||
width: "75px",
|
||||
},
|
||||
}
|
||||
: {
|
||||
|
@ -85,14 +84,13 @@ class ZHADeviceNeighbors extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
lqi: {
|
||||
title: this.hass.localize("ui.panel.config.zha.neighbors.lqi"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
type: "numeric",
|
||||
width: "75px",
|
||||
},
|
||||
relationship: {
|
||||
title: this.hass.localize(
|
||||
|
@ -100,14 +98,12 @@ class ZHADeviceNeighbors extends LitElement {
|
|||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "150px",
|
||||
},
|
||||
depth: {
|
||||
title: this.hass.localize("ui.panel.config.zha.neighbors.depth"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
type: "numeric",
|
||||
width: "75px",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -79,7 +79,7 @@ export class ZHAGroupsDashboard extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
}
|
||||
: {
|
||||
|
@ -88,19 +88,17 @@ export class ZHAGroupsDashboard extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
group_id: {
|
||||
title: this.hass.localize("ui.panel.config.zha.groups.group_id"),
|
||||
type: "numeric",
|
||||
width: "15%",
|
||||
template: (group) => html` ${formatAsPaddedHex(group.group_id)} `,
|
||||
sortable: true,
|
||||
},
|
||||
members: {
|
||||
title: this.hass.localize("ui.panel.config.zha.groups.members"),
|
||||
type: "numeric",
|
||||
width: "15%",
|
||||
template: (group) => html` ${group.members.length} `,
|
||||
sortable: true,
|
||||
},
|
||||
|
|
|
@ -47,7 +47,6 @@ class ZWaveJSProvisioned extends LitElement {
|
|||
"ui.panel.config.zwave_js.provisioned.included"
|
||||
),
|
||||
type: "icon",
|
||||
width: "100px",
|
||||
template: (entry) =>
|
||||
entry.nodeId
|
||||
? html`
|
||||
|
@ -71,13 +70,12 @@ class ZWaveJSProvisioned extends LitElement {
|
|||
title: this.hass.localize("ui.panel.config.zwave_js.provisioned.dsk"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
security_classes: {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.zwave_js.provisioned.security_classes"
|
||||
),
|
||||
width: "30%",
|
||||
hidden: narrow,
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
|
@ -97,7 +95,6 @@ class ZWaveJSProvisioned extends LitElement {
|
|||
"ui.panel.config.zwave_js.provisioned.unprovison"
|
||||
),
|
||||
type: "icon-button",
|
||||
width: "100px",
|
||||
template: (entry) => html`
|
||||
<ha-icon-button
|
||||
.label=${this.hass.localize(
|
||||
|
|
|
@ -10,6 +10,8 @@ import { LitElement, PropertyValues, html, nothing } from "lit";
|
|||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { computeCssColor } from "../../../common/color/compute-color";
|
||||
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import {
|
||||
|
@ -37,7 +39,6 @@ import "../../../layouts/hass-tabs-subpage-data-table";
|
|||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { showLabelDetailDialog } from "./show-dialog-label-detail";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
|
||||
@customElement("ha-config-labels")
|
||||
export class HaConfigLabels extends LitElement {
|
||||
|
@ -80,7 +81,7 @@ export class HaConfigLabels extends LitElement {
|
|||
})
|
||||
private _activeHiddenColumns?: string[];
|
||||
|
||||
private _columns = memoizeOne((localize: LocalizeFunc) => {
|
||||
private _columns = memoizeOne((localize: LocalizeFunc, narrow: boolean) => {
|
||||
const columns: DataTableColumnContainer<LabelRegistryEntry> = {
|
||||
icon: {
|
||||
title: "",
|
||||
|
@ -110,22 +111,60 @@ export class HaConfigLabels extends LitElement {
|
|||
name: {
|
||||
title: localize("ui.panel.config.labels.headers.name"),
|
||||
main: true,
|
||||
flex: 2,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
template: (label) => html`
|
||||
<div>${label.name}</div>
|
||||
${label.description
|
||||
? html`<div class="secondary">${label.description}</div>`
|
||||
: nothing}
|
||||
`,
|
||||
template: narrow
|
||||
? undefined
|
||||
: (label) => html`
|
||||
<div>${label.name}</div>
|
||||
${label.description
|
||||
? html`<div class="secondary">${label.description}</div>`
|
||||
: nothing}
|
||||
`,
|
||||
},
|
||||
description: {
|
||||
title: localize("ui.panel.config.labels.headers.description"),
|
||||
hidden: !narrow,
|
||||
filterable: true,
|
||||
hideable: true,
|
||||
},
|
||||
created_at: {
|
||||
title: localize("ui.panel.config.generic.headers.created_at"),
|
||||
defaultHidden: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
minWidth: "128px",
|
||||
template: (label) =>
|
||||
label.created_at
|
||||
? formatShortDateTime(
|
||||
new Date(label.created_at * 1000),
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)
|
||||
: "—",
|
||||
},
|
||||
modified_at: {
|
||||
title: localize("ui.panel.config.generic.headers.modified_at"),
|
||||
defaultHidden: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
minWidth: "128px",
|
||||
template: (label) =>
|
||||
label.modified_at
|
||||
? formatShortDateTime(
|
||||
new Date(label.modified_at * 1000),
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)
|
||||
: "—",
|
||||
},
|
||||
actions: {
|
||||
title: "",
|
||||
label: localize("ui.panel.config.generic.headers.actions"),
|
||||
showNarrow: true,
|
||||
moveable: false,
|
||||
hideable: false,
|
||||
width: "64px",
|
||||
type: "overflow-menu",
|
||||
template: (label) => html`
|
||||
<ha-icon-overflow-menu
|
||||
|
@ -182,7 +221,7 @@ export class HaConfigLabels extends LitElement {
|
|||
back-path="/config"
|
||||
.route=${this.route}
|
||||
.tabs=${configSections.areas}
|
||||
.columns=${this._columns(this.hass.localize)}
|
||||
.columns=${this._columns(this.hass.localize, this.narrow)}
|
||||
.data=${this._data(this._labels)}
|
||||
.noDataText=${this.hass.localize("ui.panel.config.labels.no_labels")}
|
||||
hasFab
|
||||
|
|
|
@ -143,7 +143,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
main: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
flex: 2,
|
||||
template: narrow
|
||||
? undefined
|
||||
: (dashboard) => html`
|
||||
|
@ -171,7 +171,6 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "20%",
|
||||
template: (dashboard) => html`
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.lovelace.dashboards.conf_mode.${dashboard.mode}`
|
||||
|
@ -183,7 +182,6 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
title: localize(
|
||||
"ui.panel.config.lovelace.dashboards.picker.headers.filename"
|
||||
),
|
||||
width: "15%",
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
};
|
||||
|
@ -195,7 +193,6 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
sortable: true,
|
||||
type: "icon",
|
||||
hidden: narrow,
|
||||
width: "100px",
|
||||
template: (dashboard) =>
|
||||
dashboard.require_admin
|
||||
? html`<ha-svg-icon .path=${mdiCheck}></ha-svg-icon>`
|
||||
|
@ -207,7 +204,6 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
),
|
||||
type: "icon",
|
||||
hidden: narrow,
|
||||
width: "121px",
|
||||
template: (dashboard) =>
|
||||
dashboard.show_in_sidebar
|
||||
? html`<ha-svg-icon .path=${mdiCheck}></ha-svg-icon>`
|
||||
|
@ -221,7 +217,6 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
),
|
||||
filterable: true,
|
||||
showNarrow: true,
|
||||
width: "100px",
|
||||
template: (dashboard) =>
|
||||
narrow
|
||||
? html`
|
||||
|
|
|
@ -94,7 +94,7 @@ export class HaConfigLovelaceRescources extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
forceLTR: true,
|
||||
},
|
||||
type: {
|
||||
|
@ -103,7 +103,6 @@ export class HaConfigLovelaceRescources extends LitElement {
|
|||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "30%",
|
||||
template: (resource) => html`
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.lovelace.resources.types.${resource.type}`
|
||||
|
|
|
@ -260,7 +260,7 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
extraTemplate: (scene) =>
|
||||
scene.labels.length
|
||||
? html`<ha-data-table-labels
|
||||
|
@ -294,7 +294,6 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||
"ui.panel.config.scene.picker.headers.last_activated"
|
||||
),
|
||||
sortable: true,
|
||||
width: "30%",
|
||||
template: (scene) => {
|
||||
const lastActivated = scene.state;
|
||||
if (!lastActivated || isUnavailableState(lastActivated)) {
|
||||
|
@ -312,7 +311,7 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||
},
|
||||
only_editable: {
|
||||
title: "",
|
||||
width: "56px",
|
||||
type: "icon",
|
||||
showNarrow: true,
|
||||
template: (scene) =>
|
||||
!scene.attributes.id
|
||||
|
@ -331,7 +330,6 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||
},
|
||||
actions: {
|
||||
title: "",
|
||||
width: "64px",
|
||||
type: "overflow-menu",
|
||||
showNarrow: true,
|
||||
moveable: false,
|
||||
|
|
|
@ -270,7 +270,7 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
extraTemplate: (script) =>
|
||||
script.labels.length
|
||||
? html`<ha-data-table-labels
|
||||
|
@ -301,7 +301,6 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||
},
|
||||
last_triggered: {
|
||||
sortable: true,
|
||||
width: "40%",
|
||||
title: localize("ui.card.automation.last_triggered"),
|
||||
template: (script) => {
|
||||
const date = new Date(script.last_triggered);
|
||||
|
@ -322,7 +321,6 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||
},
|
||||
actions: {
|
||||
title: "",
|
||||
width: "64px",
|
||||
type: "overflow-menu",
|
||||
showNarrow: true,
|
||||
moveable: false,
|
||||
|
|
|
@ -81,13 +81,12 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||
main: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
last_scanned_datetime: {
|
||||
title: localize("ui.panel.config.tag.headers.last_scanned"),
|
||||
sortable: true,
|
||||
direction: "desc",
|
||||
width: "20%",
|
||||
template: (tag) => html`
|
||||
${tag.last_scanned_datetime
|
||||
? html`<ha-relative-time
|
||||
|
|
|
@ -83,15 +83,13 @@ export class HaConfigUsers extends LitElement {
|
|||
main: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "25%",
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
username: {
|
||||
title: localize("ui.panel.config.users.picker.headers.username"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "20%",
|
||||
direction: "asc",
|
||||
template: (user) => html`${user.username || "—"}`,
|
||||
},
|
||||
|
@ -100,7 +98,6 @@ export class HaConfigUsers extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
groupable: true,
|
||||
width: "20%",
|
||||
direction: "asc",
|
||||
},
|
||||
is_active: {
|
||||
|
@ -110,7 +107,6 @@ export class HaConfigUsers extends LitElement {
|
|||
type: "icon",
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "80px",
|
||||
hidden: narrow,
|
||||
template: (user) =>
|
||||
user.is_active
|
||||
|
@ -124,7 +120,6 @@ export class HaConfigUsers extends LitElement {
|
|||
type: "icon",
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "80px",
|
||||
hidden: narrow,
|
||||
template: (user) =>
|
||||
user.system_generated
|
||||
|
@ -138,7 +133,6 @@ export class HaConfigUsers extends LitElement {
|
|||
type: "icon",
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "80px",
|
||||
hidden: narrow,
|
||||
template: (user) =>
|
||||
user.local_only
|
||||
|
@ -153,7 +147,7 @@ export class HaConfigUsers extends LitElement {
|
|||
type: "icon",
|
||||
sortable: false,
|
||||
filterable: false,
|
||||
width: "104px",
|
||||
minWidth: "104px",
|
||||
hidden: !narrow,
|
||||
showNarrow: true,
|
||||
template: (user) => {
|
||||
|
|
|
@ -42,13 +42,12 @@ class AssistDevicesPage extends LitElement {
|
|||
),
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
pipeline: {
|
||||
title: localize(
|
||||
"ui.panel.config.voice_assistants.assistants.pipeline.devices.pipeline"
|
||||
),
|
||||
width: "30%",
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
},
|
||||
|
@ -58,7 +57,6 @@ class AssistDevicesPage extends LitElement {
|
|||
),
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
width: "30%",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
flex: 2,
|
||||
template: narrow
|
||||
? undefined
|
||||
: (entry) => html`
|
||||
|
@ -197,7 +197,6 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||
sortable: true,
|
||||
groupable: true,
|
||||
filterable: true,
|
||||
width: "15%",
|
||||
},
|
||||
assistants: {
|
||||
title: localize(
|
||||
|
@ -206,7 +205,8 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||
showNarrow: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "160px",
|
||||
minWidth: "160px",
|
||||
maxWidth: "160px",
|
||||
type: "flex",
|
||||
template: (entry) =>
|
||||
html`${availableAssistants.map((key) => {
|
||||
|
@ -233,7 +233,6 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "15%",
|
||||
template: (entry) =>
|
||||
entry.aliases.length === 0
|
||||
? "-"
|
||||
|
|
|
@ -89,9 +89,10 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
|
|||
title: localize(
|
||||
"ui.panel.developer-tools.tabs.statistics.data_table.name"
|
||||
),
|
||||
main: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
flex: 2,
|
||||
},
|
||||
statistic_id: {
|
||||
title: localize(
|
||||
|
@ -100,7 +101,6 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
hidden: this.narrow,
|
||||
width: "20%",
|
||||
},
|
||||
statistics_unit_of_measurement: {
|
||||
title: localize(
|
||||
|
@ -108,7 +108,6 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
|
|||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "10%",
|
||||
forceLTR: true,
|
||||
},
|
||||
source: {
|
||||
|
@ -117,7 +116,6 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
|
|||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "10%",
|
||||
},
|
||||
issues_string: {
|
||||
title: localize(
|
||||
|
@ -126,7 +124,7 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
|
|||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
width: "30%",
|
||||
flex: 2,
|
||||
template: (statistic) =>
|
||||
html`${statistic.issues_string ??
|
||||
localize("ui.panel.developer-tools.tabs.statistics.no_issue")}`,
|
||||
|
@ -147,12 +145,15 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
|
|||
)}
|
||||
</mwc-button>`
|
||||
: "—"}`,
|
||||
width: "113px",
|
||||
minWidth: "113px",
|
||||
maxWidth: "113px",
|
||||
showNarrow: true,
|
||||
},
|
||||
actions: {
|
||||
title: "",
|
||||
label: localize("ui.panel.developer-tools.tabs.statistics.adjust_sum"),
|
||||
type: "icon-button",
|
||||
showNarrow: true,
|
||||
template: (statistic) =>
|
||||
statistic.has_sum
|
||||
? html`
|
||||
|
@ -179,6 +180,7 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
|
|||
.noDataText=${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.statistics.data_table.no_statistics"
|
||||
)}
|
||||
.narrow=${this.narrow}
|
||||
id="statistic_id"
|
||||
clickable
|
||||
@row-click=${this._rowClicked}
|
||||
|
|
|
@ -64,7 +64,8 @@ export class HuiEntityPickerTable extends LitElement {
|
|||
title: this.hass!.localize("ui.panel.lovelace.unused_entities.entity"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
flex: 2,
|
||||
main: true,
|
||||
direction: "asc",
|
||||
template: (entity: any) => html`
|
||||
<div @click=${this._handleEntityClicked} style="cursor: pointer;">
|
||||
|
@ -81,7 +82,6 @@ export class HuiEntityPickerTable extends LitElement {
|
|||
title: this.hass!.localize("ui.panel.lovelace.unused_entities.entity_id"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "30%",
|
||||
hidden: narrow,
|
||||
};
|
||||
|
||||
|
@ -89,7 +89,6 @@ export class HuiEntityPickerTable extends LitElement {
|
|||
title: this.hass!.localize("ui.panel.lovelace.unused_entities.domain"),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
width: "15%",
|
||||
hidden: narrow,
|
||||
};
|
||||
|
||||
|
@ -99,7 +98,6 @@ export class HuiEntityPickerTable extends LitElement {
|
|||
),
|
||||
type: "numeric",
|
||||
sortable: true,
|
||||
width: "15%",
|
||||
hidden: narrow,
|
||||
template: (entity) => html`
|
||||
<ha-relative-time
|
||||
|
|
|
@ -1843,6 +1843,13 @@
|
|||
"error": "An unknown error occurred"
|
||||
},
|
||||
"config": {
|
||||
"generic": {
|
||||
"headers": {
|
||||
"modified_at": "Modified",
|
||||
"created_at": "Created",
|
||||
"actions": "Actions"
|
||||
}
|
||||
},
|
||||
"header": "Configure Home Assistant",
|
||||
"dashboard": {
|
||||
"devices": {
|
||||
|
|
Loading…
Reference in New Issue