mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-14 04:46:34 +00:00
Fix lit warnings (#9204)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
bc92c0b052
commit
1b9286db76
@ -129,6 +129,7 @@ const createWebpackConfig = ({
|
|||||||
alias: {
|
alias: {
|
||||||
"lit/decorators$": "lit/decorators.js",
|
"lit/decorators$": "lit/decorators.js",
|
||||||
"lit/directive$": "lit/directive.js",
|
"lit/directive$": "lit/directive.js",
|
||||||
|
"lit/polyfill-support$": "lit/polyfill-support.js",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import wrap from "@vue/web-component-wrapper";
|
import wrap from "@vue/web-component-wrapper";
|
||||||
|
import { customElement } from "lit/decorators";
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import DateRangePicker from "vue2-daterange-picker";
|
import DateRangePicker from "vue2-daterange-picker";
|
||||||
|
// @ts-ignore
|
||||||
import dateRangePickerStyles from "vue2-daterange-picker/dist/vue2-daterange-picker.css";
|
import dateRangePickerStyles from "vue2-daterange-picker/dist/vue2-daterange-picker.css";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { Constructor } from "../types";
|
import { Constructor } from "../types";
|
||||||
@ -34,22 +35,29 @@ const Component = Vue.extend({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
render(createElement) {
|
render(createElement) {
|
||||||
|
// @ts-ignore
|
||||||
return createElement(DateRangePicker, {
|
return createElement(DateRangePicker, {
|
||||||
props: {
|
props: {
|
||||||
"time-picker": true,
|
"time-picker": true,
|
||||||
"auto-apply": false,
|
"auto-apply": false,
|
||||||
opens: "right",
|
opens: "right",
|
||||||
"show-dropdowns": false,
|
"show-dropdowns": false,
|
||||||
|
// @ts-ignore
|
||||||
"time-picker24-hour": this.twentyfourHours,
|
"time-picker24-hour": this.twentyfourHours,
|
||||||
|
// @ts-ignore
|
||||||
disabled: this.disabled,
|
disabled: this.disabled,
|
||||||
|
// @ts-ignore
|
||||||
ranges: this.ranges ? {} : false,
|
ranges: this.ranges ? {} : false,
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
value: {
|
value: {
|
||||||
|
// @ts-ignore
|
||||||
startDate: this.startDate,
|
startDate: this.startDate,
|
||||||
|
// @ts-ignore
|
||||||
endDate: this.endDate,
|
endDate: this.endDate,
|
||||||
},
|
},
|
||||||
callback: (value) => {
|
callback: (value) => {
|
||||||
|
// @ts-ignore
|
||||||
fireEvent(this.$el as HTMLElement, "change", value);
|
fireEvent(this.$el as HTMLElement, "change", value);
|
||||||
},
|
},
|
||||||
expression: "dateRange",
|
expression: "dateRange",
|
||||||
|
@ -80,7 +80,8 @@ export class HaEntityToggle extends LitElement {
|
|||||||
this.addEventListener("click", (ev) => ev.stopPropagation());
|
this.addEventListener("click", (ev) => ev.stopPropagation());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues): void {
|
public willUpdate(changedProps: PropertyValues): void {
|
||||||
|
super.willUpdate(changedProps);
|
||||||
if (changedProps.has("stateObj")) {
|
if (changedProps.has("stateObj")) {
|
||||||
this._isOn = isOn(this.stateObj);
|
this._isOn = isOn(this.stateObj);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,8 @@ export class StateBadge extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
public willUpdate(changedProps: PropertyValues) {
|
||||||
|
super.willUpdate(changedProps);
|
||||||
if (
|
if (
|
||||||
!changedProps.has("stateObj") &&
|
!changedProps.has("stateObj") &&
|
||||||
!changedProps.has("overrideImage") &&
|
!changedProps.has("overrideImage") &&
|
||||||
|
@ -55,14 +55,6 @@ export class HaCodeEditor extends ReactiveElement {
|
|||||||
|
|
||||||
public connectedCallback() {
|
public connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
// Lit 2.0 will create the shadowRoot for us, and adopt the styles, check if it was created
|
|
||||||
if (!this.shadowRoot) {
|
|
||||||
this.attachShadow({ mode: "open" }).innerHTML = `<style>
|
|
||||||
:host(.error-state) div.cm-wrap .cm-gutters {
|
|
||||||
border-color: var(--error-state-color, red);
|
|
||||||
}
|
|
||||||
</style>`;
|
|
||||||
}
|
|
||||||
if (!this.codemirror) {
|
if (!this.codemirror) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,8 @@ export class HaIcon extends LitElement {
|
|||||||
|
|
||||||
@state() private _legacy = false;
|
@state() private _legacy = false;
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
public willUpdate(changedProps: PropertyValues) {
|
||||||
|
super.willUpdate(changedProps);
|
||||||
if (changedProps.has("icon")) {
|
if (changedProps.has("icon")) {
|
||||||
this._path = undefined;
|
this._path = undefined;
|
||||||
this._viewBox = undefined;
|
this._viewBox = undefined;
|
||||||
|
@ -93,7 +93,6 @@ class HaMenuButton extends LitElement {
|
|||||||
this.style.display = newNarrow || this._alwaysVisible ? "initial" : "none";
|
this.style.display = newNarrow || this._alwaysVisible ? "initial" : "none";
|
||||||
|
|
||||||
if (!newNarrow) {
|
if (!newNarrow) {
|
||||||
this._hasNotifications = false;
|
|
||||||
if (this._unsubNotifications) {
|
if (this._unsubNotifications) {
|
||||||
this._unsubNotifications();
|
this._unsubNotifications();
|
||||||
this._unsubNotifications = undefined;
|
this._unsubNotifications = undefined;
|
||||||
|
@ -27,6 +27,7 @@ import { guard } from "lit/directives/guard";
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { LocalStorage } from "../common/decorators/local-storage";
|
import { LocalStorage } from "../common/decorators/local-storage";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
|
import { toggleAttribute } from "../common/dom/toggle_attribute";
|
||||||
import { computeDomain } from "../common/entity/compute_domain";
|
import { computeDomain } from "../common/entity/compute_domain";
|
||||||
import { compare } from "../common/string/compare";
|
import { compare } from "../common/string/compare";
|
||||||
import { computeRTL } from "../common/util/compute_rtl";
|
import { computeRTL } from "../common/util/compute_rtl";
|
||||||
@ -165,18 +166,12 @@ class HaSidebar extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public alwaysExpand = false;
|
@property({ type: Boolean }) public alwaysExpand = false;
|
||||||
|
|
||||||
@property({ type: Boolean, reflect: true }) public expanded = false;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public editMode = false;
|
@property({ type: Boolean }) public editMode = false;
|
||||||
|
|
||||||
@state() private _externalConfig?: ExternalConfig;
|
@state() private _externalConfig?: ExternalConfig;
|
||||||
|
|
||||||
@state() private _notifications?: PersistentNotification[];
|
@state() private _notifications?: PersistentNotification[];
|
||||||
|
|
||||||
// property used only in css
|
|
||||||
// @ts-ignore
|
|
||||||
@property({ type: Boolean, reflect: true }) public rtl = false;
|
|
||||||
|
|
||||||
@state() private _renderEmptySortable = false;
|
@state() private _renderEmptySortable = false;
|
||||||
|
|
||||||
private _mouseLeaveTimeout?: number;
|
private _mouseLeaveTimeout?: number;
|
||||||
@ -265,7 +260,7 @@ class HaSidebar extends LitElement {
|
|||||||
protected updated(changedProps) {
|
protected updated(changedProps) {
|
||||||
super.updated(changedProps);
|
super.updated(changedProps);
|
||||||
if (changedProps.has("alwaysExpand")) {
|
if (changedProps.has("alwaysExpand")) {
|
||||||
this.expanded = this.alwaysExpand;
|
toggleAttribute(this, "expanded", this.alwaysExpand);
|
||||||
}
|
}
|
||||||
if (changedProps.has("editMode")) {
|
if (changedProps.has("editMode")) {
|
||||||
if (this.editMode) {
|
if (this.editMode) {
|
||||||
@ -280,7 +275,7 @@ class HaSidebar extends LitElement {
|
|||||||
|
|
||||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||||
if (!oldHass || oldHass.locale !== this.hass.locale) {
|
if (!oldHass || oldHass.locale !== this.hass.locale) {
|
||||||
this.rtl = computeRTL(this.hass);
|
toggleAttribute(this, "rtl", computeRTL(this.hass));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SUPPORT_SCROLL_IF_NEEDED) {
|
if (!SUPPORT_SCROLL_IF_NEEDED) {
|
||||||
@ -428,7 +423,7 @@ class HaSidebar extends LitElement {
|
|||||||
@click=${this._handleShowNotificationDrawer}
|
@click=${this._handleShowNotificationDrawer}
|
||||||
>
|
>
|
||||||
<ha-svg-icon slot="item-icon" .path=${mdiBell}></ha-svg-icon>
|
<ha-svg-icon slot="item-icon" .path=${mdiBell}></ha-svg-icon>
|
||||||
${!this.expanded && notificationCount > 0
|
${!this.alwaysExpand && notificationCount > 0
|
||||||
? html`
|
? html`
|
||||||
<span class="notification-badge" slot="item-icon">
|
<span class="notification-badge" slot="item-icon">
|
||||||
${notificationCount}
|
${notificationCount}
|
||||||
@ -438,7 +433,7 @@ class HaSidebar extends LitElement {
|
|||||||
<span class="item-text">
|
<span class="item-text">
|
||||||
${this.hass.localize("ui.notification_drawer.title")}
|
${this.hass.localize("ui.notification_drawer.title")}
|
||||||
</span>
|
</span>
|
||||||
${this.expanded && notificationCount > 0
|
${this.alwaysExpand && notificationCount > 0
|
||||||
? html` <span class="notification-badge">${notificationCount}</span> `
|
? html` <span class="notification-badge">${notificationCount}</span> `
|
||||||
: ""}
|
: ""}
|
||||||
</paper-icon-item>
|
</paper-icon-item>
|
||||||
@ -593,7 +588,7 @@ class HaSidebar extends LitElement {
|
|||||||
// for 100ms so that we ignore it when pressing down arrow scrolls the
|
// for 100ms so that we ignore it when pressing down arrow scrolls the
|
||||||
// sidebar causing the mouse to hover a new icon
|
// sidebar causing the mouse to hover a new icon
|
||||||
if (
|
if (
|
||||||
this.expanded ||
|
this.alwaysExpand ||
|
||||||
new Date().getTime() < this._recentKeydownActiveUntil
|
new Date().getTime() < this._recentKeydownActiveUntil
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
@ -615,7 +610,7 @@ class HaSidebar extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _listboxFocusIn(ev) {
|
private _listboxFocusIn(ev) {
|
||||||
if (this.expanded || ev.target.nodeName !== "A") {
|
if (this.alwaysExpand || ev.target.nodeName !== "A") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._showTooltip(ev.target.querySelector("paper-icon-item"));
|
this._showTooltip(ev.target.querySelector("paper-icon-item"));
|
||||||
|
@ -50,6 +50,12 @@ export const showDialog = async (
|
|||||||
) => {
|
) => {
|
||||||
if (!(dialogTag in LOADED)) {
|
if (!(dialogTag in LOADED)) {
|
||||||
if (!dialogImport) {
|
if (!dialogImport) {
|
||||||
|
if (__DEV__) {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.warn(
|
||||||
|
"Asked to show dialog that's not loaded and can't be imported"
|
||||||
|
);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOADED[dialogTag] = dialogImport().then(() => {
|
LOADED[dialogTag] = dialogImport().then(() => {
|
||||||
|
@ -233,7 +233,9 @@ class MoreInfoLight extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues<this>) {
|
public willUpdate(changedProps: PropertyValues<this>) {
|
||||||
|
super.willUpdate(changedProps);
|
||||||
|
|
||||||
if (!changedProps.has("stateObj")) {
|
if (!changedProps.has("stateObj")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -106,8 +106,7 @@ class HassTabsSubpage extends LitElement {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
protected updated(changedProperties: PropertyValues) {
|
public willUpdate(changedProperties: PropertyValues) {
|
||||||
super.updated(changedProperties);
|
|
||||||
if (changedProperties.has("route")) {
|
if (changedProperties.has("route")) {
|
||||||
this._activeTab = this.tabs.find((tab) =>
|
this._activeTab = this.tabs.find((tab) =>
|
||||||
`${this.route.prefix}${this.route.path}`.includes(tab.path)
|
`${this.route.prefix}${this.route.path}`.includes(tab.path)
|
||||||
@ -121,6 +120,7 @@ class HassTabsSubpage extends LitElement {
|
|||||||
this.rtl = computeRTL(this.hass);
|
this.rtl = computeRTL(this.hass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
super.willUpdate(changedProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
@ -42,19 +42,20 @@ class HomeAssistantMain extends LitElement {
|
|||||||
|
|
||||||
@property() public route?: Route;
|
@property() public route?: Route;
|
||||||
|
|
||||||
@property({ type: Boolean }) public narrow?: boolean;
|
@property({ type: Boolean }) public narrow!: boolean;
|
||||||
|
|
||||||
@state() private _sidebarEditMode = false;
|
@state() private _sidebarEditMode = false;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
constructor() {
|
||||||
const hass = this.hass;
|
super();
|
||||||
|
listenMediaQuery("(max-width: 870px)", (matches) => {
|
||||||
if (!hass) {
|
this.narrow = matches;
|
||||||
return html``;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
const hass = this.hass;
|
||||||
const sidebarNarrow = this._sidebarNarrow;
|
const sidebarNarrow = this._sidebarNarrow;
|
||||||
|
|
||||||
const disableSwipe =
|
const disableSwipe =
|
||||||
this._sidebarEditMode ||
|
this._sidebarEditMode ||
|
||||||
!sidebarNarrow ||
|
!sidebarNarrow ||
|
||||||
@ -142,13 +143,9 @@ class HomeAssistantMain extends LitElement {
|
|||||||
|
|
||||||
this.addEventListener("hass-show-notifications", () => {
|
this.addEventListener("hass-show-notifications", () => {
|
||||||
showNotificationDrawer(this, {
|
showNotificationDrawer(this, {
|
||||||
narrow: this.narrow!,
|
narrow: this.narrow,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
listenMediaQuery("(max-width: 870px)", (matches) => {
|
|
||||||
this.narrow = matches;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
|
@ -15,13 +15,24 @@ import {
|
|||||||
import "./ha-init-page";
|
import "./ha-init-page";
|
||||||
import "./home-assistant-main";
|
import "./home-assistant-main";
|
||||||
|
|
||||||
|
const useHash = __DEMO__;
|
||||||
|
const curPath = () =>
|
||||||
|
window.decodeURIComponent(
|
||||||
|
useHash ? location.hash.substr(1) : location.pathname
|
||||||
|
);
|
||||||
|
|
||||||
|
const panelUrl = (path: string) => {
|
||||||
|
const dividerPos = path.indexOf("/", 1);
|
||||||
|
return dividerPos === -1 ? path.substr(1) : path.substr(1, dividerPos - 1);
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("home-assistant")
|
@customElement("home-assistant")
|
||||||
export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
||||||
@state() private _route?: Route;
|
@state() private _route: Route;
|
||||||
|
|
||||||
@state() private _error = false;
|
@state() private _error = false;
|
||||||
|
|
||||||
@state() private _panelUrl?: string;
|
private _panelUrl: string;
|
||||||
|
|
||||||
private _haVersion?: string;
|
private _haVersion?: string;
|
||||||
|
|
||||||
@ -29,12 +40,24 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
|||||||
|
|
||||||
private _visiblePromiseResolve?: () => void;
|
private _visiblePromiseResolve?: () => void;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
const path = curPath();
|
||||||
|
|
||||||
|
if (["", "/"].includes(path)) {
|
||||||
|
navigate(this, `/${getStorageDefaultPanelUrlPath()}`, true);
|
||||||
|
}
|
||||||
|
this._route = {
|
||||||
|
prefix: "",
|
||||||
|
path,
|
||||||
|
};
|
||||||
|
this._panelUrl = panelUrl(path);
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const hass = this.hass;
|
const hass = this.hass;
|
||||||
|
|
||||||
return this._panelUrl === undefined || this._route === undefined
|
return hass && hass.states && hass.config && hass.services
|
||||||
? html``
|
|
||||||
: hass && hass.states && hass.config && hass.services
|
|
||||||
? html`
|
? html`
|
||||||
<home-assistant-main
|
<home-assistant-main
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -56,11 +79,6 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
const useHash = __DEMO__;
|
|
||||||
const curPath = () =>
|
|
||||||
window.decodeURIComponent(
|
|
||||||
useHash ? location.hash.substr(1) : location.pathname
|
|
||||||
);
|
|
||||||
const updateRoute = (path = curPath()) => {
|
const updateRoute = (path = curPath()) => {
|
||||||
if (this._route && path === this._route.path) {
|
if (this._route && path === this._route.path) {
|
||||||
return;
|
return;
|
||||||
@ -69,9 +87,10 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
|||||||
prefix: "",
|
prefix: "",
|
||||||
path: path,
|
path: path,
|
||||||
};
|
};
|
||||||
const dividerPos = path.indexOf("/", 1);
|
|
||||||
this._panelUrl =
|
this._panelUrl = panelUrl(path);
|
||||||
dividerPos === -1 ? path.substr(1) : path.substr(1, dividerPos - 1);
|
this.panelUrlChanged(this._panelUrl!);
|
||||||
|
this._updateHass({ panelUrl: this._panelUrl });
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener("location-changed", () => updateRoute());
|
window.addEventListener("location-changed", () => updateRoute());
|
||||||
@ -90,21 +109,10 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
|||||||
navigate(this, href);
|
navigate(this, href);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle first navigation
|
|
||||||
if (["", "/"].includes(curPath())) {
|
|
||||||
navigate(this, `/${getStorageDefaultPanelUrlPath()}`, true);
|
|
||||||
} else {
|
|
||||||
updateRoute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues): void {
|
protected updated(changedProps: PropertyValues): void {
|
||||||
super.updated(changedProps);
|
super.updated(changedProps);
|
||||||
if (changedProps.has("_panelUrl")) {
|
|
||||||
this.panelUrlChanged(this._panelUrl!);
|
|
||||||
this._updateHass({ panelUrl: this._panelUrl });
|
|
||||||
}
|
|
||||||
if (changedProps.has("hass")) {
|
if (changedProps.has("hass")) {
|
||||||
this.hassChanged(
|
this.hassChanged(
|
||||||
this.hass!,
|
this.hass!,
|
||||||
|
@ -65,8 +65,8 @@ class PartialPanelResolver extends HassRouterPage {
|
|||||||
document.addEventListener("resume", () => this._checkVisibility());
|
document.addEventListener("resume", () => this._checkVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
public willUpdate(changedProps: PropertyValues) {
|
||||||
super.updated(changedProps);
|
super.willUpdate(changedProps);
|
||||||
|
|
||||||
if (!changedProps.has("hass")) {
|
if (!changedProps.has("hass")) {
|
||||||
return;
|
return;
|
||||||
|
@ -22,8 +22,8 @@ class HuiEntitiesToggle extends LitElement {
|
|||||||
|
|
||||||
@state() private _toggleEntities?: string[];
|
@state() private _toggleEntities?: string[];
|
||||||
|
|
||||||
public updated(changedProperties: PropertyValues): void {
|
public willUpdate(changedProperties: PropertyValues): void {
|
||||||
super.updated(changedProperties);
|
super.willUpdate(changedProperties);
|
||||||
if (changedProperties.has("entities")) {
|
if (changedProperties.has("entities")) {
|
||||||
this._toggleEntities = this.entities!.filter(
|
this._toggleEntities = this.entities!.filter(
|
||||||
(entityId) =>
|
(entityId) =>
|
||||||
|
@ -83,10 +83,10 @@ export class OriginalStatesStrategy {
|
|||||||
info: Parameters<LovelaceDashboardStrategy["generateDashboard"]>[0]
|
info: Parameters<LovelaceDashboardStrategy["generateDashboard"]>[0]
|
||||||
): ReturnType<LovelaceDashboardStrategy["generateDashboard"]> {
|
): ReturnType<LovelaceDashboardStrategy["generateDashboard"]> {
|
||||||
return {
|
return {
|
||||||
|
title: info.hass.config.location_name,
|
||||||
views: [
|
views: [
|
||||||
{
|
{
|
||||||
strategy: { type: "original-states" },
|
strategy: { type: "original-states" },
|
||||||
title: info.hass.config.location_name,
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -23,8 +23,6 @@ import type { HuiErrorCard } from "../cards/hui-error-card";
|
|||||||
import { computeCardSize } from "../common/compute-card-size";
|
import { computeCardSize } from "../common/compute-card-size";
|
||||||
import type { Lovelace, LovelaceBadge, LovelaceCard } from "../types";
|
import type { Lovelace, LovelaceBadge, LovelaceCard } from "../types";
|
||||||
|
|
||||||
let editCodeLoaded = false;
|
|
||||||
|
|
||||||
// Find column with < 5 size, else smallest column
|
// Find column with < 5 size, else smallest column
|
||||||
const getColumnIndex = (columnSizes: number[], size: number) => {
|
const getColumnIndex = (columnSizes: number[], size: number) => {
|
||||||
let minIndex = 0;
|
let minIndex = 0;
|
||||||
@ -71,16 +69,26 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
|
|||||||
this.addEventListener("iron-resize", (ev: Event) => ev.stopPropagation());
|
this.addEventListener("iron-resize", (ev: Event) => ev.stopPropagation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._initMqls();
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._mqls?.forEach((mql) => {
|
||||||
|
mql.removeListener(this._updateColumns);
|
||||||
|
});
|
||||||
|
this._mqls = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
public setConfig(_config: LovelaceViewConfig): void {}
|
public setConfig(_config: LovelaceViewConfig): void {}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<div
|
${this.badges.length > 0
|
||||||
id="badges"
|
? html` <div class="badges">${this.badges}</div>`
|
||||||
style=${this.badges.length > 0 ? "display: block" : "display: none"}
|
: ""}
|
||||||
>
|
|
||||||
${this.badges.map((badge) => html`${badge}`)}
|
|
||||||
</div>
|
|
||||||
<div id="columns"></div>
|
<div id="columns"></div>
|
||||||
${this.lovelace?.editMode
|
${this.lovelace?.editMode
|
||||||
? html`
|
? html`
|
||||||
@ -101,31 +109,31 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(): void {
|
private _initMqls() {
|
||||||
this._mqls = [300, 600, 900, 1200].map((width) => {
|
this._mqls = [300, 600, 900, 1200].map((width) => {
|
||||||
const mql = window.matchMedia(`(min-width: ${width}px)`);
|
const mql = window.matchMedia(`(min-width: ${width}px)`);
|
||||||
mql.addListener(() => this._updateColumns());
|
mql.addListener(this._updateColumns.bind(this));
|
||||||
return mql;
|
return mql;
|
||||||
});
|
});
|
||||||
this._updateColumns();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProperties: PropertyValues): void {
|
private get mqls(): MediaQueryList[] {
|
||||||
super.updated(changedProperties);
|
if (!this._mqls) {
|
||||||
|
this._initMqls();
|
||||||
if (this.lovelace?.editMode && !editCodeLoaded) {
|
|
||||||
editCodeLoaded = true;
|
|
||||||
import("./default-view-editable");
|
|
||||||
}
|
}
|
||||||
|
return this._mqls!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public willUpdate(changedProperties: PropertyValues) {
|
||||||
|
super.willUpdate(changedProperties);
|
||||||
|
|
||||||
if (changedProperties.has("hass")) {
|
if (changedProperties.has("hass")) {
|
||||||
const oldHass = changedProperties.get("hass") as HomeAssistant;
|
const oldHass = changedProperties.get("hass") as
|
||||||
|
| HomeAssistant
|
||||||
|
| undefined;
|
||||||
|
|
||||||
if (oldHass && this.hass!.dockedSidebar !== oldHass.dockedSidebar) {
|
if (this.hass!.dockedSidebar !== oldHass?.dockedSidebar) {
|
||||||
this._updateColumns();
|
this._updateColumns();
|
||||||
}
|
|
||||||
|
|
||||||
if (changedProperties.size === 1) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,16 +141,24 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
|
|||||||
if (changedProperties.has("narrow")) {
|
if (changedProperties.has("narrow")) {
|
||||||
this._updateColumns();
|
this._updateColumns();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedProperties: PropertyValues): void {
|
||||||
|
super.updated(changedProperties);
|
||||||
|
|
||||||
|
if (this.lovelace?.editMode) {
|
||||||
|
import("./default-view-editable");
|
||||||
|
}
|
||||||
|
|
||||||
const oldLovelace = changedProperties.get("lovelace") as
|
const oldLovelace = changedProperties.get("lovelace") as
|
||||||
| Lovelace
|
| Lovelace
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(changedProperties.has("lovelace") &&
|
changedProperties.has("lovelace") &&
|
||||||
(oldLovelace?.config !== this.lovelace?.config ||
|
oldLovelace &&
|
||||||
oldLovelace?.editMode !== this.lovelace?.editMode)) ||
|
(oldLovelace.config !== this.lovelace?.config ||
|
||||||
changedProperties.has("_columns")
|
oldLovelace.editMode !== this.lovelace?.editMode)
|
||||||
) {
|
) {
|
||||||
this._createColumns();
|
this._createColumns();
|
||||||
}
|
}
|
||||||
@ -152,6 +168,17 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
|
|||||||
fireEvent(this, "ll-create-card");
|
fireEvent(this, "ll-create-card");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _createRootElement(columns: HTMLDivElement[]) {
|
||||||
|
const root = this.shadowRoot!.getElementById("columns") as HTMLDivElement;
|
||||||
|
|
||||||
|
// Remove old columns
|
||||||
|
while (root.lastChild) {
|
||||||
|
root.removeChild(root.lastChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
columns.forEach((column) => root.appendChild(column));
|
||||||
|
}
|
||||||
|
|
||||||
private async _createColumns() {
|
private async _createColumns() {
|
||||||
if (!this._columns) {
|
if (!this._columns) {
|
||||||
return;
|
return;
|
||||||
@ -159,12 +186,6 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
|
|||||||
|
|
||||||
this._createColumnsIteration++;
|
this._createColumnsIteration++;
|
||||||
const iteration = this._createColumnsIteration;
|
const iteration = this._createColumnsIteration;
|
||||||
const root = this.shadowRoot!.getElementById("columns")!;
|
|
||||||
|
|
||||||
// Remove old columns
|
|
||||||
while (root.lastChild) {
|
|
||||||
root.removeChild(root.lastChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track the total height of cards in a columns
|
// Track the total height of cards in a columns
|
||||||
const columnSizes: number[] = [];
|
const columnSizes: number[] = [];
|
||||||
@ -173,11 +194,18 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
|
|||||||
for (let i = 0; i < Math.min(this._columns, this.cards.length); i++) {
|
for (let i = 0; i < Math.min(this._columns, this.cards.length); i++) {
|
||||||
const columnEl = document.createElement("div");
|
const columnEl = document.createElement("div");
|
||||||
columnEl.classList.add("column");
|
columnEl.classList.add("column");
|
||||||
root.appendChild(columnEl);
|
|
||||||
columnSizes.push(0);
|
columnSizes.push(0);
|
||||||
columnElements.push(columnEl);
|
columnElements.push(columnEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.hasUpdated) {
|
||||||
|
this.updateComplete.then(() => {
|
||||||
|
this._createRootElement(columnElements);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this._createRootElement(columnElements);
|
||||||
|
}
|
||||||
|
|
||||||
let tillNextRender: Promise<unknown> | undefined;
|
let tillNextRender: Promise<unknown> | undefined;
|
||||||
let start: Date | undefined;
|
let start: Date | undefined;
|
||||||
|
|
||||||
@ -244,19 +272,21 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _updateColumns() {
|
private _updateColumns() {
|
||||||
if (!this._mqls) {
|
const matchColumns = this.mqls.reduce(
|
||||||
return;
|
|
||||||
}
|
|
||||||
const matchColumns = this._mqls!.reduce(
|
|
||||||
(cols, mql) => cols + Number(mql.matches),
|
(cols, mql) => cols + Number(mql.matches),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
// Do -1 column if the menu is docked and open
|
// Do -1 column if the menu is docked and open
|
||||||
this._columns = Math.max(
|
const newColumns = Math.max(
|
||||||
1,
|
1,
|
||||||
matchColumns -
|
matchColumns -
|
||||||
Number(!this.narrow && this.hass!.dockedSidebar === "docked")
|
Number(!this.narrow && this.hass!.dockedSidebar === "docked")
|
||||||
);
|
);
|
||||||
|
if (newColumns === this._columns) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._columns = newColumns;
|
||||||
|
this._createColumns();
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
@ -268,7 +298,7 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
#badges {
|
.badges {
|
||||||
margin: 8px 16px;
|
margin: 8px 16px;
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -40,8 +40,8 @@ export class PanelView extends LitElement implements LovelaceViewElement {
|
|||||||
|
|
||||||
public setConfig(_config: LovelaceViewConfig): void {}
|
public setConfig(_config: LovelaceViewConfig): void {}
|
||||||
|
|
||||||
protected updated(changedProperties: PropertyValues): void {
|
public willUpdate(changedProperties: PropertyValues): void {
|
||||||
super.updated(changedProperties);
|
super.willUpdate(changedProperties);
|
||||||
|
|
||||||
if (this.lovelace?.editMode && !editCodeLoaded) {
|
if (this.lovelace?.editMode && !editCodeLoaded) {
|
||||||
editCodeLoaded = true;
|
editCodeLoaded = true;
|
||||||
|
@ -88,8 +88,8 @@ export class HUIView extends ReactiveElement {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProperties: PropertyValues): void {
|
public willUpdate(changedProperties: PropertyValues): void {
|
||||||
super.updated(changedProperties);
|
super.willUpdate(changedProperties);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We need to handle the following use cases:
|
We need to handle the following use cases:
|
||||||
@ -112,8 +112,11 @@ export class HUIView extends ReactiveElement {
|
|||||||
oldLovelace.config.views[this.index]))
|
oldLovelace.config.views[this.index]))
|
||||||
) {
|
) {
|
||||||
this._initializeConfig();
|
this._initializeConfig();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected update(changedProperties) {
|
||||||
|
super.update(changedProperties);
|
||||||
|
|
||||||
// If no layout element, we're still creating one
|
// If no layout element, we're still creating one
|
||||||
if (this._layoutElement) {
|
if (this._layoutElement) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// For localize
|
// For localize
|
||||||
import "@formatjs/intl-getcanonicallocales/polyfill";
|
import "@formatjs/intl-getcanonicallocales/polyfill";
|
||||||
import "@lit/polyfill-support";
|
import "lit/polyfill-support";
|
||||||
import "core-js";
|
import "core-js";
|
||||||
// To use comlink under ES5
|
// To use comlink under ES5
|
||||||
import "proxy-polyfill";
|
import "proxy-polyfill";
|
||||||
|
@ -20,7 +20,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
|||||||
protected firstUpdated(changedProps) {
|
protected firstUpdated(changedProps) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
// Need to load in advance because when disconnected, can't dynamically load code.
|
// Need to load in advance because when disconnected, can't dynamically load code.
|
||||||
import("../managers/notification-manager");
|
setTimeout(() => import("../managers/notification-manager"), 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
updated(changedProperties) {
|
updated(changedProperties) {
|
||||||
|
@ -3,10 +3,6 @@ import { LitElement } from "lit";
|
|||||||
import { property } from "lit/decorators";
|
import { property } from "lit/decorators";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
// Temporary disable warnings so the dev console is not flooded, we should fix these and then re-enable the warning
|
|
||||||
if (__DEV__) {
|
|
||||||
LitElement.disableWarning?.("change-in-update");
|
|
||||||
}
|
|
||||||
export class HassBaseEl extends LitElement {
|
export class HassBaseEl extends LitElement {
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
|
@ -12,14 +12,6 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let moreInfoImportPromise;
|
|
||||||
const importMoreInfo = () => {
|
|
||||||
if (!moreInfoImportPromise) {
|
|
||||||
moreInfoImportPromise = import("../dialogs/more-info/ha-more-info-dialog");
|
|
||||||
}
|
|
||||||
return moreInfoImportPromise;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
protected firstUpdated(changedProps: PropertyValues) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
@ -27,7 +19,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
|||||||
this.addEventListener("hass-more-info", (ev) => this._handleMoreInfo(ev));
|
this.addEventListener("hass-more-info", (ev) => this._handleMoreInfo(ev));
|
||||||
|
|
||||||
// Load it once we are having the initial rendering done.
|
// Load it once we are having the initial rendering done.
|
||||||
importMoreInfo();
|
import("../dialogs/more-info/ha-more-info-dialog");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _handleMoreInfo(ev: HASSDomEvent<MoreInfoDialogParams>) {
|
private async _handleMoreInfo(ev: HASSDomEvent<MoreInfoDialogParams>) {
|
||||||
@ -38,7 +30,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
|||||||
{
|
{
|
||||||
entityId: ev.detail.entityId,
|
entityId: ev.detail.entityId,
|
||||||
},
|
},
|
||||||
importMoreInfo
|
() => import("../dialogs/more-info/ha-more-info-dialog")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user