20240329.0 (#20277)
This commit is contained in:
commit
d24d29e42f
|
@ -185,8 +185,8 @@
|
|||
"@types/tar": "6.1.11",
|
||||
"@types/ua-parser-js": "0.7.39",
|
||||
"@types/webspeechapi": "0.0.29",
|
||||
"@typescript-eslint/eslint-plugin": "7.3.1",
|
||||
"@typescript-eslint/parser": "7.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "7.4.0",
|
||||
"@typescript-eslint/parser": "7.4.0",
|
||||
"@web/dev-server": "0.1.38",
|
||||
"@web/dev-server-rollup": "0.4.1",
|
||||
"babel-loader": "9.1.3",
|
||||
|
|
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20240328.0"
|
||||
version = "20240329.0"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
|
|
@ -512,10 +512,6 @@ export class HaDataTable extends LitElement {
|
|||
items.push({ append: true, content: this.appendRow });
|
||||
}
|
||||
|
||||
if (this.hasFab) {
|
||||
items.push({ empty: true });
|
||||
}
|
||||
|
||||
if (this.groupColumn) {
|
||||
const grouped = groupBy(items, (item) => item[this.groupColumn!]);
|
||||
if (grouped.undefined) {
|
||||
|
@ -555,6 +551,10 @@ export class HaDataTable extends LitElement {
|
|||
} else {
|
||||
this._items = items;
|
||||
}
|
||||
|
||||
if (this.hasFab) {
|
||||
this._items = [...this._items, { empty: true }];
|
||||
}
|
||||
} else {
|
||||
this._items = data;
|
||||
}
|
||||
|
|
|
@ -157,11 +157,11 @@ export class HaFilterBlueprints extends LitElement {
|
|||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--accent-color);
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
|
|
@ -78,13 +78,15 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) {
|
|||
class="ha-scrollbar"
|
||||
activatable
|
||||
>
|
||||
<ha-list-item
|
||||
.selected=${!this.value?.length}
|
||||
.activated=${!this.value?.length}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.category.filter.show_all"
|
||||
)}</ha-list-item
|
||||
>
|
||||
${this._categories.length > 0
|
||||
? html`<ha-list-item
|
||||
.selected=${!this.value?.length}
|
||||
.activated=${!this.value?.length}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.category.filter.show_all"
|
||||
)}</ha-list-item
|
||||
>`
|
||||
: nothing}
|
||||
${this._categories.map(
|
||||
(category) =>
|
||||
html`<ha-list-item
|
||||
|
@ -142,7 +144,11 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) {
|
|||
: nothing}
|
||||
</ha-expansion-panel>
|
||||
${this.expanded
|
||||
? html`<ha-list-item graphic="icon" @click=${this._addCategory}>
|
||||
? html`<ha-list-item
|
||||
graphic="icon"
|
||||
@click=${this._addCategory}
|
||||
class="add"
|
||||
>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiPlus}></ha-svg-icon>
|
||||
${this.hass.localize("ui.panel.config.category.editor.add")}
|
||||
</ha-list-item>`
|
||||
|
@ -254,6 +260,7 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) {
|
|||
css`
|
||||
:host {
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
position: relative;
|
||||
}
|
||||
:host([expanded]) {
|
||||
flex: 1;
|
||||
|
@ -277,11 +284,11 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) {
|
|||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--accent-color);
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
mwc-list {
|
||||
--mdc-list-item-meta-size: auto;
|
||||
|
@ -291,6 +298,12 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) {
|
|||
.warning {
|
||||
color: var(--error-color);
|
||||
}
|
||||
.add {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -185,11 +185,11 @@ export class HaFilterDevices extends LitElement {
|
|||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--accent-color);
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
ha-check-list-item {
|
||||
width: 100%;
|
||||
|
|
|
@ -199,11 +199,11 @@ export class HaFilterEntities extends LitElement {
|
|||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--accent-color);
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
ha-check-list-item {
|
||||
--mdc-list-item-graphic-margin: 16px;
|
||||
|
|
|
@ -267,11 +267,11 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
|
|||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--accent-color);
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
ha-check-list-item {
|
||||
--mdc-list-item-graphic-margin: 16px;
|
||||
|
|
|
@ -165,11 +165,11 @@ export class HaFilterIntegrations extends LitElement {
|
|||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--accent-color);
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
|
|
@ -3,10 +3,12 @@ import "@material/mwc-menu/mwc-menu-surface";
|
|||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { mdiPlus } from "@mdi/js";
|
||||
import { computeCssColor } from "../common/color/compute-color";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import {
|
||||
LabelRegistryEntry,
|
||||
createLabelRegistryEntry,
|
||||
subscribeLabelRegistry,
|
||||
} from "../data/label_registry";
|
||||
import { SubscribeMixin } from "../mixins/subscribe-mixin";
|
||||
|
@ -16,6 +18,7 @@ import "./ha-check-list-item";
|
|||
import "./ha-expansion-panel";
|
||||
import "./ha-icon";
|
||||
import "./ha-label";
|
||||
import { showLabelDetailDialog } from "../panels/config/labels/show-dialog-label-detail";
|
||||
|
||||
@customElement("ha-filter-labels")
|
||||
export class HaFilterLabels extends SubscribeMixin(LitElement) {
|
||||
|
@ -84,6 +87,16 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) {
|
|||
`
|
||||
: nothing}
|
||||
</ha-expansion-panel>
|
||||
${this.expanded
|
||||
? html`<ha-list-item
|
||||
graphic="icon"
|
||||
@click=${this._addLabel}
|
||||
class="add"
|
||||
>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiPlus}></ha-svg-icon>
|
||||
${this.hass.localize("ui.panel.config.labels.add_label")}
|
||||
</ha-list-item>`
|
||||
: nothing}
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -92,11 +105,17 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) {
|
|||
setTimeout(() => {
|
||||
if (!this.expanded) return;
|
||||
this.renderRoot.querySelector("mwc-list")!.style.height =
|
||||
`${this.clientHeight - 49}px`;
|
||||
`${this.clientHeight - (49 + 48)}px`;
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
|
||||
private _addLabel() {
|
||||
showLabelDetailDialog(this, {
|
||||
createEntry: (values) => createLabelRegistryEntry(this.hass, values),
|
||||
});
|
||||
}
|
||||
|
||||
private _expandedWillChange(ev) {
|
||||
this._shouldRender = ev.detail.expanded;
|
||||
}
|
||||
|
@ -134,6 +153,7 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) {
|
|||
haStyleScrollbar,
|
||||
css`
|
||||
:host {
|
||||
position: relative;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
:host([expanded]) {
|
||||
|
@ -158,11 +178,11 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) {
|
|||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--accent-color);
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
.warning {
|
||||
color: var(--error-color);
|
||||
|
@ -171,6 +191,12 @@ export class HaFilterLabels extends SubscribeMixin(LitElement) {
|
|||
--ha-label-background-color: var(--color, var(--grey-color));
|
||||
--ha-label-background-opacity: 0.5;
|
||||
}
|
||||
.add {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -147,11 +147,11 @@ export class HaFilterStates extends LitElement {
|
|||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--accent-color);
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
|
|
@ -38,10 +38,14 @@ import "./ha-list-item";
|
|||
|
||||
type ScorableFloorRegistryEntry = ScorableTextItem & FloorRegistryEntry;
|
||||
|
||||
const ADD_NEW_ID = "___ADD_NEW___";
|
||||
const NO_FLOORS_ID = "___NO_FLOORS___";
|
||||
const ADD_NEW_SUGGESTION_ID = "___ADD_NEW_SUGGESTION___";
|
||||
|
||||
const rowRenderer: ComboBoxLitRenderer<FloorRegistryEntry> = (item) =>
|
||||
html`<ha-list-item
|
||||
graphic="icon"
|
||||
class=${classMap({ "add-new": item.floor_id === "add_new" })}
|
||||
class=${classMap({ "add-new": item.floor_id === ADD_NEW_ID })}
|
||||
>
|
||||
<ha-floor-icon slot="graphic" .floor=${item}></ha-floor-icon>
|
||||
${item.name}
|
||||
|
@ -146,18 +150,6 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
noAdd: this["noAdd"],
|
||||
excludeFloors: this["excludeFloors"]
|
||||
): FloorRegistryEntry[] => {
|
||||
if (!floors.length) {
|
||||
return [
|
||||
{
|
||||
floor_id: "no_floors",
|
||||
name: this.hass.localize("ui.components.floor-picker.no_floors"),
|
||||
icon: null,
|
||||
level: 0,
|
||||
aliases: [],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
let deviceEntityLookup: DeviceEntityDisplayLookup = {};
|
||||
let inputDevices: DeviceRegistryEntry[] | undefined;
|
||||
let inputEntities: EntityRegistryDisplayEntry[] | undefined;
|
||||
|
@ -297,10 +289,10 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
if (!outputFloors.length) {
|
||||
outputFloors = [
|
||||
{
|
||||
floor_id: "no_floors",
|
||||
name: this.hass.localize("ui.components.floor-picker.no_match"),
|
||||
floor_id: NO_FLOORS_ID,
|
||||
name: this.hass.localize("ui.components.floor-picker.no_floors"),
|
||||
icon: null,
|
||||
level: 0,
|
||||
level: null,
|
||||
aliases: [],
|
||||
},
|
||||
];
|
||||
|
@ -311,10 +303,10 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
: [
|
||||
...outputFloors,
|
||||
{
|
||||
floor_id: "add_new",
|
||||
floor_id: ADD_NEW_ID,
|
||||
name: this.hass.localize("ui.components.floor-picker.add_new"),
|
||||
icon: "mdi:plus",
|
||||
level: 0,
|
||||
level: null,
|
||||
aliases: [],
|
||||
},
|
||||
];
|
||||
|
@ -341,7 +333,7 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
this.excludeFloors
|
||||
).map((floor) => ({
|
||||
...floor,
|
||||
strings: [floor.floor_id, floor.name], // ...floor.aliases
|
||||
strings: [floor.floor_id, floor.name, ...floor.aliases],
|
||||
}));
|
||||
this.comboBox.items = floors;
|
||||
this.comboBox.filteredItems = floors;
|
||||
|
@ -385,20 +377,36 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
|
||||
const filteredItems = fuzzyFilterSort<ScorableFloorRegistryEntry>(
|
||||
filterString,
|
||||
target.items || []
|
||||
target.items?.filter(
|
||||
(item) => ![NO_FLOORS_ID, ADD_NEW_ID].includes(item.label_id)
|
||||
) || []
|
||||
);
|
||||
if (!this.noAdd && filteredItems?.length === 0) {
|
||||
this._suggestion = filterString;
|
||||
this.comboBox.filteredItems = [
|
||||
{
|
||||
floor_id: "add_new_suggestion",
|
||||
name: this.hass.localize(
|
||||
"ui.components.floor-picker.add_new_sugestion",
|
||||
{ name: this._suggestion }
|
||||
),
|
||||
picture: null,
|
||||
},
|
||||
];
|
||||
if (filteredItems.length === 0) {
|
||||
if (this.noAdd) {
|
||||
this.comboBox.filteredItems = [
|
||||
{
|
||||
floor_id: NO_FLOORS_ID,
|
||||
name: this.hass.localize("ui.components.floor-picker.no_floors"),
|
||||
icon: null,
|
||||
level: null,
|
||||
aliases: [],
|
||||
},
|
||||
] as FloorRegistryEntry[];
|
||||
} else {
|
||||
this._suggestion = filterString;
|
||||
this.comboBox.filteredItems = [
|
||||
{
|
||||
floor_id: ADD_NEW_SUGGESTION_ID,
|
||||
name: this.hass.localize(
|
||||
"ui.components.floor-picker.add_new_sugestion",
|
||||
{ name: this._suggestion }
|
||||
),
|
||||
icon: "mdi:plus",
|
||||
level: null,
|
||||
aliases: [],
|
||||
},
|
||||
] as FloorRegistryEntry[];
|
||||
}
|
||||
} else {
|
||||
this.comboBox.filteredItems = filteredItems;
|
||||
}
|
||||
|
@ -416,11 +424,13 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
ev.stopPropagation();
|
||||
let newValue = ev.detail.value;
|
||||
|
||||
if (newValue === "no_floors") {
|
||||
if (newValue === NO_FLOORS_ID) {
|
||||
newValue = "";
|
||||
this.comboBox.setInputValue("");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!["add_new_suggestion", "add_new"].includes(newValue)) {
|
||||
if (![ADD_NEW_SUGGESTION_ID, ADD_NEW_ID].includes(newValue)) {
|
||||
if (newValue !== this._value) {
|
||||
this._setValue(newValue);
|
||||
}
|
||||
|
@ -438,7 +448,7 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||
"ui.components.floor-picker.add_dialog.name"
|
||||
),
|
||||
defaultValue:
|
||||
newValue === "add_new_suggestion" ? this._suggestion : undefined,
|
||||
newValue === ADD_NEW_SUGGESTION_ID ? this._suggestion : undefined,
|
||||
confirm: async (name) => {
|
||||
if (!name) {
|
||||
return;
|
||||
|
|
|
@ -385,8 +385,8 @@ export class HaLabelPicker extends SubscribeMixin(LitElement) {
|
|||
|
||||
const filteredItems = fuzzyFilterSort<ScorableLabelItem>(
|
||||
filterString,
|
||||
target.items?.filter((item) =>
|
||||
[NO_LABELS_ID, ADD_NEW_ID].includes(item.ignoreFilter)
|
||||
target.items?.filter(
|
||||
(item) => ![NO_LABELS_ID, ADD_NEW_ID].includes(item.label_id)
|
||||
) || []
|
||||
);
|
||||
if (filteredItems.length === 0) {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import { MdOutlinedTextField } from "@material/web/textfield/outlined-text-field";
|
||||
import "element-internals-polyfill";
|
||||
import { css } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
|
||||
@customElement("ha-outlined-text-field")
|
||||
export class HaOutlinedTextField extends MdOutlinedTextField {
|
||||
static override styles = [
|
||||
...super.styles,
|
||||
css`
|
||||
:host {
|
||||
--md-sys-color-on-surface: var(--primary-text-color);
|
||||
--md-sys-color-primary: var(--primary-text-color);
|
||||
--md-outlined-text-field-input-text-color: var(--primary-text-color);
|
||||
--md-sys-color-on-surface-variant: var(--secondary-text-color);
|
||||
--md-outlined-field-outline-color: var(--outline-color);
|
||||
--md-outlined-field-focus-outline-color: var(--primary-color);
|
||||
--md-outlined-field-hover-outline-color: var(--outline-hover-color);
|
||||
}
|
||||
:host([dense]) {
|
||||
--md-outlined-field-top-space: 5.5px;
|
||||
--md-outlined-field-bottom-space: 5.5px;
|
||||
--md-outlined-field-container-shape-start-start: 10px;
|
||||
--md-outlined-field-container-shape-start-end: 10px;
|
||||
--md-outlined-field-container-shape-end-end: 10px;
|
||||
--md-outlined-field-container-shape-end-start: 10px;
|
||||
--md-outlined-field-focus-outline-width: 1px;
|
||||
--mdc-icon-size: var(--md-input-chip-icon-size, 18px);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-outlined-text-field": HaOutlinedTextField;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
import "@material/web/textfield/outlined-text-field";
|
||||
import type { MdOutlinedTextField } from "@material/web/textfield/outlined-text-field";
|
||||
import { mdiMagnify } from "@mdi/js";
|
||||
import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { HomeAssistant } from "../types";
|
||||
import "./ha-icon-button";
|
||||
import "./ha-outlined-text-field";
|
||||
import type { HaOutlinedTextField } from "./ha-outlined-text-field";
|
||||
import "./ha-svg-icon";
|
||||
|
||||
@customElement("search-input-outlined")
|
||||
|
@ -30,19 +30,22 @@ class SearchInputOutlined extends LitElement {
|
|||
this._input?.focus();
|
||||
}
|
||||
|
||||
@query("md-outlined-text-field", true) private _input!: MdOutlinedTextField;
|
||||
@query("ha-outlined-text-field", true) private _input!: HaOutlinedTextField;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const placeholder =
|
||||
this.placeholder || this.hass.localize("ui.common.search");
|
||||
|
||||
return html`
|
||||
<md-outlined-text-field
|
||||
<ha-outlined-text-field
|
||||
.autofocus=${this.autofocus}
|
||||
.aria-label=${this.label || this.hass.localize("ui.common.search")}
|
||||
.placeholder=${this.placeholder ||
|
||||
this.hass.localize("ui.common.search")}
|
||||
.placeholder=${placeholder}
|
||||
.value=${this.filter || ""}
|
||||
icon
|
||||
.iconTrailing=${this.filter || this.suffix}
|
||||
@input=${this._filterInputChanged}
|
||||
dense
|
||||
>
|
||||
<slot name="prefix" slot="leading-icon">
|
||||
<ha-svg-icon
|
||||
|
@ -51,7 +54,7 @@ class SearchInputOutlined extends LitElement {
|
|||
.path=${mdiMagnify}
|
||||
></ha-svg-icon>
|
||||
</slot>
|
||||
</md-outlined-text-field>
|
||||
</ha-outlined-text-field>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -67,40 +70,21 @@ class SearchInputOutlined extends LitElement {
|
|||
return css`
|
||||
:host {
|
||||
display: inline-flex;
|
||||
/* For iOS */
|
||||
z-index: 0;
|
||||
}
|
||||
md-outlined-text-field {
|
||||
ha-outlined-text-field {
|
||||
display: block;
|
||||
width: 100%;
|
||||
--md-sys-color-on-surface: var(--primary-text-color);
|
||||
--md-sys-color-primary: var(--primary-text-color);
|
||||
--md-outlined-text-field-input-text-color: var(--primary-text-color);
|
||||
--md-sys-color-on-surface-variant: var(--secondary-text-color);
|
||||
--md-outlined-field-top-space: 5.5px;
|
||||
--md-outlined-field-bottom-space: 5.5px;
|
||||
--md-outlined-field-outline-color: var(--outline-color);
|
||||
--md-outlined-field-container-shape-start-start: 10px;
|
||||
--md-outlined-field-container-shape-start-end: 10px;
|
||||
--md-outlined-field-container-shape-end-end: 10px;
|
||||
--md-outlined-field-container-shape-end-start: 10px;
|
||||
--md-outlined-field-focus-outline-width: 1px;
|
||||
--md-outlined-field-focus-outline-color: var(--primary-color);
|
||||
}
|
||||
ha-svg-icon,
|
||||
ha-icon-button {
|
||||
display: flex;
|
||||
--mdc-icon-size: var(--md-input-chip-icon-size, 18px);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
ha-svg-icon {
|
||||
outline: none;
|
||||
}
|
||||
.clear-button {
|
||||
--mdc-icon-size: 20px;
|
||||
}
|
||||
.trailing {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { computeDomain } from "../common/entity/compute_domain";
|
|||
|
||||
export { subscribeEntityRegistryDisplay } from "./ws-entity_registry_display";
|
||||
|
||||
type entityCategory = "config" | "diagnostic";
|
||||
type EntityCategory = "config" | "diagnostic";
|
||||
|
||||
export interface EntityRegistryDisplayEntry {
|
||||
entity_id: string;
|
||||
|
@ -20,7 +20,7 @@ export interface EntityRegistryDisplayEntry {
|
|||
area_id?: string;
|
||||
labels: string[];
|
||||
hidden?: boolean;
|
||||
entity_category?: entityCategory;
|
||||
entity_category?: EntityCategory;
|
||||
translation_key?: string;
|
||||
platform?: string;
|
||||
display_precision?: number;
|
||||
|
@ -40,7 +40,7 @@ export interface EntityRegistryDisplayEntryResponse {
|
|||
hb?: boolean;
|
||||
dp?: number;
|
||||
}[];
|
||||
entity_categories: Record<number, entityCategory>;
|
||||
entity_categories: Record<number, EntityCategory>;
|
||||
}
|
||||
|
||||
export interface EntityRegistryEntry {
|
||||
|
@ -55,7 +55,7 @@ export interface EntityRegistryEntry {
|
|||
labels: string[];
|
||||
disabled_by: "user" | "device" | "integration" | "config_entry" | null;
|
||||
hidden_by: Exclude<EntityRegistryEntry["disabled_by"], "config_entry">;
|
||||
entity_category: entityCategory | null;
|
||||
entity_category: EntityCategory | null;
|
||||
has_entity_name: boolean;
|
||||
original_name?: string;
|
||||
unique_id: string;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { ResizeController } from "@lit-labs/observers/resize-controller";
|
||||
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@material/web/menu/menu";
|
||||
import type { MdMenu } from "@material/web/menu/menu";
|
||||
import "@material/web/menu/menu-item";
|
||||
import {
|
||||
mdiArrowDown,
|
||||
mdiArrowUp,
|
||||
|
@ -19,6 +22,7 @@ import {
|
|||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { LocalizeFunc } from "../common/translations/localize";
|
||||
import "../components/chips/ha-assist-chip";
|
||||
|
@ -173,6 +177,10 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||
|
||||
@query("ha-data-table", true) private _dataTable!: HaDataTable;
|
||||
|
||||
@query("#group-by-menu") private _groupByMenu!: MdMenu;
|
||||
|
||||
@query("#sort-by-menu") private _sortByMenu!: MdMenu;
|
||||
|
||||
private _showPaneController = new ResizeController(this, {
|
||||
callback: (entries) => entries[0]?.contentRect.width > 750,
|
||||
});
|
||||
|
@ -187,6 +195,14 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||
}
|
||||
}
|
||||
|
||||
private _toggleGroupBy() {
|
||||
this._groupByMenu.open = !this._groupByMenu.open;
|
||||
}
|
||||
|
||||
private _toggleSortBy() {
|
||||
this._sortByMenu.open = !this._sortByMenu.open;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const localize = this.localizeFunc || this.hass.localize;
|
||||
const showPane = this._showPaneController.value ?? !this.narrow;
|
||||
|
@ -226,73 +242,35 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||
</search-input-outlined>`;
|
||||
|
||||
const sortByMenu = Object.values(this.columns).find((col) => col.sortable)
|
||||
? html`<ha-button-menu fixed>
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
.label=${localize("ui.components.subpage-data-table.sort_by", {
|
||||
sortColumn: this._sortColumn
|
||||
? ` ${this.columns[this._sortColumn].title || this.columns[this._sortColumn].label}`
|
||||
: "",
|
||||
})}
|
||||
slot="trigger"
|
||||
id="sort-by-anchor"
|
||||
@click=${this._toggleSortBy}
|
||||
>
|
||||
<ha-svg-icon slot="trailing-icon" .path=${mdiMenuDown}></ha-svg-icon
|
||||
></ha-assist-chip>
|
||||
${Object.entries(this.columns).map(([id, column]) =>
|
||||
column.sortable
|
||||
? html`<ha-list-item
|
||||
.value=${id}
|
||||
@request-selected=${this._handleSortBy}
|
||||
hasMeta
|
||||
.activated=${id === this._sortColumn}
|
||||
>
|
||||
${this._sortColumn === id
|
||||
? html`<ha-svg-icon
|
||||
slot="meta"
|
||||
.path=${this._sortDirection === "desc"
|
||||
? mdiArrowDown
|
||||
: mdiArrowUp}
|
||||
></ha-svg-icon>`
|
||||
: nothing}
|
||||
${column.title || column.label}
|
||||
</ha-list-item>`
|
||||
: nothing
|
||||
)}
|
||||
</ha-button-menu>`
|
||||
`
|
||||
: nothing;
|
||||
|
||||
const groupByMenu = Object.values(this.columns).find((col) => col.groupable)
|
||||
? html`<ha-button-menu fixed>
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
.label=${localize("ui.components.subpage-data-table.group_by", {
|
||||
groupColumn: this._groupColumn
|
||||
? ` ${this.columns[this._groupColumn].title || this.columns[this._groupColumn].label}`
|
||||
: "",
|
||||
})}
|
||||
slot="trigger"
|
||||
id="group-by-anchor"
|
||||
@click=${this._toggleGroupBy}
|
||||
>
|
||||
<ha-svg-icon slot="trailing-icon" .path=${mdiMenuDown}></ha-svg-icon
|
||||
></ha-assist-chip>
|
||||
${Object.entries(this.columns).map(([id, column]) =>
|
||||
column.groupable
|
||||
? html`<ha-list-item
|
||||
.value=${id}
|
||||
@request-selected=${this._handleGroupBy}
|
||||
.activated=${id === this._groupColumn}
|
||||
>
|
||||
${column.title || column.label}
|
||||
</ha-list-item> `
|
||||
: nothing
|
||||
)}
|
||||
<li divider role="separator"></li>
|
||||
<ha-list-item
|
||||
.value=${undefined}
|
||||
@request-selected=${this._handleGroupBy}
|
||||
.activated=${this._groupColumn === undefined}
|
||||
>${localize(
|
||||
"ui.components.subpage-data-table.dont_group_by"
|
||||
)}</ha-list-item
|
||||
>
|
||||
</ha-button-menu>`
|
||||
`
|
||||
: nothing;
|
||||
|
||||
return html`
|
||||
|
@ -431,6 +409,58 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||
</ha-data-table>`}
|
||||
<div slot="fab"><slot name="fab"></slot></div>
|
||||
</hass-tabs-subpage>
|
||||
<md-menu anchor="group-by-anchor" id="group-by-menu" positioning="fixed">
|
||||
${Object.entries(this.columns).map(([id, column]) =>
|
||||
column.groupable
|
||||
? html`
|
||||
<md-menu-item
|
||||
.value=${id}
|
||||
@click=${this._handleGroupBy}
|
||||
.selected=${id === this._groupColumn}
|
||||
class=${classMap({ selected: id === this._groupColumn })}
|
||||
>
|
||||
${column.title || column.label}
|
||||
</md-menu-item>
|
||||
`
|
||||
: nothing
|
||||
)}
|
||||
<li divider role="separator"></li>
|
||||
<md-menu-item
|
||||
.value=${undefined}
|
||||
@click=${this._handleGroupBy}
|
||||
.selected=${this._groupColumn === undefined}
|
||||
class=${classMap({ selected: this._groupColumn === undefined })}
|
||||
>${localize(
|
||||
"ui.components.subpage-data-table.dont_group_by"
|
||||
)}</md-menu-item
|
||||
>
|
||||
</md-menu>
|
||||
<md-menu anchor="sort-by-anchor" id="sort-by-menu" positioning="fixed">
|
||||
${Object.entries(this.columns).map(([id, column]) =>
|
||||
column.sortable
|
||||
? html`
|
||||
<md-menu-item
|
||||
.value=${id}
|
||||
@click=${this._handleSortBy}
|
||||
.selected=${id === this._sortColumn}
|
||||
class=${classMap({ selected: id === this._sortColumn })}
|
||||
>
|
||||
${this._sortColumn === id
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
slot="end"
|
||||
.path=${this._sortDirection === "desc"
|
||||
? mdiArrowDown
|
||||
: mdiArrowUp}
|
||||
></ha-svg-icon>
|
||||
`
|
||||
: nothing}
|
||||
${column.title || column.label}
|
||||
</md-menu-item>
|
||||
`
|
||||
: nothing
|
||||
)}
|
||||
</md-menu>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -449,6 +479,7 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||
|
||||
private _handleSortBy(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
const columnId = ev.currentTarget.value;
|
||||
if (!this._sortDirection || this._sortColumn !== columnId) {
|
||||
this._sortDirection = "asc";
|
||||
|
@ -611,11 +642,11 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--accent-color);
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
|
||||
.narrow-header-row {
|
||||
|
@ -656,13 +687,6 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||
ha-assist-chip {
|
||||
--ha-assist-chip-container-shape: 10px;
|
||||
}
|
||||
ha-button-menu {
|
||||
--mdc-list-item-meta-size: 16px;
|
||||
--mdc-list-item-meta-display: flex;
|
||||
}
|
||||
ha-button-menu ha-assist-chip {
|
||||
--md-assist-chip-trailing-space: 8px;
|
||||
}
|
||||
|
||||
.select-mode-chip {
|
||||
--md-assist-chip-icon-label-space: 0;
|
||||
|
@ -688,6 +712,25 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
/* TODO: Migrate to ha-menu and ha-menu-item */
|
||||
md-menu {
|
||||
--md-menu-container-color: var(--card-background-color);
|
||||
}
|
||||
md-menu-item {
|
||||
--md-menu-item-label-text-color: var(--primary-text-color);
|
||||
--mdc-icon-size: 16px;
|
||||
--md-menu-item-selected-container-color: rgba(
|
||||
var(--rgb-primary-color),
|
||||
0.15
|
||||
);
|
||||
}
|
||||
md-menu-item.selected {
|
||||
--md-menu-item-label-text-color: var(--primary-color);
|
||||
}
|
||||
#sort-by-anchor,
|
||||
#group-by-anchor {
|
||||
--md-assist-chip-trailing-space: 8px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
|||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
css,
|
||||
html,
|
||||
|
@ -38,13 +39,15 @@ import type {
|
|||
DataTableColumnContainer,
|
||||
RowClickedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/data-table/ha-data-table-labels";
|
||||
import "../../../components/entity/ha-entity-toggle";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-filter-floor-areas";
|
||||
import "../../../components/ha-filter-blueprints";
|
||||
import "../../../components/ha-filter-categories";
|
||||
import "../../../components/ha-filter-devices";
|
||||
import "../../../components/ha-filter-entities";
|
||||
import "../../../components/ha-filter-floor-areas";
|
||||
import "../../../components/ha-filter-labels";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-icon-overflow-menu";
|
||||
import "../../../components/ha-svg-icon";
|
||||
|
@ -64,6 +67,10 @@ import {
|
|||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import {
|
||||
LabelRegistryEntry,
|
||||
subscribeLabelRegistry,
|
||||
} from "../../../data/label_registry";
|
||||
import { findRelated } from "../../../data/search";
|
||||
import {
|
||||
showAlertDialog,
|
||||
|
@ -77,12 +84,6 @@ import { documentationUrl } from "../../../util/documentation-url";
|
|||
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { showNewAutomationDialog } from "./show-dialog-new-automation";
|
||||
import "../../../components/data-table/ha-data-table-labels";
|
||||
import {
|
||||
LabelRegistryEntry,
|
||||
subscribeLabelRegistry,
|
||||
} from "../../../data/label_registry";
|
||||
import "../../../components/ha-filter-labels";
|
||||
|
||||
type AutomationItem = AutomationEntity & {
|
||||
name: string;
|
||||
|
@ -509,6 +510,13 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||
`;
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
super.updated(changedProps);
|
||||
if (changedProps.has("_entityReg")) {
|
||||
this._applyFilters();
|
||||
}
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
if (this._searchParms.has("blueprint")) {
|
||||
this._filterBlueprint();
|
||||
|
|
|
@ -179,7 +179,9 @@ export class HaCategoryPicker extends SubscribeMixin(LitElement) {
|
|||
|
||||
const filteredItems = fuzzyFilterSort<ScorableCategoryRegistryEntry>(
|
||||
filterString,
|
||||
target.items || []
|
||||
target.items?.filter(
|
||||
(item) => ![NO_CATEGORIES_ID, ADD_NEW_ID].includes(item.category_id)
|
||||
) || []
|
||||
);
|
||||
if (filteredItems?.length === 0) {
|
||||
if (this.noAdd) {
|
||||
|
@ -224,6 +226,8 @@ export class HaCategoryPicker extends SubscribeMixin(LitElement) {
|
|||
|
||||
if (newValue === NO_CATEGORIES_ID) {
|
||||
newValue = "";
|
||||
this.comboBox.setInputValue("");
|
||||
return;
|
||||
}
|
||||
|
||||
if (![ADD_NEW_SUGGESTION_ID, ADD_NEW_ID].includes(newValue)) {
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
nothing,
|
||||
} from "lit";
|
||||
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||
|
@ -24,16 +25,18 @@ import {
|
|||
DataTableColumnContainer,
|
||||
RowClickedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/data-table/ha-data-table-labels";
|
||||
import "../../../components/entity/ha-battery-icon";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-check-list-item";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-filter-devices";
|
||||
import "../../../components/ha-filter-floor-areas";
|
||||
import "../../../components/ha-filter-integrations";
|
||||
import "../../../components/ha-filter-labels";
|
||||
import "../../../components/ha-filter-states";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-alert";
|
||||
import { ConfigEntry, sortConfigEntries } from "../../../data/config_entries";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import {
|
||||
|
@ -47,7 +50,12 @@ import {
|
|||
findBatteryEntity,
|
||||
} from "../../../data/entity_registry";
|
||||
import { IntegrationManifest } from "../../../data/integration";
|
||||
import {
|
||||
LabelRegistryEntry,
|
||||
subscribeLabelRegistry,
|
||||
} from "../../../data/label_registry";
|
||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { brandsUrl } from "../../../util/brands-url";
|
||||
|
@ -60,10 +68,11 @@ interface DeviceRowData extends DeviceRegistryEntry {
|
|||
area?: string;
|
||||
integration?: string;
|
||||
battery_entity?: [string | undefined, string | undefined];
|
||||
label_entries: EntityRegistryEntry[];
|
||||
}
|
||||
|
||||
@customElement("ha-config-devices-dashboard")
|
||||
export class HaConfigDeviceDashboard extends LitElement {
|
||||
export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
@ -91,6 +100,9 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
|
||||
@state() private _expandedFilter?: string;
|
||||
|
||||
@state()
|
||||
_labels!: LabelRegistryEntry[];
|
||||
|
||||
private _ignoreLocationChange = false;
|
||||
|
||||
public connectedCallback() {
|
||||
|
@ -190,11 +202,17 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
string,
|
||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
||||
>,
|
||||
localize: LocalizeFunc
|
||||
localize: LocalizeFunc,
|
||||
labelReg?: LabelRegistryEntry[]
|
||||
) => {
|
||||
// Some older installations might have devices pointing at invalid entryIDs
|
||||
// So we guard for that.
|
||||
let outputDevices: DeviceRowData[] = Object.values(devices);
|
||||
let outputDevices: DeviceRowData[] = Object.values(devices).map(
|
||||
(device) => ({
|
||||
...device,
|
||||
label_entries: [],
|
||||
})
|
||||
);
|
||||
|
||||
const deviceEntityLookup: DeviceEntityLookup = {};
|
||||
for (const entity of entities) {
|
||||
|
@ -221,16 +239,16 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
|
||||
const filteredDomains = new Set<string>();
|
||||
|
||||
Object.entries(filters).forEach(([key, flter]) => {
|
||||
if (key === "config_entry" && flter.value?.length) {
|
||||
Object.entries(filters).forEach(([key, filter]) => {
|
||||
if (key === "config_entry" && filter.value?.length) {
|
||||
outputDevices = outputDevices.filter((device) =>
|
||||
device.config_entries.some((entryId) =>
|
||||
flter.value?.includes(entryId)
|
||||
filter.value?.includes(entryId)
|
||||
)
|
||||
);
|
||||
|
||||
const configEntries = entries.filter(
|
||||
(entry) => entry.entry_id && flter.value?.includes(entry.entry_id)
|
||||
(entry) => entry.entry_id && filter.value?.includes(entry.entry_id)
|
||||
);
|
||||
|
||||
configEntries.forEach((configEntry) => {
|
||||
|
@ -239,17 +257,21 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
if (configEntries.length === 1) {
|
||||
filteredConfigEntry = configEntries[0];
|
||||
}
|
||||
} else if (key === "ha-filter-integrations" && flter.value?.length) {
|
||||
} else if (key === "ha-filter-integrations" && filter.value?.length) {
|
||||
const entryIds = entries
|
||||
.filter((entry) => flter.value!.includes(entry.domain))
|
||||
.filter((entry) => filter.value!.includes(entry.domain))
|
||||
.map((entry) => entry.entry_id);
|
||||
outputDevices = outputDevices.filter((device) =>
|
||||
device.config_entries.some((entryId) => entryIds.includes(entryId))
|
||||
);
|
||||
flter.value!.forEach((domain) => filteredDomains.add(domain));
|
||||
} else if (flter.items) {
|
||||
filter.value!.forEach((domain) => filteredDomains.add(domain));
|
||||
} else if (key === "ha-filter-labels" && filter.value?.length) {
|
||||
outputDevices = outputDevices.filter((device) =>
|
||||
flter.items!.has(device.id)
|
||||
device.labels.some((lbl) => filter.value!.includes(lbl))
|
||||
);
|
||||
} else if (filter.items) {
|
||||
outputDevices = outputDevices.filter((device) =>
|
||||
filter.items!.has(device.id)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -270,6 +292,12 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
.map((entId) => entryLookup[entId]),
|
||||
manifestLookup
|
||||
);
|
||||
|
||||
const labels = labelReg && device?.labels;
|
||||
const labelsEntries = (labels || []).map(
|
||||
(lbl) => labelReg!.find((label) => label.label_id === lbl)!
|
||||
);
|
||||
|
||||
return {
|
||||
...device,
|
||||
name: computeDeviceName(
|
||||
|
@ -306,6 +334,7 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
this.hass.states[
|
||||
this._batteryEntity(device.id, deviceEntityLookup) || ""
|
||||
]?.state,
|
||||
label_entries: labelsEntries,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -351,8 +380,15 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
direction: "asc",
|
||||
grows: true,
|
||||
template: (device) => html`
|
||||
${device.name}
|
||||
<div style="font-size: 14px;">${device.name}</div>
|
||||
<div class="secondary">${device.area} | ${device.integration}</div>
|
||||
${device.label_entries.length
|
||||
? html`
|
||||
<ha-data-table-labels
|
||||
.labels=${device.label_entries}
|
||||
></ha-data-table-labels>
|
||||
`
|
||||
: nothing}
|
||||
`,
|
||||
};
|
||||
} else {
|
||||
|
@ -361,8 +397,18 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
main: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
template: (device) => html`
|
||||
<div style="font-size: 14px;">${device.name}</div>
|
||||
${device.label_entries.length
|
||||
? html`
|
||||
<ha-data-table-labels
|
||||
.labels=${device.label_entries}
|
||||
></ha-data-table-labels>
|
||||
`
|
||||
: nothing}
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -441,9 +487,25 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
? this.hass.localize("ui.panel.config.devices.disabled")
|
||||
: "",
|
||||
};
|
||||
columns.labels = {
|
||||
title: "",
|
||||
hidden: true,
|
||||
filterable: true,
|
||||
template: (device) =>
|
||||
device.label_entries.map((lbl) => lbl.name).join(" "),
|
||||
};
|
||||
|
||||
return columns;
|
||||
});
|
||||
|
||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
||||
return [
|
||||
subscribeLabelRegistry(this.hass.connection, (labels) => {
|
||||
this._labels = labels;
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const { devicesOutput } = this._devicesAndFilterDomains(
|
||||
this.hass.devices,
|
||||
|
@ -452,7 +514,8 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
this.hass.areas,
|
||||
this.manifests,
|
||||
this._filters,
|
||||
this.hass.localize
|
||||
this.hass.localize,
|
||||
this._labels
|
||||
);
|
||||
|
||||
return html`
|
||||
|
@ -479,6 +542,7 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
@row-click=${this._handleRowClicked}
|
||||
clickable
|
||||
hasFab
|
||||
class=${this.narrow ? "narrow" : ""}
|
||||
>
|
||||
<ha-integration-overflow-menu
|
||||
.hass=${this.hass}
|
||||
|
@ -531,6 +595,15 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
.narrow=${this.narrow}
|
||||
@expanded-changed=${this._filterExpanded}
|
||||
></ha-filter-states>
|
||||
<ha-filter-labels
|
||||
.hass=${this.hass}
|
||||
.value=${this._filters["ha-filter-labels"]?.value}
|
||||
@data-table-filter-changed=${this._filterChanged}
|
||||
slot="filter-pane"
|
||||
.expanded=${this._expandedFilter === "ha-filter-labels"}
|
||||
.narrow=${this.narrow}
|
||||
@expanded-changed=${this._filterExpanded}
|
||||
></ha-filter-labels>
|
||||
</hass-tabs-subpage-data-table>
|
||||
`;
|
||||
}
|
||||
|
@ -590,8 +663,10 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
this.hass.areas,
|
||||
this.manifests,
|
||||
this._filters,
|
||||
this.hass.localize
|
||||
this.hass.localize,
|
||||
this._labels
|
||||
);
|
||||
|
||||
if (
|
||||
filteredDomains.size === 1 &&
|
||||
(PROTOCOL_INTEGRATIONS as ReadonlyArray<string>).includes(
|
||||
|
@ -611,6 +686,12 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
css`
|
||||
hass-tabs-subpage-data-table {
|
||||
--data-table-row-height: 60px;
|
||||
}
|
||||
hass-tabs-subpage-data-table.narrow {
|
||||
--data-table-row-height: 72px;
|
||||
}
|
||||
ha-button-menu {
|
||||
margin-left: 8px;
|
||||
margin-inline-start: 8px;
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
mdiRestoreAlert,
|
||||
mdiUndo,
|
||||
} from "@mdi/js";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
|
@ -37,16 +37,18 @@ import type {
|
|||
RowClickedEvent,
|
||||
SelectionChangedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/data-table/ha-data-table-labels";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-check-list-item";
|
||||
import "../../../components/ha-filter-devices";
|
||||
import "../../../components/ha-filter-floor-areas";
|
||||
import "../../../components/ha-filter-integrations";
|
||||
import "../../../components/ha-filter-states";
|
||||
import "../../../components/ha-filter-labels";
|
||||
import "../../../components/ha-icon";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-alert";
|
||||
import { ConfigEntry, getConfigEntries } from "../../../data/config_entries";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
|
@ -57,6 +59,10 @@ import {
|
|||
updateEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { entryIcon } from "../../../data/icons";
|
||||
import {
|
||||
LabelRegistryEntry,
|
||||
subscribeLabelRegistry,
|
||||
} from "../../../data/label_registry";
|
||||
import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
|
@ -65,6 +71,7 @@ import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info
|
|||
import "../../../layouts/hass-loading-screen";
|
||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import type { HaTabsSubpageDataTable } from "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
@ -86,10 +93,11 @@ export interface EntityRow extends StateEntity {
|
|||
status: string | undefined;
|
||||
area?: string;
|
||||
localized_platform: string;
|
||||
label_entries: LabelRegistryEntry[];
|
||||
}
|
||||
|
||||
@customElement("ha-config-entities")
|
||||
export class HaConfigEntities extends LitElement {
|
||||
export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ type: Boolean }) public isWide = false;
|
||||
|
@ -119,6 +127,9 @@ export class HaConfigEntities extends LitElement {
|
|||
|
||||
@state() private _expandedFilter?: string;
|
||||
|
||||
@state()
|
||||
_labels!: LabelRegistryEntry[];
|
||||
|
||||
@query("hass-tabs-subpage-data-table", true)
|
||||
private _dataTable!: HaTabsSubpageDataTable;
|
||||
|
||||
|
@ -202,14 +213,21 @@ export class HaConfigEntities extends LitElement {
|
|||
filterable: true,
|
||||
direction: "asc",
|
||||
grows: true,
|
||||
template: narrow
|
||||
? (entry) => html`
|
||||
${entry.name}<br />
|
||||
<div class="secondary">
|
||||
template: (entry) => html`
|
||||
<div style="font-size: 14px;">${entry.name}</div>
|
||||
${narrow
|
||||
? html`<div class="secondary">
|
||||
${entry.entity_id} | ${entry.localized_platform}
|
||||
</div>
|
||||
`
|
||||
: undefined,
|
||||
</div>`
|
||||
: nothing}
|
||||
${entry.label_entries.length
|
||||
? html`
|
||||
<ha-data-table-labels
|
||||
.labels=${entry.label_entries}
|
||||
></ha-data-table-labels>
|
||||
`
|
||||
: nothing}
|
||||
`,
|
||||
},
|
||||
entity_id: {
|
||||
title: localize("ui.panel.config.entities.picker.headers.entity_id"),
|
||||
|
@ -301,6 +319,13 @@ export class HaConfigEntities extends LitElement {
|
|||
`
|
||||
: "—",
|
||||
},
|
||||
labels: {
|
||||
title: "",
|
||||
hidden: true,
|
||||
filterable: true,
|
||||
template: (entry) =>
|
||||
entry.label_entries.map((lbl) => lbl.name).join(" "),
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -315,7 +340,8 @@ export class HaConfigEntities extends LitElement {
|
|||
string,
|
||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
||||
>,
|
||||
entries?: ConfigEntry[]
|
||||
entries?: ConfigEntry[],
|
||||
labelReg?: LabelRegistryEntry[]
|
||||
) => {
|
||||
const result: EntityRow[] = [];
|
||||
|
||||
|
@ -337,12 +363,12 @@ export class HaConfigEntities extends LitElement {
|
|||
let filteredConfigEntry: ConfigEntry | undefined;
|
||||
const filteredDomains = new Set<string>();
|
||||
|
||||
Object.entries(filters).forEach(([key, flter]) => {
|
||||
if (key === "config_entry" && flter.value?.length) {
|
||||
Object.entries(filters).forEach(([key, filter]) => {
|
||||
if (key === "config_entry" && filter.value?.length) {
|
||||
filteredEntities = filteredEntities.filter(
|
||||
(entity) =>
|
||||
entity.config_entry_id &&
|
||||
flter.value?.includes(entity.config_entry_id)
|
||||
filter.value?.includes(entity.config_entry_id)
|
||||
);
|
||||
|
||||
if (!entries) {
|
||||
|
@ -351,7 +377,7 @@ export class HaConfigEntities extends LitElement {
|
|||
}
|
||||
|
||||
const configEntries = entries.filter(
|
||||
(entry) => entry.entry_id && flter.value?.includes(entry.entry_id)
|
||||
(entry) => entry.entry_id && filter.value?.includes(entry.entry_id)
|
||||
);
|
||||
|
||||
configEntries.forEach((configEntry) => {
|
||||
|
@ -360,23 +386,27 @@ export class HaConfigEntities extends LitElement {
|
|||
if (configEntries.length === 1) {
|
||||
filteredConfigEntry = configEntries[0];
|
||||
}
|
||||
} else if (key === "ha-filter-integrations" && flter.value?.length) {
|
||||
} else if (key === "ha-filter-integrations" && filter.value?.length) {
|
||||
if (!entries) {
|
||||
this._loadConfigEntries();
|
||||
return;
|
||||
}
|
||||
const entryIds = entries
|
||||
.filter((entry) => flter.value!.includes(entry.domain))
|
||||
.filter((entry) => filter.value!.includes(entry.domain))
|
||||
.map((entry) => entry.entry_id);
|
||||
filteredEntities = filteredEntities.filter(
|
||||
(entity) =>
|
||||
entity.config_entry_id &&
|
||||
entryIds.includes(entity.config_entry_id)
|
||||
);
|
||||
flter.value!.forEach((domain) => filteredDomains.add(domain));
|
||||
} else if (flter.items) {
|
||||
filter.value!.forEach((domain) => filteredDomains.add(domain));
|
||||
} else if (key === "ha-filter-labels" && filter.value?.length) {
|
||||
filteredEntities = filteredEntities.filter((entity) =>
|
||||
flter.items!.has(entity.entity_id)
|
||||
entity.labels.some((lbl) => filter.value!.includes(lbl))
|
||||
);
|
||||
} else if (filter.items) {
|
||||
filteredEntities = filteredEntities.filter((entity) =>
|
||||
filter.items!.has(entity.entity_id)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -404,6 +434,11 @@ export class HaConfigEntities extends LitElement {
|
|||
continue;
|
||||
}
|
||||
|
||||
const labels = labelReg && entry?.labels;
|
||||
const labelsEntries = (labels || []).map(
|
||||
(lbl) => labelReg!.find((label) => label.label_id === lbl)!
|
||||
);
|
||||
|
||||
result.push({
|
||||
...entry,
|
||||
entity,
|
||||
|
@ -431,6 +466,7 @@ export class HaConfigEntities extends LitElement {
|
|||
: localize(
|
||||
"ui.panel.config.entities.picker.status.available"
|
||||
),
|
||||
label_entries: labelsEntries,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -438,6 +474,14 @@ export class HaConfigEntities extends LitElement {
|
|||
}
|
||||
);
|
||||
|
||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
||||
return [
|
||||
subscribeLabelRegistry(this.hass.connection, (labels) => {
|
||||
this._labels = labels;
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this.hass || this._entities === undefined) {
|
||||
return html` <hass-loading-screen></hass-loading-screen> `;
|
||||
|
@ -451,7 +495,8 @@ export class HaConfigEntities extends LitElement {
|
|||
this.hass.areas,
|
||||
this._stateEntities,
|
||||
this._filters,
|
||||
this._entries
|
||||
this._entries,
|
||||
this._labels
|
||||
);
|
||||
|
||||
const includeAddDeviceFab =
|
||||
|
@ -492,6 +537,7 @@ export class HaConfigEntities extends LitElement {
|
|||
@row-click=${this._openEditEntry}
|
||||
id="entity_id"
|
||||
.hasFab=${includeAddDeviceFab}
|
||||
class=${this.narrow ? "narrow" : ""}
|
||||
>
|
||||
<ha-integration-overflow-menu
|
||||
.hass=${this.hass}
|
||||
|
@ -633,6 +679,15 @@ export class HaConfigEntities extends LitElement {
|
|||
.narrow=${this.narrow}
|
||||
@expanded-changed=${this._filterExpanded}
|
||||
></ha-filter-states>
|
||||
<ha-filter-labels
|
||||
.hass=${this.hass}
|
||||
.value=${this._filters["ha-filter-labels"]?.value}
|
||||
@data-table-filter-changed=${this._filterChanged}
|
||||
slot="filter-pane"
|
||||
.expanded=${this._expandedFilter === "ha-filter-labels"}
|
||||
.narrow=${this.narrow}
|
||||
@expanded-changed=${this._filterExpanded}
|
||||
></ha-filter-labels>
|
||||
${includeAddDeviceFab
|
||||
? html`<ha-fab
|
||||
.label=${this.hass.localize("ui.panel.config.devices.add_device")}
|
||||
|
@ -918,7 +973,8 @@ export class HaConfigEntities extends LitElement {
|
|||
this.hass.areas,
|
||||
this._stateEntities,
|
||||
this._filters,
|
||||
this._entries
|
||||
this._entries,
|
||||
this._labels
|
||||
);
|
||||
if (
|
||||
filteredDomains.size === 1 &&
|
||||
|
@ -940,6 +996,12 @@ export class HaConfigEntities extends LitElement {
|
|||
return [
|
||||
haStyle,
|
||||
css`
|
||||
hass-tabs-subpage-data-table {
|
||||
--data-table-row-height: 60px;
|
||||
}
|
||||
hass-tabs-subpage-data-table.narrow {
|
||||
--data-table-row-height: 72px;
|
||||
}
|
||||
hass-loading-screen {
|
||||
--app-header-background-color: var(--sidebar-background-color);
|
||||
--app-header-text-color: var(--sidebar-text-color);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { mdiHelpCircle, mdiPlus } from "@mdi/js";
|
||||
import { mdiDelete, mdiHelpCircle, mdiPlus } from "@mdi/js";
|
||||
import { LitElement, PropertyValues, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
|
@ -11,6 +11,7 @@ import {
|
|||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-relative-time";
|
||||
import "../../../components/ha-icon-overflow-menu";
|
||||
import {
|
||||
LabelRegistryEntry,
|
||||
LabelRegistryEntryMutableParams,
|
||||
|
@ -71,6 +72,26 @@ export class HaConfigLabels extends LitElement {
|
|||
filterable: true,
|
||||
grows: true,
|
||||
},
|
||||
actions: {
|
||||
title: "",
|
||||
width: "64px",
|
||||
type: "overflow-menu",
|
||||
template: (label) => html`
|
||||
<ha-icon-overflow-menu
|
||||
.hass=${this.hass}
|
||||
narrow
|
||||
.items=${[
|
||||
{
|
||||
label: this.hass.localize("ui.common.delete"),
|
||||
path: mdiDelete,
|
||||
action: () => this._removeLabel(label),
|
||||
warning: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
</ha-icon-overflow-menu>
|
||||
`,
|
||||
},
|
||||
};
|
||||
return columns;
|
||||
});
|
||||
|
@ -189,6 +210,7 @@ export class HaConfigLabels extends LitElement {
|
|||
}),
|
||||
dismissText: this.hass!.localize("ui.common.cancel"),
|
||||
confirmText: this.hass!.localize("ui.common.remove"),
|
||||
destructive: true,
|
||||
}))
|
||||
) {
|
||||
return false;
|
||||
|
|
|
@ -16,6 +16,7 @@ import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
|||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
css,
|
||||
html,
|
||||
|
@ -297,6 +298,13 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||
}
|
||||
);
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
super.updated(changedProps);
|
||||
if (changedProps.has("_entityReg")) {
|
||||
this._applyFilters();
|
||||
}
|
||||
}
|
||||
|
||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
||||
return [
|
||||
subscribeCategoryRegistry(this.hass.connection, "scene", (categories) => {
|
||||
|
|
|
@ -15,6 +15,7 @@ import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
|||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
css,
|
||||
html,
|
||||
|
@ -560,6 +561,13 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||
this._filteredScripts = items ? [...items] : undefined;
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
super.updated(changedProps);
|
||||
if (changedProps.has("_entityReg")) {
|
||||
this._applyFilters();
|
||||
}
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
if (this._searchParms.has("blueprint")) {
|
||||
this._filterBlueprint();
|
||||
|
|
|
@ -98,10 +98,10 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
|
|||
display: block;
|
||||
padding: 24px 16px 16px;
|
||||
}
|
||||
:host {
|
||||
--ha-card-border-radius: inherit !important;
|
||||
--ha-card-border-width: inherit !important;
|
||||
--ha-card-box-shadow: inherit !important;
|
||||
#root {
|
||||
--ha-card-border-radius: var(--restore-card-border-radius, inherit);
|
||||
--ha-card-border-width: var(--restore-card-border-width, inherit);
|
||||
--ha-card-box-shadow: var(--restore-card-border-shadow, inherit);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ export class PanelView extends LitElement implements LovelaceViewElement {
|
|||
|
||||
const card: LovelaceCard = this.cards[0];
|
||||
card.isPanel = true;
|
||||
card.toggleAttribute("no-border", true);
|
||||
|
||||
if (this.isStrategy || !this.lovelace?.editMode) {
|
||||
card.editMode = false;
|
||||
|
@ -116,6 +117,7 @@ export class PanelView extends LitElement implements LovelaceViewElement {
|
|||
}
|
||||
|
||||
const wrapper = document.createElement("hui-card-options");
|
||||
wrapper.toggleAttribute("no-border", true);
|
||||
wrapper.hass = this.hass;
|
||||
wrapper.lovelace = this.lovelace;
|
||||
wrapper.path = [this.index!, 0];
|
||||
|
@ -130,9 +132,12 @@ export class PanelView extends LitElement implements LovelaceViewElement {
|
|||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
--restore-card-border-radius: var(--ha-card-border-radius, 12px);
|
||||
--restore-card-border-width: var(--ha-card-border-width, 1px);
|
||||
--restore-card-box-shadow: var(--ha-card-box-shadow, none);
|
||||
}
|
||||
|
||||
* {
|
||||
[no-border] {
|
||||
--ha-card-border-radius: 0;
|
||||
--ha-card-border-width: 0;
|
||||
--ha-card-box-shadow: none;
|
||||
|
|
|
@ -32,6 +32,7 @@ const mainStyles = css`
|
|||
--accent-color: ${unsafeCSS(DEFAULT_ACCENT_COLOR)};
|
||||
--divider-color: rgba(0, 0, 0, 0.12);
|
||||
--outline-color: rgba(0, 0, 0, 0.12);
|
||||
--outline-hover-color: rgba(0, 0, 0, 0.24);
|
||||
|
||||
--scrollbar-thumb-color: rgb(194, 194, 194);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ export const darkStyles = {
|
|||
"switch-unchecked-track-color": "#9b9b9b",
|
||||
"divider-color": "rgba(225, 225, 225, .12)",
|
||||
"outline-color": "rgba(225, 225, 225, .12)",
|
||||
"outline-hover-color": "rgba(225, 225, 225, .24)",
|
||||
"mdc-ripple-color": "#AAAAAA",
|
||||
"mdc-linear-progress-buffer-color": "rgba(255, 255, 255, 0.1)",
|
||||
|
||||
|
|
|
@ -1959,7 +1959,11 @@
|
|||
"labels": {
|
||||
"caption": "Labels",
|
||||
"description": "Group devices and entities",
|
||||
"headers": { "name": "Name", "icon": "Icon", "color": "Color" },
|
||||
"headers": {
|
||||
"name": "Name",
|
||||
"icon": "Icon",
|
||||
"color": "Color"
|
||||
},
|
||||
"add_label": "Add label",
|
||||
"no_labels": "You don't have any labels",
|
||||
"introduction": "Labels can help you organize your areas, devices and entities. They can be used to filter in the UI, or use them as a target in automations.",
|
||||
|
@ -5388,7 +5392,6 @@
|
|||
"type": "View type",
|
||||
"type_warning_sections": "You can not change your view to use the 'sections' view type because migration is not supported yet. Start from scratch with a new view if you want to experiment with the 'sections' view.",
|
||||
"type_warning_others": "You can not change your view to an other type because migration is not supported yet. Start from scratch with a new view if you want to use another view type.",
|
||||
|
||||
"types": {
|
||||
"masonry": "Masonry (default)",
|
||||
"sidebar": "Sidebar",
|
||||
|
|
104
yarn.lock
104
yarn.lock
|
@ -4543,15 +4543,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/eslint-plugin@npm:7.3.1":
|
||||
version: 7.3.1
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:7.3.1"
|
||||
"@typescript-eslint/eslint-plugin@npm:7.4.0":
|
||||
version: 7.4.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:7.4.0"
|
||||
dependencies:
|
||||
"@eslint-community/regexpp": "npm:^4.5.1"
|
||||
"@typescript-eslint/scope-manager": "npm:7.3.1"
|
||||
"@typescript-eslint/type-utils": "npm:7.3.1"
|
||||
"@typescript-eslint/utils": "npm:7.3.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.3.1"
|
||||
"@typescript-eslint/scope-manager": "npm:7.4.0"
|
||||
"@typescript-eslint/type-utils": "npm:7.4.0"
|
||||
"@typescript-eslint/utils": "npm:7.4.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.4.0"
|
||||
debug: "npm:^4.3.4"
|
||||
graphemer: "npm:^1.4.0"
|
||||
ignore: "npm:^5.2.4"
|
||||
|
@ -4564,44 +4564,44 @@ __metadata:
|
|||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10/8ed276113a714d93ab3ababb1179e4785bd9378e6d97726519ea1d2ac502a94475e0be988c2ec427dcfc1e6950329d58da6e64131ee87028fce63493461cc51a
|
||||
checksum: 10/9bd8852c7e4e9608c3fded94f7c60506cc7d2b6d8a8c1cad6d48969a7363751b20282874e55ccdf180635cf204cb10b3e1e5c3d1cff34d4fcd07762be3fc138e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/parser@npm:7.3.1":
|
||||
version: 7.3.1
|
||||
resolution: "@typescript-eslint/parser@npm:7.3.1"
|
||||
"@typescript-eslint/parser@npm:7.4.0":
|
||||
version: 7.4.0
|
||||
resolution: "@typescript-eslint/parser@npm:7.4.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager": "npm:7.3.1"
|
||||
"@typescript-eslint/types": "npm:7.3.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.3.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.3.1"
|
||||
"@typescript-eslint/scope-manager": "npm:7.4.0"
|
||||
"@typescript-eslint/types": "npm:7.4.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.4.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.4.0"
|
||||
debug: "npm:^4.3.4"
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10/018326010fec1dcefd75809ccac5102a475bf1e052d824b898d707e7c0bf3e51e101164b410d1b2a513628985c96eb412538644d2005e26b99a22db6eb9402df
|
||||
checksum: 10/142a9e1187d305ed43b4fef659c36fa4e28359467198c986f0955c70b4067c9799f4c85d9881fbf099c55dfb265e30666e28b3ef290520e242b45ca7cb8e4ca9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/scope-manager@npm:7.3.1":
|
||||
version: 7.3.1
|
||||
resolution: "@typescript-eslint/scope-manager@npm:7.3.1"
|
||||
"@typescript-eslint/scope-manager@npm:7.4.0":
|
||||
version: 7.4.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:7.4.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:7.3.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.3.1"
|
||||
checksum: 10/7384d1f46d7f3678a1135a1ac0bd8b6dfa2f01e93b19e2510c7082766cf6983a1bf80b4ccf498651199a81d9f2bdb65101fd7a19226a723260514204d0c30b34
|
||||
"@typescript-eslint/types": "npm:7.4.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.4.0"
|
||||
checksum: 10/8cf9292444f9731017a707cac34bef5ae0eb33b5cd42ed07fcd046e981d97889d9201d48e02f470f2315123f53771435e10b1dc81642af28a11df5352a8e8be2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/type-utils@npm:7.3.1":
|
||||
version: 7.3.1
|
||||
resolution: "@typescript-eslint/type-utils@npm:7.3.1"
|
||||
"@typescript-eslint/type-utils@npm:7.4.0":
|
||||
version: 7.4.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:7.4.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree": "npm:7.3.1"
|
||||
"@typescript-eslint/utils": "npm:7.3.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.4.0"
|
||||
"@typescript-eslint/utils": "npm:7.4.0"
|
||||
debug: "npm:^4.3.4"
|
||||
ts-api-utils: "npm:^1.0.1"
|
||||
peerDependencies:
|
||||
|
@ -4609,23 +4609,23 @@ __metadata:
|
|||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10/fae9003a76a8f2a2a4bb88dc0f82c0a1ca0688633183fac391920e7124a12807aac84bb287a21f61e99523c15223d1c08e7680685ebf21d07429604cba6c420b
|
||||
checksum: 10/a8bd0929d8237679b2b8a7817f070a4b9658ee976882fba8ff37e4a70dd33f87793e1b157771104111fe8054eaa8ad437a010b6aa465072fbdb932647125db2d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/types@npm:7.3.1":
|
||||
version: 7.3.1
|
||||
resolution: "@typescript-eslint/types@npm:7.3.1"
|
||||
checksum: 10/c9c8eae1cf937cececd99a253bd65eb71b40206e79cf917ad9c3b3ab80cc7ce5fefb2804f9fd2a70e7438951f0d1e63df3031fc61e3a08dfef5fde208a12e0ed
|
||||
"@typescript-eslint/types@npm:7.4.0":
|
||||
version: 7.4.0
|
||||
resolution: "@typescript-eslint/types@npm:7.4.0"
|
||||
checksum: 10/2782c5bf65cd3dfa9cd32bc3023676bbca22144987c3f6c6b67fd96c73d4a60b85a57458c49fd11b9971ac6531824bb3ae0664491e7a6de25d80c523c9be92b7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/typescript-estree@npm:7.3.1":
|
||||
version: 7.3.1
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:7.3.1"
|
||||
"@typescript-eslint/typescript-estree@npm:7.4.0":
|
||||
version: 7.4.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:7.4.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:7.3.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.3.1"
|
||||
"@typescript-eslint/types": "npm:7.4.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.4.0"
|
||||
debug: "npm:^4.3.4"
|
||||
globby: "npm:^11.1.0"
|
||||
is-glob: "npm:^4.0.3"
|
||||
|
@ -4635,34 +4635,34 @@ __metadata:
|
|||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10/363ad9864b56394b4000dff7c2b77d0ea52042c3c20e3b86c0f3c66044915632d9890255527c6f3a5ef056886dec72e38fbcfce49d4ad092c160440f54128230
|
||||
checksum: 10/162ec9d7582f45588342e1be36fdb60e41f50bbdfbc3035c91b517ff5d45244f776921c88d88e543e1c7d0f1e6ada5474a8316b78f1b0e6d2233b101bc45b166
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/utils@npm:7.3.1":
|
||||
version: 7.3.1
|
||||
resolution: "@typescript-eslint/utils@npm:7.3.1"
|
||||
"@typescript-eslint/utils@npm:7.4.0":
|
||||
version: 7.4.0
|
||||
resolution: "@typescript-eslint/utils@npm:7.4.0"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.4.0"
|
||||
"@types/json-schema": "npm:^7.0.12"
|
||||
"@types/semver": "npm:^7.5.0"
|
||||
"@typescript-eslint/scope-manager": "npm:7.3.1"
|
||||
"@typescript-eslint/types": "npm:7.3.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.3.1"
|
||||
"@typescript-eslint/scope-manager": "npm:7.4.0"
|
||||
"@typescript-eslint/types": "npm:7.4.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.4.0"
|
||||
semver: "npm:^7.5.4"
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
checksum: 10/234d9d65fe5d0f4a31345bd8f5a6f2879a578b3a531a14c2b3edaa7fb587c71d26249f86c41857382c0405384dc104955c02b588b3cee6fc2734f1ae40aef07b
|
||||
checksum: 10/ffed27e770c486cd000ff892d9049b0afe8b9d6318452a5355b78a37436cbb414bceacae413a2ac813f3e584684825d5e0baa2e6376b7ad6013a108ac91bc19d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/visitor-keys@npm:7.3.1":
|
||||
version: 7.3.1
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:7.3.1"
|
||||
"@typescript-eslint/visitor-keys@npm:7.4.0":
|
||||
version: 7.4.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:7.4.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:7.3.1"
|
||||
"@typescript-eslint/types": "npm:7.4.0"
|
||||
eslint-visitor-keys: "npm:^3.4.1"
|
||||
checksum: 10/163a93597c1d696920a19b3c1627d02368bdd52059f811c0fadd680c38034bb6418ebefe99d8ce26e0dd44ae184f18fab186af775de1a8771256be1a7905c174
|
||||
checksum: 10/70dc99f2ad116c6e2d9e55af249e4453e06bba2ceea515adef2d2e86e97e557865bb1b1d467667462443eb0d624baba36f7442fd1082f3874339bbc381c26e93
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -9688,8 +9688,8 @@ __metadata:
|
|||
"@types/tar": "npm:6.1.11"
|
||||
"@types/ua-parser-js": "npm:0.7.39"
|
||||
"@types/webspeechapi": "npm:0.0.29"
|
||||
"@typescript-eslint/eslint-plugin": "npm:7.3.1"
|
||||
"@typescript-eslint/parser": "npm:7.3.1"
|
||||
"@typescript-eslint/eslint-plugin": "npm:7.4.0"
|
||||
"@typescript-eslint/parser": "npm:7.4.0"
|
||||
"@vaadin/combo-box": "npm:24.3.10"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:24.3.10"
|
||||
"@vibrant/color": "npm:3.2.1-alpha.1"
|
||||
|
|
Loading…
Reference in New Issue