I added frequently used settings pages to my sidebar (Entities, Automations, Integrations, etc.) Plus a one-click Restart button

Here’s my new sidebar:

I got tired of doing this: Scroll down on the sidebar menu, click Settings, click Devices & Services, click Entities. Or automations, add-ons, integrations, helpers, etc. So I set up some Custom Panels to add quick links to these pages:

  • Entities
  • States
  • Automations
  • Helpers
  • Add-ons
  • Integrations

I use packages to split up my configuration.yaml into different files.

  • configuration.yaml:
homeassistant:
  packages: !include_dir_merge_named packages/

Here’s all the menu items I configured in a sidebar_menu package:

  • packages/sidebar_menu.yaml:
sidebar_menu:
  panel_custom:
    - name: ha_addons
      sidebar_title: Add-ons
      sidebar_icon: mdi:toy-brick-outline
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'hassio/dashboard'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_automations
      sidebar_title: Automations
      sidebar_icon: mdi:robot
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/automation'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_entities
      sidebar_title: Entities
      sidebar_icon: mdi:devices
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/entities'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_helpers
      sidebar_title: Helpers
      sidebar_icon: mdi:toggle-switch-outline
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/helpers'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_integrations
      sidebar_title: Integrations
      sidebar_icon: mdi:chip
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/integrations'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_states
      sidebar_title: States
      sidebar_icon: mdi:details
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'developer-tools/state'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - 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

Then I went to the profile settings page (/profile) and changed the order to put them at the top. (“Change the order and hide items from the sidebar” => Edit)


One-click Restart Button

I also figured out how to add a one-click Restart button to the bottom of the menu, above Developer Tools:

I wrote some JavaScript 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, then you still end up on the developer-tools/yaml page where you can click the Restart button manually.)

Here’s how you can set this up:

  • 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();

I’m glad I figured out how to send commands via the websocket connection, that could be handy for some other UI customizations.

35 Likes

I also figured out how to save and restore my profile settings across multiple devices and sessions: WTH: Why most settings are browser instance dependant - #16 by ndbroadbent

Otherwise it would be really annoying if I kept losing the custom order of my sidebar items.

8 Likes

Big cinema, thank you very much. FINALLY, I now can clean cache without starting and starting again with reorganizing.

A realy good job thanks ! :star_struck:

Amazin job, as I am thinking always forward.
In this restart button, do you think it is possible to do the check config and if all fine, restart?
or if check config is false (not fine) then warn something in screen.

This would be game changer hahaha

Hi @alexandrechoske, yes this is already the behavior of the homeassistant.restart service that I am calling. If the configuration check fails then it will show a notification.

SERVICE HOMEASSISTANT.RESTART

Restarts the Home Assistant instance (also reloading the configuration on start).

This will also do a configuration check before doing a restart. If the configuration check fails then Home Assistant will not be restarted, instead a persistent notification with the ID persistent_notification.homeassistant_check_config will be created. The logs will show details on what failed the configuration check.

1 Like

Amazin then!!!
Nice job!
I already implemented here and holy shit this is a absurd time SAVER, I enter on develop tools like 100 times a day, now with just one click!!!
Thank you so much!

I added two handmade “dividers” between the zones.

First zone → Dash
Second zone → Addons
Third zone → shortcuts to HA pages

5 Likes

@ndbroadbent is there a way to show a confirmation popup box when press the restart button?
I am thinkin about accidentaly pressing the button!

Oh yeah that’s a good idea! Could just add a confirm call in JavaScript before calling the restart service, something like this:

if (confirm("Are you sure you want to restart Home Assistant?")) {
  // restart
}

Yeah this works, here’s the whole JS function that will prompt for confirmation:


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..."
  );
  if (!confirm("Are you sure you want to restart Home Assistant?")) return;

  // 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,
      })
    );
  });
}
5 Likes

This custom.js does directly restart Home Assistant without any warning. Please help.

# 2023-10-06: https://community.home-assistant.io/t/i-added-frequently-used-settings-pages-to-my-sidebar-entities-automations-integrations-etc-plus-a-one-click-restart-button/483416/11


// 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..."
  );
  if (!confirm("Are you sure you want to restart Home Assistant?")) return;

  // 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();

Hi, thanks for sharing the config. I have the same problem as @ajd_ht up here. Restart without confirmation.
I don’t really care about that, but I mainly wanted to have a restart button at the bottom like in the picture. But I can’t put it there. Doesn’t this custom.js make a problem with hacs browser_mode?

@VietNgoc

Here my configuration.yaml

################################################################################
# CUSTOM PANEL                                                                 #
################################################################################

# https://home-assistant-guide.com/guide/how-to-add-internal-links-to-the-home-assistant-sidebar/#adding-internal-links-to-the-home-assistant-sidebar
# https://community.home-assistant.io/t/i-added-frequently-used-settings-pages-to-my-sidebar-entities-automations-integrations-etc-plus-a-one-click-restart-button/483416


panel_custom:

#   PANEL_ADDONS
    - name: panel_addons
      sidebar_title: Add-ons
      sidebar_icon: mdi:toy-brick-outline
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'hassio/dashboard'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator

#   PANEL_AUTOMATIONS
    - name: panel_automations
      sidebar_title: Automations
      sidebar_icon: mdi:robot
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/automation'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator

#   PANEL_ENTITIES
    - name: panel_entities
      sidebar_title: Entities
      sidebar_icon: mdi:devices
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/entities'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
        
#   PANEL_HELPERS
    - name: panel_helpers
      sidebar_title: Helpers
      sidebar_icon: mdi:toggle-switch-outline
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/helpers'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
        
#   PANEL_INTEGRATIONS        
    - name: panel_integrations
      sidebar_title: Integrations
      sidebar_icon: mdi:chip
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/integrations'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
        
#   PANEL_STATES        
    - name: panel_states
      sidebar_title: States
      sidebar_icon: mdi:details
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'developer-tools/state'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
        
#   PANEL_RESTART        
    - name: panel_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

Long click “Home Assistant”

image

makes it possible to edit the panel

Yes, I did the same procedure including adding a custom.js file. The custom fields in the sidebar are. Only this restart position should be at the bottom.
Screen-Recording-2023-10-07-at-17.27

Looks great! Can you show your YAML for the divider please?

This is awesome! I’m a new HA user, so I may be missing something obvious here. Any ideas why this is not working?
I’ve restarted HA, but the new items are not showing up.

I added lines to my configuration.yaml

# Loads default set of integrations. Do not remove.
default_config:
my:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

homeassistant:
  packages: !include_dir_merge_named packages/

And created a new folder (homeassistant/packages) and created a new sidebar_menu_yaml and pasted in everything execpt for the 1 click restart.

sidebar_menu:
  panel_custom:
    - name: ha_addons
      sidebar_title: Add-ons
      sidebar_icon: mdi:toy-brick-outline
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'hassio/dashboard'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_automations
      sidebar_title: Automations
      sidebar_icon: mdi:robot
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/automation'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_entities
      sidebar_title: Entities
      sidebar_icon: mdi:devices
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/entities'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_helpers
      sidebar_title: Helpers
      sidebar_icon: mdi:toggle-switch-outline
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/helpers'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_integrations
      sidebar_title: Integrations
      sidebar_icon: mdi:chip
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'config/integrations'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator
    - name: ha_states
      sidebar_title: States
      sidebar_icon: mdi:details
      js_url: /api/hassio/app/entrypoint.js
      url_path: 'developer-tools/state'
      embed_iframe: true
      require_admin: true
      config:
        ingress: core_configurator

You need to name the file with .yaml, not _yaml.
A was faced with this problem too :slight_smile:

God bless you sir!!! :smiley:

Thank you so much for this!