mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-26 18:56:39 +00:00
Only ask to refresh dashboard if necessary (#24993)
This commit is contained in:
parent
929a0b9cd4
commit
14e0666c3a
@ -9,6 +9,8 @@ import {
|
|||||||
addSearchParam,
|
addSearchParam,
|
||||||
removeSearchParam,
|
removeSearchParam,
|
||||||
} from "../../common/url/search-params";
|
} from "../../common/url/search-params";
|
||||||
|
import { debounce } from "../../common/util/debounce";
|
||||||
|
import { deepEqual } from "../../common/util/deep-equal";
|
||||||
import { domainToName } from "../../data/integration";
|
import { domainToName } from "../../data/integration";
|
||||||
import { subscribeLovelaceUpdates } from "../../data/lovelace";
|
import { subscribeLovelaceUpdates } from "../../data/lovelace";
|
||||||
import type {
|
import type {
|
||||||
@ -51,6 +53,12 @@ interface LovelacePanelConfig {
|
|||||||
let editorLoaded = false;
|
let editorLoaded = false;
|
||||||
let resourcesLoaded = false;
|
let resourcesLoaded = false;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HASSDomEvents {
|
||||||
|
"strategy-config-changed": undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@customElement("ha-panel-lovelace")
|
@customElement("ha-panel-lovelace")
|
||||||
export class LovelacePanel extends LitElement {
|
export class LovelacePanel extends LitElement {
|
||||||
@property({ attribute: false }) public panel?: PanelInfo<LovelacePanelConfig>;
|
@property({ attribute: false }) public panel?: PanelInfo<LovelacePanelConfig>;
|
||||||
@ -127,6 +135,7 @@ export class LovelacePanel extends LitElement {
|
|||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
@config-refresh=${this._forceFetchConfig}
|
@config-refresh=${this._forceFetchConfig}
|
||||||
|
@strategy-config-changed=${this._strategyConfigChanged}
|
||||||
></hui-root>
|
></hui-root>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -199,7 +208,7 @@ export class LovelacePanel extends LitElement {
|
|||||||
oldHass.floors !== this.hass.floors
|
oldHass.floors !== this.hass.floors
|
||||||
) {
|
) {
|
||||||
if (this.hass.config.state === "RUNNING") {
|
if (this.hass.config.state === "RUNNING") {
|
||||||
this._askRefreshConfig();
|
this._debounceRegistriesChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If ha started, refresh the config
|
// If ha started, refresh the config
|
||||||
@ -207,25 +216,59 @@ export class LovelacePanel extends LitElement {
|
|||||||
this.hass.config.state === "RUNNING" &&
|
this.hass.config.state === "RUNNING" &&
|
||||||
oldHass.config.state !== "RUNNING"
|
oldHass.config.state !== "RUNNING"
|
||||||
) {
|
) {
|
||||||
this._refreshConfig();
|
this._regenerateStrategyConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _askRefreshConfig = () => {
|
private _debounceRegistriesChanged = debounce(
|
||||||
|
() => this._registriesChanged(),
|
||||||
|
200
|
||||||
|
);
|
||||||
|
|
||||||
|
private _registriesChanged = async () => {
|
||||||
|
if (!this.hass || !this.lovelace) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rawConfig = this.lovelace.rawConfig;
|
||||||
|
|
||||||
|
if (!isStrategyDashboard(rawConfig)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldConfig = this.lovelace.config;
|
||||||
|
const generatedConfig = await generateLovelaceDashboardStrategy(
|
||||||
|
rawConfig,
|
||||||
|
this.hass!
|
||||||
|
);
|
||||||
|
|
||||||
|
const newConfig = checkLovelaceConfig(generatedConfig) as LovelaceConfig;
|
||||||
|
|
||||||
|
// Ask to regenerate if the config changed
|
||||||
|
if (!deepEqual(newConfig, oldConfig)) {
|
||||||
|
this._askRegenerateStrategyConfig();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private _strategyConfigChanged = (ev: CustomEvent) => {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this._askRegenerateStrategyConfig();
|
||||||
|
};
|
||||||
|
|
||||||
|
private _askRegenerateStrategyConfig = () => {
|
||||||
showToast(this, {
|
showToast(this, {
|
||||||
message: this.hass!.localize("ui.panel.lovelace.changed_toast.message"),
|
message: this.hass!.localize("ui.panel.lovelace.changed_toast.message"),
|
||||||
action: {
|
action: {
|
||||||
action: () => this._refreshConfig(),
|
action: () => this._regenerateStrategyConfig(),
|
||||||
text: this.hass!.localize("ui.common.refresh"),
|
text: this.hass!.localize("ui.common.refresh"),
|
||||||
},
|
},
|
||||||
duration: -1,
|
duration: -1,
|
||||||
id: "entity-registry-changed",
|
id: "regenerate-strategy-config",
|
||||||
dismissable: false,
|
dismissable: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private async _refreshConfig() {
|
private async _regenerateStrategyConfig() {
|
||||||
if (!this.hass || !this.lovelace) {
|
if (!this.hass || !this.lovelace) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,9 @@ import type { PropertyValues } from "lit";
|
|||||||
import { ReactiveElement } from "lit";
|
import { ReactiveElement } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { storage } from "../../../common/decorators/storage";
|
import { storage } from "../../../common/decorators/storage";
|
||||||
import type { HASSDomEvent } from "../../../common/dom/fire_event";
|
import { fireEvent, type HASSDomEvent } from "../../../common/dom/fire_event";
|
||||||
|
import { debounce } from "../../../common/util/debounce";
|
||||||
|
import { deepEqual } from "../../../common/util/deep-equal";
|
||||||
import "../../../components/entity/ha-state-label-badge";
|
import "../../../components/entity/ha-state-label-badge";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import type { LovelaceViewElement } from "../../../data/lovelace";
|
import type { LovelaceViewElement } from "../../../data/lovelace";
|
||||||
@ -11,7 +13,10 @@ import type { LovelaceBadgeConfig } from "../../../data/lovelace/config/badge";
|
|||||||
import { ensureBadgeConfig } from "../../../data/lovelace/config/badge";
|
import { ensureBadgeConfig } from "../../../data/lovelace/config/badge";
|
||||||
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
||||||
import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
|
import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
|
||||||
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
|
import type {
|
||||||
|
LovelaceViewConfig,
|
||||||
|
LovelaceViewRawConfig,
|
||||||
|
} from "../../../data/lovelace/config/view";
|
||||||
import { isStrategyView } from "../../../data/lovelace/config/view";
|
import { isStrategyView } from "../../../data/lovelace/config/view";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import "../badges/hui-badge";
|
import "../badges/hui-badge";
|
||||||
@ -85,6 +90,10 @@ export class HUIView extends ReactiveElement {
|
|||||||
|
|
||||||
private _layoutElement?: LovelaceViewElement;
|
private _layoutElement?: LovelaceViewElement;
|
||||||
|
|
||||||
|
private _layoutElementConfig?: LovelaceViewConfig;
|
||||||
|
|
||||||
|
private _rendered = false;
|
||||||
|
|
||||||
@storage({
|
@storage({
|
||||||
key: "dashboardCardClipboard",
|
key: "dashboardCardClipboard",
|
||||||
state: false,
|
state: false,
|
||||||
@ -145,6 +154,18 @@ export class HUIView extends ReactiveElement {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connectedCallback(): void {
|
||||||
|
super.connectedCallback();
|
||||||
|
this.updateComplete.then(() => {
|
||||||
|
this._rendered = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback(): void {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._rendered = false;
|
||||||
|
}
|
||||||
|
|
||||||
public willUpdate(changedProperties: PropertyValues<typeof this>): void {
|
public willUpdate(changedProperties: PropertyValues<typeof this>): void {
|
||||||
super.willUpdate(changedProperties);
|
super.willUpdate(changedProperties);
|
||||||
|
|
||||||
@ -169,9 +190,62 @@ export class HUIView extends ReactiveElement {
|
|||||||
oldLovelace.config.views[this.index]))
|
oldLovelace.config.views[this.index]))
|
||||||
) {
|
) {
|
||||||
this._initializeConfig();
|
this._initializeConfig();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!changedProperties.has("hass")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldHass = changedProperties.get("hass") as HomeAssistant | undefined;
|
||||||
|
const viewConfig = this.lovelace.config.views[this.index];
|
||||||
|
if (oldHass && this.hass && this.lovelace && isStrategyView(viewConfig)) {
|
||||||
|
if (
|
||||||
|
oldHass.entities !== this.hass.entities ||
|
||||||
|
oldHass.devices !== this.hass.devices ||
|
||||||
|
oldHass.areas !== this.hass.areas ||
|
||||||
|
oldHass.floors !== this.hass.floors
|
||||||
|
) {
|
||||||
|
if (this.hass.config.state === "RUNNING") {
|
||||||
|
// If the page is not rendered yet, we can force the refresh
|
||||||
|
if (this._rendered) {
|
||||||
|
this._debounceRefreshConfig(false);
|
||||||
|
} else {
|
||||||
|
this._refreshConfig(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _debounceRefreshConfig = debounce(
|
||||||
|
(force: boolean) => this._refreshConfig(force),
|
||||||
|
200
|
||||||
|
);
|
||||||
|
|
||||||
|
private _refreshConfig = async (force: boolean) => {
|
||||||
|
if (!this.hass || !this.lovelace) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const viewConfig = this.lovelace.config.views[this.index];
|
||||||
|
|
||||||
|
if (!isStrategyView(viewConfig)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldConfig = this._layoutElementConfig;
|
||||||
|
const newConfig = await this._generateConfig(viewConfig);
|
||||||
|
|
||||||
|
// Don't ask if the config is the same
|
||||||
|
if (!deepEqual(newConfig, oldConfig)) {
|
||||||
|
if (force) {
|
||||||
|
this._setConfig(newConfig, true);
|
||||||
|
} else {
|
||||||
|
fireEvent(this, "strategy-config-changed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
protected update(changedProperties: PropertyValues) {
|
protected update(changedProperties: PropertyValues) {
|
||||||
super.update(changedProperties);
|
super.update(changedProperties);
|
||||||
|
|
||||||
@ -227,20 +301,30 @@ export class HUIView extends ReactiveElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _initializeConfig() {
|
private async _generateConfig(
|
||||||
let viewConfig = this.lovelace.config.views[this.index];
|
config: LovelaceViewRawConfig
|
||||||
let isStrategy = false;
|
): Promise<LovelaceViewConfig> {
|
||||||
|
if (isStrategyView(config)) {
|
||||||
if (isStrategyView(viewConfig)) {
|
const generatedConfig = await generateLovelaceViewStrategy(
|
||||||
isStrategy = true;
|
config,
|
||||||
viewConfig = await generateLovelaceViewStrategy(viewConfig, this.hass!);
|
this.hass!
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...generatedConfig,
|
||||||
|
type: getViewType(generatedConfig),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
viewConfig = {
|
return {
|
||||||
...viewConfig,
|
...config,
|
||||||
type: getViewType(viewConfig),
|
type: getViewType(config),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _setConfig(
|
||||||
|
viewConfig: LovelaceViewConfig,
|
||||||
|
isStrategy: boolean
|
||||||
|
) {
|
||||||
// Create a new layout element if necessary.
|
// Create a new layout element if necessary.
|
||||||
let addLayoutElement = false;
|
let addLayoutElement = false;
|
||||||
|
|
||||||
@ -248,7 +332,7 @@ export class HUIView extends ReactiveElement {
|
|||||||
addLayoutElement = true;
|
addLayoutElement = true;
|
||||||
this._createLayoutElement(viewConfig);
|
this._createLayoutElement(viewConfig);
|
||||||
}
|
}
|
||||||
|
this._layoutElementConfig = viewConfig;
|
||||||
this._createBadges(viewConfig);
|
this._createBadges(viewConfig);
|
||||||
this._createCards(viewConfig);
|
this._createCards(viewConfig);
|
||||||
this._createSections(viewConfig);
|
this._createSections(viewConfig);
|
||||||
@ -269,6 +353,15 @@ export class HUIView extends ReactiveElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _initializeConfig() {
|
||||||
|
const rawConfig = this.lovelace.config.views[this.index];
|
||||||
|
|
||||||
|
const viewConfig = await this._generateConfig(rawConfig);
|
||||||
|
const isStrategy = isStrategyView(viewConfig);
|
||||||
|
|
||||||
|
this._setConfig(viewConfig, isStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
private _createLayoutElement(config: LovelaceViewConfig): void {
|
private _createLayoutElement(config: LovelaceViewConfig): void {
|
||||||
this._layoutElement = createViewElement(config) as LovelaceViewElement;
|
this._layoutElement = createViewElement(config) as LovelaceViewElement;
|
||||||
this._layoutElementType = config.type;
|
this._layoutElementType = config.type;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user