From 41bbf7e541eb8a739812dd43059f496e0dd89753 Mon Sep 17 00:00:00 2001 From: Jamil Date: Mon, 25 Sep 2023 14:29:56 -0700 Subject: [PATCH] fix(portal): sidebar active item state (#2119) Adds `active_path` to determine whether or not to highlight a sidebar item. ~~Leaving as draft for now to allow @devsnaked to contribute. Edit: Will use this PR as the base for @devsnaked's upcoming changes~~ Edit: fixes #2065 --- .github/workflows/elixir.yml | 6 - .../lib/web/components/layouts/app.html.heex | 49 +++++- .../web/components/navigation_components.ex | 17 +- elixir/apps/web/lib/web/nav.ex | 12 ++ elixir/apps/web/lib/web/router.ex | 3 +- .../web/test/web/live/nav/sidebar_test.exs | 155 ++++++++++++++++++ 6 files changed, 224 insertions(+), 18 deletions(-) create mode 100644 elixir/apps/web/lib/web/nav.ex create mode 100644 elixir/apps/web/test/web/live/nav/sidebar_test.exs diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index e609d3834..04f1dd044 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -307,12 +307,6 @@ jobs: options: --cap-add=IPC_LOCK steps: - uses: nanasess/setup-chromedriver@v2 - with: - # XXX: This is an unfortunate workaround due to this issue: - # https://github.com/nanasess/setup-chromedriver/issues/199 - # Still, it may not hurt to pin chromedriver and/or Chrome for more repeatable tests and - # possibly even matrix these to multiple versions to increase browser coverage. - chromedriver-version: '117.0.5938' - uses: erlef/setup-beam@v1 with: otp-version: "26.0.2" diff --git a/elixir/apps/web/lib/web/components/layouts/app.html.heex b/elixir/apps/web/lib/web/components/layouts/app.html.heex index b4e2b3867..fca659809 100644 --- a/elixir/apps/web/lib/web/components/layouts/app.html.heex +++ b/elixir/apps/web/lib/web/components/layouts/app.html.heex @@ -1,44 +1,75 @@ <.topbar subject={@subject} /> <.sidebar> - <.sidebar_item navigate={~p"/#{@account}/dashboard"} icon="hero-chart-bar-square-solid"> + <.sidebar_item + current_path={@current_path} + navigate={~p"/#{@account}/dashboard"} + icon="hero-chart-bar-square-solid" + > Dashboard - <.sidebar_item navigate={~p"/#{@account}/actors"} icon="hero-user-circle-solid"> + <.sidebar_item + current_path={@current_path} + navigate={~p"/#{@account}/actors"} + icon="hero-user-circle-solid" + > Actors - <.sidebar_item navigate={~p"/#{@account}/groups"} icon="hero-user-group-solid"> + <.sidebar_item + current_path={@current_path} + navigate={~p"/#{@account}/groups"} + icon="hero-user-group-solid" + > Groups - <.sidebar_item navigate={~p"/#{@account}/clients"} icon="hero-device-phone-mobile-solid"> + <.sidebar_item + current_path={@current_path} + navigate={~p"/#{@account}/clients"} + icon="hero-device-phone-mobile-solid" + > Clients <.sidebar_item + current_path={@current_path} navigate={~p"/#{@account}/gateway_groups"} icon="hero-arrow-left-on-rectangle-solid" > Gateways - <.sidebar_item navigate={~p"/#{@account}/relay_groups"} icon="hero-arrows-right-left"> + <.sidebar_item + current_path={@current_path} + navigate={~p"/#{@account}/relay_groups"} + icon="hero-arrows-right-left" + > Relays - <.sidebar_item navigate={~p"/#{@account}/resources"} icon="hero-server-stack-solid"> + <.sidebar_item + current_path={@current_path} + navigate={~p"/#{@account}/resources"} + icon="hero-server-stack-solid" + > Resources - <.sidebar_item navigate={~p"/#{@account}/policies"} icon="hero-shield-check-solid"> + <.sidebar_item + current_path={@current_path} + navigate={~p"/#{@account}/policies"} + icon="hero-shield-check-solid" + > Policies - <.sidebar_item_group id="settings" icon="hero-cog-solid"> + <.sidebar_item_group current_path={@current_path} id="settings" icon="hero-cog-solid"> <:name>Settings <:item navigate={~p"/#{@account}/settings/account"}>Account - <:item navigate={~p"/#{@account}/settings/identity_providers"}>Identity Providers + <:item navigate={~p"/#{@account}/settings/identity_providers"}> + Identity Providers + <:item navigate={~p"/#{@account}/settings/dns"}>DNS diff --git a/elixir/apps/web/lib/web/components/navigation_components.ex b/elixir/apps/web/lib/web/components/navigation_components.ex index 3cfa8a6d0..8748aa8fe 100644 --- a/elixir/apps/web/lib/web/components/navigation_components.ex +++ b/elixir/apps/web/lib/web/components/navigation_components.ex @@ -146,6 +146,8 @@ defmodule Web.NavigationComponents do attr :icon, :string, required: true attr :navigate, :string, required: true slot :inner_block, required: true + attr :current_path, :string, required: true + attr :active_class, :string, required: false, default: "dark:bg-gray-700 bg-gray-100" def sidebar_item(assigns) do ~H""" @@ -154,6 +156,7 @@ defmodule Web.NavigationComponents do flex items-center p-2 text-base font-medium text-gray-900 rounded-lg + #{String.starts_with?(@current_path, @navigate) && @active_class} hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700 group]}> <.icon name={@icon} class={~w[ @@ -170,7 +173,8 @@ defmodule Web.NavigationComponents do attr :id, :string, required: true, doc: "ID of the nav group container" attr :icon, :string, required: true - # attr :navigate, :string, required: true + attr :current_path, :string, required: true + attr :active_class, :string, required: false, default: "dark:bg-gray-700 bg-gray-100" slot :name, required: true @@ -179,6 +183,13 @@ defmodule Web.NavigationComponents do end def sidebar_item_group(assigns) do + dropdown_hidden = + !Enum.any?(assigns.item, fn item -> + String.starts_with?(assigns.current_path, item.navigate) + end) + + assigns = assign(assigns, dropdown_hidden: dropdown_hidden) + ~H"""
  • -