mirror of
https://github.com/home-assistant/frontend.git
synced 2026-05-24 18:17:10 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a2b24fbcd | |||
| 89ab0b4a3d | |||
| dd4cb1df72 | |||
| b81cd37776 | |||
| 34112e7446 | |||
| 2dee45b465 | |||
| 10eb0a8b87 | |||
| 551035238f | |||
| eb9359e9e1 |
+3
-3
@@ -89,8 +89,8 @@
|
||||
"@thomasloven/round-slider": "0.6.0",
|
||||
"@tsparticles/engine": "3.8.1",
|
||||
"@tsparticles/preset-links": "3.2.0",
|
||||
"@vaadin/combo-box": "24.7.9",
|
||||
"@vaadin/vaadin-themable-mixin": "24.7.9",
|
||||
"@vaadin/combo-box": "24.8.0",
|
||||
"@vaadin/vaadin-themable-mixin": "24.8.0",
|
||||
"@vibrant/color": "4.0.0",
|
||||
"@vue/web-component-wrapper": "1.3.0",
|
||||
"@webcomponents/scoped-custom-element-registry": "0.0.10",
|
||||
@@ -210,7 +210,7 @@
|
||||
"lodash.template": "4.5.0",
|
||||
"map-stream": "0.0.7",
|
||||
"pinst": "3.0.0",
|
||||
"prettier": "3.5.3",
|
||||
"prettier": "3.6.0",
|
||||
"rspack-manifest-plugin": "5.0.3",
|
||||
"serve": "14.2.4",
|
||||
"sinon": "21.0.0",
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20250702.2"
|
||||
version = "20250625.0"
|
||||
license = "Apache-2.0"
|
||||
license-files = ["LICENSE*"]
|
||||
description = "The Home Assistant frontend"
|
||||
|
||||
@@ -202,6 +202,7 @@ export function storage(options: {
|
||||
// Don't set the initial value if we have a value in localStorage
|
||||
if (this.__initialized || getValue() === undefined) {
|
||||
setValue(this, value);
|
||||
this.requestUpdate(propertyKey, undefined);
|
||||
}
|
||||
},
|
||||
configurable: true,
|
||||
@@ -211,13 +212,11 @@ export function storage(options: {
|
||||
const oldSetter = descriptor.set;
|
||||
newDescriptor = {
|
||||
...descriptor,
|
||||
get(this: ReactiveStorageElement) {
|
||||
return getValue();
|
||||
},
|
||||
set(this: ReactiveStorageElement, value) {
|
||||
// Don't set the initial value if we have a value in localStorage
|
||||
if (this.__initialized || getValue() === undefined) {
|
||||
setValue(this, value);
|
||||
this.requestUpdate(propertyKey, undefined);
|
||||
}
|
||||
oldSetter?.call(this, value);
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import { callService, type HassEntity } from "home-assistant-js-websocket";
|
||||
import { computeStateDomain } from "./compute_state_domain";
|
||||
import { isUnavailableState, UNAVAILABLE } from "../../data/entity";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
@@ -62,7 +62,7 @@ export const toggleGroupEntities = (
|
||||
|
||||
const entitiesIds = states.map((stateObj) => stateObj.entity_id);
|
||||
|
||||
hass.callService(domain, service, {
|
||||
callService(hass.connection, domain, service, {
|
||||
entity_id: entitiesIds,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -390,7 +390,6 @@ export class HaChartBase extends LitElement {
|
||||
type: "inside",
|
||||
orient: "horizontal",
|
||||
filterMode: "none",
|
||||
xAxisIndex: 0,
|
||||
moveOnMouseMove: !this._isTouchDevice || this._isZoomed,
|
||||
preventDefaultMouseMove: !this._isTouchDevice || this._isZoomed,
|
||||
zoomLock: !this._isTouchDevice && !this._modifierPressed,
|
||||
|
||||
@@ -366,7 +366,6 @@ export class HaAreaPicker extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.autofocus=${this.autofocus}
|
||||
.label=${this.label}
|
||||
.helper=${this.helper}
|
||||
.notFoundLabel=${this.hass.localize(
|
||||
"ui.components.area-picker.no_match"
|
||||
)}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { mdiDrag, mdiTextureBox } from "@mdi/js";
|
||||
import { mdiTextureBox } from "@mdi/js";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { computeFloorName } from "../common/entity/compute_floor_name";
|
||||
import { getAreaContext } from "../common/entity/context/get_area_context";
|
||||
import { stringCompare } from "../common/string/compare";
|
||||
import { areaCompare } from "../data/area_registry";
|
||||
import type { FloorRegistryEntry } from "../data/floor_registry";
|
||||
import { getFloors } from "../panels/lovelace/strategies/areas/helpers/areas-strategy-helper";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import "./ha-expansion-panel";
|
||||
import "./ha-floor-icon";
|
||||
@@ -18,14 +17,9 @@ import type { DisplayItem, DisplayValue } from "./ha-items-display-editor";
|
||||
import "./ha-svg-icon";
|
||||
import "./ha-textfield";
|
||||
|
||||
export interface AreasFloorsDisplayValue {
|
||||
areas_display?: {
|
||||
hidden?: string[];
|
||||
order?: string[];
|
||||
};
|
||||
floors_display?: {
|
||||
order?: string[];
|
||||
};
|
||||
export interface AreasDisplayValue {
|
||||
hidden?: string[];
|
||||
order?: string[];
|
||||
}
|
||||
|
||||
const UNASSIGNED_FLOOR = "__unassigned__";
|
||||
@@ -36,10 +30,12 @@ export class HaAreasFloorsDisplayEditor extends LitElement {
|
||||
|
||||
@property() public label?: string;
|
||||
|
||||
@property({ attribute: false }) public value?: AreasFloorsDisplayValue;
|
||||
@property({ attribute: false }) public value?: AreasDisplayValue;
|
||||
|
||||
@property() public helper?: string;
|
||||
|
||||
@property({ type: Boolean }) public expanded = false;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
@property({ type: Boolean }) public required = false;
|
||||
@@ -48,79 +44,51 @@ export class HaAreasFloorsDisplayEditor extends LitElement {
|
||||
public showNavigationButton = false;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const groupedAreasItems = this._groupedAreasItems(
|
||||
this.hass.areas,
|
||||
this.hass.floors
|
||||
);
|
||||
const groupedItems = this._groupedItems(this.hass.areas, this.hass.floors);
|
||||
|
||||
const filteredFloors = this._sortedFloors(
|
||||
this.hass.floors,
|
||||
this.value?.floors_display?.order
|
||||
).filter(
|
||||
const filteredFloors = this._sortedFloors(this.hass.floors).filter(
|
||||
(floor) =>
|
||||
// Only include floors that have areas assigned to them
|
||||
groupedAreasItems[floor.floor_id]?.length > 0
|
||||
groupedItems[floor.floor_id]?.length > 0
|
||||
);
|
||||
|
||||
const value: DisplayValue = {
|
||||
order: this.value?.areas_display?.order ?? [],
|
||||
hidden: this.value?.areas_display?.hidden ?? [],
|
||||
order: this.value?.order ?? [],
|
||||
hidden: this.value?.hidden ?? [],
|
||||
};
|
||||
|
||||
const canReorderFloors =
|
||||
filteredFloors.filter((floor) => floor.floor_id !== UNASSIGNED_FLOOR)
|
||||
.length > 1;
|
||||
|
||||
return html`
|
||||
${this.label ? html`<label>${this.label}</label>` : nothing}
|
||||
<ha-sortable
|
||||
draggable-selector=".draggable"
|
||||
handle-selector=".handle"
|
||||
@item-moved=${this._floorMoved}
|
||||
.disabled=${this.disabled || !canReorderFloors}
|
||||
invert-swap
|
||||
<ha-expansion-panel
|
||||
outlined
|
||||
.header=${this.label}
|
||||
.expanded=${this.expanded}
|
||||
>
|
||||
<div>
|
||||
${repeat(
|
||||
filteredFloors,
|
||||
(floor) => floor.floor_id,
|
||||
(floor: FloorRegistryEntry) => html`
|
||||
<ha-expansion-panel
|
||||
outlined
|
||||
.header=${computeFloorName(floor)}
|
||||
left-chevron
|
||||
class=${floor.floor_id === UNASSIGNED_FLOOR ? "" : "draggable"}
|
||||
>
|
||||
<ha-floor-icon
|
||||
slot="leading-icon"
|
||||
.floor=${floor}
|
||||
></ha-floor-icon>
|
||||
${floor.floor_id === UNASSIGNED_FLOOR || !canReorderFloors
|
||||
? nothing
|
||||
: html`
|
||||
<ha-svg-icon
|
||||
class="handle"
|
||||
slot="icons"
|
||||
.path=${mdiDrag}
|
||||
></ha-svg-icon>
|
||||
`}
|
||||
<ha-svg-icon slot="leading-icon" .path=${mdiTextureBox}></ha-svg-icon>
|
||||
${filteredFloors.map(
|
||||
(floor) => html`
|
||||
<div class="floor">
|
||||
<div class="header">
|
||||
<ha-floor-icon .floor=${floor}></ha-floor-icon>
|
||||
<p>${computeFloorName(floor)}</p>
|
||||
</div>
|
||||
<div class="areas">
|
||||
<ha-items-display-editor
|
||||
.hass=${this.hass}
|
||||
.items=${groupedAreasItems[floor.floor_id]}
|
||||
.items=${groupedItems[floor.floor_id] || []}
|
||||
.value=${value}
|
||||
.floorId=${floor.floor_id}
|
||||
@value-changed=${this._areaDisplayChanged}
|
||||
.showNavigationButton=${this.showNavigationButton}
|
||||
></ha-items-display-editor>
|
||||
</ha-expansion-panel>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
</ha-sortable>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</ha-expansion-panel>
|
||||
`;
|
||||
}
|
||||
|
||||
private _groupedAreasItems = memoizeOne(
|
||||
private _groupedItems = memoizeOne(
|
||||
(
|
||||
hassAreas: HomeAssistant["areas"],
|
||||
// update items if floors change
|
||||
@@ -144,6 +112,7 @@ export class HaAreasFloorsDisplayEditor extends LitElement {
|
||||
label: area.name,
|
||||
icon: area.icon ?? undefined,
|
||||
iconPath: mdiTextureBox,
|
||||
description: floor?.name,
|
||||
});
|
||||
|
||||
return acc;
|
||||
@@ -155,19 +124,20 @@ export class HaAreasFloorsDisplayEditor extends LitElement {
|
||||
);
|
||||
|
||||
private _sortedFloors = memoizeOne(
|
||||
(
|
||||
hassFloors: HomeAssistant["floors"],
|
||||
order: string[] | undefined
|
||||
): FloorRegistryEntry[] => {
|
||||
const floors = getFloors(hassFloors, order);
|
||||
const noFloors = floors.length === 0;
|
||||
(hassFloors: HomeAssistant["floors"]): FloorRegistryEntry[] => {
|
||||
const floors = Object.values(hassFloors).sort((floorA, floorB) => {
|
||||
if (floorA.level !== floorB.level) {
|
||||
return (floorA.level ?? 0) - (floorB.level ?? 0);
|
||||
}
|
||||
return stringCompare(floorA.name, floorB.name);
|
||||
});
|
||||
floors.push({
|
||||
floor_id: UNASSIGNED_FLOOR,
|
||||
name: noFloors
|
||||
? this.hass.localize("ui.panel.lovelace.strategy.areas.areas")
|
||||
: this.hass.localize("ui.panel.lovelace.strategy.areas.other_areas"),
|
||||
name: this.hass.localize(
|
||||
"ui.panel.lovelace.strategy.areas.unassigned_areas"
|
||||
),
|
||||
icon: null,
|
||||
level: null,
|
||||
level: 999999,
|
||||
aliases: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
@@ -176,101 +146,68 @@ export class HaAreasFloorsDisplayEditor extends LitElement {
|
||||
}
|
||||
);
|
||||
|
||||
private _floorMoved(ev: CustomEvent<HASSDomEvents["item-moved"]>) {
|
||||
private async _areaDisplayChanged(ev) {
|
||||
ev.stopPropagation();
|
||||
const newIndex = ev.detail.newIndex;
|
||||
const oldIndex = ev.detail.oldIndex;
|
||||
const floorIds = this._sortedFloors(
|
||||
this.hass.floors,
|
||||
this.value?.floors_display?.order
|
||||
).map((floor) => floor.floor_id);
|
||||
const newOrder = [...floorIds];
|
||||
const movedFloorId = newOrder.splice(oldIndex, 1)[0];
|
||||
newOrder.splice(newIndex, 0, movedFloorId);
|
||||
const newValue: AreasFloorsDisplayValue = {
|
||||
areas_display: this.value?.areas_display,
|
||||
floors_display: {
|
||||
order: newOrder,
|
||||
},
|
||||
};
|
||||
if (newValue.floors_display?.order?.length === 0) {
|
||||
delete newValue.floors_display.order;
|
||||
}
|
||||
fireEvent(this, "value-changed", { value: newValue });
|
||||
}
|
||||
const value = ev.detail.value as DisplayValue;
|
||||
const currentFloorId = ev.currentTarget.floorId;
|
||||
|
||||
private async _areaDisplayChanged(ev: CustomEvent<{ value: DisplayValue }>) {
|
||||
ev.stopPropagation();
|
||||
const value = ev.detail.value;
|
||||
const currentFloorId = (ev.currentTarget as any).floorId;
|
||||
|
||||
const floorIds = this._sortedFloors(
|
||||
this.hass.floors,
|
||||
this.value?.floors_display?.order
|
||||
).map((floor) => floor.floor_id);
|
||||
|
||||
const oldAreaDisplay = this.value?.areas_display ?? {};
|
||||
|
||||
const oldHidden = oldAreaDisplay?.hidden ?? [];
|
||||
const oldOrder = oldAreaDisplay?.order ?? [];
|
||||
const floorIds = this._sortedFloors(this.hass.floors).map(
|
||||
(floor) => floor.floor_id
|
||||
);
|
||||
|
||||
const newHidden: string[] = [];
|
||||
const newOrder: string[] = [];
|
||||
|
||||
for (const floorId of floorIds) {
|
||||
if ((currentFloorId ?? UNASSIGNED_FLOOR) === floorId) {
|
||||
if (currentFloorId === floorId) {
|
||||
newHidden.push(...(value.hidden ?? []));
|
||||
newOrder.push(...(value.order ?? []));
|
||||
continue;
|
||||
}
|
||||
const hidden = oldHidden.filter((areaId) => {
|
||||
const id = this.hass.areas[areaId]?.floor_id ?? UNASSIGNED_FLOOR;
|
||||
return id === floorId;
|
||||
});
|
||||
if (hidden?.length) {
|
||||
const hidden = this.value?.hidden?.filter(
|
||||
(areaId) => this.hass.areas[areaId]?.floor_id === floorId
|
||||
);
|
||||
if (hidden) {
|
||||
newHidden.push(...hidden);
|
||||
}
|
||||
const order = oldOrder.filter((areaId) => {
|
||||
const id = this.hass.areas[areaId]?.floor_id ?? UNASSIGNED_FLOOR;
|
||||
return id === floorId;
|
||||
});
|
||||
if (order?.length) {
|
||||
const order = this.value?.order?.filter(
|
||||
(areaId) => this.hass.areas[areaId]?.floor_id === floorId
|
||||
);
|
||||
if (order) {
|
||||
newOrder.push(...order);
|
||||
}
|
||||
}
|
||||
|
||||
const newValue: AreasFloorsDisplayValue = {
|
||||
areas_display: {
|
||||
hidden: newHidden,
|
||||
order: newOrder,
|
||||
},
|
||||
floors_display: this.value?.floors_display,
|
||||
const newValue: AreasDisplayValue = {
|
||||
hidden: newHidden,
|
||||
order: newOrder,
|
||||
};
|
||||
if (newValue.areas_display?.hidden?.length === 0) {
|
||||
delete newValue.areas_display.hidden;
|
||||
if (newValue.hidden?.length === 0) {
|
||||
delete newValue.hidden;
|
||||
}
|
||||
if (newValue.areas_display?.order?.length === 0) {
|
||||
delete newValue.areas_display.order;
|
||||
}
|
||||
if (newValue.floors_display?.order?.length === 0) {
|
||||
delete newValue.floors_display.order;
|
||||
if (newValue.order?.length === 0) {
|
||||
delete newValue.order;
|
||||
}
|
||||
|
||||
fireEvent(this, "value-changed", { value: newValue });
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-expansion-panel {
|
||||
margin-bottom: 8px;
|
||||
--expansion-panel-summary-padding: 0 16px;
|
||||
.floor .header p {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
flex: 1:
|
||||
}
|
||||
ha-expansion-panel [slot="leading-icon"] {
|
||||
margin-inline-end: 16px;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
margin-bottom: 8px;
|
||||
.floor .header {
|
||||
margin: 16px 0 8px 0;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ export class HaCodeEditor extends ReactiveElement {
|
||||
|
||||
@property({ type: Boolean }) public error = false;
|
||||
|
||||
@property({ type: Boolean, attribute: "disable-fullscreen" })
|
||||
public disableFullscreen = false;
|
||||
@property({ type: Boolean, attribute: "enable-fullscreen" })
|
||||
public enableFullscreen = true;
|
||||
|
||||
@state() private _value = "";
|
||||
|
||||
@@ -179,7 +179,7 @@ export class HaCodeEditor extends ReactiveElement {
|
||||
if (changedProps.has("_isFullscreen")) {
|
||||
this.classList.toggle("fullscreen", this._isFullscreen);
|
||||
}
|
||||
if (changedProps.has("disableFullscreen")) {
|
||||
if (changedProps.has("enableFullscreen")) {
|
||||
this._updateFullscreenButton();
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ export class HaCodeEditor extends ReactiveElement {
|
||||
private _updateFullscreenButton() {
|
||||
const existingButton = this.renderRoot.querySelector(".fullscreen-button");
|
||||
|
||||
if (this.disableFullscreen) {
|
||||
if (!this.enableFullscreen) {
|
||||
// Remove button if it exists and fullscreen is disabled
|
||||
if (existingButton) {
|
||||
existingButton.remove();
|
||||
@@ -317,7 +317,7 @@ export class HaCodeEditor extends ReactiveElement {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this._toggleFullscreen();
|
||||
} else if (e.key === "F11" && !this.disableFullscreen) {
|
||||
} else if (e.key === "F11" && this.enableFullscreen) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this._toggleFullscreen();
|
||||
@@ -557,11 +557,11 @@ export class HaCodeEditor extends ReactiveElement {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
z-index: 1;
|
||||
z-index: 10;
|
||||
color: var(--secondary-text-color);
|
||||
background-color: var(--secondary-background-color);
|
||||
background-color: var(--card-background-color);
|
||||
border-radius: 50%;
|
||||
opacity: 0.9;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s;
|
||||
--mdc-icon-button-size: 32px;
|
||||
--mdc-icon-size: 18px;
|
||||
@@ -584,25 +584,22 @@ export class HaCodeEditor extends ReactiveElement {
|
||||
|
||||
:host(.fullscreen) {
|
||||
position: fixed !important;
|
||||
top: calc(var(--header-height, 56px) + 8px) !important;
|
||||
left: 8px !important;
|
||||
right: 8px !important;
|
||||
bottom: 8px !important;
|
||||
top: var(--header-height, 56px) !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
z-index: 9999 !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3) !important;
|
||||
overflow: hidden !important;
|
||||
background-color: var(
|
||||
--code-editor-background-color,
|
||||
var(--card-background-color)
|
||||
) !important;
|
||||
background-color: var(--primary-background-color) !important;
|
||||
margin: 0 !important;
|
||||
padding-top: var(--safe-area-inset-top) !important;
|
||||
padding-left: var(--safe-area-inset-left) !important;
|
||||
padding-right: var(--safe-area-inset-right) !important;
|
||||
padding-bottom: var(--safe-area-inset-bottom) !important;
|
||||
padding: 16px !important;
|
||||
/* Respect iOS safe areas while accounting for header */
|
||||
padding-top: max(16px, env(safe-area-inset-top)) !important;
|
||||
padding-left: max(16px, env(safe-area-inset-left)) !important;
|
||||
padding-right: max(16px, env(safe-area-inset-right)) !important;
|
||||
padding-bottom: max(16px, env(safe-area-inset-bottom)) !important;
|
||||
box-sizing: border-box !important;
|
||||
display: block !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
:host(.fullscreen) .cm-editor {
|
||||
@@ -612,8 +609,12 @@ export class HaCodeEditor extends ReactiveElement {
|
||||
}
|
||||
|
||||
:host(.fullscreen) .fullscreen-button {
|
||||
top: calc(var(--safe-area-inset-top, 0px) + 8px);
|
||||
right: calc(var(--safe-area-inset-right, 0px) + 8px);
|
||||
position: fixed;
|
||||
top: calc(
|
||||
var(--header-height, 56px) + max(8px, env(safe-area-inset-top))
|
||||
);
|
||||
right: max(24px, calc(env(safe-area-inset-right) + 8px));
|
||||
z-index: 10000;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -369,6 +369,7 @@ export class HaComboBox extends LitElement {
|
||||
}
|
||||
vaadin-combo-box-light {
|
||||
position: relative;
|
||||
--vaadin-combo-box-overlay-max-height: calc(45vh - 56px);
|
||||
}
|
||||
ha-combo-box-textfield {
|
||||
width: 100%;
|
||||
|
||||
@@ -26,6 +26,7 @@ export class HaControlButtonGroup extends LitElement {
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: var(--control-button-group-alignment, start);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import "./ha-check-list-item";
|
||||
import "./ha-expansion-panel";
|
||||
import "./ha-icon-button";
|
||||
import "./ha-list";
|
||||
import { deepEqual } from "../common/util/deep-equal";
|
||||
|
||||
@customElement("ha-filter-blueprints")
|
||||
export class HaFilterBlueprints extends LitElement {
|
||||
@@ -35,11 +34,10 @@ export class HaFilterBlueprints extends LitElement {
|
||||
public willUpdate(properties: PropertyValues) {
|
||||
super.willUpdate(properties);
|
||||
|
||||
if (
|
||||
properties.has("value") &&
|
||||
!deepEqual(this.value, properties.get("value"))
|
||||
) {
|
||||
this._findRelated();
|
||||
if (!this.hasUpdated) {
|
||||
if (this.value?.length) {
|
||||
this._findRelated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,15 +130,17 @@ export class HaFilterBlueprints extends LitElement {
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
|
||||
this._findRelated();
|
||||
}
|
||||
|
||||
private async _findRelated() {
|
||||
if (!this.value?.length) {
|
||||
this.value = [];
|
||||
fireEvent(this, "data-table-filter-changed", {
|
||||
value: [],
|
||||
items: undefined,
|
||||
});
|
||||
this.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../common/entity/compute_device_name";
|
||||
import { stringCompare } from "../common/string/compare";
|
||||
import { deepEqual } from "../common/util/deep-equal";
|
||||
import type { RelatedResult } from "../data/search";
|
||||
import { findRelated } from "../data/search";
|
||||
import { haStyleScrollbar } from "../resources/styles";
|
||||
@@ -38,13 +37,9 @@ export class HaFilterDevices extends LitElement {
|
||||
|
||||
if (!this.hasUpdated) {
|
||||
loadVirtualizer();
|
||||
}
|
||||
|
||||
if (
|
||||
properties.has("value") &&
|
||||
!deepEqual(this.value, properties.get("value"))
|
||||
) {
|
||||
this._findRelated();
|
||||
if (this.value?.length) {
|
||||
this._findRelated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +110,7 @@ export class HaFilterDevices extends LitElement {
|
||||
this.value = [...(this.value || []), value];
|
||||
}
|
||||
listItem.selected = this.value?.includes(value);
|
||||
this._findRelated();
|
||||
}
|
||||
|
||||
protected updated(changed) {
|
||||
@@ -164,11 +160,11 @@ export class HaFilterDevices extends LitElement {
|
||||
const relatedPromises: Promise<RelatedResult>[] = [];
|
||||
|
||||
if (!this.value?.length) {
|
||||
this.value = [];
|
||||
fireEvent(this, "data-table-filter-changed", {
|
||||
value: [],
|
||||
items: undefined,
|
||||
});
|
||||
this.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -180,6 +176,7 @@ export class HaFilterDevices extends LitElement {
|
||||
relatedPromises.push(findRelated(this.hass, "device", deviceId));
|
||||
}
|
||||
}
|
||||
this.value = value;
|
||||
const results = await Promise.all(relatedPromises);
|
||||
const items = new Set<string>();
|
||||
for (const result of results) {
|
||||
|
||||
@@ -17,7 +17,6 @@ import "./ha-expansion-panel";
|
||||
import "./ha-list";
|
||||
import "./ha-state-icon";
|
||||
import "./search-input-outlined";
|
||||
import { deepEqual } from "../common/util/deep-equal";
|
||||
|
||||
@customElement("ha-filter-entities")
|
||||
export class HaFilterEntities extends LitElement {
|
||||
@@ -40,13 +39,9 @@ export class HaFilterEntities extends LitElement {
|
||||
|
||||
if (!this.hasUpdated) {
|
||||
loadVirtualizer();
|
||||
}
|
||||
|
||||
if (
|
||||
properties.has("value") &&
|
||||
!deepEqual(this.value, properties.get("value"))
|
||||
) {
|
||||
this._findRelated();
|
||||
if (this.value?.length) {
|
||||
this._findRelated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +131,7 @@ export class HaFilterEntities extends LitElement {
|
||||
this.value = [...(this.value || []), value];
|
||||
}
|
||||
listItem.selected = this.value?.includes(value);
|
||||
this._findRelated();
|
||||
}
|
||||
|
||||
private _expandedWillChange(ev) {
|
||||
@@ -182,11 +178,11 @@ export class HaFilterEntities extends LitElement {
|
||||
const relatedPromises: Promise<RelatedResult>[] = [];
|
||||
|
||||
if (!this.value?.length) {
|
||||
this.value = [];
|
||||
fireEvent(this, "data-table-filter-changed", {
|
||||
value: [],
|
||||
items: undefined,
|
||||
});
|
||||
this.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import "./ha-icon-button";
|
||||
import "./ha-list";
|
||||
import "./ha-svg-icon";
|
||||
import "./ha-tree-indicator";
|
||||
import { deepEqual } from "../common/util/deep-equal";
|
||||
|
||||
@customElement("ha-filter-floor-areas")
|
||||
export class HaFilterFloorAreas extends LitElement {
|
||||
@@ -42,11 +41,10 @@ export class HaFilterFloorAreas extends LitElement {
|
||||
public willUpdate(properties: PropertyValues) {
|
||||
super.willUpdate(properties);
|
||||
|
||||
if (
|
||||
properties.has("value") &&
|
||||
!deepEqual(this.value, properties.get("value"))
|
||||
) {
|
||||
this._findRelated();
|
||||
if (!this.hasUpdated) {
|
||||
if (this.value?.floors?.length || this.value?.areas?.length) {
|
||||
this._findRelated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,6 +174,8 @@ export class HaFilterFloorAreas extends LitElement {
|
||||
}
|
||||
|
||||
listItem.selected = this.value[type]?.includes(value);
|
||||
|
||||
this._findRelated();
|
||||
}
|
||||
|
||||
protected updated(changed) {
|
||||
@@ -188,6 +188,10 @@ export class HaFilterFloorAreas extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
protected firstUpdated() {
|
||||
this._findRelated();
|
||||
}
|
||||
|
||||
private _expandedWillChange(ev) {
|
||||
this._shouldRender = ev.detail.expanded;
|
||||
}
|
||||
@@ -222,7 +226,6 @@ export class HaFilterFloorAreas extends LitElement {
|
||||
!this.value ||
|
||||
(!this.value.areas?.length && !this.value.floors?.length)
|
||||
) {
|
||||
this.value = {};
|
||||
fireEvent(this, "data-table-filter-changed", {
|
||||
value: {},
|
||||
items: undefined,
|
||||
|
||||
@@ -433,7 +433,6 @@ export class HaFloorPicker extends LitElement {
|
||||
}
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this._setValue(value);
|
||||
|
||||
@@ -122,6 +122,22 @@ export class HaItemDisplayEditor extends LitElement {
|
||||
${description
|
||||
? html`<span slot="supporting-text">${description}</span>`
|
||||
: nothing}
|
||||
${isVisible && !disableSorting
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
tabindex=${ifDefined(
|
||||
this.showNavigationButton ? "0" : undefined
|
||||
)}
|
||||
.idx=${idx}
|
||||
@keydown=${this.showNavigationButton
|
||||
? this._dragHandleKeydown
|
||||
: undefined}
|
||||
class="handle"
|
||||
.path=${mdiDrag}
|
||||
slot="start"
|
||||
></ha-svg-icon>
|
||||
`
|
||||
: html`<ha-svg-icon slot="start"></ha-svg-icon>`}
|
||||
${!showIcon
|
||||
? nothing
|
||||
: icon
|
||||
@@ -146,9 +162,6 @@ export class HaItemDisplayEditor extends LitElement {
|
||||
<span slot="end"> ${this.actionsRenderer(item)} </span>
|
||||
`
|
||||
: nothing}
|
||||
${this.showNavigationButton
|
||||
? html`<ha-icon-next slot="end"></ha-icon-next>`
|
||||
: nothing}
|
||||
<ha-icon-button
|
||||
.path=${isVisible ? mdiEye : mdiEyeOff}
|
||||
slot="end"
|
||||
@@ -161,22 +174,9 @@ export class HaItemDisplayEditor extends LitElement {
|
||||
.value=${value}
|
||||
@click=${this._toggle}
|
||||
></ha-icon-button>
|
||||
${isVisible && !disableSorting
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
tabindex=${ifDefined(
|
||||
this.showNavigationButton ? "0" : undefined
|
||||
)}
|
||||
.idx=${idx}
|
||||
@keydown=${this.showNavigationButton
|
||||
? this._dragHandleKeydown
|
||||
: undefined}
|
||||
class="handle"
|
||||
.path=${mdiDrag}
|
||||
slot="end"
|
||||
></ha-svg-icon>
|
||||
`
|
||||
: html`<ha-svg-icon slot="end"></ha-svg-icon>`}
|
||||
${this.showNavigationButton
|
||||
? html` <ha-icon-next slot="end"></ha-icon-next> `
|
||||
: nothing}
|
||||
</ha-md-list-item>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -24,10 +24,6 @@ const MANUAL_SCHEMA = [
|
||||
{ name: "media_content_type", required: false, selector: { text: {} } },
|
||||
] as const;
|
||||
|
||||
const INCLUDE_DOMAINS = ["media_player"];
|
||||
|
||||
const EMPTY_FORM = {};
|
||||
|
||||
@customElement("ha-selector-media")
|
||||
export class HaMediaSelector extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@@ -88,7 +84,7 @@ export class HaMediaSelector extends LitElement {
|
||||
(stateObj &&
|
||||
supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA));
|
||||
|
||||
const hasAccept = this.selector?.media?.accept?.length;
|
||||
const hasAccept = this.selector.media?.accept?.length;
|
||||
|
||||
return html`
|
||||
${hasAccept
|
||||
@@ -104,7 +100,7 @@ export class HaMediaSelector extends LitElement {
|
||||
.disabled=${this.disabled}
|
||||
.helper=${this.helper}
|
||||
.required=${this.required}
|
||||
.includeDomains=${INCLUDE_DOMAINS}
|
||||
include-domains='["media_player"]'
|
||||
allow-custom-entity
|
||||
@value-changed=${this._entityChanged}
|
||||
></ha-entity-picker>
|
||||
@@ -118,7 +114,7 @@ export class HaMediaSelector extends LitElement {
|
||||
</ha-alert>
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this.value || EMPTY_FORM}
|
||||
.data=${this.value}
|
||||
.schema=${MANUAL_SCHEMA}
|
||||
.computeLabel=${this._computeLabelCallback}
|
||||
></ha-form>
|
||||
@@ -126,62 +122,63 @@ export class HaMediaSelector extends LitElement {
|
||||
: html`
|
||||
<ha-card
|
||||
outlined
|
||||
tabindex="0"
|
||||
role="button"
|
||||
aria-label=${!this.value?.media_content_id
|
||||
? this.hass.localize("ui.components.selectors.media.pick_media")
|
||||
: this.value.metadata?.title || this.value.media_content_id}
|
||||
@click=${this._pickMedia}
|
||||
@keydown=${this._handleKeyDown}
|
||||
class=${this.disabled || (!this.value?.entity_id && !hasAccept)
|
||||
? "disabled"
|
||||
: ""}
|
||||
>
|
||||
<div class="content-container">
|
||||
<div class="thumbnail">
|
||||
${this.value?.metadata?.thumbnail
|
||||
? html`
|
||||
<div
|
||||
class="${classMap({
|
||||
"centered-image":
|
||||
!!this.value.metadata.media_class &&
|
||||
["app", "directory"].includes(
|
||||
this.value.metadata.media_class
|
||||
),
|
||||
})}
|
||||
image"
|
||||
style=${this._thumbnailUrl
|
||||
? `background-image: url(${this._thumbnailUrl});`
|
||||
: ""}
|
||||
></div>
|
||||
`
|
||||
: html`
|
||||
<div class="icon-holder image">
|
||||
<ha-svg-icon
|
||||
class="folder"
|
||||
.path=${!this.value?.media_content_id
|
||||
? mdiPlus
|
||||
: this.value?.metadata?.media_class
|
||||
? MediaClassBrowserSettings[
|
||||
this.value.metadata.media_class ===
|
||||
"directory"
|
||||
? this.value.metadata
|
||||
.children_media_class ||
|
||||
this.value.metadata.media_class
|
||||
: this.value.metadata.media_class
|
||||
].icon
|
||||
: mdiPlayBox}
|
||||
></ha-svg-icon>
|
||||
</div>
|
||||
`}
|
||||
</div>
|
||||
<div class="title">
|
||||
${!this.value?.media_content_id
|
||||
? this.hass.localize(
|
||||
"ui.components.selectors.media.pick_media"
|
||||
)
|
||||
: this.value.metadata?.title || this.value.media_content_id}
|
||||
</div>
|
||||
<div
|
||||
class="thumbnail ${classMap({
|
||||
portrait:
|
||||
!!this.value?.metadata?.media_class &&
|
||||
MediaClassBrowserSettings[
|
||||
this.value.metadata.children_media_class ||
|
||||
this.value.metadata.media_class
|
||||
].thumbnail_ratio === "portrait",
|
||||
})}"
|
||||
>
|
||||
${this.value?.metadata?.thumbnail
|
||||
? html`
|
||||
<div
|
||||
class="${classMap({
|
||||
"centered-image":
|
||||
!!this.value.metadata.media_class &&
|
||||
["app", "directory"].includes(
|
||||
this.value.metadata.media_class
|
||||
),
|
||||
})}
|
||||
image"
|
||||
style=${this._thumbnailUrl
|
||||
? `background-image: url(${this._thumbnailUrl});`
|
||||
: ""}
|
||||
></div>
|
||||
`
|
||||
: html`
|
||||
<div class="icon-holder image">
|
||||
<ha-svg-icon
|
||||
class="folder"
|
||||
.path=${!this.value?.media_content_id
|
||||
? mdiPlus
|
||||
: this.value?.metadata?.media_class
|
||||
? MediaClassBrowserSettings[
|
||||
this.value.metadata.media_class ===
|
||||
"directory"
|
||||
? this.value.metadata
|
||||
.children_media_class ||
|
||||
this.value.metadata.media_class
|
||||
: this.value.metadata.media_class
|
||||
].icon
|
||||
: mdiPlayBox}
|
||||
></ha-svg-icon>
|
||||
</div>
|
||||
`}
|
||||
</div>
|
||||
<div class="title">
|
||||
${!this.value?.media_content_id
|
||||
? this.hass.localize(
|
||||
"ui.components.selectors.media.pick_media"
|
||||
)
|
||||
: this.value.metadata?.title || this.value.media_content_id}
|
||||
</div>
|
||||
</ha-card>
|
||||
`}
|
||||
@@ -232,13 +229,6 @@ export class HaMediaSelector extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _handleKeyDown(ev: KeyboardEvent) {
|
||||
if (ev.key === "Enter" || ev.key === " ") {
|
||||
ev.preventDefault();
|
||||
this._pickMedia();
|
||||
}
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-entity-picker {
|
||||
display: block;
|
||||
@@ -253,52 +243,41 @@ export class HaMediaSelector extends LitElement {
|
||||
}
|
||||
ha-card {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
width: 200px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
transition: background-color 180ms ease-in-out;
|
||||
min-height: 56px;
|
||||
}
|
||||
ha-card:hover:not(.disabled),
|
||||
ha-card:focus:not(.disabled) {
|
||||
background-color: var(--state-icon-hover-color, rgba(0, 0, 0, 0.04));
|
||||
}
|
||||
ha-card:focus {
|
||||
outline: none;
|
||||
}
|
||||
ha-card.disabled {
|
||||
pointer-events: none;
|
||||
color: var(--disabled-text-color);
|
||||
}
|
||||
.content-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
gap: 12px;
|
||||
}
|
||||
ha-card .thumbnail {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
transition: padding-bottom 0.1s ease-out;
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
ha-card .thumbnail.portrait {
|
||||
padding-bottom: 150%;
|
||||
}
|
||||
ha-card .image {
|
||||
border-radius: 8px;
|
||||
border-radius: 3px 3px 0 0;
|
||||
}
|
||||
.folder {
|
||||
--mdc-icon-size: 24px;
|
||||
--mdc-icon-size: calc(var(--media-browse-item-size, 175px) * 0.4);
|
||||
}
|
||||
.title {
|
||||
font-size: var(--ha-font-size-m);
|
||||
font-size: var(--ha-font-size-l);
|
||||
padding-top: 16px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-bottom: 16px;
|
||||
padding-left: 16px;
|
||||
padding-right: 4px;
|
||||
padding-inline-start: 16px;
|
||||
padding-inline-end: 4px;
|
||||
white-space: nowrap;
|
||||
line-height: 1.4;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.image {
|
||||
position: absolute;
|
||||
@@ -311,15 +290,13 @@ export class HaMediaSelector extends LitElement {
|
||||
background-position: center;
|
||||
}
|
||||
.centered-image {
|
||||
margin: 4px;
|
||||
margin: 0 8px;
|
||||
background-size: contain;
|
||||
}
|
||||
.icon-holder {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,11 @@ export class HaObjectSelector extends LitElement {
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (this.selector.object?.fields) {
|
||||
if (!this.selector.object) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
if (this.selector.object.fields) {
|
||||
if (this.selector.object.multiple) {
|
||||
const items = ensureArray(this.value ?? []);
|
||||
return html`
|
||||
|
||||
@@ -89,7 +89,6 @@ export class HaSettingsRow extends LitElement {
|
||||
display: var(--settings-row-content-display, flex);
|
||||
justify-content: flex-end;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 16px 0;
|
||||
}
|
||||
.content ::slotted(*) {
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
mdiTooltipAccount,
|
||||
mdiViewDashboard,
|
||||
} from "@mdi/js";
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import {
|
||||
@@ -206,8 +205,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
|
||||
private _recentKeydownActiveUntil = 0;
|
||||
|
||||
private _unsubPersistentNotifications: UnsubscribeFunc | undefined;
|
||||
|
||||
@query(".tooltip") private _tooltip!: HTMLDivElement;
|
||||
|
||||
public hassSubscribe() {
|
||||
@@ -230,6 +227,9 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
),
|
||||
subscribeNotifications(this.hass.connection, (notifications) => {
|
||||
this._notifications = notifications;
|
||||
}),
|
||||
...(this.hass.user?.is_admin
|
||||
? [
|
||||
subscribeRepairsIssueRegistry(this.hass.connection!, (repairs) => {
|
||||
@@ -300,23 +300,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
);
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
this._subscribePersistentNotifications();
|
||||
}
|
||||
|
||||
private _subscribePersistentNotifications(): void {
|
||||
if (this._unsubPersistentNotifications) {
|
||||
this._unsubPersistentNotifications();
|
||||
}
|
||||
this._unsubPersistentNotifications = subscribeNotifications(
|
||||
this.hass.connection,
|
||||
(notifications) => {
|
||||
this._notifications = notifications;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected updated(changedProps) {
|
||||
super.updated(changedProps);
|
||||
if (changedProps.has("alwaysExpand")) {
|
||||
@@ -328,14 +311,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
|
||||
if (
|
||||
this.hass &&
|
||||
oldHass?.connected === false &&
|
||||
this.hass.connected === true
|
||||
) {
|
||||
this._subscribePersistentNotifications();
|
||||
}
|
||||
|
||||
this._calculateCounts();
|
||||
|
||||
if (!SUPPORT_SCROLL_IF_NEEDED) {
|
||||
|
||||
@@ -44,9 +44,6 @@ export class HaYamlEditor extends LitElement {
|
||||
|
||||
@property({ attribute: "read-only", type: Boolean }) public readOnly = false;
|
||||
|
||||
@property({ type: Boolean, attribute: "disable-fullscreen" })
|
||||
public disableFullscreen = false;
|
||||
|
||||
@property({ type: Boolean }) public required = false;
|
||||
|
||||
@property({ attribute: "copy-clipboard", type: Boolean })
|
||||
@@ -113,7 +110,6 @@ export class HaYamlEditor extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.value=${this._yaml}
|
||||
.readOnly=${this.readOnly}
|
||||
.disableFullscreen=${this.disableFullscreen}
|
||||
mode="yaml"
|
||||
autocomplete-entities
|
||||
autocomplete-icons
|
||||
|
||||
+2
-8
@@ -354,10 +354,7 @@ const getIconFromTranslations = (
|
||||
}
|
||||
// Then check for range-based icons if we have a numeric state
|
||||
if (state !== undefined && translations.range && !isNaN(Number(state))) {
|
||||
return (
|
||||
getIconFromRange(Number(state), translations.range) ??
|
||||
translations.default
|
||||
);
|
||||
return getIconFromRange(Number(state), translations.range);
|
||||
}
|
||||
// Fallback to default icon
|
||||
return translations.default;
|
||||
@@ -521,10 +518,7 @@ export const domainIcon = async (
|
||||
}
|
||||
// Then check for range-based icons if we have a numeric state
|
||||
if (state !== undefined && translations.range && !isNaN(Number(state))) {
|
||||
return (
|
||||
getIconFromRange(Number(state), translations.range) ??
|
||||
translations.default
|
||||
);
|
||||
return getIconFromRange(Number(state), translations.range);
|
||||
}
|
||||
// Fallback to default icon
|
||||
return translations.default;
|
||||
|
||||
@@ -286,7 +286,7 @@ class DataEntryFlowDialog extends LitElement {
|
||||
scrimClickAction
|
||||
escapeKeyAction
|
||||
hideActions
|
||||
.heading=${dialogTitle || true}
|
||||
.heading=${dialogTitle}
|
||||
>
|
||||
<ha-dialog-header slot="heading">
|
||||
<ha-icon-button
|
||||
|
||||
@@ -35,16 +35,10 @@ export const showConfigFlowDialog = (
|
||||
return step;
|
||||
},
|
||||
fetchFlow: async (hass, flowId) => {
|
||||
const [step] = await Promise.all([
|
||||
fetchConfigFlow(hass, flowId),
|
||||
hass.loadFragmentTranslation("config"),
|
||||
]);
|
||||
await Promise.all([
|
||||
hass.loadBackendTranslation("config", step.handler),
|
||||
hass.loadBackendTranslation("selector", step.handler),
|
||||
// Used as fallback if no header defined for step
|
||||
hass.loadBackendTranslation("title", step.handler),
|
||||
]);
|
||||
const step = await fetchConfigFlow(hass, flowId);
|
||||
await hass.loadFragmentTranslation("config");
|
||||
await hass.loadBackendTranslation("config", step.handler);
|
||||
await hass.loadBackendTranslation("selector", step.handler);
|
||||
return step;
|
||||
},
|
||||
handleFlowStep: handleConfigFlowStep,
|
||||
|
||||
@@ -2,19 +2,12 @@ import { html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import "../../../../../components/ha-selector/ha-selector";
|
||||
import "../../../../../components/ha-selector/ha-selector-media";
|
||||
import type { PlayMediaAction } from "../../../../../data/script";
|
||||
import type {
|
||||
MediaSelectorValue,
|
||||
Selector,
|
||||
} from "../../../../../data/selector";
|
||||
import type { MediaSelectorValue } from "../../../../../data/selector";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import type { ActionElement } from "../ha-automation-action-row";
|
||||
|
||||
const MEDIA_SELECTOR_SCHEMA: Selector = {
|
||||
media: {},
|
||||
};
|
||||
|
||||
@customElement("ha-automation-action-play_media")
|
||||
export class HaPlayMediaAction extends LitElement implements ActionElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@@ -45,13 +38,12 @@ export class HaPlayMediaAction extends LitElement implements ActionElement {
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<ha-selector
|
||||
.selector=${MEDIA_SELECTOR_SCHEMA}
|
||||
<ha-selector-media
|
||||
.hass=${this.hass}
|
||||
.disabled=${this.disabled}
|
||||
.value=${this._getSelectorValue(this.action)}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-selector>
|
||||
></ha-selector-media>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -502,7 +502,6 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
.readOnly=${this._readOnly}
|
||||
@value-changed=${this._yamlChanged}
|
||||
.showErrors=${false}
|
||||
disable-fullscreen
|
||||
></ha-yaml-editor>`
|
||||
: nothing}
|
||||
</div>
|
||||
|
||||
@@ -566,7 +566,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
text: html`
|
||||
<ha-yaml-editor
|
||||
read-only
|
||||
disable-fullscreen
|
||||
.hass=${this.hass}
|
||||
.defaultValue=${this._triggered}
|
||||
></ha-yaml-editor>
|
||||
|
||||
@@ -173,7 +173,6 @@ export abstract class HaBlueprintGenericEditor extends LitElement {
|
||||
.content=${value?.description}
|
||||
></ha-markdown>
|
||||
${html`<ha-selector
|
||||
narrow
|
||||
.hass=${this.hass}
|
||||
.selector=${selector}
|
||||
.key=${key}
|
||||
|
||||
@@ -58,7 +58,7 @@ export class DashboardCard extends LitElement {
|
||||
.card-header {
|
||||
padding: 12px;
|
||||
display: block;
|
||||
text-align: var(--float-start);
|
||||
text-align: left;
|
||||
gap: 8px;
|
||||
}
|
||||
.preview {
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
mdiPlusCircle,
|
||||
mdiRestore,
|
||||
} from "@mdi/js";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
@@ -273,24 +273,22 @@ export class HaConfigDevicePage extends LitElement {
|
||||
findBatteryChargingEntity(this.hass, entities)
|
||||
);
|
||||
|
||||
public willUpdate(changedProps: PropertyValues<this>) {
|
||||
public willUpdate(changedProps) {
|
||||
super.willUpdate(changedProps);
|
||||
|
||||
if (changedProps.has("deviceId")) {
|
||||
if (changedProps.has("deviceId") || changedProps.has("entries")) {
|
||||
this._deviceActions = [];
|
||||
this._deviceAlerts = [];
|
||||
this._deleteButtons = [];
|
||||
this._diagnosticDownloadLinks = [];
|
||||
}
|
||||
|
||||
if (changedProps.has("deviceId") || changedProps.has("entries")) {
|
||||
this._fetchData();
|
||||
}
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
protected firstUpdated(changedProps) {
|
||||
super.firstUpdated(changedProps);
|
||||
loadDeviceRegistryDetailDialog();
|
||||
this._fetchData();
|
||||
}
|
||||
|
||||
protected updated(changedProps) {
|
||||
@@ -991,7 +989,6 @@ export class HaConfigDevicePage extends LitElement {
|
||||
}
|
||||
|
||||
private _getDeleteActions() {
|
||||
const deviceId = this.deviceId;
|
||||
const device = this.hass.devices[this.deviceId];
|
||||
|
||||
if (!device) {
|
||||
@@ -1061,18 +1058,12 @@ export class HaConfigDevicePage extends LitElement {
|
||||
}
|
||||
);
|
||||
|
||||
if (this.deviceId !== deviceId) {
|
||||
// abort if the device has changed
|
||||
return;
|
||||
}
|
||||
|
||||
if (buttons.length > 0) {
|
||||
this._deleteButtons = buttons;
|
||||
}
|
||||
}
|
||||
|
||||
private async _getDeviceActions() {
|
||||
const deviceId = this.deviceId;
|
||||
const device = this.hass.devices[this.deviceId];
|
||||
|
||||
if (!device) {
|
||||
@@ -1166,25 +1157,14 @@ export class HaConfigDevicePage extends LitElement {
|
||||
|
||||
// load matter device actions async to avoid an UI with 0 actions when the matter integration needs very long to get node diagnostics
|
||||
matter.getMatterDeviceActions(this, this.hass, device).then((actions) => {
|
||||
if (this.deviceId !== deviceId) {
|
||||
// abort if the device has changed
|
||||
return;
|
||||
}
|
||||
this._deviceActions = [...actions, ...(this._deviceActions || [])];
|
||||
});
|
||||
}
|
||||
|
||||
if (this.deviceId !== deviceId) {
|
||||
// abort if the device has changed
|
||||
return;
|
||||
}
|
||||
|
||||
this._deviceActions = deviceActions;
|
||||
}
|
||||
|
||||
private async _getDeviceAlerts() {
|
||||
const deviceId = this.deviceId;
|
||||
|
||||
const device = this.hass.devices[this.deviceId];
|
||||
|
||||
if (!device) {
|
||||
@@ -1208,11 +1188,6 @@ export class HaConfigDevicePage extends LitElement {
|
||||
deviceAlerts.push(...alerts);
|
||||
}
|
||||
|
||||
if (this.deviceId !== deviceId) {
|
||||
// abort if the device has changed
|
||||
return;
|
||||
}
|
||||
|
||||
this._deviceAlerts = deviceAlerts;
|
||||
if (deviceAlerts.length) {
|
||||
this._deviceAlertsActionsTimeout = window.setTimeout(() => {
|
||||
|
||||
@@ -1099,10 +1099,10 @@ ${
|
||||
}
|
||||
|
||||
protected firstUpdated() {
|
||||
this._setFiltersFromUrl();
|
||||
fetchEntitySourcesWithCache(this.hass).then((sources) => {
|
||||
this._entitySources = sources;
|
||||
});
|
||||
this._setFiltersFromUrl();
|
||||
if (Object.keys(this._filters).length) {
|
||||
return;
|
||||
}
|
||||
@@ -1116,7 +1116,7 @@ ${
|
||||
const configEntry = this._searchParms.get("config_entry");
|
||||
const subEntry = this._searchParms.get("sub_entry");
|
||||
const device = this._searchParms.get("device");
|
||||
const label = this._searchParms.get("label");
|
||||
const label = this._searchParms.has("label");
|
||||
|
||||
if (!domain && !configEntry && !label && !device) {
|
||||
return;
|
||||
@@ -1128,10 +1128,21 @@ ${
|
||||
"ha-filter-states": [],
|
||||
"ha-filter-integrations": domain ? [domain] : [],
|
||||
"ha-filter-devices": device ? [device] : [],
|
||||
"ha-filter-labels": label ? [label] : [],
|
||||
config_entry: configEntry ? [configEntry] : [],
|
||||
sub_entry: subEntry ? [subEntry] : [],
|
||||
};
|
||||
this._filterLabel();
|
||||
}
|
||||
|
||||
private _filterLabel() {
|
||||
const label = this._searchParms.get("label");
|
||||
if (!label) {
|
||||
return;
|
||||
}
|
||||
this._filters = {
|
||||
...this._filters,
|
||||
"ha-filter-labels": [label],
|
||||
};
|
||||
}
|
||||
|
||||
private _clearFilter() {
|
||||
@@ -1141,11 +1152,6 @@ ${
|
||||
|
||||
public willUpdate(changedProps: PropertyValues): void {
|
||||
super.willUpdate(changedProps);
|
||||
|
||||
if (!this.hasUpdated) {
|
||||
this._setFiltersFromUrl();
|
||||
}
|
||||
|
||||
const oldHass = changedProps.get("hass");
|
||||
let changed = false;
|
||||
if (!this.hass || !this._entities) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import {
|
||||
mdiCogOutline,
|
||||
mdiDelete,
|
||||
mdiDevices,
|
||||
mdiDotsVertical,
|
||||
mdiPencil,
|
||||
mdiShapeOutline,
|
||||
mdiStopCircleOutline,
|
||||
mdiTransitConnectionVariant,
|
||||
} from "@mdi/js";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
@@ -58,118 +57,111 @@ class HaConfigEntryDeviceRow extends LitElement {
|
||||
area ? area.name : undefined,
|
||||
].filter(Boolean);
|
||||
|
||||
return html`<ha-md-list-item
|
||||
type="button"
|
||||
@click=${this._handleNavigateToDevice}
|
||||
class=${classMap({ disabled: Boolean(device.disabled_by) })}
|
||||
>
|
||||
<ha-svg-icon
|
||||
.path=${device.entry_type === "service"
|
||||
? mdiTransitConnectionVariant
|
||||
: mdiDevices}
|
||||
slot="start"
|
||||
></ha-svg-icon>
|
||||
<div slot="headline">${computeDeviceNameDisplay(device, this.hass)}</div>
|
||||
return html`<ha-md-list-item @click=${this.narrow ? this._handleNavigateToDevice : undefined} class=${classMap({ disabled: Boolean(device.disabled_by) })}>
|
||||
<ha-svg-icon .path=${mdiDevices} slot="start"></ha-svg-icon>
|
||||
<div slot="headline"></div>${computeDeviceNameDisplay(device, this.hass)}</div>
|
||||
<span slot="supporting-text"
|
||||
>${supportingText.join(" • ")}
|
||||
${supportingText.length && entities.length ? " • " : nothing}
|
||||
${entities.length
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.entities",
|
||||
{ count: entities.length }
|
||||
)
|
||||
: nothing}</span
|
||||
${
|
||||
entities.length
|
||||
? this.narrow
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.entities",
|
||||
{ count: entities.length }
|
||||
)
|
||||
: html`<a
|
||||
href=${`/config/entities/?historyBack=1&device=${device.id}`}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.entities",
|
||||
{ count: entities.length }
|
||||
)}</a
|
||||
>`
|
||||
: nothing
|
||||
}</span
|
||||
>
|
||||
${!this.narrow
|
||||
? html`<ha-icon-next slot="end"> </ha-icon-next>`
|
||||
: nothing}
|
||||
${
|
||||
!this.narrow
|
||||
? html`<ha-icon-button-next
|
||||
slot="end"
|
||||
@click=${this._handleNavigateToDevice}
|
||||
>
|
||||
</ha-icon-button-next>`
|
||||
: nothing
|
||||
}
|
||||
</ha-icon-button>
|
||||
<div class="vertical-divider" slot="end" @click=${stopPropagation}></div>
|
||||
${!this.narrow
|
||||
? html`<ha-icon-button
|
||||
slot="end"
|
||||
@click=${this._handleEditDevice}
|
||||
.path=${mdiPencil}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.device.edit"
|
||||
)}
|
||||
></ha-icon-button>`
|
||||
: nothing}
|
||||
|
||||
<ha-md-button-menu
|
||||
positioning="popover"
|
||||
slot="end"
|
||||
@click=${stopPropagation}
|
||||
>
|
||||
${
|
||||
!this.narrow
|
||||
? html`<ha-icon-button
|
||||
slot="end"
|
||||
@click=${this._handleConfigureDevice}
|
||||
.path=${mdiPencil}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.device.configure"
|
||||
)}
|
||||
></ha-icon-button>`
|
||||
: nothing
|
||||
}
|
||||
</ha-icon-button>
|
||||
<ha-md-button-menu positioning="popover" slot="end" @click=${stopPropagation}>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
.path=${mdiDotsVertical}
|
||||
></ha-icon-button>
|
||||
${this.narrow
|
||||
? html`<ha-md-menu-item @click=${this._handleEditDevice}>
|
||||
<ha-svg-icon .path=${mdiPencil} slot="start"></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.device.edit"
|
||||
)}
|
||||
</ha-md-menu-item>`
|
||||
: nothing}
|
||||
${entities.length
|
||||
? html`
|
||||
<ha-md-menu-item
|
||||
href=${`/config/entities/?historyBack=1&device=${device.id}`}
|
||||
>
|
||||
<ha-svg-icon
|
||||
.path=${mdiShapeOutline}
|
||||
slot="start"
|
||||
></ha-svg-icon>
|
||||
${
|
||||
this.narrow
|
||||
? html`<ha-md-menu-item @click=${this._handleConfigureDevice}>
|
||||
<ha-svg-icon .path=${mdiCogOutline} slot="start"></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.integrations.config_entry.entities`,
|
||||
{ count: entities.length }
|
||||
"ui.panel.config.integrations.config_entry.device.configure"
|
||||
)}
|
||||
<ha-icon-next slot="end"></ha-icon-next>
|
||||
</ha-md-menu-item>
|
||||
`
|
||||
: nothing}
|
||||
<ha-md-menu-item
|
||||
class=${device.disabled_by !== "user" ? "warning" : ""}
|
||||
@click=${this._handleDisableDevice}
|
||||
.disabled=${device.disabled_by !== "user" && device.disabled_by}
|
||||
>
|
||||
</ha-md-menu-item>`
|
||||
: nothing
|
||||
}
|
||||
<ha-md-menu-item class=${device.disabled_by !== "user" ? "warning" : ""} @click=${this._handleDisableDevice} .disabled=${device.disabled_by !== "user" && device.disabled_by}>
|
||||
<ha-svg-icon .path=${mdiStopCircleOutline} slot="start"></ha-svg-icon>
|
||||
|
||||
${device.disabled_by && device.disabled_by !== "user"
|
||||
? this.hass.localize(
|
||||
"ui.dialogs.device-registry-detail.enabled_cause",
|
||||
{
|
||||
type: this.hass.localize(
|
||||
`ui.dialogs.device-registry-detail.type.${
|
||||
device.entry_type || "device"
|
||||
}`
|
||||
),
|
||||
cause: this.hass.localize(
|
||||
`config_entry.disabled_by.${device.disabled_by}`
|
||||
),
|
||||
}
|
||||
)
|
||||
: device.disabled_by
|
||||
|
||||
${
|
||||
device.disabled_by && device.disabled_by !== "user"
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.device.enable"
|
||||
"ui.dialogs.device-registry-detail.enabled_cause",
|
||||
{
|
||||
type: this.hass.localize(
|
||||
`ui.dialogs.device-registry-detail.type.${
|
||||
device.entry_type || "device"
|
||||
}`
|
||||
),
|
||||
cause: this.hass.localize(
|
||||
`config_entry.disabled_by.${device.disabled_by}`
|
||||
),
|
||||
}
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.device.disable"
|
||||
)}
|
||||
: device.disabled_by
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.device.enable"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.device.disable"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
</ha-md-menu-item>
|
||||
${this.entry.supports_remove_device
|
||||
? html`<ha-md-menu-item
|
||||
class="warning"
|
||||
@click=${this._handleDeleteDevice}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiDelete} slot="start"></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.device.delete"
|
||||
)}
|
||||
</ha-md-menu-item>`
|
||||
: nothing}
|
||||
${
|
||||
this.entry.supports_remove_device
|
||||
? html` <ha-md-menu-item
|
||||
class="warning"
|
||||
@click=${this._handleDeleteDevice}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiDelete} slot="start"></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.device.delete"
|
||||
)}
|
||||
</ha-md-menu-item>`
|
||||
: nothing
|
||||
}
|
||||
</ha-md-button-menu>
|
||||
</ha-md-list-item> `;
|
||||
}
|
||||
@@ -177,7 +169,7 @@ class HaConfigEntryDeviceRow extends LitElement {
|
||||
private _getEntities = (): EntityRegistryEntry[] =>
|
||||
this.entities?.filter((entity) => entity.device_id === this.device.id);
|
||||
|
||||
private _handleEditDevice(ev: MouseEvent) {
|
||||
private _handleConfigureDevice(ev: MouseEvent) {
|
||||
ev.stopPropagation(); // Prevent triggering the click handler on the list item
|
||||
showDeviceRegistryDetailDialog(this, {
|
||||
device: this.device,
|
||||
@@ -302,8 +294,6 @@ class HaConfigEntryDeviceRow extends LitElement {
|
||||
}
|
||||
ha-md-list-item {
|
||||
--md-list-item-leading-space: 56px;
|
||||
--md-ripple-hover-color: transparent;
|
||||
--md-ripple-pressed-color: transparent;
|
||||
}
|
||||
.disabled {
|
||||
opacity: 0.5;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
mdiAlertCircle,
|
||||
mdiChevronDown,
|
||||
mdiChevronUp,
|
||||
mdiCogOutline,
|
||||
mdiDelete,
|
||||
mdiDevices,
|
||||
@@ -57,7 +58,6 @@ import { showConfigEntrySystemOptionsDialog } from "../../../dialogs/config-entr
|
||||
import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-config-flow";
|
||||
import { showOptionsFlowDialog } from "../../../dialogs/config-flow/show-dialog-options-flow";
|
||||
import { showSubConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-sub-config-flow";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
import { fileDownload } from "../../../util/file_download";
|
||||
@@ -69,6 +69,7 @@ import {
|
||||
import "./ha-config-entry-device-row";
|
||||
import { renderConfigEntryError } from "./ha-config-integration-page";
|
||||
import "./ha-config-sub-entry-row";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
|
||||
@customElement("ha-config-entry-row")
|
||||
class HaConfigEntryRow extends LitElement {
|
||||
@@ -154,10 +155,7 @@ class HaConfigEntryRow extends LitElement {
|
||||
statusLine.push(
|
||||
html`<a
|
||||
href=${`/config/entities/?historyBack=1&config_entry=${item.entry_id}`}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.entities",
|
||||
{ count: entities.length }
|
||||
)}</a
|
||||
>${entities.length} entities</a
|
||||
>`
|
||||
);
|
||||
}
|
||||
@@ -180,8 +178,8 @@ class HaConfigEntryRow extends LitElement {
|
||||
>
|
||||
${subEntries.length || ownDevices.length
|
||||
? html`<ha-icon-button
|
||||
class="expand-button ${classMap({ expanded: this._expanded })}"
|
||||
.path=${mdiChevronDown}
|
||||
class="expand-button"
|
||||
.path=${this._expanded ? mdiChevronDown : mdiChevronUp}
|
||||
slot="start"
|
||||
@click=${this._toggleExpand}
|
||||
></ha-icon-button>`
|
||||
@@ -412,15 +410,12 @@ class HaConfigEntryRow extends LitElement {
|
||||
<ha-md-list-item
|
||||
@click=${this._toggleOwnDevices}
|
||||
type="button"
|
||||
class="toggle-devices-row ${classMap({
|
||||
expanded: this._devicesExpanded,
|
||||
})}"
|
||||
>
|
||||
<ha-icon-button
|
||||
class="expand-button ${classMap({
|
||||
expanded: this._devicesExpanded,
|
||||
})}"
|
||||
.path=${mdiChevronDown}
|
||||
class="expand-button"
|
||||
.path=${this._devicesExpanded
|
||||
? mdiChevronDown
|
||||
: mdiChevronUp}
|
||||
slot="start"
|
||||
>
|
||||
</ha-icon-button>
|
||||
@@ -744,10 +739,6 @@ class HaConfigEntryRow extends LitElement {
|
||||
css`
|
||||
.expand-button {
|
||||
margin: 0 -12px;
|
||||
transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
.expand-button.expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
ha-md-list {
|
||||
border: 1px solid var(--divider-color);
|
||||
@@ -768,14 +759,6 @@ class HaConfigEntryRow extends LitElement {
|
||||
var(--md-sys-color-on-surface-variant, #49454f)
|
||||
);
|
||||
}
|
||||
.toggle-devices-row {
|
||||
overflow: hidden;
|
||||
border-radius: var(--ha-card-border-radius, 12px);
|
||||
}
|
||||
.toggle-devices-row.expanded {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -380,14 +380,6 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
||||
<div class="title">
|
||||
<h1>${domainToName(this.hass.localize, this.domain)}</h1>
|
||||
<div class="sub">
|
||||
${this._manifest?.version != null
|
||||
? html`<span class="version"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.version",
|
||||
{ version: this._manifest.version }
|
||||
)}</span
|
||||
>`
|
||||
: nothing}
|
||||
${this._manifest?.is_built_in === false
|
||||
? html`<div
|
||||
class=${`integration-info ${
|
||||
@@ -432,8 +424,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
||||
)}
|
||||
</div>`
|
||||
: nothing}
|
||||
${this._manifest?.is_built_in &&
|
||||
this._manifest.quality_scale &&
|
||||
${this._manifest?.quality_scale &&
|
||||
Object.keys(QUALITY_SCALE_MAP).includes(
|
||||
this._manifest.quality_scale
|
||||
)
|
||||
@@ -902,12 +893,12 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
gap: 8px;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.title h1 {
|
||||
font-family: var(--ha-font-family-body);
|
||||
font-family: Roboto;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
line-height: 40px;
|
||||
@@ -920,7 +911,6 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px 16px;
|
||||
align-items: center;
|
||||
}
|
||||
.card-content {
|
||||
padding: 16px 0 8px;
|
||||
@@ -938,14 +928,15 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-right: 16px;
|
||||
margin-inline-end: 16px;
|
||||
margin-inline-start: initial;
|
||||
padding: 0 8px;
|
||||
}
|
||||
.logo-container img {
|
||||
width: 80px;
|
||||
}
|
||||
.version {
|
||||
padding-top: 8px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.overview .card-actions {
|
||||
@@ -973,7 +964,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
||||
margin-inline-start: 16px;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 6px;
|
||||
font-family: var(--ha-font-family-body);
|
||||
font-family: Roboto;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
|
||||
@@ -406,7 +406,11 @@ class HaConfigIntegrationsDashboard extends KeyboardShortcutMixin(
|
||||
${!this._showDisabled && this.narrow && disabledConfigEntries.length
|
||||
? html`<span class="badge">${disabledConfigEntries.length}</span>`
|
||||
: ""}
|
||||
<ha-button-menu multi @action=${this._handleMenuAction}>
|
||||
<ha-button-menu
|
||||
multi
|
||||
@action=${this._handleMenuAction}
|
||||
@click=${this._preventDefault}
|
||||
>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
mdiChevronDown,
|
||||
mdiChevronUp,
|
||||
mdiCogOutline,
|
||||
mdiDelete,
|
||||
mdiDevices,
|
||||
@@ -9,7 +10,6 @@ import {
|
||||
} from "@mdi/js";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import type { ConfigEntry, SubEntry } from "../../../data/config_entries";
|
||||
import { deleteSubEntry } from "../../../data/config_entries";
|
||||
import type { DeviceRegistryEntry } from "../../../data/device_registry";
|
||||
@@ -56,8 +56,8 @@ class HaConfigSubEntryRow extends LitElement {
|
||||
>
|
||||
${devices.length || services.length
|
||||
? html`<ha-icon-button
|
||||
class="expand-button ${classMap({ expanded: this._expanded })}"
|
||||
.path=${mdiChevronDown}
|
||||
class="expand-button"
|
||||
.path=${this._expanded ? mdiChevronDown : mdiChevronUp}
|
||||
slot="start"
|
||||
@click=${this._toggleExpand}
|
||||
></ha-icon-button>`
|
||||
@@ -239,10 +239,6 @@ class HaConfigSubEntryRow extends LitElement {
|
||||
static styles = css`
|
||||
.expand-button {
|
||||
margin: 0 -12px;
|
||||
transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
.expand-button.expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
ha-md-list {
|
||||
border: 1px solid var(--divider-color);
|
||||
|
||||
@@ -321,7 +321,6 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
.defaultValue=${this._config}
|
||||
@value-changed=${this._yamlChanged}
|
||||
.showErrors=${false}
|
||||
disable-fullscreen
|
||||
></ha-yaml-editor>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -440,7 +440,6 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
.hass=${this.hass}
|
||||
.defaultValue=${this._preprocessYaml()}
|
||||
.readOnly=${this._readOnly}
|
||||
disable-fullscreen
|
||||
@value-changed=${this._yamlChanged}
|
||||
.showErrors=${false}
|
||||
></ha-yaml-editor>`
|
||||
|
||||
@@ -25,6 +25,9 @@ export const cardFeatureStyles = css`
|
||||
flex-basis: 20px;
|
||||
--control-button-padding: 0px;
|
||||
}
|
||||
ha-control-button-group[no-stretch] > ha-control-button {
|
||||
max-width: 48px;
|
||||
}
|
||||
ha-control-button {
|
||||
--control-button-focus-color: var(--feature-color);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { ensureArray } from "../../../common/array/ensure-array";
|
||||
@@ -14,7 +13,6 @@ import { stateActive } from "../../../common/entity/state_active";
|
||||
import { domainColorProperties } from "../../../common/entity/state_color";
|
||||
import "../../../components/ha-control-button";
|
||||
import "../../../components/ha-control-button-group";
|
||||
import "../../../components/ha-domain-icon";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import type { AreaRegistryEntry } from "../../../data/area_registry";
|
||||
import { forwardHaptic } from "../../../data/haptics";
|
||||
@@ -231,11 +229,7 @@ class HuiAreaControlsCardFeature
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-control-button-group
|
||||
class=${classMap({
|
||||
"no-stretch": this.position === "inline",
|
||||
})}
|
||||
>
|
||||
<ha-control-button-group ?no-stretch=${this.position === "inline"}>
|
||||
${displayControls.map((control) => {
|
||||
const button = AREA_CONTROLS_BUTTONS[control];
|
||||
|
||||
@@ -298,22 +292,8 @@ class HuiAreaControlsCardFeature
|
||||
return [
|
||||
cardFeatureStyles,
|
||||
css`
|
||||
:host {
|
||||
pointer-events: none !important;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
ha-control-button-group {
|
||||
pointer-events: auto;
|
||||
width: 100%;
|
||||
}
|
||||
ha-control-button-group.no-stretch {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
ha-control-button-group.no-stretch > ha-control-button {
|
||||
width: 48px;
|
||||
--control-button-group-alignment: flex-end;
|
||||
}
|
||||
ha-control-button {
|
||||
--active-color: var(--state-active-color);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { LitElement, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { HuiErrorCard } from "../cards/hui-error-card";
|
||||
@@ -56,12 +56,6 @@ export class HuiCardFeature extends LitElement {
|
||||
}
|
||||
return html`${element}`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host > * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -46,7 +46,6 @@ export class HuiCardFeatures extends LitElement {
|
||||
--feature-height: 42px;
|
||||
--feature-border-radius: 12px;
|
||||
--feature-button-spacing: 12px;
|
||||
pointer-events: none;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
@@ -348,14 +348,6 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If only one entity, return its formatted state
|
||||
if (entities.length === 1) {
|
||||
const stateObj = entities[0];
|
||||
return isUnavailableState(stateObj.state)
|
||||
? ""
|
||||
: this.hass.formatEntityState(stateObj);
|
||||
}
|
||||
|
||||
// Use the first entity's unit_of_measurement for formatting
|
||||
const uom = entities.find(
|
||||
(entity) => entity.attributes.unit_of_measurement
|
||||
|
||||
@@ -82,7 +82,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
||||
|
||||
const width = entries[0]?.contentRect.width;
|
||||
if (width < 245) {
|
||||
result.width = "very-very-narrow";
|
||||
result.height = "very-very-narrow";
|
||||
} else if (width < 300) {
|
||||
result.width = "very-narrow";
|
||||
} else if (width < 375) {
|
||||
@@ -93,6 +93,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
||||
if (height < 235) {
|
||||
result.height = "short";
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
});
|
||||
@@ -242,11 +243,11 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
||||
);
|
||||
|
||||
let itemsToShow = this._config?.forecast_slots ?? 5;
|
||||
if (this._sizeController.value?.width === "very-very-narrow") {
|
||||
if (this._sizeController.value.width === "very-very-narrow") {
|
||||
itemsToShow = Math.min(3, itemsToShow);
|
||||
} else if (this._sizeController.value?.width === "very-narrow") {
|
||||
} else if (this._sizeController.value.width === "very-narrow") {
|
||||
itemsToShow = Math.min(5, itemsToShow);
|
||||
} else if (this._sizeController.value?.width === "narrow") {
|
||||
} else if (this._sizeController.value.width === "narrow") {
|
||||
itemsToShow = Math.min(7, itemsToShow);
|
||||
}
|
||||
|
||||
@@ -265,12 +266,8 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
||||
return html`
|
||||
<ha-card
|
||||
class=${classMap({
|
||||
[this._sizeController.value?.height]: Boolean(
|
||||
this._sizeController.value
|
||||
),
|
||||
[this._sizeController.value?.width]: Boolean(
|
||||
this._sizeController.value
|
||||
),
|
||||
[this._sizeController.value.height]: true,
|
||||
[this._sizeController.value.width]: true,
|
||||
})}
|
||||
@action=${this._handleAction}
|
||||
.actionHandler=${actionHandler({
|
||||
|
||||
@@ -74,6 +74,8 @@ export class HuiDialogEditCard
|
||||
|
||||
@state() private _dirty = false;
|
||||
|
||||
@state() private _isEscapeEnabled = true;
|
||||
|
||||
public async showDialog(params: EditCardDialogParams): Promise<void> {
|
||||
this._params = params;
|
||||
this._GUImode = true;
|
||||
@@ -91,6 +93,9 @@ export class HuiDialogEditCard
|
||||
}
|
||||
|
||||
public closeDialog(): boolean {
|
||||
this._isEscapeEnabled = true;
|
||||
window.removeEventListener("dialog-closed", this._enableEscapeKeyClose);
|
||||
window.removeEventListener("hass-more-info", this._disableEscapeKeyClose);
|
||||
if (this._dirty) {
|
||||
this._confirmCancel();
|
||||
return false;
|
||||
@@ -119,6 +124,16 @@ export class HuiDialogEditCard
|
||||
}
|
||||
}
|
||||
|
||||
private _enableEscapeKeyClose = (ev: any) => {
|
||||
if (ev.detail.dialog === "ha-more-info-dialog") {
|
||||
this._isEscapeEnabled = true;
|
||||
}
|
||||
};
|
||||
|
||||
private _disableEscapeKeyClose = () => {
|
||||
this._isEscapeEnabled = false;
|
||||
};
|
||||
|
||||
protected render() {
|
||||
if (!this._params || !this._cardConfig) {
|
||||
return nothing;
|
||||
@@ -155,7 +170,7 @@ export class HuiDialogEditCard
|
||||
<ha-dialog
|
||||
open
|
||||
scrimClickAction
|
||||
escapeKeyAction
|
||||
.escapeKeyAction=${this._isEscapeEnabled ? undefined : ""}
|
||||
@keydown=${this._ignoreKeydown}
|
||||
@closed=${this._cancel}
|
||||
@opened=${this._opened}
|
||||
@@ -289,6 +304,8 @@ export class HuiDialogEditCard
|
||||
}
|
||||
|
||||
private _opened() {
|
||||
window.addEventListener("dialog-closed", this._enableEscapeKeyClose);
|
||||
window.addEventListener("hass-more-info", this._disableEscapeKeyClose);
|
||||
this._cardEditorEl?.focusYamlEditor();
|
||||
}
|
||||
|
||||
|
||||
-3
@@ -144,9 +144,6 @@ class DialogDashboardStrategyEditor extends LitElement {
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
<span slot="title" .title=${title}>${title}</span>
|
||||
${this._params.title
|
||||
? html`<span slot="subtitle">${this._params.title}</span>`
|
||||
: nothing}
|
||||
<ha-button-menu
|
||||
corner="BOTTOM_END"
|
||||
menu-corner="END"
|
||||
|
||||
-1
@@ -3,7 +3,6 @@ import type { LovelaceDashboardStrategyConfig } from "../../../../../data/lovela
|
||||
|
||||
export interface DashboardStrategyEditorDialogParams {
|
||||
config: LovelaceDashboardStrategyConfig;
|
||||
title?: string;
|
||||
saveConfig: (config: LovelaceDashboardStrategyConfig) => void;
|
||||
takeControl: () => void;
|
||||
deleteDashboard: () => Promise<boolean>;
|
||||
|
||||
@@ -89,7 +89,6 @@ class LovelaceFullConfigEditor extends LitElement {
|
||||
.hass=${this.hass}
|
||||
@value-changed=${this._yamlChanged}
|
||||
@editor-save=${this._handleSave}
|
||||
disable-fullscreen
|
||||
dir="ltr"
|
||||
>
|
||||
</ha-code-editor>
|
||||
|
||||
@@ -782,7 +782,6 @@ class HUIRoot extends LitElement {
|
||||
|
||||
showDashboardStrategyEditorDialog(this, {
|
||||
config: this.lovelace!.rawConfig,
|
||||
title: this.panel ? getPanelTitle(this.hass, this.panel) : undefined,
|
||||
saveConfig: this.lovelace!.saveConfig,
|
||||
takeControl: () => {
|
||||
showSaveDialog(this, {
|
||||
|
||||
@@ -22,9 +22,6 @@ export interface AreasDashboardStrategyConfig {
|
||||
hidden?: string[];
|
||||
order?: string[];
|
||||
};
|
||||
floors_display?: {
|
||||
order?: string[];
|
||||
};
|
||||
areas_options?: Record<string, AreaOptions>;
|
||||
}
|
||||
|
||||
@@ -81,13 +78,13 @@ export class AreasDashboardStrategy extends ReactiveElement {
|
||||
return {
|
||||
views: [
|
||||
{
|
||||
title: "Home",
|
||||
icon: "mdi:home",
|
||||
path: "home",
|
||||
strategy: {
|
||||
type: "areas-overview",
|
||||
areas_display: config.areas_display,
|
||||
areas_options: config.areas_options,
|
||||
floors_display: config.floors_display,
|
||||
} satisfies AreasViewStrategyConfig,
|
||||
},
|
||||
...areaViews,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ReactiveElement } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
import { stringCompare } from "../../../../common/string/compare";
|
||||
import { floorDefaultIcon } from "../../../../components/ha-floor-icon";
|
||||
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
||||
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||
@@ -8,11 +9,7 @@ import { getAreaControlEntities } from "../../card-features/hui-area-controls-ca
|
||||
import { AREA_CONTROLS, type AreaControl } from "../../card-features/types";
|
||||
import type { AreaCardConfig, HeadingCardConfig } from "../../cards/types";
|
||||
import type { EntitiesDisplay } from "./area-view-strategy";
|
||||
import {
|
||||
computeAreaPath,
|
||||
getAreas,
|
||||
getFloors,
|
||||
} from "./helpers/areas-strategy-helper";
|
||||
import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helper";
|
||||
|
||||
const UNASSIGNED_FLOOR = "__unassigned__";
|
||||
|
||||
@@ -26,9 +23,6 @@ export interface AreasViewStrategyConfig {
|
||||
hidden?: string[];
|
||||
order?: string[];
|
||||
};
|
||||
floors_display?: {
|
||||
order?: string[];
|
||||
};
|
||||
areas_options?: Record<string, AreaOptions>;
|
||||
}
|
||||
|
||||
@@ -38,35 +32,43 @@ export class AreasOverviewViewStrategy extends ReactiveElement {
|
||||
config: AreasViewStrategyConfig,
|
||||
hass: HomeAssistant
|
||||
): Promise<LovelaceViewConfig> {
|
||||
const displayedAreas = getAreas(
|
||||
const areas = getAreas(
|
||||
hass.areas,
|
||||
config.areas_display?.hidden,
|
||||
config.areas_display?.order
|
||||
);
|
||||
|
||||
const floors = getFloors(hass.floors, config.floors_display?.order);
|
||||
const floors = Object.values(hass.floors);
|
||||
floors.sort((floorA, floorB) => {
|
||||
if (floorA.level !== floorB.level) {
|
||||
return (floorA.level ?? 0) - (floorB.level ?? 0);
|
||||
}
|
||||
return stringCompare(floorA.name, floorB.name);
|
||||
});
|
||||
|
||||
const floorSections = [
|
||||
...floors,
|
||||
{
|
||||
floor_id: UNASSIGNED_FLOOR,
|
||||
name: hass.localize("ui.panel.lovelace.strategy.areas.other_areas"),
|
||||
name: hass.localize(
|
||||
"ui.panel.lovelace.strategy.areas.unassigned_areas"
|
||||
),
|
||||
level: null,
|
||||
icon: null,
|
||||
},
|
||||
]
|
||||
.map((floor) => {
|
||||
const areasInFloors = displayedAreas.filter(
|
||||
.map<LovelaceSectionConfig | undefined>((floor) => {
|
||||
const areasInFloors = areas.filter(
|
||||
(area) =>
|
||||
area.floor_id === floor.floor_id ||
|
||||
(!area.floor_id && floor.floor_id === UNASSIGNED_FLOOR)
|
||||
);
|
||||
|
||||
return [floor, areasInFloors] as const;
|
||||
})
|
||||
.filter(([_, areas]) => areas.length)
|
||||
.map<LovelaceSectionConfig | undefined>(([floor, areas], _, array) => {
|
||||
const areasCards = areas.map<AreaCardConfig>((area) => {
|
||||
if (areasInFloors.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const areasCards = areasInFloors.map<AreaCardConfig>((area) => {
|
||||
const path = computeAreaPath(area.area_id);
|
||||
|
||||
const areaOptions = config.areas_options?.[area.area_id] || {};
|
||||
@@ -89,19 +91,11 @@ export class AreasOverviewViewStrategy extends ReactiveElement {
|
||||
(control) => controlEntities[control].length > 0
|
||||
);
|
||||
|
||||
const sensorClasses: string[] = [];
|
||||
if (area.temperature_entity_id) {
|
||||
sensorClasses.push("temperature");
|
||||
}
|
||||
if (area.humidity_entity_id) {
|
||||
sensorClasses.push("humidity");
|
||||
}
|
||||
|
||||
return {
|
||||
type: "area",
|
||||
area: area.area_id,
|
||||
display_type: "compact",
|
||||
sensor_classes: sensorClasses,
|
||||
sensor_classes: ["temperature", "humidity"],
|
||||
exclude_entities: hiddenEntities,
|
||||
features: filteredControls.length
|
||||
? [
|
||||
@@ -120,17 +114,10 @@ export class AreasOverviewViewStrategy extends ReactiveElement {
|
||||
};
|
||||
});
|
||||
|
||||
const noFloors =
|
||||
array.length === 1 && floor.floor_id === UNASSIGNED_FLOOR;
|
||||
|
||||
const headingTitle = noFloors
|
||||
? hass.localize("ui.panel.lovelace.strategy.areas.areas")
|
||||
: floor.name;
|
||||
|
||||
const headingCard: HeadingCardConfig = {
|
||||
type: "heading",
|
||||
heading_style: "title",
|
||||
heading: headingTitle,
|
||||
heading: floor.name,
|
||||
icon: floor.icon || floorDefaultIcon(floor),
|
||||
};
|
||||
|
||||
|
||||
+18
-37
@@ -1,32 +1,28 @@
|
||||
import { mdiThermometerWater } from "@mdi/js";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import "../../../../../components/ha-areas-display-editor";
|
||||
import type { AreasDisplayValue } from "../../../../../components/ha-areas-display-editor";
|
||||
import "../../../../../components/ha-areas-floors-display-editor";
|
||||
import type { AreasFloorsDisplayValue } from "../../../../../components/ha-areas-floors-display-editor";
|
||||
import "../../../../../components/ha-entities-display-editor";
|
||||
import "../../../../../components/ha-icon";
|
||||
import "../../../../../components/ha-icon-button";
|
||||
import "../../../../../components/ha-icon-button-prev";
|
||||
import "../../../../../components/ha-svg-icon";
|
||||
import {
|
||||
updateAreaRegistryEntry,
|
||||
type AreaRegistryEntry,
|
||||
} from "../../../../../data/area_registry";
|
||||
import { buttonLinkStyle } from "../../../../../resources/styles";
|
||||
import "../../../../../components/ha-icon";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import { showAreaRegistryDetailDialog } from "../../../../config/areas/show-dialog-area-registry-detail";
|
||||
import type { LovelaceStrategyEditor } from "../../types";
|
||||
import type { AreasDashboardStrategyConfig } from "../areas-dashboard-strategy";
|
||||
import type { AreaStrategyGroup } from "../helpers/areas-strategy-helper";
|
||||
import {
|
||||
AREA_STRATEGY_GROUP_ICONS,
|
||||
AREA_STRATEGY_GROUPS,
|
||||
getAreaGroupedEntities,
|
||||
} from "../helpers/areas-strategy-helper";
|
||||
import type { LovelaceStrategyEditor } from "../../types";
|
||||
import type { AreasDashboardStrategyConfig } from "../areas-dashboard-strategy";
|
||||
import { showAreaRegistryDetailDialog } from "../../../../config/areas/show-dialog-area-registry-detail";
|
||||
import {
|
||||
updateAreaRegistryEntry,
|
||||
type AreaRegistryEntry,
|
||||
} from "../../../../../data/area_registry";
|
||||
import { buttonLinkStyle } from "../../../../../resources/styles";
|
||||
import "../../../../../components/ha-areas-floors-display-editor";
|
||||
|
||||
@customElement("hui-areas-dashboard-strategy-editor")
|
||||
export class HuiAreasDashboardStrategyEditor
|
||||
@@ -62,18 +58,14 @@ export class HuiAreasDashboardStrategyEditor
|
||||
</div>
|
||||
<ha-expansion-panel
|
||||
.header=${this.hass!.localize(
|
||||
`ui.panel.lovelace.strategy.areas.sensors`
|
||||
`ui.panel.lovelace.strategy.areas.header`
|
||||
)}
|
||||
expanded
|
||||
outlined
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="leading-icon"
|
||||
.path=${mdiThermometerWater}
|
||||
></ha-svg-icon>
|
||||
<p>
|
||||
${this.hass!.localize(
|
||||
`ui.panel.lovelace.strategy.areas.sensors_description`,
|
||||
`ui.panel.lovelace.strategy.areas.header_description`,
|
||||
{
|
||||
edit_the_area: html`
|
||||
<button class="link" @click=${this._editArea} .area=${area}>
|
||||
@@ -128,7 +120,7 @@ export class HuiAreasDashboardStrategyEditor
|
||||
`;
|
||||
}
|
||||
|
||||
const value = this._areasFloorsDisplayValue(this._config);
|
||||
const value = this._config.areas_display;
|
||||
|
||||
return html`
|
||||
<ha-areas-floors-display-editor
|
||||
@@ -137,7 +129,7 @@ export class HuiAreasDashboardStrategyEditor
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.lovelace.editor.strategy.areas.areas_display"
|
||||
)}
|
||||
@value-changed=${this._areasFloorsDisplayChanged}
|
||||
@value-changed=${this._areasDisplayChanged}
|
||||
expanded
|
||||
show-navigation-button
|
||||
@item-display-navigate-clicked=${this._handleAreaNavigate}
|
||||
@@ -151,13 +143,6 @@ export class HuiAreasDashboardStrategyEditor
|
||||
}
|
||||
}
|
||||
|
||||
private _areasFloorsDisplayValue = memoizeOne(
|
||||
(config: AreasDashboardStrategyConfig): AreasFloorsDisplayValue => ({
|
||||
areas_display: config.areas_display,
|
||||
floors_display: config.floors_display,
|
||||
})
|
||||
);
|
||||
|
||||
private _editArea(ev: Event): void {
|
||||
ev.stopPropagation();
|
||||
const area = (ev.currentTarget! as any).area as AreaRegistryEntry;
|
||||
@@ -172,11 +157,11 @@ export class HuiAreasDashboardStrategyEditor
|
||||
this._area = ev.detail.value;
|
||||
}
|
||||
|
||||
private _areasFloorsDisplayChanged(ev: CustomEvent): void {
|
||||
const value = ev.detail.value as AreasFloorsDisplayValue;
|
||||
private _areasDisplayChanged(ev: CustomEvent): void {
|
||||
const value = ev.detail.value as AreasDisplayValue;
|
||||
const newConfig: AreasDashboardStrategyConfig = {
|
||||
...this._config!,
|
||||
...value,
|
||||
areas_display: value,
|
||||
};
|
||||
|
||||
fireEvent(this, "config-changed", { config: newConfig });
|
||||
@@ -228,13 +213,9 @@ export class HuiAreasDashboardStrategyEditor
|
||||
ha-expansion-panel {
|
||||
margin-bottom: 8px;
|
||||
max-width: 600px;
|
||||
--expansion-panel-summary-padding: 0 16px;
|
||||
}
|
||||
ha-expansion-panel [slot="leading-icon"] {
|
||||
margin-inline-end: 16px;
|
||||
}
|
||||
ha-expansion-panel p {
|
||||
margin: 8px 8px 16px 8px;
|
||||
margin: 8px 2px;
|
||||
}
|
||||
button.link {
|
||||
color: var(--primary-color);
|
||||
|
||||
@@ -3,13 +3,9 @@ import { computeStateName } from "../../../../../common/entity/compute_state_nam
|
||||
import type { EntityFilterFunc } from "../../../../../common/entity/entity_filter";
|
||||
import { generateEntityFilter } from "../../../../../common/entity/entity_filter";
|
||||
import { stripPrefixFromEntityName } from "../../../../../common/entity/strip_prefix_from_entity_name";
|
||||
import {
|
||||
orderCompare,
|
||||
stringCompare,
|
||||
} from "../../../../../common/string/compare";
|
||||
import { orderCompare } from "../../../../../common/string/compare";
|
||||
import type { AreaRegistryEntry } from "../../../../../data/area_registry";
|
||||
import { areaCompare } from "../../../../../data/area_registry";
|
||||
import type { FloorRegistryEntry } from "../../../../../data/floor_registry";
|
||||
import type { LovelaceCardConfig } from "../../../../../data/lovelace/config/card";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import { supportsAlarmModesCardFeature } from "../../../card-features/hui-alarm-modes-card-feature";
|
||||
@@ -294,23 +290,4 @@ export const getAreas = (
|
||||
return sortedAreas;
|
||||
};
|
||||
|
||||
export const getFloors = (
|
||||
entries: HomeAssistant["floors"],
|
||||
floorsOrder?: string[]
|
||||
): FloorRegistryEntry[] => {
|
||||
const floors = Object.values(entries);
|
||||
const compare = orderCompare(floorsOrder || []);
|
||||
|
||||
return floors.sort((floorA, floorB) => {
|
||||
const order = compare(floorA.floor_id, floorB.floor_id);
|
||||
if (order !== 0) {
|
||||
return order;
|
||||
}
|
||||
if (floorA.level !== floorB.level) {
|
||||
return (floorA.level ?? 0) - (floorB.level ?? 0);
|
||||
}
|
||||
return stringCompare(floorA.name, floorB.name);
|
||||
});
|
||||
};
|
||||
|
||||
export const computeAreaPath = (areaId: string): string => `areas-${areaId}`;
|
||||
|
||||
@@ -51,7 +51,7 @@ export const haTheme = EditorView.theme({
|
||||
"&": {
|
||||
color: "var(--primary-text-color)",
|
||||
backgroundColor:
|
||||
"var(--code-editor-background-color, var(--card-background-color))",
|
||||
"var(--code-editor-background-color, var(--mdc-text-field-fill-color, whitesmoke))",
|
||||
borderRadius:
|
||||
"var(--mdc-shape-small, 4px) var(--mdc-shape-small, 4px) 0px 0px",
|
||||
caretColor: "var(--secondary-text-color)",
|
||||
|
||||
+89
-91
@@ -51,7 +51,7 @@
|
||||
"owner": "Owner",
|
||||
"system-admin": "Administrators",
|
||||
"system-users": "Users",
|
||||
"system-read-only": "Read-only users"
|
||||
"system-read-only": "Read-Only Users"
|
||||
},
|
||||
"config_entry": {
|
||||
"disabled_by": {
|
||||
@@ -471,7 +471,7 @@
|
||||
"radius_meters": "[%key:ui::panel::config::core::section::core::core_config::elevation_meters%]"
|
||||
},
|
||||
"selector": {
|
||||
"options": "Selector options",
|
||||
"options": "Selector Options",
|
||||
"types": {
|
||||
"action": "Action",
|
||||
"area": "Area",
|
||||
@@ -480,7 +480,7 @@
|
||||
"color_temp": "Color temperature",
|
||||
"condition": "Condition",
|
||||
"date": "Date",
|
||||
"datetime": "Date and time",
|
||||
"datetime": "Date and Time",
|
||||
"device": "Device",
|
||||
"duration": "Duration",
|
||||
"entity": "Entity",
|
||||
@@ -490,7 +490,7 @@
|
||||
"media": "Media",
|
||||
"number": "Number",
|
||||
"object": "Object",
|
||||
"color_rgb": "RGB color",
|
||||
"color_rgb": "RGB Color",
|
||||
"select": "Select",
|
||||
"state": "State",
|
||||
"target": "Target",
|
||||
@@ -498,7 +498,7 @@
|
||||
"text": "Text",
|
||||
"theme": "Theme",
|
||||
"time": "Time",
|
||||
"manual": "Manual entry"
|
||||
"manual": "Manual Entry"
|
||||
}
|
||||
},
|
||||
"template": {
|
||||
@@ -857,7 +857,7 @@
|
||||
"cyan": "Cyan",
|
||||
"teal": "Teal",
|
||||
"green": "Green",
|
||||
"light-green": "Light green",
|
||||
"light-green": "Light Green",
|
||||
"lime": "Lime",
|
||||
"yellow": "Yellow",
|
||||
"amber": "Amber",
|
||||
@@ -1045,7 +1045,7 @@
|
||||
"podcast": "Podcast",
|
||||
"season": "Season",
|
||||
"track": "Track",
|
||||
"tv_show": "TV show",
|
||||
"tv_show": "TV Show",
|
||||
"url": "URL",
|
||||
"video": "Video"
|
||||
},
|
||||
@@ -2935,7 +2935,7 @@
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
"tag_id": "Tag ID",
|
||||
"tag_id_placeholder": "Auto-generated if left empty",
|
||||
"tag_id_placeholder": "Autogenerated if left empty",
|
||||
"delete": "Delete",
|
||||
"update": "Update",
|
||||
"create": "Create",
|
||||
@@ -4193,13 +4193,13 @@
|
||||
"mode_after": "[%key:ui::panel::config::automation::editor::conditions::type::time::after%]",
|
||||
"mode_before": "[%key:ui::panel::config::automation::editor::conditions::type::time::before%]",
|
||||
"weekdays": {
|
||||
"mon": "Monday",
|
||||
"tue": "Tuesday",
|
||||
"wed": "Wednesday",
|
||||
"thu": "Thursday",
|
||||
"fri": "Friday",
|
||||
"sat": "Saturday",
|
||||
"sun": "Sunday"
|
||||
"mon": "[%key:ui::weekdays::monday%]",
|
||||
"tue": "[%key:ui::weekdays::tuesday%]",
|
||||
"wed": "[%key:ui::weekdays::wednesday%]",
|
||||
"thu": "[%key:ui::weekdays::thursday%]",
|
||||
"fri": "[%key:ui::weekdays::friday%]",
|
||||
"sat": "[%key:ui::weekdays::saturday%]",
|
||||
"sun": "[%key:ui::weekdays::sunday%]"
|
||||
},
|
||||
"description": {
|
||||
"picker": "If the current time is before or after a specified time.",
|
||||
@@ -4490,14 +4490,14 @@
|
||||
"trace_no_longer_available": "Chosen trace is no longer available",
|
||||
"enter_downloaded_trace": "Enter downloaded trace",
|
||||
"tabs": {
|
||||
"details": "Step details",
|
||||
"timeline": "Trace timeline",
|
||||
"details": "Step Details",
|
||||
"timeline": "Trace Timeline",
|
||||
"logbook": "Related logbook entries",
|
||||
"automation_config": "Automation config",
|
||||
"step_config": "Step config",
|
||||
"changed_variables": "Changed variables",
|
||||
"blueprint_config": "Blueprint config",
|
||||
"script_config": "Script config"
|
||||
"automation_config": "Automation Config",
|
||||
"step_config": "Step Config",
|
||||
"changed_variables": "Changed Variables",
|
||||
"blueprint_config": "Blueprint Config",
|
||||
"script_config": "Script Config"
|
||||
},
|
||||
"path": {
|
||||
"choose": "Select a step on the left for more information.",
|
||||
@@ -4544,7 +4544,7 @@
|
||||
"caption": "Blueprints",
|
||||
"description": "Manage blueprints",
|
||||
"overview": {
|
||||
"header": "Blueprint editor",
|
||||
"header": "Blueprint Editor",
|
||||
"introduction": "The blueprint configuration allows you to import and manage your blueprints.",
|
||||
"learn_more": "Learn more about using blueprints",
|
||||
"headers": {
|
||||
@@ -4601,14 +4601,14 @@
|
||||
"override_description": "Importing it will override the existing blueprint. If the updated blueprint is not compatible, it can break your automations. Automations will have to be adjusted manually.",
|
||||
"error_no_url": "Please enter the blueprint address.",
|
||||
"unsupported_blueprint": "This blueprint is not supported",
|
||||
"file_name": "Blueprint path"
|
||||
"file_name": "Blueprint Path"
|
||||
}
|
||||
},
|
||||
"script": {
|
||||
"caption": "Scripts",
|
||||
"description": "Execute a sequence of actions",
|
||||
"picker": {
|
||||
"header": "Script editor",
|
||||
"header": "Script Editor",
|
||||
"introduction": "The script editor allows you to create and edit scripts. Please follow the link below to read the instructions to make sure that you have configured Home Assistant correctly.",
|
||||
"learn_more": "Learn more about scripts",
|
||||
"no_scripts": "We couldn't find any scripts",
|
||||
@@ -4684,7 +4684,7 @@
|
||||
"field_delete_confirm_title": "Delete field?",
|
||||
"field_delete_confirm_text": "[%key:ui::panel::config::automation::editor::triggers::delete_confirm_text%]",
|
||||
"header": "Script: {name}",
|
||||
"default_name": "New script",
|
||||
"default_name": "New Script",
|
||||
"modes": {
|
||||
"label": "[%key:ui::panel::config::automation::editor::modes::label%]",
|
||||
"learn_more": "[%key:ui::panel::config::automation::editor::modes::learn_more%]",
|
||||
@@ -4729,7 +4729,7 @@
|
||||
"description": "Capture device states and easily recall them later",
|
||||
"activated": "Activated scene {name}.",
|
||||
"picker": {
|
||||
"header": "Scene editor",
|
||||
"header": "Scene Editor",
|
||||
"introduction": "The scene editor allows you to create and edit scenes. Please follow the link below to read the instructions to make sure that you have configured Home Assistant correctly.",
|
||||
"learn_more": "Learn more about scenes",
|
||||
"pick_scene": "Pick scene to edit",
|
||||
@@ -4993,7 +4993,7 @@
|
||||
"other_home_assistant": "Other Home Assistant",
|
||||
"instance_name": "Instance name",
|
||||
"instance_version": "Instance version",
|
||||
"ip_address": "IP address",
|
||||
"ip_address": "IP Address",
|
||||
"connected_at": "Connected at",
|
||||
"obfuscated_ip": {
|
||||
"show": "Show IP address",
|
||||
@@ -5129,7 +5129,7 @@
|
||||
"hidden": "Hidden"
|
||||
},
|
||||
"confirm_disable_config_entry_title": "Disable config entry?",
|
||||
"confirm_disable_config_entry_message": "There are no more devices for the config entry {name}, do you want to disable the config entry instead?",
|
||||
"confirm_disable_config_entry_message": "There are no more devices for the config entry {name}, do you want to instead disable the config entry?",
|
||||
"update_device_error": "Updating the device failed",
|
||||
"disabled": "Disabled",
|
||||
"data_table": {
|
||||
@@ -5381,9 +5381,8 @@
|
||||
"enable": "Enable device",
|
||||
"disable": "Disable device",
|
||||
"confirm_disable_title": "Disable device?",
|
||||
"confirm_disable_message": "Are you sure you want to disable {name} and all of its entities?",
|
||||
"confirm_disable_message": "Are you sure you want to disable {name} and all of it’s entities?",
|
||||
"configure": "Configure device",
|
||||
"edit": "Edit device",
|
||||
"delete": "Remove device"
|
||||
},
|
||||
"devices": "{count} {count, plural,\n one {device}\n other {devices}\n}",
|
||||
@@ -5417,7 +5416,7 @@
|
||||
"via": "Connected via",
|
||||
"firmware": "Firmware: {version}",
|
||||
"hardware": "Hardware: {version}",
|
||||
"version": "Version {version}",
|
||||
"version": "Version: {version}",
|
||||
"serial_number": "Serial number: {serial_number}",
|
||||
"unnamed_entry": "Unnamed entry",
|
||||
"unknown_via_device": "Unknown device",
|
||||
@@ -5662,9 +5661,9 @@
|
||||
},
|
||||
"dhcp": {
|
||||
"title": "DHCP discovery",
|
||||
"mac_address": "MAC address",
|
||||
"mac_address": "MAC Address",
|
||||
"hostname": "Hostname",
|
||||
"ip_address": "IP address",
|
||||
"ip_address": "IP Address",
|
||||
"no_devices_found": "No recent DHCP requests found; no matching discoveries detected"
|
||||
},
|
||||
"thread": {
|
||||
@@ -5723,7 +5722,7 @@
|
||||
"name": "Name",
|
||||
"type": "Type",
|
||||
"port": "Port",
|
||||
"ip_addresses": "IP addresses",
|
||||
"ip_addresses": "IP Addresses",
|
||||
"properties": "Properties",
|
||||
"discovery_information": "Discovery information",
|
||||
"copy_to_clipboard": "Copy to clipboard",
|
||||
@@ -5890,7 +5889,7 @@
|
||||
"not_ready": "{count} not ready",
|
||||
"nvm_backup": {
|
||||
"title": "Backup and restore",
|
||||
"description": "Back up or restore your Z-Wave adapter's non-volatile memory (NVM). The NVM contains your network information including paired devices. It's recommended to create a backup before making any major changes to your Z-Wave network.",
|
||||
"description": "Back up or restore your Z-Wave controller's non-volatile memory (NVM). The NVM contains your network information including paired devices. It's recommended to create a backup before making any major changes to your Z-Wave network.",
|
||||
"download_backup": "Download backup",
|
||||
"restore_backup": "Restore from backup",
|
||||
"backup_failed": "Failed to download backup",
|
||||
@@ -5898,21 +5897,21 @@
|
||||
"restore_failed": "Failed to restore backup",
|
||||
"creating": "Creating backup",
|
||||
"restoring": "Restoring backup",
|
||||
"migrate": "Migrate adapter"
|
||||
"migrate": "Migrate controller"
|
||||
},
|
||||
"statistics": {
|
||||
"title": "Adapter statistics",
|
||||
"title": "Controller statistics",
|
||||
"messages_tx": {
|
||||
"label": "Messages TX",
|
||||
"tooltip": "Number of messages successfully sent to the adapter"
|
||||
"tooltip": "Number of messages successfully sent to the controller"
|
||||
},
|
||||
"messages_rx": {
|
||||
"label": "Messages RX",
|
||||
"tooltip": "Number of messages successfully received by the adapter"
|
||||
"tooltip": "Number of messages successfully received by the controller"
|
||||
},
|
||||
"messages_dropped_tx": {
|
||||
"label": "Dropped messages TX",
|
||||
"tooltip": "Number of messages from the adapter that were dropped by the host"
|
||||
"tooltip": "Number of messages from the controller that were dropped by the host"
|
||||
},
|
||||
"messages_dropped_rx": {
|
||||
"label": "Dropped messages RX",
|
||||
@@ -5920,23 +5919,23 @@
|
||||
},
|
||||
"nak": {
|
||||
"label": "NAK",
|
||||
"tooltip": "Number of messages that the adapter did not accept"
|
||||
"tooltip": "Number of messages that the controller did not accept"
|
||||
},
|
||||
"can": {
|
||||
"label": "CAN",
|
||||
"tooltip": "Number of collisions while sending a message to the adapter"
|
||||
"tooltip": "Number of collisions while sending a message to the controller"
|
||||
},
|
||||
"timeout_ack": {
|
||||
"label": "Timeout ACK",
|
||||
"tooltip": "Number of transmission attempts where an ACK was missing from the adapter"
|
||||
"tooltip": "Number of transmission attempts where an ACK was missing from the controller"
|
||||
},
|
||||
"timeout_response": {
|
||||
"label": "Timeout response",
|
||||
"tooltip": "Number of transmission attempts where the adapter response did not come in time"
|
||||
"tooltip": "Number of transmission attempts where the controller response did not come in time"
|
||||
},
|
||||
"timeout_callback": {
|
||||
"label": "Timeout callback",
|
||||
"tooltip": "Number of transmission attempts where the adapter callback did not come in time"
|
||||
"tooltip": "Number of transmission attempts where the controller callback did not come in time"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5959,18 +5958,18 @@
|
||||
},
|
||||
"hard_reset_controller": {
|
||||
"NotStarted": {
|
||||
"title": "Reset adapter to factory settings",
|
||||
"body": "If you decide to move forward, you will reset your adapter to factory settings. As a result, the adapter will forget all devices it is paired with and all Z-Wave devices for this network will be removed from Home Assistant. If there are any devices still paired with the adapter when it is reset, they will have to go through the exclusion process before they can be re-paired. Would you like to continue?"
|
||||
"title": "Reset controller to factory settings",
|
||||
"body": "If you decide to move forward, you will reset your controller to factory settings. As a result, the controller will forget all devices it is paired with and all Z-Wave devices for this network will be removed from Home Assistant. If there are any devices still paired with the controller when it is reset, they will have to go through the exclusion process before they can be re-paired. Would you like to continue?"
|
||||
},
|
||||
"InProgress": {
|
||||
"title": "Resetting adapter",
|
||||
"body": "Your adapter is being reset and restarted. Wait until the process is complete before closing this dialog"
|
||||
"title": "Resetting controller",
|
||||
"body": "Your controller is being reset and restarted. Wait until the process is complete before closing this dialog"
|
||||
},
|
||||
"Done": {
|
||||
"title": "Adapter reset complete",
|
||||
"body": "Your adapter has been reset to factory settings and has been restarted! You can now close this dialog."
|
||||
"title": "Controller reset complete",
|
||||
"body": "Your controller has been reset to factory settings and has been restarted! You can now close this dialog."
|
||||
},
|
||||
"confirmation": "This action cannot be undone unless you have a backup from your adapter."
|
||||
"confirmation": "This action cannot be undone unless you have an NVM backup from your controller."
|
||||
},
|
||||
"node_statistics": {
|
||||
"title": "Device statistics",
|
||||
@@ -6035,7 +6034,7 @@
|
||||
},
|
||||
"rssi": {
|
||||
"label": "RSSI",
|
||||
"tooltip": "The RSSI of the ACK frame received by the adapter"
|
||||
"tooltip": "The RSSI of the ACK frame received by the controller"
|
||||
},
|
||||
"route_failed_between": {
|
||||
"label": "Route failed between",
|
||||
@@ -6254,7 +6253,7 @@
|
||||
},
|
||||
"rebuild_node_routes": {
|
||||
"title": "Rebuild routes for a Z-Wave device",
|
||||
"introduction": "Assign new routes between {device} and the adapter. This can help with communication issues if you have recently moved the device or your adapter.",
|
||||
"introduction": "Tell {device} to update its routes back to the controller. This can help with communication issues if you have recently moved the device or your controller.",
|
||||
"traffic_warning": "The route rebuilding process generates a large amount of traffic on the Z-Wave network. This may cause devices to respond slowly (or not at all) while the rebuilding is in progress.",
|
||||
"start_rebuilding_routes": "Rebuild Routes for Device",
|
||||
"rebuilding_routes_failed": "{device} routes could not be rebuild.",
|
||||
@@ -6266,7 +6265,7 @@
|
||||
"update_firmware": {
|
||||
"title": "Update device firmware",
|
||||
"warning": "WARNING: Firmware updates can brick your device if you do not correctly follow the manufacturer's guidance. The Home Assistant and Z-Wave JS teams do not take any responsibility for any damages to your device as a result of the firmware update and will not be able to help you if you brick your device. Would you still like to continue?",
|
||||
"warning_controller": "WARNING: Firmware updates can brick your adapter if you do not use the right firmware files, or if you attempt to stop the firmware update before it completes. The Home Assistant and Z-Wave JS teams do not take any responsibility for any damages to your adapter as a result of the firmware update and will not be able to help you if you brick your adapter. Would you still like to continue?",
|
||||
"warning_controller": "WARNING: Firmware updates can brick your controller if you do not use the right firmware files, or if you attempt to stop the firmware update before it completes. The Home Assistant and Z-Wave JS teams do not take any responsibility for any damages to your controller as a result of the firmware update and will not be able to help you if you brick your controller. Would you still like to continue?",
|
||||
"introduction": "Select the firmware file you would like to use to update {device}.",
|
||||
"introduction_controller": "Select the firmware file you would like to use to update {device}. Note that once you start a firmware update, you MUST wait for the update to complete.",
|
||||
"firmware_target_intro": "Select the firmware target (0 for the Z-Wave chip, ≥1 for other chips if they exist) for this update.",
|
||||
@@ -6287,7 +6286,7 @@
|
||||
"error": "Unable to update firmware on {device}: {message}.",
|
||||
"try_again": "To attempt the firmware update again, select the new firmware file you would like to use.",
|
||||
"done": "The firmware update is complete! If you want to attempt another firmware update on this device, please wait until it gets re-interviewed.",
|
||||
"done_controller": "The firmware update is complete! Your adapter is being restarted and your network will temporarily be unavailable.",
|
||||
"done_controller": "The firmware update is complete! Your controller is being restarted and your network will temporarily be unavailable.",
|
||||
"Error_Timeout": "Timed out",
|
||||
"Error_Checksum": "Checksum error",
|
||||
"Error_TransmissionFailed": "Transmission failed",
|
||||
@@ -6355,7 +6354,7 @@
|
||||
"title": "Door lock",
|
||||
"twist_assist": "Twist assist",
|
||||
"block_to_block": "Block to block",
|
||||
"auto_relock_time": "Autorelock time",
|
||||
"auto_relock_time": "Auto relock time",
|
||||
"hold_release_time": "Hold and release time",
|
||||
"operation_type": "Operation type",
|
||||
"operation_types": {
|
||||
@@ -6526,13 +6525,13 @@
|
||||
"prefix": "Subnet prefix",
|
||||
"add_address": "Add address",
|
||||
"gateway": "Gateway address",
|
||||
"dns_server": "DNS server",
|
||||
"add_dns_server": "Add DNS server",
|
||||
"dns_server": "DNS Server",
|
||||
"add_dns_server": "Add DNS Server",
|
||||
"custom_dns": "Custom",
|
||||
"unsaved": "You have unsaved changes, these will get lost if you change tabs, do you want to continue?",
|
||||
"failed_to_change": "Failed to change network settings",
|
||||
"hostname": {
|
||||
"title": "Hostname",
|
||||
"title": "Host name",
|
||||
"description": "The name your instance will have on your network",
|
||||
"failed_to_set_hostname": "Setting hostname failed"
|
||||
}
|
||||
@@ -6549,9 +6548,9 @@
|
||||
},
|
||||
"network_adapter": "Network adapter",
|
||||
"network_adapter_info": "Configure which network adapters integrations will use. A restart is required for these settings to apply.",
|
||||
"ip_information": "IP information",
|
||||
"ip_information": "IP Information",
|
||||
"adapter": {
|
||||
"auto_configure": "Autoconfigure",
|
||||
"auto_configure": "Auto configure",
|
||||
"detected": "Detected",
|
||||
"adapter": "Adapter"
|
||||
}
|
||||
@@ -6560,7 +6559,7 @@
|
||||
"caption": "Storage",
|
||||
"description": "{percent_used} used - {free_space} free",
|
||||
"used_space": "Used space",
|
||||
"emmc_lifetime_used": "eMMC lifetime used",
|
||||
"emmc_lifetime_used": "eMMC Lifetime Used",
|
||||
"disk_metrics": "Disk metrics",
|
||||
"datadisk": {
|
||||
"title": "Move data disk",
|
||||
@@ -6674,8 +6673,8 @@
|
||||
},
|
||||
"areas": {
|
||||
"no_entities": "No entities in this area.",
|
||||
"sensors": "Sensors",
|
||||
"sensors_description": "To display temperature and humidity sensors in the overview and in the area view, add a sensor to that area and {edit_the_area} to configure related sensors.",
|
||||
"header": "Area badges",
|
||||
"header_description": "To display temperature and humidity sensors in the overview and in the area view, add a sensor to that area and {edit_the_area} to configure related sensors.",
|
||||
"edit_the_area": "edit the area",
|
||||
"groups": {
|
||||
"lights": "Lights",
|
||||
@@ -6686,8 +6685,7 @@
|
||||
"actions": "Actions",
|
||||
"others": "Others"
|
||||
},
|
||||
"other_areas": "Other areas",
|
||||
"areas": "Areas"
|
||||
"unassigned_areas": "[%key:ui::panel::config::areas::picker::unassigned_areas%]"
|
||||
}
|
||||
},
|
||||
"cards": {
|
||||
@@ -6911,7 +6909,7 @@
|
||||
},
|
||||
"edit_view": {
|
||||
"header": "View configuration",
|
||||
"header_name": "{name} view configuration",
|
||||
"header_name": "{name} View Configuration",
|
||||
"add": "Add view",
|
||||
"background": {
|
||||
"settings": "Background settings",
|
||||
@@ -7027,7 +7025,7 @@
|
||||
},
|
||||
"edit_card": {
|
||||
"header": "Card configuration",
|
||||
"typed_header": "{type} card configuration",
|
||||
"typed_header": "{type} Card configuration",
|
||||
"pick_card": "Add to dashboard",
|
||||
"pick_card_title": "Which card would you like to add to {name}",
|
||||
"toggle_editor": "Toggle editor",
|
||||
@@ -7097,7 +7095,7 @@
|
||||
"move_card": {
|
||||
"header": "Choose a view to move the card to",
|
||||
"strategy_error_title": "Impossible to move the card",
|
||||
"strategy_error_text_strategy": "Moving a card to an auto-generated view is not supported.",
|
||||
"strategy_error_text_strategy": "Moving a card to an auto generated view is not supported.",
|
||||
"success": "Card moved successfully",
|
||||
"error": "Error while moving card"
|
||||
},
|
||||
@@ -7432,7 +7430,7 @@
|
||||
},
|
||||
"light": {
|
||||
"name": "Light",
|
||||
"description": "The Light card allows you to change the brightness of a light."
|
||||
"description": "The Light card allows you to change the brightness of the light."
|
||||
},
|
||||
"generic": {
|
||||
"alt_text": "Alternative text",
|
||||
@@ -7520,13 +7518,13 @@
|
||||
"geo_location_sources": "Geolocation sources",
|
||||
"no_geo_location_sources": "No geolocation sources available",
|
||||
"appearance": "Appearance",
|
||||
"theme_mode": "Theme mode",
|
||||
"theme_mode": "Theme Mode",
|
||||
"theme_modes": {
|
||||
"auto": "Auto",
|
||||
"light": "Light",
|
||||
"dark": "Dark"
|
||||
},
|
||||
"default_zoom": "Default zoom",
|
||||
"default_zoom": "Default Zoom",
|
||||
"source": "Source",
|
||||
"description": "The Map card that allows you to display entities on a map."
|
||||
},
|
||||
@@ -7574,7 +7572,7 @@
|
||||
"picture-elements": {
|
||||
"name": "Picture elements",
|
||||
"description": "The Picture elements card is one of the most versatile types of cards. The cards allow you to position icons or text and even actions! On an image based on coordinates.",
|
||||
"card_options": "Card options",
|
||||
"card_options": "Card Options",
|
||||
"elements": "Elements",
|
||||
"new_element": "Add new element",
|
||||
"confirm_delete_element": "Are you sure you want to delete the {type} element?",
|
||||
@@ -7613,7 +7611,7 @@
|
||||
"none": "None",
|
||||
"line": "Line"
|
||||
},
|
||||
"description": "The Sensor card gives you a quick overview of a sensor's state with an optional graph to visualize change over time.",
|
||||
"description": "The Sensor card gives you a quick overview of your sensors state with an optional graph to visualize change over time.",
|
||||
"limit_min": "Minimum value",
|
||||
"limit_max": "Maximum value"
|
||||
},
|
||||
@@ -7623,14 +7621,14 @@
|
||||
"integration_not_loaded": "This card requires the `todo` integration to be set up.",
|
||||
"hide_completed": "Hide completed items",
|
||||
"hide_create": "Hide 'Add item' field",
|
||||
"display_order": "Display order",
|
||||
"display_order": "Display Order",
|
||||
"sort_modes": {
|
||||
"none": "Default",
|
||||
"manual": "Manual",
|
||||
"alpha_asc": "Alphabetical (A-Z)",
|
||||
"alpha_desc": "Alphabetical (Z-A)",
|
||||
"duedate_asc": "Due date (Soonest first)",
|
||||
"duedate_desc": "Due date (Latest first)"
|
||||
"duedate_asc": "Due Date (Soonest First)",
|
||||
"duedate_desc": "Due Date (Latest First)"
|
||||
}
|
||||
},
|
||||
"thermostat": {
|
||||
@@ -7640,7 +7638,7 @@
|
||||
},
|
||||
"tile": {
|
||||
"name": "Tile",
|
||||
"description": "The Tile card gives you a quick overview of an entity. The card allows you to toggle the entity, show the More info dialog or trigger custom actions.",
|
||||
"description": "The tile card gives you a quick overview of your entity. The card allows you to toggle the entity, show the More info dialog or trigger custom actions.",
|
||||
"color": "Color",
|
||||
"color_helper": "Inactive state (e.g. off, closed) will not be colored.",
|
||||
"icon_tap_action": "Icon tap behavior",
|
||||
@@ -7694,7 +7692,7 @@
|
||||
"badge": {
|
||||
"entity": {
|
||||
"name": "Entity",
|
||||
"description": "The Entity badge gives you a quick overview of an entity.",
|
||||
"description": "The Entity badge gives you a quick overview of your entity.",
|
||||
"color": "[%key:ui::panel::lovelace::editor::card::tile::color%]",
|
||||
"color_helper": "[%key:ui::panel::lovelace::editor::card::tile::color_helper%]",
|
||||
"show_entity_picture": "Show entity picture",
|
||||
@@ -8232,14 +8230,14 @@
|
||||
"confirm_delete_title": "Delete long-lived access token?",
|
||||
"confirm_delete_text": "Are you sure you want to delete the long-lived access token for {name}?",
|
||||
"delete_failed": "Failed to delete the access token.",
|
||||
"create": "Create token",
|
||||
"create": "Create Token",
|
||||
"create_failed": "Failed to create the access token.",
|
||||
"name": "Name",
|
||||
"prompt_name": "Give the token a name",
|
||||
"prompt_copy_token": "Copy your access token. It will not be shown again.",
|
||||
"empty_state": "You have no long-lived access tokens yet.",
|
||||
"qr_code_image": "QR code for token {name}",
|
||||
"generate_qr_code": "Generate QR code"
|
||||
"generate_qr_code": "Generate QR Code"
|
||||
}
|
||||
},
|
||||
"todo": {
|
||||
@@ -8396,7 +8394,7 @@
|
||||
"hdmi_input": "HDMI input",
|
||||
"hdmi_switcher": "HDMI switcher",
|
||||
"volume": "Volume",
|
||||
"total_tv_time": "Total TV time",
|
||||
"total_tv_time": "Total TV Time",
|
||||
"turn_tv_off": "Turn television off",
|
||||
"air": "Air"
|
||||
},
|
||||
@@ -8666,7 +8664,7 @@
|
||||
"input_button": "Input buttons",
|
||||
"input_text": "Input texts",
|
||||
"input_number": "Input numbers",
|
||||
"input_datetime": "Input datetimes",
|
||||
"input_datetime": "Input date times",
|
||||
"input_select": "Input selects",
|
||||
"template": "Template entities",
|
||||
"universal": "Universal media player entities",
|
||||
@@ -9077,7 +9075,7 @@
|
||||
},
|
||||
"capability": {
|
||||
"stage": {
|
||||
"title": "Add-on stage",
|
||||
"title": "Add-on Stage",
|
||||
"description": "Add-ons can have one of three stages:\n\n{icon_stable} **Stable**: These are add-ons ready to be used in production.\n\n{icon_experimental} **Experimental**: These may contain bugs, and may be unfinished.\n\n{icon_deprecated} **Deprecated**: These add-ons will no longer receive any updates."
|
||||
},
|
||||
"rating": {
|
||||
@@ -9159,8 +9157,8 @@
|
||||
"description": "This will restart the add-on if it crashes"
|
||||
},
|
||||
"auto_update": {
|
||||
"title": "Autoupdate",
|
||||
"description": "Autoupdate the add-on when there is a new version available"
|
||||
"title": "Auto update",
|
||||
"description": "Auto update the add-on when there is a new version available"
|
||||
},
|
||||
"ingress_panel": {
|
||||
"title": "Show in sidebar",
|
||||
@@ -9271,7 +9269,7 @@
|
||||
"addons": "Add-ons",
|
||||
"dashboard": "Dashboard",
|
||||
"backups": "Backups",
|
||||
"store": "Add-on store",
|
||||
"store": "Add-on Store",
|
||||
"system": "System"
|
||||
},
|
||||
"my": {
|
||||
@@ -9361,7 +9359,7 @@
|
||||
"hostname": "Hostname",
|
||||
"change_hostname": "Change hostname",
|
||||
"new_hostname": "Please enter a new hostname:",
|
||||
"ip_address": "IP address",
|
||||
"ip_address": "IP Address",
|
||||
"change": "Change",
|
||||
"operating_system": "Operating system",
|
||||
"docker_version": "Docker version",
|
||||
@@ -9413,7 +9411,7 @@
|
||||
"confirm_password": "Confirm encryption key",
|
||||
"password_protection": "Password protection",
|
||||
"enter_password": "Please enter a password.",
|
||||
"passwords_not_matching": "The passwords do not match",
|
||||
"passwords_not_matching": "The passwords does not match",
|
||||
"backup_already_running": "A backup or restore is already running. Creating a new backup is currently not possible, try again later.",
|
||||
"confirm_restore_partial_backup_title": "Restore partial backup",
|
||||
"confirm_restore_partial_backup_text": "The backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shutdown and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again.",
|
||||
|
||||
@@ -5017,131 +5017,131 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/a11y-base@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/a11y-base@npm:24.7.9"
|
||||
"@vaadin/a11y-base@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/a11y-base@npm:24.8.0"
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin": "npm:^1.3.0"
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/component-base": "npm:~24.7.9"
|
||||
"@vaadin/component-base": "npm:^24.8.0"
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/7ea96ca92f292a899e0a911f190d194eb330f2916c2dfdfc5de83771b6f339af2413e8f8f8909ac66b2bd876854cc5e9043484062c817e997ef72fc467af3709
|
||||
checksum: 10/67aa4700b9f385aa92ca18e68abaa2fb592336673f2286dd2ef2b5eaba1fb8b882f454590fb68e975d4caf0a8698a953ffddcece943d10f91b960272152db564
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/combo-box@npm:24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/combo-box@npm:24.7.9"
|
||||
"@vaadin/combo-box@npm:24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/combo-box@npm:24.8.0"
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin": "npm:^1.3.0"
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/a11y-base": "npm:~24.7.9"
|
||||
"@vaadin/component-base": "npm:~24.7.9"
|
||||
"@vaadin/field-base": "npm:~24.7.9"
|
||||
"@vaadin/input-container": "npm:~24.7.9"
|
||||
"@vaadin/item": "npm:~24.7.9"
|
||||
"@vaadin/lit-renderer": "npm:~24.7.9"
|
||||
"@vaadin/overlay": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-material-styles": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:~24.7.9"
|
||||
"@vaadin/a11y-base": "npm:^24.8.0"
|
||||
"@vaadin/component-base": "npm:^24.8.0"
|
||||
"@vaadin/field-base": "npm:^24.8.0"
|
||||
"@vaadin/input-container": "npm:^24.8.0"
|
||||
"@vaadin/item": "npm:^24.8.0"
|
||||
"@vaadin/lit-renderer": "npm:^24.8.0"
|
||||
"@vaadin/overlay": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-material-styles": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:^24.8.0"
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/cd63ecbb0b8b260907aa5853faac8846f1d8c0d5ace1a7621b896109eb254afe1d68ff8b41d776bb253d04655e01c2905a4c361f1ad917de9dbde30c8cf9a5fd
|
||||
checksum: 10/c448e127ec53abfd3beca525518342a6d61ad62874e5c8ed3dea56cab66b7f9e132d40d6727ebe42dad53d0b343d30405ca6d9018d3a3a8b7b96c1f50b6d0133
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/component-base@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/component-base@npm:24.7.9"
|
||||
"@vaadin/component-base@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/component-base@npm:24.8.0"
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin": "npm:^1.3.0"
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/vaadin-development-mode-detector": "npm:^2.0.0"
|
||||
"@vaadin/vaadin-usage-statistics": "npm:^2.1.0"
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/24c11b6d395978b82ff54503dc578ef89ce6b2644d2768f1f25ec058b921ab3f9e3d011bf9a739db30112a40c1f89f61ec2cec41c2c0031a603f3c484c6ead11
|
||||
checksum: 10/7111877c340af80fceb9042d3a58f7916579b0c6639268fa899bc107f61c357b65154e07247232ca9f922ba3399c43b1176fa2226f4faa1091f51ab11c74c572
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/field-base@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/field-base@npm:24.7.9"
|
||||
"@vaadin/field-base@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/field-base@npm:24.8.0"
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin": "npm:^1.3.0"
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/a11y-base": "npm:~24.7.9"
|
||||
"@vaadin/component-base": "npm:~24.7.9"
|
||||
"@vaadin/a11y-base": "npm:^24.8.0"
|
||||
"@vaadin/component-base": "npm:^24.8.0"
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/4c93e46621871daace3a202e33e5da0f8021c5f3847675ebc608e813a2c2a466a8f5743288eb591296b5119f2735bb18c754e360928b179221271ecae943f240
|
||||
checksum: 10/3357d43a310464d9c76f10e782ec658ae5af9b5a9308faf6de878e3e110b4c20ebc6af8b7f33954f73cfd0f527798787c1994498675067cc814c01ef0588deeb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/icon@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/icon@npm:24.7.9"
|
||||
"@vaadin/icon@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/icon@npm:24.8.0"
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin": "npm:^1.3.0"
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/component-base": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:~24.7.9"
|
||||
"@vaadin/component-base": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:^24.8.0"
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/277156010b88541b7cf473683899c0c2004d049f98a1aeb76555bf0e728663193d273a4224d88a04c1eabefbd6710c7a77f11c5b01c3e1037ef1b95c9c2c5ffc
|
||||
checksum: 10/e0a90e694179d59228c32e8e93c89e0cc2ebc9509995d6a24679137086796a116b6de9c7fd2e64cec532445bbb20a9991f958d6482cedbf271d041e611163558
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/input-container@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/input-container@npm:24.7.9"
|
||||
"@vaadin/input-container@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/input-container@npm:24.8.0"
|
||||
dependencies:
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/component-base": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-material-styles": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:~24.7.9"
|
||||
"@vaadin/component-base": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-material-styles": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:^24.8.0"
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/6cc5934626c056178ba35bbe21a4f4094591e40955931630fc7a00c7a3db89be59b6884a75ef956b6f39eab1ced4309bffed9f57f084775b73e5d8b7a27c4ed7
|
||||
checksum: 10/b9ae6590936f68cfb77d5d4ff29b7acb63c16482059391efd64f72837984df084aeb6f39313adb3ea482496adb6f3d84a3195dd265d59f508ccffcb0d5d7b9a4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/item@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/item@npm:24.7.9"
|
||||
"@vaadin/item@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/item@npm:24.8.0"
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin": "npm:^1.3.0"
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/a11y-base": "npm:~24.7.9"
|
||||
"@vaadin/component-base": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-material-styles": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:~24.7.9"
|
||||
"@vaadin/a11y-base": "npm:^24.8.0"
|
||||
"@vaadin/component-base": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-material-styles": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:^24.8.0"
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/d0317af3876686cc9353fe42d582f3b03ebb0d3f7f6c7760f95ac8f8e50b7995abccb1804e1fc2df58265b710eab53a881ed07e52c0a716d4da84e275560c95f
|
||||
checksum: 10/a4eb618e7d204147379732244fc5bf3cdf7420ce168f91e0db9cb2a809fad267af4f54eac117a7fbb287a33489a12c7d4724d3a4e7a7fdd415ac30eb6f3554b5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/lit-renderer@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/lit-renderer@npm:24.7.9"
|
||||
"@vaadin/lit-renderer@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/lit-renderer@npm:24.8.0"
|
||||
dependencies:
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/a2101e428a537537e63be12f151f59fb70ae47778186c26465d3c4513372f8ffa4b8be4824b0b6110c03593bd680bc43ac4825f19190434c1dd63abdda0555f4
|
||||
checksum: 10/f843d389f8f1958ec70d5180535a620e774f90bd3e3e5e77e41c6b89f4820272df2a68a70a5d6d752dbb3078b966985767d8ca079054a5fc0daa95d000524d27
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/overlay@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/overlay@npm:24.7.9"
|
||||
"@vaadin/overlay@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/overlay@npm:24.8.0"
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin": "npm:^1.3.0"
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/a11y-base": "npm:~24.7.9"
|
||||
"@vaadin/component-base": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-material-styles": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:~24.7.9"
|
||||
"@vaadin/a11y-base": "npm:^24.8.0"
|
||||
"@vaadin/component-base": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-lumo-styles": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-material-styles": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:^24.8.0"
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/6790f954a39782f635312ad29edc939257cc4b3007908986ad4f04102cbc21348627aa5fc38ea63e261890fc1a77cd136e935df8ffda48dce65c090f7df4e438
|
||||
checksum: 10/d26330e761868a682013937c66977b5c6662251afa32df7fed0aea218977c25dc0f24a8d9b96561754b746943563c82c7a91e365cf50f8713a549562d63d9ec7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5152,36 +5152,37 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/vaadin-lumo-styles@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/vaadin-lumo-styles@npm:24.7.9"
|
||||
"@vaadin/vaadin-lumo-styles@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/vaadin-lumo-styles@npm:24.8.0"
|
||||
dependencies:
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/component-base": "npm:~24.7.9"
|
||||
"@vaadin/icon": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:~24.7.9"
|
||||
checksum: 10/a75ae75ca18fa4c4257f155e8632625b7379a4654c019e29ad5899fea0997275fb8ff519d0d37516e7d8f29466f449187b21f0d03cbd3d0e0a2b79abedf83e18
|
||||
"@vaadin/component-base": "npm:^24.8.0"
|
||||
"@vaadin/icon": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:^24.8.0"
|
||||
checksum: 10/14d9c942ed88a9aa4579f0c8b8193d51affe3c0fdff781ecb9fb53aef6746d86317eb372526a15b0723017cd67b16bbb3ed252b01c89faa89bb0fca3d1b19855
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/vaadin-material-styles@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/vaadin-material-styles@npm:24.7.9"
|
||||
"@vaadin/vaadin-material-styles@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/vaadin-material-styles@npm:24.8.0"
|
||||
dependencies:
|
||||
"@polymer/polymer": "npm:^3.0.0"
|
||||
"@vaadin/component-base": "npm:~24.7.9"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:~24.7.9"
|
||||
checksum: 10/642bcd8ce3b696b34c80f35c4fdf95b79a34cc956c3eeb2de06335f6db31b07e80d956af3209e3874d1c0df04ecec20efc3358292b50e0aa495a5f94adf649cd
|
||||
"@vaadin/component-base": "npm:^24.8.0"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:^24.8.0"
|
||||
checksum: 10/87917d5b20a1d77e7e38aff1e5be1d28a52a7c08777a01f44a6198cb4f0904ddf7257b23d622a02d098f38928ae3b168e2f2c81ac2c7b952e8056b4958154692
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vaadin/vaadin-themable-mixin@npm:24.7.9, @vaadin/vaadin-themable-mixin@npm:~24.7.9":
|
||||
version: 24.7.9
|
||||
resolution: "@vaadin/vaadin-themable-mixin@npm:24.7.9"
|
||||
"@vaadin/vaadin-themable-mixin@npm:24.8.0, @vaadin/vaadin-themable-mixin@npm:^24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "@vaadin/vaadin-themable-mixin@npm:24.8.0"
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin": "npm:^1.3.0"
|
||||
lit: "npm:^3.0.0"
|
||||
checksum: 10/167827b3082b2fb1028f4ab036d6503667b20f51d81b5857f75390a0341d78067c13064073268de996b24383b4c7d732c621a617e57357003d32e76d1b464a0c
|
||||
style-observer: "npm:^0.0.8"
|
||||
checksum: 10/141f8756e3330b9ee4efdd34e2febf832a70cf86802908d7fec589567bd4d3ce2820345cbe39fe5a6315bc6dee84065f781f48842ce864ef0a59589607ba1faa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -9337,8 +9338,8 @@ __metadata:
|
||||
"@types/tar": "npm:6.1.13"
|
||||
"@types/ua-parser-js": "npm:0.7.39"
|
||||
"@types/webspeechapi": "npm:0.0.29"
|
||||
"@vaadin/combo-box": "npm:24.7.9"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:24.7.9"
|
||||
"@vaadin/combo-box": "npm:24.8.0"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:24.8.0"
|
||||
"@vibrant/color": "npm:4.0.0"
|
||||
"@vitest/coverage-v8": "npm:3.2.4"
|
||||
"@vue/web-component-wrapper": "npm:1.3.0"
|
||||
@@ -9405,7 +9406,7 @@ __metadata:
|
||||
node-vibrant: "npm:4.0.3"
|
||||
object-hash: "npm:3.0.0"
|
||||
pinst: "npm:3.0.0"
|
||||
prettier: "npm:3.5.3"
|
||||
prettier: "npm:3.6.0"
|
||||
punycode: "npm:2.3.1"
|
||||
qr-scanner: "npm:1.4.2"
|
||||
qrcode: "npm:1.5.4"
|
||||
@@ -12244,12 +12245,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:3.5.3":
|
||||
version: 3.5.3
|
||||
resolution: "prettier@npm:3.5.3"
|
||||
"prettier@npm:3.6.0":
|
||||
version: 3.6.0
|
||||
resolution: "prettier@npm:3.6.0"
|
||||
bin:
|
||||
prettier: bin/prettier.cjs
|
||||
checksum: 10/7050c08f674d9e49fbd9a4c008291d0715471f64e94cc5e4b01729affce221dfc6875c8de7e66b728c64abc9352eefb7eaae071b5f79d30081be207b53774b78
|
||||
checksum: 10/5c0db5a8e32d2ac9824d8bc652990dfd534bc7a7c6f26d99d50c9146a2d9befb3cd1cc86c4aee71caf6b264d421a4b4b5961e31a62dda3790b8fec2521a76eef
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -13882,6 +13883,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"style-observer@npm:^0.0.8":
|
||||
version: 0.0.8
|
||||
resolution: "style-observer@npm:0.0.8"
|
||||
checksum: 10/9c72ee12c61d48f64622a625ebff9bc4df009877e7ed9b26cec08e8159f6270f428aeea120f0e7c5567c8bbaa701846528fb5339dbdb930e84f2a66d382aeeb6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"superstruct@npm:2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "superstruct@npm:2.0.2"
|
||||
|
||||
Reference in New Issue
Block a user