mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
Close dialogs on history back (#6354)
This commit is contained in:
parent
3bc54aa9e0
commit
3d32e6310d
@ -35,6 +35,7 @@ import "./step-flow-external";
|
|||||||
import "./step-flow-form";
|
import "./step-flow-form";
|
||||||
import "./step-flow-loading";
|
import "./step-flow-loading";
|
||||||
import "./step-flow-pick-handler";
|
import "./step-flow-pick-handler";
|
||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
import { computeRTL } from "../../common/util/compute_rtl";
|
import { computeRTL } from "../../common/util/compute_rtl";
|
||||||
|
|
||||||
let instance = 0;
|
let instance = 0;
|
||||||
@ -114,6 +115,17 @@ class DataEntryFlowDialog extends LitElement {
|
|||||||
this._loading = false;
|
this._loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public closeDialog() {
|
||||||
|
if (this._step) {
|
||||||
|
this._flowDone();
|
||||||
|
} else if (this._step === null) {
|
||||||
|
// Flow aborted during picking flow
|
||||||
|
this._step = undefined;
|
||||||
|
this._params = undefined;
|
||||||
|
}
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this._params) {
|
if (!this._params) {
|
||||||
return html``;
|
return html``;
|
||||||
@ -122,7 +134,7 @@ class DataEntryFlowDialog extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-dialog
|
||||||
open
|
open
|
||||||
@closing=${this._close}
|
@closed=${this.closeDialog}
|
||||||
scrimClickAction
|
scrimClickAction
|
||||||
escapeKeyAction
|
escapeKeyAction
|
||||||
hideActions
|
hideActions
|
||||||
@ -297,16 +309,6 @@ class DataEntryFlowDialog extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _close(): void {
|
|
||||||
if (this._step) {
|
|
||||||
this._flowDone();
|
|
||||||
} else if (this._step === null) {
|
|
||||||
// Flow aborted during picking flow
|
|
||||||
this._step = undefined;
|
|
||||||
this._params = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles(): CSSResultArray {
|
static get styles(): CSSResultArray {
|
||||||
return [
|
return [
|
||||||
haStyleDialog,
|
haStyleDialog,
|
||||||
|
@ -16,6 +16,7 @@ import { PolymerChangedEvent } from "../../polymer-types";
|
|||||||
import { haStyleDialog } from "../../resources/styles";
|
import { haStyleDialog } from "../../resources/styles";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { DialogParams } from "./show-dialog-box";
|
import { DialogParams } from "./show-dialog-box";
|
||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
|
||||||
@customElement("dialog-box")
|
@customElement("dialog-box")
|
||||||
class DialogBox extends LitElement {
|
class DialogBox extends LitElement {
|
||||||
@ -32,6 +33,17 @@ class DialogBox extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public closeDialog(): boolean {
|
||||||
|
if (this._params?.confirmation || this._params?.prompt) {
|
||||||
|
this._dismiss();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (this._params) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this._params) {
|
if (!this._params) {
|
||||||
return html``;
|
return html``;
|
||||||
@ -100,11 +112,11 @@ class DialogBox extends LitElement {
|
|||||||
this._value = ev.detail.value;
|
this._value = ev.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _dismiss(): Promise<void> {
|
private _dismiss(): void {
|
||||||
if (this._params!.cancel) {
|
if (this._params!.cancel) {
|
||||||
this._params!.cancel();
|
this._params!.cancel();
|
||||||
}
|
}
|
||||||
this._params = undefined;
|
this._close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleKeyUp(ev: KeyboardEvent) {
|
private _handleKeyUp(ev: KeyboardEvent) {
|
||||||
@ -113,15 +125,16 @@ class DialogBox extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _confirm(): Promise<void> {
|
private _confirm(): void {
|
||||||
if (this._params!.confirm) {
|
if (this._params!.confirm) {
|
||||||
this._params!.confirm(this._value);
|
this._params!.confirm(this._value);
|
||||||
}
|
}
|
||||||
this._dismiss();
|
this._close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _close(): void {
|
private _close(): void {
|
||||||
this._params = undefined;
|
this._params = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
|
@ -6,15 +6,18 @@ declare global {
|
|||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"show-dialog": ShowDialogParams<unknown>;
|
"show-dialog": ShowDialogParams<unknown>;
|
||||||
"close-dialog": undefined;
|
"close-dialog": undefined;
|
||||||
|
"dialog-closed": DialogClosedParams;
|
||||||
}
|
}
|
||||||
// for add event listener
|
// for add event listener
|
||||||
interface HTMLElementEventMap {
|
interface HTMLElementEventMap {
|
||||||
"show-dialog": HASSDomEvent<ShowDialogParams<unknown>>;
|
"show-dialog": HASSDomEvent<ShowDialogParams<unknown>>;
|
||||||
|
"dialog-closed": HASSDomEvent<DialogClosedParams>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HassDialog<T = HASSDomEvents[ValidHassDomEvent]> extends HTMLElement {
|
interface HassDialog<T = HASSDomEvents[ValidHassDomEvent]> extends HTMLElement {
|
||||||
showDialog(params: T);
|
showDialog(params: T);
|
||||||
|
closeDialog?: () => boolean | void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ShowDialogParams<T> {
|
interface ShowDialogParams<T> {
|
||||||
@ -23,16 +26,30 @@ interface ShowDialogParams<T> {
|
|||||||
dialogParams: T;
|
dialogParams: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DialogClosedParams {
|
||||||
|
dialog: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DialogState {
|
||||||
|
dialog: string;
|
||||||
|
open: boolean;
|
||||||
|
oldState: null | DialogState;
|
||||||
|
dialogParams?: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
const LOADED = {};
|
const LOADED = {};
|
||||||
|
|
||||||
export const showDialog = async (
|
export const showDialog = async (
|
||||||
element: HTMLElement & ProvideHassElement,
|
element: HTMLElement & ProvideHassElement,
|
||||||
root: ShadowRoot | HTMLElement,
|
root: ShadowRoot | HTMLElement,
|
||||||
dialogImport: () => Promise<unknown>,
|
|
||||||
dialogTag: string,
|
dialogTag: string,
|
||||||
dialogParams: unknown
|
dialogParams: unknown,
|
||||||
|
dialogImport?: () => Promise<unknown>
|
||||||
) => {
|
) => {
|
||||||
if (!(dialogTag in LOADED)) {
|
if (!(dialogTag in LOADED)) {
|
||||||
|
if (!dialogImport) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
LOADED[dialogTag] = dialogImport().then(() => {
|
LOADED[dialogTag] = dialogImport().then(() => {
|
||||||
const dialogEl = document.createElement(dialogTag) as HassDialog;
|
const dialogEl = document.createElement(dialogTag) as HassDialog;
|
||||||
element.provideHass(dialogEl);
|
element.provideHass(dialogEl);
|
||||||
@ -40,19 +57,55 @@ export const showDialog = async (
|
|||||||
return dialogEl;
|
return dialogEl;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
history.replaceState(
|
||||||
|
{
|
||||||
|
dialog: dialogTag,
|
||||||
|
open: false,
|
||||||
|
oldState:
|
||||||
|
history.state?.open && history.state?.dialog !== dialogTag
|
||||||
|
? history.state
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
""
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
history.pushState(
|
||||||
|
{ dialog: dialogTag, dialogParams: dialogParams, open: true },
|
||||||
|
""
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
// dialogParams could not be cloned, probably contains callback
|
||||||
|
history.pushState(
|
||||||
|
{ dialog: dialogTag, dialogParams: null, open: true },
|
||||||
|
""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const dialogElement = await LOADED[dialogTag];
|
const dialogElement = await LOADED[dialogTag];
|
||||||
dialogElement.showDialog(dialogParams);
|
dialogElement.showDialog(dialogParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const closeDialog = async (dialogTag: string): Promise<boolean> => {
|
||||||
|
if (!(dialogTag in LOADED)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const dialogElement = await LOADED[dialogTag];
|
||||||
|
if (dialogElement.closeDialog) {
|
||||||
|
return dialogElement.closeDialog() !== false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
export const makeDialogManager = (
|
export const makeDialogManager = (
|
||||||
element: HTMLElement & ProvideHassElement,
|
element: HTMLElement & ProvideHassElement,
|
||||||
root: ShadowRoot | HTMLElement
|
root: ShadowRoot | HTMLElement
|
||||||
) => {
|
) => {
|
||||||
element.addEventListener(
|
element.addEventListener(
|
||||||
"show-dialog",
|
"show-dialog",
|
||||||
async (e: HASSDomEvent<ShowDialogParams<unknown>>) => {
|
(e: HASSDomEvent<ShowDialogParams<unknown>>) => {
|
||||||
const { dialogTag, dialogImport, dialogParams } = e.detail;
|
const { dialogTag, dialogImport, dialogParams } = e.detail;
|
||||||
showDialog(element, root, dialogImport, dialogTag, dialogParams);
|
showDialog(element, root, dialogTag, dialogParams, dialogImport);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@ import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
|||||||
import { DOMAINS_MORE_INFO_NO_HISTORY } from "../../common/const";
|
import { DOMAINS_MORE_INFO_NO_HISTORY } from "../../common/const";
|
||||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||||
import { navigate } from "../../common/navigate";
|
import { navigate } from "../../common/navigate";
|
||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
import "../../components/state-history-charts";
|
import "../../components/state-history-charts";
|
||||||
import { removeEntityRegistryEntry } from "../../data/entity_registry";
|
import { removeEntityRegistryEntry } from "../../data/entity_registry";
|
||||||
import { showEntityEditorDialog } from "../../panels/config/entities/show-dialog-entity-editor";
|
import { showEntityEditorDialog } from "../../panels/config/entities/show-dialog-entity-editor";
|
||||||
@ -24,7 +25,6 @@ import {
|
|||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { haStyleDialog } from "../../resources/styles";
|
import { haStyleDialog } from "../../resources/styles";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { fireEvent } from "../../common/dom/fire_event";
|
|
||||||
import { getRecentWithCache } from "../../data/cached-history";
|
import { getRecentWithCache } from "../../data/cached-history";
|
||||||
import { computeDomain } from "../../common/entity/compute_domain";
|
import { computeDomain } from "../../common/entity/compute_domain";
|
||||||
import { mdiClose, mdiCog, mdiPencil } from "@mdi/js";
|
import { mdiClose, mdiCog, mdiPencil } from "@mdi/js";
|
||||||
@ -34,6 +34,10 @@ const DOMAINS_NO_INFO = ["camera", "configurator", "history_graph"];
|
|||||||
const EDITABLE_DOMAINS_WITH_ID = ["scene", "automation"];
|
const EDITABLE_DOMAINS_WITH_ID = ["scene", "automation"];
|
||||||
const EDITABLE_DOMAINS = ["script"];
|
const EDITABLE_DOMAINS = ["script"];
|
||||||
|
|
||||||
|
export interface MoreInfoDialogParams {
|
||||||
|
entityId: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
@customElement("ha-more-info-dialog")
|
@customElement("ha-more-info-dialog")
|
||||||
export class MoreInfoDialog extends LitElement {
|
export class MoreInfoDialog extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@ -42,39 +46,39 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
|
|
||||||
@internalProperty() private _stateHistory?: HistoryResult;
|
@internalProperty() private _stateHistory?: HistoryResult;
|
||||||
|
|
||||||
|
@internalProperty() private _entityId?: string | null;
|
||||||
|
|
||||||
private _historyRefreshInterval?: number;
|
private _historyRefreshInterval?: number;
|
||||||
|
|
||||||
protected updated(changedProperties) {
|
public showDialog(params: MoreInfoDialogParams) {
|
||||||
super.updated(changedProperties);
|
this._entityId = params.entityId;
|
||||||
if (!changedProperties.has("hass")) {
|
if (!this._entityId) {
|
||||||
return;
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
const oldHass = changedProperties.get("hass");
|
|
||||||
if (oldHass && oldHass.moreInfoEntityId === this.hass.moreInfoEntityId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.hass.moreInfoEntityId) {
|
|
||||||
this.large = false;
|
this.large = false;
|
||||||
this._stateHistory = undefined;
|
this._stateHistory = undefined;
|
||||||
if (this._computeShowHistoryComponent(this.hass.moreInfoEntityId)) {
|
if (this._computeShowHistoryComponent(this._entityId)) {
|
||||||
this._getStateHistory();
|
this._getStateHistory();
|
||||||
clearInterval(this._historyRefreshInterval);
|
clearInterval(this._historyRefreshInterval);
|
||||||
this._historyRefreshInterval = window.setInterval(() => {
|
this._historyRefreshInterval = window.setInterval(() => {
|
||||||
this._getStateHistory();
|
this._getStateHistory();
|
||||||
}, 60 * 1000);
|
}, 60 * 1000);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
public closeDialog() {
|
||||||
|
this._entityId = undefined;
|
||||||
this._stateHistory = undefined;
|
this._stateHistory = undefined;
|
||||||
clearInterval(this._historyRefreshInterval);
|
clearInterval(this._historyRefreshInterval);
|
||||||
this._historyRefreshInterval = undefined;
|
this._historyRefreshInterval = undefined;
|
||||||
}
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this.hass.moreInfoEntityId) {
|
if (!this._entityId) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
const entityId = this.hass.moreInfoEntityId;
|
const entityId = this._entityId;
|
||||||
const stateObj = this.hass.states[entityId];
|
const stateObj = this.hass.states[entityId];
|
||||||
const domain = computeDomain(entityId);
|
const domain = computeDomain(entityId);
|
||||||
|
|
||||||
@ -85,7 +89,7 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-dialog
|
||||||
open
|
open
|
||||||
@closed=${this._close}
|
@closed=${this.closeDialog}
|
||||||
.heading=${true}
|
.heading=${true}
|
||||||
hideActions
|
hideActions
|
||||||
data-domain=${domain}
|
data-domain=${domain}
|
||||||
@ -174,15 +178,15 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _getStateHistory(): Promise<void> {
|
private async _getStateHistory(): Promise<void> {
|
||||||
if (!this.hass.moreInfoEntityId) {
|
if (!this._entityId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._stateHistory = await getRecentWithCache(
|
this._stateHistory = await getRecentWithCache(
|
||||||
this.hass!,
|
this.hass!,
|
||||||
this.hass.moreInfoEntityId,
|
this._entityId,
|
||||||
{
|
{
|
||||||
refresh: 60,
|
refresh: 60,
|
||||||
cacheKey: `more_info.${this.hass.moreInfoEntityId}`,
|
cacheKey: `more_info.${this._entityId}`,
|
||||||
hoursToShow: 24,
|
hoursToShow: 24,
|
||||||
},
|
},
|
||||||
this.hass!.localize,
|
this.hass!.localize,
|
||||||
@ -198,7 +202,7 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _removeEntity() {
|
private _removeEntity() {
|
||||||
const entityId = this.hass.moreInfoEntityId!;
|
const entityId = this._entityId!;
|
||||||
showConfirmationDialog(this, {
|
showConfirmationDialog(this, {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
"ui.dialogs.more_info_control.restored.confirm_remove_title"
|
"ui.dialogs.more_info_control.restored.confirm_remove_title"
|
||||||
@ -216,14 +220,14 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
|
|
||||||
private _gotoSettings() {
|
private _gotoSettings() {
|
||||||
showEntityEditorDialog(this, {
|
showEntityEditorDialog(this, {
|
||||||
entity_id: this.hass.moreInfoEntityId!,
|
entity_id: this._entityId!,
|
||||||
});
|
});
|
||||||
fireEvent(this, "hass-more-info", { entityId: null });
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _gotoEdit() {
|
private _gotoEdit() {
|
||||||
const stateObj = this.hass.states[this.hass.moreInfoEntityId!];
|
const stateObj = this.hass.states[this._entityId!];
|
||||||
const domain = computeDomain(this.hass.moreInfoEntityId!);
|
const domain = computeDomain(this._entityId!);
|
||||||
navigate(
|
navigate(
|
||||||
this,
|
this,
|
||||||
`/config/${domain}/edit/${
|
`/config/${domain}/edit/${
|
||||||
@ -232,11 +236,7 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
: stateObj.entity_id
|
: stateObj.entity_id
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
this._close();
|
this.closeDialog();
|
||||||
}
|
|
||||||
|
|
||||||
private _close() {
|
|
||||||
fireEvent(this, "hass-more-info", { entityId: null });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
@ -274,7 +274,7 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
--mdc-dialog-max-width: 90vw;
|
--mdc-dialog-max-width: 90vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
app-toolbar {
|
ha-dialog:not([data-domain="camera"]) app-toolbar {
|
||||||
max-width: 368px;
|
max-width: 368px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ import {
|
|||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { cache } from "lit-html/directives/cache";
|
import { cache } from "lit-html/directives/cache";
|
||||||
import { dynamicElement } from "../../../common/dom/dynamic-element-directive";
|
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
|
import { dynamicElement } from "../../../common/dom/dynamic-element-directive";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
import "../../../components/ha-dialog";
|
import "../../../components/ha-dialog";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
@ -72,6 +72,7 @@ export class DialogEntityEditor extends LitElement {
|
|||||||
|
|
||||||
public closeDialog(): void {
|
public closeDialog(): void {
|
||||||
this._params = undefined;
|
this._params = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
@ -20,6 +20,7 @@ import { haStyleDialog } from "../../../resources/styles";
|
|||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { SystemLogDetailDialogParams } from "./show-dialog-system-log-detail";
|
import { SystemLogDetailDialogParams } from "./show-dialog-system-log-detail";
|
||||||
import { formatSystemLogTime } from "./util";
|
import { formatSystemLogTime } from "./util";
|
||||||
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
|
|
||||||
class DialogSystemLogDetail extends LitElement {
|
class DialogSystemLogDetail extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@ -34,6 +35,11 @@ class DialogSystemLogDetail extends LitElement {
|
|||||||
await this.updateComplete;
|
await this.updateComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public closeDialog() {
|
||||||
|
this._params = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
protected updated(changedProps) {
|
protected updated(changedProps) {
|
||||||
super.updated(changedProps);
|
super.updated(changedProps);
|
||||||
if (!changedProps.has("_params") || !this._params) {
|
if (!changedProps.has("_params") || !this._params) {
|
||||||
@ -137,7 +143,7 @@ class DialogSystemLogDetail extends LitElement {
|
|||||||
|
|
||||||
private _openedChanged(ev: PolymerChangedEvent<boolean>): void {
|
private _openedChanged(ev: PolymerChangedEvent<boolean>): void {
|
||||||
if (!(ev.detail as any).value) {
|
if (!(ev.detail as any).value) {
|
||||||
this._params = undefined;
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
property,
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { addDistanceToCoord } from "../../../common/location/add_distance_to_coord";
|
import { addDistanceToCoord } from "../../../common/location/add_distance_to_coord";
|
||||||
import { createCloseHeading } from "../../../components/ha-dialog";
|
import { createCloseHeading } from "../../../components/ha-dialog";
|
||||||
import "../../../components/ha-switch";
|
import "../../../components/ha-switch";
|
||||||
@ -45,7 +46,7 @@ class DialogZoneDetail extends LitElement {
|
|||||||
|
|
||||||
@property() private _submitting = false;
|
@property() private _submitting = false;
|
||||||
|
|
||||||
public async showDialog(params: ZoneDetailDialogParams): Promise<void> {
|
public showDialog(params: ZoneDetailDialogParams): void {
|
||||||
this._params = params;
|
this._params = params;
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
if (this._params.entry) {
|
if (this._params.entry) {
|
||||||
@ -74,7 +75,11 @@ class DialogZoneDetail extends LitElement {
|
|||||||
this._passive = false;
|
this._passive = false;
|
||||||
this._radius = 100;
|
this._radius = 100;
|
||||||
}
|
}
|
||||||
await this.updateComplete;
|
}
|
||||||
|
|
||||||
|
public closeDialog(): void {
|
||||||
|
this._params = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
@ -93,7 +98,7 @@ class DialogZoneDetail extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-dialog
|
||||||
open
|
open
|
||||||
@closing="${this._close}"
|
@closed="${this.closeDialog}"
|
||||||
scrimClickAction=""
|
scrimClickAction=""
|
||||||
escapeKeyAction=""
|
escapeKeyAction=""
|
||||||
.heading=${createCloseHeading(
|
.heading=${createCloseHeading(
|
||||||
@ -276,10 +281,6 @@ class DialogZoneDetail extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _close(): void {
|
|
||||||
this._params = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [
|
return [
|
||||||
haStyleDialog,
|
haStyleDialog,
|
||||||
|
@ -2,6 +2,7 @@ import { HASSDomEvent } from "../common/dom/fire_event";
|
|||||||
import { makeDialogManager, showDialog } from "../dialogs/make-dialog-manager";
|
import { makeDialogManager, showDialog } from "../dialogs/make-dialog-manager";
|
||||||
import { Constructor } from "../types";
|
import { Constructor } from "../types";
|
||||||
import { HassBaseEl } from "./hass-base-mixin";
|
import { HassBaseEl } from "./hass-base-mixin";
|
||||||
|
import { PropertyValues } from "lit-element";
|
||||||
|
|
||||||
interface RegisterDialogParams {
|
interface RegisterDialogParams {
|
||||||
dialogShowEvent: keyof HASSDomEvents;
|
dialogShowEvent: keyof HASSDomEvents;
|
||||||
@ -24,7 +25,7 @@ export const dialogManagerMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
superClass: T
|
superClass: T
|
||||||
) =>
|
) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
protected firstUpdated(changedProps) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
// deprecated
|
// deprecated
|
||||||
this.addEventListener("register-dialog", (e) =>
|
this.addEventListener("register-dialog", (e) =>
|
||||||
@ -42,9 +43,9 @@ export const dialogManagerMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
showDialog(
|
showDialog(
|
||||||
this,
|
this,
|
||||||
this.shadowRoot!,
|
this.shadowRoot!,
|
||||||
dialogImport,
|
|
||||||
dialogTag,
|
dialogTag,
|
||||||
(showEv as HASSDomEvent<unknown>).detail
|
(showEv as HASSDomEvent<unknown>).detail,
|
||||||
|
dialogImport
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,46 @@
|
|||||||
import { Constructor } from "../types";
|
import { showDialog } from "../dialogs/make-dialog-manager";
|
||||||
import { HassBaseEl } from "./hass-base-mixin";
|
import type { Constructor } from "../types";
|
||||||
|
import type { HassBaseEl } from "./hass-base-mixin";
|
||||||
|
import type { MoreInfoDialogParams } from "../dialogs/more-info/ha-more-info-dialog";
|
||||||
|
import type { PropertyValues } from "lit-element";
|
||||||
|
import type { HASSDomEvent } from "../common/dom/fire_event";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
// for fire event
|
// for fire event
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"hass-more-info": {
|
"hass-more-info": MoreInfoDialogParams;
|
||||||
entityId: string | null;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
let moreInfoImportPromise;
|
||||||
class extends superClass {
|
const importMoreInfo = () => {
|
||||||
private _moreInfoEl?: any;
|
if (!moreInfoImportPromise) {
|
||||||
|
moreInfoImportPromise = import(
|
||||||
protected firstUpdated(changedProps) {
|
|
||||||
super.firstUpdated(changedProps);
|
|
||||||
this.addEventListener("hass-more-info", (e) => this._handleMoreInfo(e));
|
|
||||||
|
|
||||||
// Load it once we are having the initial rendering done.
|
|
||||||
import(
|
|
||||||
/* webpackChunkName: "more-info-dialog" */ "../dialogs/more-info/ha-more-info-dialog"
|
/* webpackChunkName: "more-info-dialog" */ "../dialogs/more-info/ha-more-info-dialog"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return moreInfoImportPromise;
|
||||||
|
};
|
||||||
|
|
||||||
private async _handleMoreInfo(ev) {
|
export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
||||||
if (!this._moreInfoEl) {
|
class extends superClass {
|
||||||
this._moreInfoEl = document.createElement("ha-more-info-dialog");
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
this.shadowRoot!.appendChild(this._moreInfoEl);
|
super.firstUpdated(changedProps);
|
||||||
this.provideHass(this._moreInfoEl);
|
this.addEventListener("hass-more-info", (ev) => this._handleMoreInfo(ev));
|
||||||
|
|
||||||
|
// Load it once we are having the initial rendering done.
|
||||||
|
importMoreInfo();
|
||||||
}
|
}
|
||||||
this._updateHass({ moreInfoEntityId: ev.detail.entityId });
|
|
||||||
|
private async _handleMoreInfo(ev: HASSDomEvent<MoreInfoDialogParams>) {
|
||||||
|
showDialog(
|
||||||
|
this,
|
||||||
|
this.shadowRoot!,
|
||||||
|
"ha-more-info-dialog",
|
||||||
|
{
|
||||||
|
entityId: ev.detail.entityId,
|
||||||
|
},
|
||||||
|
importMoreInfo
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import {
|
||||||
|
closeDialog,
|
||||||
|
showDialog,
|
||||||
|
DialogState,
|
||||||
|
DialogClosedParams,
|
||||||
|
} from "../dialogs/make-dialog-manager";
|
||||||
import { Constructor } from "../types";
|
import { Constructor } from "../types";
|
||||||
import { HassBaseEl } from "./hass-base-mixin";
|
import { HassBaseEl } from "./hass-base-mixin";
|
||||||
|
import { HASSDomEvent } from "../common/dom/fire_event";
|
||||||
|
|
||||||
const DEBUG = false;
|
const DEBUG = true;
|
||||||
|
|
||||||
export const urlSyncMixin = <T extends Constructor<HassBaseEl>>(
|
export const urlSyncMixin = <T extends Constructor<HassBaseEl>>(
|
||||||
superClass: T
|
superClass: T
|
||||||
@ -12,81 +18,77 @@ export const urlSyncMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
__DEMO__
|
__DEMO__
|
||||||
? superClass
|
? superClass
|
||||||
: class extends superClass {
|
: class extends superClass {
|
||||||
private _ignoreNextHassChange = false;
|
private _ignoreNextPopState = false;
|
||||||
|
|
||||||
private _ignoreNextPopstate = false;
|
|
||||||
|
|
||||||
private _moreInfoOpenedFromPath?: string;
|
|
||||||
|
|
||||||
public connectedCallback(): void {
|
public connectedCallback(): void {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
window.addEventListener("popstate", this._popstateChangeListener);
|
window.addEventListener("popstate", this._popstateChangeListener);
|
||||||
|
this.addEventListener("dialog-closed", this._dialogClosedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public disconnectedCallback(): void {
|
public disconnectedCallback(): void {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
window.removeEventListener("popstate", this._popstateChangeListener);
|
window.removeEventListener("popstate", this._popstateChangeListener);
|
||||||
|
this.removeEventListener("dialog-closed", this._dialogClosedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected hassChanged(newHass, oldHass): void {
|
private _dialogClosedListener = (
|
||||||
super.hassChanged(newHass, oldHass);
|
ev: HASSDomEvent<DialogClosedParams>
|
||||||
|
) => {
|
||||||
if (this._ignoreNextHassChange) {
|
// If not closed by navigating back, and not a new dialog is open, remove the open state from history
|
||||||
if (DEBUG) {
|
|
||||||
console.log("ignore hasschange");
|
|
||||||
}
|
|
||||||
this._ignoreNextHassChange = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
!oldHass ||
|
history.state?.open &&
|
||||||
oldHass.moreInfoEntityId === newHass.moreInfoEntityId
|
history.state?.dialog === ev.detail.dialog
|
||||||
) {
|
) {
|
||||||
if (DEBUG) {
|
this._ignoreNextPopState = true;
|
||||||
console.log("ignoring hass change");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newHass.moreInfoEntityId) {
|
|
||||||
if (DEBUG) {
|
|
||||||
console.log("pushing state");
|
|
||||||
}
|
|
||||||
// We keep track of where we opened moreInfo from so that we don't
|
|
||||||
// pop the state when we close the modal if the modal has navigated
|
|
||||||
// us away.
|
|
||||||
this._moreInfoOpenedFromPath = window.location.pathname;
|
|
||||||
history.pushState(null, "", window.location.pathname);
|
|
||||||
} else if (
|
|
||||||
window.location.pathname === this._moreInfoOpenedFromPath
|
|
||||||
) {
|
|
||||||
if (DEBUG) {
|
|
||||||
console.log("history back");
|
|
||||||
}
|
|
||||||
this._ignoreNextPopstate = true;
|
|
||||||
history.back();
|
history.back();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
private _popstateChangeListener = (ev) => {
|
private _popstateChangeListener = (ev: PopStateEvent) => {
|
||||||
if (this._ignoreNextPopstate) {
|
if (this._ignoreNextPopState) {
|
||||||
if (DEBUG) {
|
this._ignoreNextPopState = false;
|
||||||
console.log("ignore popstate");
|
|
||||||
}
|
|
||||||
this._ignoreNextPopstate = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ev.state && "dialog" in ev.state) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
console.log("popstate", ev);
|
console.log("popstate", ev);
|
||||||
}
|
}
|
||||||
|
this._handleDialogStateChange(ev.state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (this.hass && this.hass.moreInfoEntityId) {
|
private async _handleDialogStateChange(state: DialogState) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
console.log("deselect entity");
|
console.log("handle state", state);
|
||||||
|
}
|
||||||
|
if (!state.open) {
|
||||||
|
const closed = await closeDialog(state.dialog);
|
||||||
|
if (!closed) {
|
||||||
|
// dialog could not be closed, push state again
|
||||||
|
history.pushState(
|
||||||
|
{
|
||||||
|
dialog: state.dialog,
|
||||||
|
open: true,
|
||||||
|
dialogParams: null,
|
||||||
|
oldState: null,
|
||||||
|
},
|
||||||
|
""
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state.oldState) {
|
||||||
|
this._handleDialogStateChange(state.oldState);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state.dialogParams !== null) {
|
||||||
|
showDialog(
|
||||||
|
this,
|
||||||
|
this.shadowRoot!,
|
||||||
|
state.dialog,
|
||||||
|
state.dialogParams
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this._ignoreNextHassChange = true;
|
|
||||||
fireEvent(this, "hass-more-info", { entityId: null });
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user