${index === 0 ||
@@ -123,58 +129,73 @@ class HaLogbook extends LitElement {
`
: html``}
-
-
- ${formatTimeWithSeconds(new Date(item.when), this.hass.language)}
-
+
${!this.noIcon
? html`
`
: ""}
-
- ${!this.noName
- ? !item.entity_id
- ? html`
${item.name}`
- : html`
-
${item.name}
- `
- : ""}
- ${item.message}
- ${item_username
- ? ` by ${item_username}`
- : !item.context_event_type
- ? ""
- : item.context_event_type === "call_service"
- ? // Service Call
- ` by service
+
+
+ ${!this.noName
+ ? html`
${item.name}`
+ : ""}
+ ${item.message}
+ ${item_username
+ ? ` ${this.hass.localize(
+ "ui.components.logbook.by"
+ )} ${item_username}`
+ : !item.context_event_type
+ ? ""
+ : item.context_event_type === "call_service"
+ ? // Service Call
+ ` ${this.hass.localize("ui.components.logbook.by_service")}
${item.context_domain}.${item.context_service}`
- : item.context_entity_id === item.entity_id
- ? // HomeKit or something that self references
- ` by
+ : item.context_entity_id === item.entity_id
+ ? // HomeKit or something that self references
+ ` ${this.hass.localize("ui.components.logbook.by")}
${
item.context_name
? item.context_name
: item.context_event_type
}`
- : // Another entity such as an automation or script
- html` by
-
${item.context_entity_id_name}`}
+ : // Another entity such as an automation or script
+ html` ${this.hass.localize("ui.components.logbook.by")}
+
${item.context_entity_id_name}`}
+
+
+ ${formatTimeWithSeconds(
+ new Date(item.when),
+ this.hass.language
+ )}
+ -
+
+
@@ -188,110 +209,131 @@ class HaLogbook extends LitElement {
}
private _entityClicked(ev: Event) {
+ const entityId = (ev.currentTarget as any).entityId;
+ if (!entityId) {
+ return;
+ }
+
ev.preventDefault();
+ ev.stopPropagation();
fireEvent(this, "hass-more-info", {
- entityId: (ev.target as any).entityId,
+ entityId: entityId,
});
}
- static get styles(): CSSResult {
- return css`
- :host {
- display: block;
- height: 100%;
- }
-
- .rtl {
- direction: ltr;
- }
-
- .entry-container {
- width: 100%;
- }
-
- .entry {
- display: flex;
- width: 100%;
- line-height: 2em;
- padding: 8px 16px;
- box-sizing: border-box;
- border-top: 1px solid
- var(--mdc-dialog-scroll-divider-color, rgba(0, 0, 0, 0.12));
- }
-
- .time {
- display: flex;
- justify-content: center;
- flex-direction: column;
- width: 75px;
- flex-shrink: 0;
- font-size: 12px;
- color: var(--secondary-text-color);
- }
-
- .date {
- margin: 8px 0;
- padding: 0 16px;
- }
-
- .narrow .date {
- padding: 0 8px;
- }
-
- .rtl .date {
- direction: rtl;
- }
-
- .icon-message {
- display: flex;
- align-items: center;
- }
-
- .no-entries {
- text-align: center;
- color: var(--secondary-text-color);
- }
-
- ha-icon {
- margin: 0 8px 0 16px;
- flex-shrink: 0;
- color: var(--primary-text-color);
- }
-
- .message {
- color: var(--primary-text-color);
- }
-
- .no-name .message:first-letter {
- text-transform: capitalize;
- }
-
- a {
- color: var(--primary-color);
- }
-
- .uni-virtualizer-host {
- display: block;
- position: relative;
- contain: strict;
- height: 100%;
- overflow: auto;
- }
-
- .uni-virtualizer-host > * {
- box-sizing: border-box;
- }
-
- .narrow .entry {
- flex-direction: column;
- line-height: 1.5;
- padding: 8px 0;
- }
-
- .narrow .icon-message ha-icon {
- margin-left: 0;
- }
- `;
+ static get styles(): CSSResultArray {
+ return [
+ haStyle,
+ css`
+ :host {
+ display: block;
+ height: 100%;
+ }
+
+ .rtl {
+ direction: ltr;
+ }
+
+ .entry-container {
+ width: 100%;
+ }
+
+ .entry {
+ display: flex;
+ width: 100%;
+ line-height: 2em;
+ padding: 8px 16px;
+ box-sizing: border-box;
+ border-top: 1px solid
+ var(--mdc-dialog-scroll-divider-color, rgba(0, 0, 0, 0.12));
+ }
+
+ .entry.no-entity,
+ .no-name .entry {
+ cursor: default;
+ }
+
+ .entry:hover {
+ background-color: rgba(var(--rgb-primary-text-color), 0.04);
+ }
+
+ .narrow:not(.no-icon) .time {
+ margin-left: 32px;
+ }
+
+ .message-relative_time {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .secondary {
+ font-size: 12px;
+ line-height: 1.7;
+ }
+
+ .date {
+ margin: 8px 0;
+ padding: 0 16px;
+ }
+
+ .narrow .date {
+ padding: 0 8px;
+ }
+
+ .rtl .date {
+ direction: rtl;
+ }
+
+ .icon-message {
+ display: flex;
+ align-items: center;
+ }
+
+ .no-entries {
+ text-align: center;
+ color: var(--secondary-text-color);
+ }
+
+ ha-icon {
+ margin-right: 16px;
+ flex-shrink: 0;
+ color: var(--state-icon-color);
+ }
+
+ .message {
+ color: var(--primary-text-color);
+ }
+
+ .no-name .message:first-letter {
+ text-transform: capitalize;
+ }
+
+ a {
+ color: var(--primary-color);
+ }
+
+ .uni-virtualizer-host {
+ display: block;
+ position: relative;
+ contain: strict;
+ height: 100%;
+ overflow: auto;
+ }
+
+ .uni-virtualizer-host > * {
+ box-sizing: border-box;
+ }
+
+ .narrow .entry {
+ line-height: 1.5;
+ padding: 8px;
+ }
+
+ .narrow .icon-message ha-icon {
+ margin-left: 0;
+ }
+ `,
+ ];
}
}
diff --git a/src/panels/logbook/ha-panel-logbook.ts b/src/panels/logbook/ha-panel-logbook.ts
index 806cb5ac6bdd..e3542ba572ec 100644
--- a/src/panels/logbook/ha-panel-logbook.ts
+++ b/src/panels/logbook/ha-panel-logbook.ts
@@ -115,18 +115,22 @@ export class HaPanelLogbook extends LitElement {
${this._isLoading
- ? html`
-
-
`
- : html`
`}
+ ? html`
+
+
+
+ `
+ : html`
+
+ `}
`;
}
@@ -268,6 +272,7 @@ export class HaPanelLogbook extends LitElement {
),
this._fetchUserDone,
]);
+
// Fixed in TS 3.9 but upgrade out of scope for this PR.
// @ts-ignore
this._entries = entries;
diff --git a/src/panels/lovelace/cards/hui-calendar-card.ts b/src/panels/lovelace/cards/hui-calendar-card.ts
index ee94fb807ce1..625e915fac98 100644
--- a/src/panels/lovelace/cards/hui-calendar-card.ts
+++ b/src/panels/lovelace/cards/hui-calendar-card.ts
@@ -3,34 +3,32 @@ import {
CSSResult,
customElement,
html,
+ internalProperty,
LitElement,
property,
PropertyValues,
TemplateResult,
- internalProperty,
} from "lit-element";
-
+import { HA_COLOR_PALETTE } from "../../../common/const";
+import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
+import { HASSDomEvent } from "../../../common/dom/fire_event";
+import { debounce } from "../../../common/util/debounce";
import "../../../components/ha-card";
import "../../../components/ha-icon";
-import "../../calendar/ha-full-calendar";
-
+import { fetchCalendarEvents } from "../../../data/calendar";
import type {
- HomeAssistant,
- CalendarEvent,
Calendar,
+ CalendarEvent,
CalendarViewChanged,
FullCalendarView,
+ HomeAssistant,
} from "../../../types";
-import type { LovelaceCard, LovelaceCardEditor } from "../types";
-import type { CalendarCardConfig } from "./types";
+import "../../calendar/ha-full-calendar";
import { findEntities } from "../common/find-entites";
-import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
-import "../components/hui-warning";
-import { fetchCalendarEvents } from "../../../data/calendar";
-import { HASSDomEvent } from "../../../common/dom/fire_event";
-import { HA_COLOR_PALETTE } from "../../../common/const";
-import { debounce } from "../../../common/util/debounce";
import { installResizeObserver } from "../common/install-resize-observer";
+import "../components/hui-warning";
+import type { LovelaceCard, LovelaceCardEditor } from "../types";
+import type { CalendarCardConfig } from "./types";
@customElement("hui-calendar-card")
export class HuiCalendarCard extends LitElement implements LovelaceCard {
@@ -73,6 +71,10 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard {
@internalProperty() private _veryNarrow = false;
+ private _startDate?: Date;
+
+ private _endDate?: Date;
+
private _resizeObserver?: ResizeObserver;
public setConfig(config: CalendarCardConfig): void {
@@ -91,7 +93,11 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard {
};
});
- this._config = config;
+ if (this._config?.entities !== config.entities) {
+ this._fetchCalendarEvents();
+ }
+
+ this._config = { initial_view: "dayGridMonth", ...config };
}
public getCardSize(): number {
@@ -126,6 +132,7 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard {
.events=${this._events}
.hass=${this.hass}
.views=${views}
+ .initialView=${this._config.initial_view!}
@view-changed=${this._handleViewChanged}
>
@@ -153,13 +160,21 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard {
}
}
- private async _handleViewChanged(
- ev: HASSDomEvent
- ): Promise {
+ private _handleViewChanged(ev: HASSDomEvent): void {
+ this._startDate = ev.detail.start;
+ this._endDate = ev.detail.end;
+ this._fetchCalendarEvents();
+ }
+
+ private async _fetchCalendarEvents(): Promise {
+ if (!this._startDate || !this._endDate) {
+ return;
+ }
+
this._events = await fetchCalendarEvents(
this.hass!,
- ev.detail.start,
- ev.detail.end,
+ this._startDate,
+ this._endDate,
this._calendars
);
}
diff --git a/src/panels/lovelace/cards/hui-error-card.ts b/src/panels/lovelace/cards/hui-error-card.ts
index b995c6c04d43..194a423a3210 100644
--- a/src/panels/lovelace/cards/hui-error-card.ts
+++ b/src/panels/lovelace/cards/hui-error-card.ts
@@ -50,6 +50,9 @@ export class HuiErrorCard extends LitElement implements LovelaceCard {
user-select: text;
cursor: default;
}
+ pre {
+ font-family: var(--code-font-family, monospace);
+ }
`;
}
}
diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts
index 0aa6389e218f..91831a601c58 100644
--- a/src/panels/lovelace/cards/hui-media-control-card.ts
+++ b/src/panels/lovelace/cards/hui-media-control-card.ts
@@ -1,3 +1,5 @@
+import "@material/mwc-icon-button";
+import { mdiPlayBoxMultiple } from "@mdi/js";
import "@polymer/paper-progress/paper-progress";
import type { PaperProgressElement } from "@polymer/paper-progress/paper-progress";
import {
@@ -25,6 +27,7 @@ import { debounce } from "../../../common/util/debounce";
import "../../../components/ha-card";
import "../../../components/ha-icon";
import "../../../components/ha-icon-button";
+import "../../../components/ha-svg-icon";
import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog";
import { UNAVAILABLE_STATES } from "../../../data/entity";
import {
@@ -403,14 +406,16 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
)}
${supportsFeature(stateObj, SUPPORT_BROWSE_MEDIA)
? html`
-
+ >
`
: ""}
@@ -813,7 +818,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
position: absolute;
right: 0;
height: 100%;
- background-image: url("../static/images/card_media_player_bg.png");
+ background-image: url("/static/images/card_media_player_bg.png");
width: 50%;
transition: opacity 0.8s, background-color 0.8s;
}
@@ -866,7 +871,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
--mdc-icon-size: 40px;
}
- ha-icon-button.browse-media {
+ mwc-icon-button.browse-media {
position: absolute;
right: 0;
--mdc-icon-size: 24px;
diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts
index 234549a4fd84..98726230bcd4 100644
--- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts
+++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts
@@ -163,6 +163,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
: undefined;
let hourly: boolean | undefined;
+ let dayNight: boolean | undefined;
if (forecast?.length && forecast?.length > 2) {
const date1 = new Date(forecast[1].datetime);
@@ -170,6 +171,14 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
const timeDiff = date2.getTime() - date1.getTime();
hourly = timeDiff < DAY_IN_MILLISECONDS;
+
+ if (hourly) {
+ const dateFirst = new Date(forecast[0].datetime);
+ const datelast = new Date(forecast[forecast.length - 1].datetime);
+ const dayDiff = datelast.getTime() - dateFirst.getTime();
+
+ dayNight = dayDiff > DAY_IN_MILLISECONDS;
+ }
}
const weatherStateIcon = getWeatherStateIcon(stateObj.state, this);
@@ -235,7 +244,21 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
(item) => html`
- ${hourly
+ ${dayNight
+ ? html`
+ ${new Date(item.datetime).toLocaleDateString(
+ this.hass!.language,
+ { weekday: "short" }
+ )}
+
+ ${item.daytime === undefined || item.daytime
+ ? this.hass!.localize("ui.card.weather.day")
+ : this.hass!.localize(
+ "ui.card.weather.night"
+ )}
+
+ `
+ : hourly
? html`
${new Date(item.datetime).toLocaleTimeString(
this.hass!.language,
@@ -254,7 +277,11 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
${item.condition !== undefined && item.condition !== null
? html`
- ${getWeatherStateIcon(item.condition, this)}
+ ${getWeatherStateIcon(
+ item.condition,
+ this,
+ !(item.daytime || item.daytime === undefined)
+ )}
`
: ""}
@@ -445,6 +472,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
.attribute,
.templow,
+ .daynight,
.name {
color: var(--secondary-text-color);
}
diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts
index ac3feafc799a..8c2923967db0 100644
--- a/src/panels/lovelace/cards/types.ts
+++ b/src/panels/lovelace/cards/types.ts
@@ -1,4 +1,5 @@
import { ActionConfig, LovelaceCardConfig } from "../../../data/lovelace";
+import { FullCalendarView } from "../../../types";
import { Condition } from "../common/validate-condition";
import { HuiImage } from "../components/hui-image";
import { LovelaceElementConfig } from "../elements/types";
@@ -14,6 +15,7 @@ export interface AlarmPanelCardConfig extends LovelaceCardConfig {
export interface CalendarCardConfig extends LovelaceCardConfig {
entities: string[];
+ initial_view?: FullCalendarView;
title?: string;
theme?: string;
}
diff --git a/src/panels/lovelace/common/evaluate-filter.ts b/src/panels/lovelace/common/evaluate-filter.ts
index 66f738384e46..31c2f14d5dd6 100644
--- a/src/panels/lovelace/common/evaluate-filter.ts
+++ b/src/panels/lovelace/common/evaluate-filter.ts
@@ -21,13 +21,13 @@ export const evaluateFilter = (stateObj: HassEntity, filter: any): boolean => {
case "!=":
return state !== value;
case "in":
- if (Array.isArray(state) || typeof state === "string") {
- return state.includes(value);
+ if (Array.isArray(value) || typeof value === "string") {
+ return value.includes(state);
}
return false;
case "not in":
- if (Array.isArray(state) || typeof state === "string") {
- return !state.includes(value);
+ if (Array.isArray(value) || typeof value === "string") {
+ return !value.includes(state);
}
return false;
case "regex": {
diff --git a/src/panels/lovelace/components/hui-action-editor.ts b/src/panels/lovelace/components/hui-action-editor.ts
index dea53bd0d3d7..7946138d6e19 100644
--- a/src/panels/lovelace/components/hui-action-editor.ts
+++ b/src/panels/lovelace/components/hui-action-editor.ts
@@ -3,7 +3,10 @@ import "@polymer/paper-input/paper-input";
import "@polymer/paper-input/paper-textarea";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
+import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox";
import {
+ css,
+ CSSResult,
customElement,
html,
LitElement,
@@ -11,6 +14,7 @@ import {
TemplateResult,
} from "lit-element";
import { fireEvent } from "../../../common/dom/fire_event";
+import "../../../components/ha-help-tooltip";
import "../../../components/ha-service-picker";
import {
ActionConfig,
@@ -29,11 +33,9 @@ export class HuiActionEditor extends LitElement {
@property() public actions?: string[];
- @property() protected hass?: HomeAssistant;
+ @property() public tooltipText?: string;
- get _action(): string {
- return this.config?.action || "";
- }
+ @property() protected hass?: HomeAssistant;
get _navigation_path(): string {
const config = this.config as NavigateActionConfig;
@@ -54,72 +56,131 @@ export class HuiActionEditor extends LitElement {
if (!this.hass || !this.actions) {
return html``;
}
+
return html`
-
-
+
- ${this.actions.map((action) => {
- return html` ${action} `;
- })}
-
-
- ${this._action === "navigate"
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.action-editor.actions.default_action"
+ )}
+ ${this.actions.map((action) => {
+ return html`
+ ${this.hass!.localize(
+ `ui.panel.lovelace.editor.action-editor.actions.${action}`
+ )}
+ `;
+ })}
+
+
+ ${this.tooltipText
+ ? html`
+
+ `
+ : ""}
+
+ ${this.config?.action === "navigate"
? html`
`
: ""}
- ${this._action === "url"
+ ${this.config?.action === "url"
? html`
`
: ""}
- ${this.config && this.config.action === "call-service"
+ ${this.config?.action === "call-service"
? html`
-
Service data can only be entered in the code editor
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.action-editor.editor_service_data"
+ )}
+
`
: ""}
`;
}
- private _valueChanged(ev: Event): void {
+ private _actionPicked(ev: CustomEvent): void {
+ ev.stopPropagation();
+ if (!this.hass) {
+ return;
+ }
+ const item = ev.detail.item;
+ const value = item.value;
+ if (this.config?.action === value) {
+ return;
+ }
+ if (value === "default") {
+ fireEvent(this, "value-changed", { value: undefined });
+ if (this.config?.action) {
+ (this.shadowRoot!.querySelector(
+ "paper-listbox"
+ ) as PaperListboxElement).select(this.config.action);
+ }
+ return;
+ }
+ fireEvent(this, "value-changed", {
+ value: { action: value },
+ });
+ }
+
+ private _valueChanged(ev: CustomEvent): void {
ev.stopPropagation();
if (!this.hass) {
return;
}
const target = ev.target! as EditorTarget;
- if (this[`_${target.configValue}`] === target.value) {
+ const value = ev.detail.value;
+ if (this[`_${target.configValue}`] === value) {
return;
}
if (target.configValue) {
- const newConfig =
- target.configValue === "action"
- ? { action: target.value }
- : { ...this.config!, [target.configValue!]: target.value };
- fireEvent(this, "value-changed", { value: newConfig });
+ fireEvent(this, "value-changed", {
+ value: { ...this.config!, [target.configValue!]: value },
+ });
}
}
+
+ static get styles(): CSSResult {
+ return css`
+ .dropdown {
+ display: flex;
+ }
+ `;
+ }
}
declare global {
diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts
index ec9f8aacf408..4e6d5ddb3d90 100644
--- a/src/panels/lovelace/components/hui-card-options.ts
+++ b/src/panels/lovelace/components/hui-card-options.ts
@@ -108,6 +108,10 @@ export class HuiCardOptions extends LitElement {
outline: 2px solid var(--primary-color);
}
+ ::slotted(*) {
+ display: block;
+ }
+
ha-card {
border-top-right-radius: 0;
border-top-left-radius: 0;
diff --git a/src/panels/lovelace/create-element/create-element-base.ts b/src/panels/lovelace/create-element/create-element-base.ts
index b1afedcb281f..23b2083e1e1b 100644
--- a/src/panels/lovelace/create-element/create-element-base.ts
+++ b/src/panels/lovelace/create-element/create-element-base.ts
@@ -2,9 +2,12 @@ import { fireEvent } from "../../../common/dom/fire_event";
import {
LovelaceBadgeConfig,
LovelaceCardConfig,
+ LovelaceViewConfig,
+ LovelaceViewElement,
} from "../../../data/lovelace";
import { CUSTOM_TYPE_PREFIX } from "../../../data/lovelace_custom_cards";
import type { HuiErrorCard } from "../cards/hui-error-card";
+import type { ErrorCardConfig } from "../cards/types";
import { LovelaceElement, LovelaceElementConfig } from "../elements/types";
import { LovelaceRow, LovelaceRowConfig } from "../entity-rows/types";
import { LovelaceHeaderFooterConfig } from "../header-footer/types";
@@ -14,7 +17,6 @@ import {
LovelaceCardConstructor,
LovelaceHeaderFooter,
} from "../types";
-import type { ErrorCardConfig } from "../cards/types";
const TIMEOUT = 2000;
@@ -44,6 +46,11 @@ interface CreateElementConfigTypes {
element: LovelaceHeaderFooter;
constructor: unknown;
};
+ view: {
+ config: LovelaceViewConfig;
+ element: LovelaceViewElement;
+ constructor: unknown;
+ };
}
export const createErrorCardElement = (config: ErrorCardConfig) => {
diff --git a/src/panels/lovelace/create-element/create-row-element.ts b/src/panels/lovelace/create-element/create-row-element.ts
index 178192fa4803..433b50e0a589 100644
--- a/src/panels/lovelace/create-element/create-row-element.ts
+++ b/src/panels/lovelace/create-element/create-row-element.ts
@@ -24,6 +24,7 @@ const LAZY_LOAD_TYPES = {
"climate-entity": () => import("../entity-rows/hui-climate-entity-row"),
"cover-entity": () => import("../entity-rows/hui-cover-entity-row"),
"group-entity": () => import("../entity-rows/hui-group-entity-row"),
+ "humidifier-entity": () => import("../entity-rows/hui-humidifier-entity-row"),
"input-datetime-entity": () =>
import("../entity-rows/hui-input-datetime-entity-row"),
"input-number-entity": () =>
@@ -51,7 +52,7 @@ const DOMAIN_TO_ELEMENT_TYPE = {
cover: "cover",
fan: "toggle",
group: "group",
- humidifier: "toggle",
+ humidifier: "humidifier",
input_boolean: "toggle",
input_number: "input-number",
input_select: "input-select",
diff --git a/src/panels/lovelace/create-element/create-view-element.ts b/src/panels/lovelace/create-element/create-view-element.ts
new file mode 100644
index 000000000000..d8cec5fa485c
--- /dev/null
+++ b/src/panels/lovelace/create-element/create-view-element.ts
@@ -0,0 +1,23 @@
+import {
+ LovelaceViewConfig,
+ LovelaceViewElement,
+} from "../../../data/lovelace";
+import "../views/hui-masonry-view";
+import { createLovelaceElement } from "./create-element-base";
+
+const ALWAYS_LOADED_LAYOUTS = new Set(["masonry"]);
+
+const LAZY_LOAD_LAYOUTS = {
+ panel: () => import("../views/hui-panel-view"),
+};
+
+export const createViewElement = (
+ config: LovelaceViewConfig
+): LovelaceViewElement => {
+ return createLovelaceElement(
+ "view",
+ config,
+ ALWAYS_LOADED_LAYOUTS,
+ LAZY_LOAD_LAYOUTS
+ );
+};
diff --git a/src/panels/lovelace/custom-card-helpers.ts b/src/panels/lovelace/custom-card-helpers.ts
index 2896d349b204..36efb72a7083 100644
--- a/src/panels/lovelace/custom-card-helpers.ts
+++ b/src/panels/lovelace/custom-card-helpers.ts
@@ -3,3 +3,4 @@ export { createCardElement } from "./create-element/create-card-element";
export { createHeaderFooterElement } from "./create-element/create-header-footer-element";
export { createHuiElement } from "./create-element/create-hui-element";
export { createRowElement } from "./create-element/create-row-element";
+export { importMoreInfoControl } from "../../dialogs/more-info/state_more_info_control";
diff --git a/src/panels/lovelace/editor/card-editor/hui-card-editor.ts b/src/panels/lovelace/editor/card-editor/hui-card-editor.ts
index 5c786ad71e89..ff4613ed0e83 100644
--- a/src/panels/lovelace/editor/card-editor/hui-card-editor.ts
+++ b/src/panels/lovelace/editor/card-editor/hui-card-editor.ts
@@ -24,7 +24,7 @@ import type {
import type { HomeAssistant } from "../../../../types";
import { handleStructError } from "../../common/structs/handle-errors";
import { getCardElementClass } from "../../create-element/create-card-element";
-import type { EntityConfig } from "../../entity-rows/types";
+import type { LovelaceRowConfig } from "../../entity-rows/types";
import type { LovelaceCardEditor } from "../../types";
import { GUISupportError } from "../gui-support-error";
import type { GUIModeChangedEvent } from "../types";
@@ -38,7 +38,7 @@ export interface ConfigChangedEvent {
declare global {
interface HASSDomEvents {
"entities-changed": {
- entities: EntityConfig[];
+ entities: LovelaceRowConfig[];
};
"config-changed": ConfigChangedEvent;
"GUImode-changed": GUIModeChangedEvent;
diff --git a/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts
index a2285c087d6c..b1930365d595 100644
--- a/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts
+++ b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts
@@ -38,6 +38,15 @@ const cardConfigStruct = object({
show_state: optional(boolean()),
});
+const actions = [
+ "more-info",
+ "toggle",
+ "navigate",
+ "url",
+ "call-service",
+ "none",
+];
+
@customElement("hui-button-card-editor")
export class HuiButtonCardEditor extends LitElement
implements LovelaceCardEditor {
@@ -80,8 +89,8 @@ export class HuiButtonCardEditor extends LitElement
: "";
}
- get _tap_action(): ActionConfig {
- return this._config!.tap_action || { action: "toggle" };
+ get _tap_action(): ActionConfig | undefined {
+ return this._config!.tap_action;
}
get _hold_action(): ActionConfig {
@@ -97,14 +106,6 @@ export class HuiButtonCardEditor extends LitElement
return html``;
}
- const actions = [
- "more-info",
- "toggle",
- "navigate",
- "url",
- "call-service",
- "none",
- ];
const dir = computeRTLDirection(this.hass!);
return html`
@@ -117,9 +118,9 @@ export class HuiButtonCardEditor extends LitElement
"ui.panel.lovelace.editor.card.config.optional"
)})"
.hass=${this.hass}
- .value="${this._entity}"
+ .value=${this._entity}
.configValue=${"entity"}
- @value-changed="${this._valueChanged}"
+ @value-changed=${this._valueChanged}
allow-custom-entity
>
@@ -129,9 +130,9 @@ export class HuiButtonCardEditor extends LitElement
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})"
- .value="${this._name}"
- .configValue="${"name"}"
- @value-changed="${this._valueChanged}"
+ .value=${this._name}
+ .configValue=${"name"}
+ @value-changed=${this._valueChanged}
>
@@ -183,9 +184,9 @@ export class HuiButtonCardEditor extends LitElement
.dir=${dir}
>
@@ -197,17 +198,17 @@ export class HuiButtonCardEditor extends LitElement
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})"
- .value="${this._icon_height}"
- .configValue="${"icon_height"}"
- @value-changed="${this._valueChanged}"
+ .value=${this._icon_height}
+ .configValue=${"icon_height"}
+ @value-changed=${this._valueChanged}
type="number"
>