1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-02-15 07:25:54 +00:00

Add created/modified to registry tables (#21494)

This commit is contained in:
Bram Kragten
2024-07-30 11:18:50 +02:00
committed by GitHub
parent a85dda3365
commit 4ade39543d
40 changed files with 320 additions and 151 deletions

View File

@@ -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,
},
]);

View File

@@ -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,
},
];

View File

@@ -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,
},
];

View File

@@ -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,
},

View File

@@ -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,
},
];

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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[];
}

View File

@@ -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[];
}

View File

@@ -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,
},
];
}

View File

@@ -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;

View File

@@ -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]>;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

4
src/data/registry.ts Normal file
View File

@@ -0,0 +1,4 @@
export interface RegistryEntry {
created_at: number;
modified_at: number;
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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}

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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%",
},
}
);

View File

@@ -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

View File

@@ -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",
},
}
);

View File

@@ -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,
},

View File

@@ -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(

View File

@@ -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

View File

@@ -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`

View File

@@ -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}`

View File

@@ -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,

View File

@@ -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,

View File

@@ -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

View File

@@ -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) => {

View File

@@ -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%",
},
};

View File

@@ -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
? "-"

View File

@@ -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}

View File

@@ -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

View File

@@ -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": {