Skip to content

Instantly share code, notes, and snippets.

@balloob
Created June 22, 2020 04:51
Show Gist options
  • Save balloob/580deaf8c3fc76948559c5963ed4d436 to your computer and use it in GitHub Desktop.
Save balloob/580deaf8c3fc76948559c5963ed4d436 to your computer and use it in GitHub Desktop.
Add redirects to the Home Assistant sidebar to any place in Home Assistant
/*
Add a link to the sidebar to any path in Home Assistant
Put this file in <config>/www/panel-redirect.js
In configuration.yaml:
panel_custom:
- name: panel-redirect
# url_path needs to be unique for each panel_custom config
url_path: redirect-server-controls
sidebar_title: Server Controls
sidebar_icon: mdi:server
module_url: /local/panel-redirect.js
config:
# Where you want to redirect to
target: /config/server_control
*/
class PanelRedirect extends HTMLElement {
connectedCallback() {
if (this._info) {
this._navigate();
}
}
set panel(info) {
this._info = info;
if (this.isConnected) {
this._navigate();
}
}
_navigate() {
history.replaceState(null, "", this._info.config.target);
const event = new Event("location-changed", {
bubbles: true,
composed: true,
});
event.detail = { replace: true };
this.dispatchEvent(event);
}
}
customElements.define("panel-redirect", PanelRedirect);
@tomlut
Copy link

tomlut commented Jun 14, 2022

Is there any advantage over using this?

panel_custom:
  - name: server_logs
    sidebar_title: Logs
    sidebar_icon: mdi:cog-transfer
    js_url: /api/hassio/app/entrypoint.js
    url_path: "config/logs"
    embed_iframe: true
    require_admin: true
    config:
      ingress: core_configurator
  - name: automation
    sidebar_title: Automations
    sidebar_icon: mdi:cog-transfer
    js_url: /api/hassio/app/entrypoint.js
    url_path: "config/automation/dashboard"
    embed_iframe: true
    require_admin: true
    config:
      ingress: core_configurator
  - name: states
    sidebar_title: States
    sidebar_icon: mdi:cog-transfer
    js_url: /api/hassio/app/entrypoint.js
    url_path: "developer-tools/state"
    embed_iframe: true
    require_admin: true
    config:
      ingress: core_configurator

@ndbroadbent
Copy link

I figured out how to add a sidebar menu item to restart Home Assistant with one click. I wrote some custom JS that checks for ?shouldRestart=1 in the URL. If this is found, then it calls the homeassistant.restart service via the websocket connection (after clearing the query param so it doesn't keep restarting in a loop.) If the JS doesn't work for any reason, then you still end up on the developer-tools/yaml page where you can click the Restart button manually.

  • config/configuration.yaml:
frontend:
  extra_module_url:
    - /local/custom.js

panel_custom:
  - name: ha_restart
    sidebar_title: Restart
    sidebar_icon: mdi:restart
    js_url: /api/hassio/app/entrypoint.js
    url_path: 'developer-tools/yaml?shouldRestart=1'
    embed_iframe: true
    require_admin: true
    config:
      ingress: core_configurator
  • config/www/custom.js:
// We need a 'locationchange' event
(function () {
  const pushState = history.pushState;
  history.pushState = function () {
    pushState.apply(history, arguments);
    window.dispatchEvent(new Event("pushstate"));
    window.dispatchEvent(new Event("locationchange"));
  };
})();

function checkShouldRestart() {
  const urlSearchParams = new URLSearchParams(location.search);
  if (urlSearchParams.get("shouldRestart") !== "1") {
    return;
  }
  console.warn(
    "Found ?shouldRestart=1 in URL, restarting Home Assistant Core..."
  );
  // Clear shouldRestart parameter from URL
  const newUrl = new URL(document.location.href);
  newUrl.search = "";
  history.pushState({}, "", newUrl);

  hassConnection.then(({ conn }) => {
    console.warn("Sending restart command...");
    conn.socket.send(
      JSON.stringify({
        type: "execute_script",
        sequence: [
          {
            service: "homeassistant.restart",
            data: {},
          },
        ],
        id: ++conn.commandId,
      })
    );
  });
}

window.addEventListener("locationchange", checkShouldRestart);
checkShouldRestart();

@danielbrunt57
Copy link

The JS did not work for me...

@jareau
Copy link

jareau commented Mar 10, 2023

I have panel-redirect.js working well in Home Assistant 2023.3.3.

I noticed https://www.home-assistant.io/integrations/panel_iframe/ shows an optional require_admin: true parameter that limits the link to Admin Users.

Is require_admin: true possible in panel-redirect.js?

@ncodee
Copy link

ncodee commented Dec 28, 2023

Why isn't this implemented in the UI already?

@danielbrunt57
Copy link

danielbrunt57 commented Dec 29, 2023

Why isn't this implemented in the UI already?

Maybe one day but today is only Stardate 270457.6 BT (BT is Before Trek so that's -270457.6 before Stardate 00000.0)

@MikeGuest
Copy link

Hi - any clues anyone please? I'm lost.

I want to add an additional Settings menu to my sidebar. The existing one can't be moved to the top of the screen. I want all my most frequently used menu items on the first page to avoid too much scrolling. I'd like to do the same with the development tools too.

I'm set up like this, but the link persists in redirecting the url to /lovelace/0 or /lovelace/dashboard

panel_custom:
  - name: settings
    # url_path needs to be unique for each panel_custom config
    url_path: ***********.duckdns.org:8123/config
    sidebar_title: Settings
    sidebar_icon: mdi:cog
    module_url: /local/panel-redirect.js
    config:
      # Where you want to redirect to
      target: /config

@tomlut
Copy link

tomlut commented Mar 5, 2024

The existing one can't be moved to the top of the screen

All of them can be moved. Long click the menu title.

@MikeGuest
Copy link

The existing one can't be moved to the top of the screen

All of them can be moved. Long click the menu title.

Nope - settings and developer tools are pinned and cannot be moved - at least on my installation

@tomlut
Copy link

tomlut commented Mar 8, 2024

Ah, sorry. Yes you are correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment