1
0
mirror of https://github.com/home-assistant/frontend.git synced 2025-12-20 02:38:53 +00:00

Create and implement goBack helper function (#27015)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Aidan Timson
2025-09-12 10:39:45 +01:00
committed by GitHub
parent 7eb87c78cc
commit 0d8d18617c
17 changed files with 57 additions and 32 deletions

View File

@@ -3,7 +3,7 @@ import type { PropertyValues, TemplateResult } from "lit";
import { css, html, LitElement } from "lit"; import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../src/common/dom/fire_event"; import { fireEvent } from "../../../src/common/dom/fire_event";
import { navigate } from "../../../src/common/navigate"; import { goBack, navigate } from "../../../src/common/navigate";
import { extractSearchParam } from "../../../src/common/url/search-params"; import { extractSearchParam } from "../../../src/common/url/search-params";
import { nextRender } from "../../../src/common/util/render-status"; import { nextRender } from "../../../src/common/util/render-status";
import "../../../src/components/ha-icon-button"; import "../../../src/components/ha-icon-button";
@@ -193,7 +193,7 @@ class HassioIngressView extends LitElement {
title: addon.name, title: addon.name,
}); });
await nextRender(); await nextRender();
history.back(); goBack();
return; return;
} }
@@ -275,7 +275,7 @@ class HassioIngressView extends LitElement {
title: addon.name, title: addon.name,
}); });
await nextRender(); await nextRender();
history.back(); goBack();
return; return;
} }

View File

@@ -2,6 +2,7 @@ import type { TemplateResult } from "lit";
import { css, html, LitElement } from "lit"; import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import type { Supervisor } from "../../../src/data/supervisor/supervisor"; import type { Supervisor } from "../../../src/data/supervisor/supervisor";
import { goBack } from "../../../src/common/navigate";
import "../../../src/layouts/hass-subpage"; import "../../../src/layouts/hass-subpage";
import type { HomeAssistant, Route } from "../../../src/types"; import type { HomeAssistant, Route } from "../../../src/types";
import "./update-available-card"; import "./update-available-card";
@@ -35,7 +36,7 @@ class UpdateAvailableDashboard extends LitElement {
} }
private _updateComplete() { private _updateComplete() {
history.back(); goBack();
} }
static styles = css` static styles = css`

View File

@@ -63,3 +63,21 @@ export const navigate = async (
}); });
return true; return true;
}; };
/**
* Navigate back in history, with fallback to a default path if no history exists.
* This prevents a user from getting stuck when they navigate directly to a page with no history.
*/
export const goBack = (fallbackPath?: string) => {
const { history } = mainWindow;
// Check if we have history to go back to
if (history.length > 1) {
history.back();
return;
}
// No history available, navigate to fallback path
const fallback = fallbackPath || "/";
navigate(fallback, { replace: true });
};

View File

@@ -1,6 +1,7 @@
import type { CSSResultGroup, TemplateResult } from "lit"; import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement } from "lit"; import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { goBack } from "../common/navigate";
import "../components/ha-icon-button-arrow-prev"; import "../components/ha-icon-button-arrow-prev";
import "../components/ha-button"; import "../components/ha-button";
import "../components/ha-menu-button"; import "../components/ha-menu-button";
@@ -50,7 +51,7 @@ class HassErrorScreen extends LitElement {
} }
private _handleBack(): void { private _handleBack(): void {
history.back(); goBack();
} }
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {

View File

@@ -1,6 +1,7 @@
import type { CSSResultGroup, TemplateResult } from "lit"; import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { goBack } from "../common/navigate";
import "../components/ha-spinner"; import "../components/ha-spinner";
import "../components/ha-icon-button-arrow-prev"; import "../components/ha-icon-button-arrow-prev";
import "../components/ha-menu-button"; import "../components/ha-menu-button";
@@ -49,7 +50,7 @@ class HassLoadingScreen extends LitElement {
} }
private _handleBack() { private _handleBack() {
history.back(); goBack();
} }
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {

View File

@@ -2,6 +2,7 @@ import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement } from "lit"; import { css, html, LitElement } from "lit";
import { customElement, eventOptions, property } from "lit/decorators"; import { customElement, eventOptions, property } from "lit/decorators";
import { restoreScroll } from "../common/decorators/restore-scroll"; import { restoreScroll } from "../common/decorators/restore-scroll";
import { goBack } from "../common/navigate";
import "../components/ha-icon-button-arrow-prev"; import "../components/ha-icon-button-arrow-prev";
import "../components/ha-menu-button"; import "../components/ha-menu-button";
import type { HomeAssistant } from "../types"; import type { HomeAssistant } from "../types";
@@ -78,7 +79,7 @@ class HassSubpage extends LitElement {
this.backCallback(); this.backCallback();
return; return;
} }
history.back(); goBack();
} }
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {

View File

@@ -4,6 +4,7 @@ import { customElement, eventOptions, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { canShowPage } from "../common/config/can_show_page"; import { canShowPage } from "../common/config/can_show_page";
import { goBack } from "../common/navigate";
import { restoreScroll } from "../common/decorators/restore-scroll"; import { restoreScroll } from "../common/decorators/restore-scroll";
import type { LocalizeFunc } from "../common/translations/localize"; import type { LocalizeFunc } from "../common/translations/localize";
import "../components/ha-icon-button-arrow-prev"; import "../components/ha-icon-button-arrow-prev";
@@ -205,7 +206,7 @@ class HassTabsSubpage extends LitElement {
this.backCallback(); this.backCallback();
return; return;
} }
history.back(); goBack();
} }
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {

View File

@@ -7,6 +7,7 @@ import { customElement, property, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined"; import { ifDefined } from "lit/directives/if-defined";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { goBack } from "../../../common/navigate";
import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name"; import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name";
import { computeDomain } from "../../../common/entity/compute_domain"; import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateName } from "../../../common/entity/compute_state_name"; import { computeStateName } from "../../../common/entity/compute_state_name";
@@ -643,7 +644,7 @@ class HaConfigAreaPage extends LitElement {
destructive: true, destructive: true,
confirm: async () => { confirm: async () => {
await deleteAreaRegistryEntry(this.hass!, area!.area_id); await deleteAreaRegistryEntry(this.hass!, area!.area_id);
afterNextRender(() => history.back()); afterNextRender(() => goBack("/config"));
}, },
}); });
} }

View File

@@ -24,7 +24,7 @@ import { property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { transform } from "../../../common/decorators/transform"; import { transform } from "../../../common/decorators/transform";
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import { navigate } from "../../../common/navigate"; import { goBack, navigate } from "../../../common/navigate";
import { promiseTimeout } from "../../../common/util/promise-timeout"; import { promiseTimeout } from "../../../common/util/promise-timeout";
import { afterNextRender } from "../../../common/util/render-status"; import { afterNextRender } from "../../../common/util/render-status";
import "../../../components/ha-button"; import "../../../components/ha-button";
@@ -702,7 +702,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
{ err_no: err.status_code } { err_no: err.status_code }
), ),
}); });
history.back(); goBack("/config");
} }
} }
@@ -853,7 +853,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
private _backTapped = async () => { private _backTapped = async () => {
const result = await this._confirmUnsavedChanged(); const result = await this._confirmUnsavedChanged();
if (result) { if (result) {
afterNextRender(() => history.back()); afterNextRender(() => goBack("/config"));
} }
}; };
@@ -941,7 +941,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
private async _delete() { private async _delete() {
if (this.automationId) { if (this.automationId) {
await deleteAutomation(this.hass, this.automationId); await deleteAutomation(this.hass, this.automationId);
history.back(); goBack("/config");
} }
} }

View File

@@ -5,7 +5,7 @@ import {
mdiGroup, mdiGroup,
mdiPlus, mdiPlus,
} from "@mdi/js"; } from "@mdi/js";
import { navigate } from "../../../../../../common/navigate"; import { goBack, navigate } from "../../../../../../common/navigate";
import type { DeviceRegistryEntry } from "../../../../../../data/device_registry"; import type { DeviceRegistryEntry } from "../../../../../../data/device_registry";
import { fetchZHADevice } from "../../../../../../data/zha"; import { fetchZHADevice } from "../../../../../../data/zha";
import { showConfirmationDialog } from "../../../../../../dialogs/generic/show-dialog-box"; import { showConfirmationDialog } from "../../../../../../dialogs/generic/show-dialog-box";
@@ -102,7 +102,7 @@ export const getZHADeviceActions = async (
ieee: zhaDevice.ieee, ieee: zhaDevice.ieee,
}); });
history.back(); goBack("/config");
}, },
}); });
} }

View File

@@ -21,6 +21,7 @@ import "../../../../../components/ha-list-item";
import "../../../../../components/ha-progress-ring"; import "../../../../../components/ha-progress-ring";
import "../../../../../components/ha-spinner"; import "../../../../../components/ha-spinner";
import "../../../../../components/ha-svg-icon"; import "../../../../../components/ha-svg-icon";
import { goBack } from "../../../../../common/navigate";
import type { ConfigEntry } from "../../../../../data/config_entries"; import type { ConfigEntry } from "../../../../../data/config_entries";
import { import {
ERROR_STATES, ERROR_STATES,
@@ -618,7 +619,7 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
} }
private _handleBack(): void { private _handleBack(): void {
history.back(); goBack("/config");
} }
private _fetchData = async () => { private _fetchData = async () => {

View File

@@ -24,7 +24,7 @@ import { fireEvent } from "../../../common/dom/fire_event";
import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name"; import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name";
import { computeDomain } from "../../../common/entity/compute_domain"; import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateName } from "../../../common/entity/compute_state_name"; import { computeStateName } from "../../../common/entity/compute_state_name";
import { navigate } from "../../../common/navigate"; import { goBack, navigate } from "../../../common/navigate";
import { computeRTL } from "../../../common/util/compute_rtl"; import { computeRTL } from "../../../common/util/compute_rtl";
import { afterNextRender } from "../../../common/util/render-status"; import { afterNextRender } from "../../../common/util/render-status";
import "../../../components/device/ha-device-picker"; import "../../../components/device/ha-device-picker";
@@ -806,7 +806,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
{ err_no: err.status_code } { err_no: err.status_code }
), ),
}); });
history.back(); goBack("/config");
return; return;
} }
@@ -988,7 +988,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
if (this._mode === "live") { if (this._mode === "live") {
applyScene(this.hass, this._storedStates); applyScene(this.hass, this._storedStates);
} }
afterNextRender(() => history.back()); afterNextRender(() => goBack("/config"));
} }
private _deleteTapped(): void { private _deleteTapped(): void {
@@ -1012,7 +1012,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
if (this._mode === "live") { if (this._mode === "live") {
applyScene(this.hass, this._storedStates); applyScene(this.hass, this._storedStates);
} }
history.back(); goBack("/config");
} }
private async _confirmUnsavedChanged(): Promise<boolean> { private async _confirmUnsavedChanged(): Promise<boolean> {

View File

@@ -21,7 +21,7 @@ import { LitElement, css, html, nothing } from "lit";
import { property, query, state } from "lit/decorators"; import { property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import { navigate } from "../../../common/navigate"; import { goBack, navigate } from "../../../common/navigate";
import { slugify } from "../../../common/string/slugify"; import { slugify } from "../../../common/string/slugify";
import { promiseTimeout } from "../../../common/util/promise-timeout"; import { promiseTimeout } from "../../../common/util/promise-timeout";
import { afterNextRender } from "../../../common/util/render-status"; import { afterNextRender } from "../../../common/util/render-status";
@@ -596,7 +596,7 @@ export class HaScriptEditor extends SubscribeMixin(
{ err_no: resp.status_code || resp.code } { err_no: resp.status_code || resp.code }
) )
); );
history.back(); goBack("/config");
} }
); );
} }
@@ -762,7 +762,7 @@ export class HaScriptEditor extends SubscribeMixin(
private _backTapped = async () => { private _backTapped = async () => {
const result = await this._confirmUnsavedChanged(); const result = await this._confirmUnsavedChanged();
if (result) { if (result) {
afterNextRender(() => history.back()); afterNextRender(() => goBack("/config"));
} }
}; };
@@ -852,7 +852,7 @@ export class HaScriptEditor extends SubscribeMixin(
private async _delete() { private async _delete() {
await deleteScript(this.hass, this.scriptId!); await deleteScript(this.hass, this.scriptId!);
history.back(); goBack("/config");
} }
private async _switchUiMode() { private async _switchUiMode() {

View File

@@ -13,7 +13,7 @@ import "../lovelace/components/hui-energy-period-selector";
import type { Lovelace } from "../lovelace/types"; import type { Lovelace } from "../lovelace/types";
import "../lovelace/views/hui-view"; import "../lovelace/views/hui-view";
import "../lovelace/views/hui-view-container"; import "../lovelace/views/hui-view-container";
import { navigate } from "../../common/navigate"; import { goBack, navigate } from "../../common/navigate";
import type { import type {
GridSourceTypeEnergyPreference, GridSourceTypeEnergyPreference,
SolarSourceTypeEnergyPreference, SolarSourceTypeEnergyPreference,
@@ -70,7 +70,7 @@ class PanelEnergy extends LitElement {
private _back(ev) { private _back(ev) {
ev.stopPropagation(); ev.stopPropagation();
history.back(); goBack();
} }
protected render(): TemplateResult { protected render(): TemplateResult {

View File

@@ -17,7 +17,7 @@ import memoizeOne from "memoize-one";
import { ensureArray } from "../../common/array/ensure-array"; import { ensureArray } from "../../common/array/ensure-array";
import { storage } from "../../common/decorators/storage"; import { storage } from "../../common/decorators/storage";
import { computeDomain } from "../../common/entity/compute_domain"; import { computeDomain } from "../../common/entity/compute_domain";
import { navigate } from "../../common/navigate"; import { goBack, navigate } from "../../common/navigate";
import { constructUrlCurrentPath } from "../../common/url/construct-url"; import { constructUrlCurrentPath } from "../../common/url/construct-url";
import { import {
createSearchParam, createSearchParam,
@@ -114,7 +114,7 @@ class HaPanelHistory extends LitElement {
} }
private _goBack(): void { private _goBack(): void {
history.back(); goBack();
} }
protected render() { protected render() {

View File

@@ -4,7 +4,7 @@ import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import type { HassServiceTarget } from "home-assistant-js-websocket"; import type { HassServiceTarget } from "home-assistant-js-websocket";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { navigate } from "../../common/navigate"; import { goBack, navigate } from "../../common/navigate";
import { constructUrlCurrentPath } from "../../common/url/construct-url"; import { constructUrlCurrentPath } from "../../common/url/construct-url";
import { import {
createSearchParam, createSearchParam,
@@ -60,7 +60,7 @@ export class HaPanelLogbook extends LitElement {
} }
private _goBack(): void { private _goBack(): void {
history.back(); goBack();
} }
protected render() { protected render() {

View File

@@ -26,7 +26,7 @@ import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import { shouldHandleRequestSelectedEvent } from "../../common/mwc/handle-request-selected-event"; import { shouldHandleRequestSelectedEvent } from "../../common/mwc/handle-request-selected-event";
import { navigate } from "../../common/navigate"; import { goBack, navigate } from "../../common/navigate";
import type { LocalizeKeys } from "../../common/translations/localize"; import type { LocalizeKeys } from "../../common/translations/localize";
import { constructUrlCurrentPath } from "../../common/url/construct-url"; import { constructUrlCurrentPath } from "../../common/url/construct-url";
import { import {
@@ -799,7 +799,7 @@ class HUIRoot extends LitElement {
if (curViewConfig?.back_path != null) { if (curViewConfig?.back_path != null) {
navigate(curViewConfig.back_path, { replace: true }); navigate(curViewConfig.back_path, { replace: true });
} else if (history.length > 1) { } else if (history.length > 1) {
history.back(); goBack();
} else if (!views[0].subview) { } else if (!views[0].subview) {
navigate(this.route!.prefix, { replace: true }); navigate(this.route!.prefix, { replace: true });
} else { } else {