mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-04 10:42:23 +00:00
fix(ui): restore the main menu row that reopens the resource menu
- On a resource page, the main menu starts with a row that shows the resource name and opens the deepest resource menu again. - Pass the resource name to registerMainNavContext() again. - Document the row in DESIGN.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b3ec26c3b1
commit
49346aeb29
12 files changed
+36
-18
No files matched your search
@@ -311,8 +311,10 @@ Class names below are examples. Keep the values and structure.
|
||||
and no frame around it. Only the expanded sidebar shows Search as an input.
|
||||
- A menu that replaces another menu in place starts with a back row: a
|
||||
centered label and a 12px left chevron (`‹ Dashboard`).
|
||||
- The main menu has no row above its items. Dashboard is the first item, right
|
||||
under Search, on every page.
|
||||
- On a resource page, the main menu starts with a row that opens the resource
|
||||
menu again. It points right and shows the resource name (`adonisjs ›`). On
|
||||
other pages the main menu has no row above its items, and Dashboard is the
|
||||
first item, right under Search.
|
||||
|
||||
### Card (outer box, title row, well)
|
||||
|
||||
@@ -800,9 +802,9 @@ state because it can disappear after polling or a Livewire morph.
|
||||
From `xl`, the resource menu replaces the main menu in the main sidebar
|
||||
(`x-main-nav-menu`, `registerMainNavContext()`, `components/navbar.blade.php`).
|
||||
Its back row (`‹ Dashboard`, `‹ Servers`, `‹ Service`) shows the menu one depth
|
||||
lower, without a page load. The main menu has no row that opens the resource
|
||||
menu again; to get back to it, open the resource again. Dashboard is always the
|
||||
first item under Search.
|
||||
lower, without a page load. On a resource page the main menu starts with a row
|
||||
(`adonisjs ›`) that opens the deepest resource menu again, also without a page
|
||||
load.
|
||||
|
||||
The global topbar owns the current resource identity, its compact status
|
||||
badges, configuration warnings (`#configuration-warning-hud-slot`), and the
|
||||
|
||||
@@ -4760,11 +4760,12 @@ function wireNavigate(): string
|
||||
* Registers a resource menu that the main sidebar and the mobile drawer show in place of their main menu
|
||||
* (see components/navbar.blade.php). The menu teleports itself into #main-nav-context-{depth}.
|
||||
* Back on a menu shows the menu one depth lower, and Back at depth 0 shows the main menu.
|
||||
* The main menu then shows a row (labelled with $name) that opens the deepest resource menu again.
|
||||
*/
|
||||
function registerMainNavContext(int $depth, string $label, string $backTitle): void
|
||||
function registerMainNavContext(int $depth, string $label, string $backTitle, ?string $name = null): void
|
||||
{
|
||||
$levels = request()->attributes->get('mainNavContext', []);
|
||||
$levels[$depth] = ['label' => $label, 'backTitle' => $backTitle];
|
||||
$levels[$depth] = ['label' => $label, 'backTitle' => $backTitle, 'name' => $name];
|
||||
ksort($levels);
|
||||
|
||||
request()->attributes->set('mainNavContext', $levels);
|
||||
|
||||
@@ -228,7 +228,7 @@
|
||||
|
||||
@php
|
||||
// The main sidebar and the mobile drawer show this menu (see components/navbar.blade.php).
|
||||
registerMainNavContext(0, 'Dashboard', 'Back to the main menu');
|
||||
registerMainNavContext(0, 'Dashboard', 'Back to the main menu', $application->name);
|
||||
@endphp
|
||||
|
||||
{{-- Rendered twice: in the page (CSS hides it; it keeps the command palette items), and teleported into the main sidebar.
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
@php
|
||||
// The main sidebar and the mobile drawer show this menu (see components/navbar.blade.php).
|
||||
registerMainNavContext(0, 'Dashboard', 'Back to the main menu');
|
||||
registerMainNavContext(0, 'Dashboard', 'Back to the main menu', $database->name);
|
||||
@endphp
|
||||
|
||||
{{-- Rendered twice: in the page (CSS hides it; it keeps the command palette items), and teleported into the main sidebar.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@props(['backLabel', 'backTitle' => 'Back to the main menu', 'depth' => 0, 'navOnly' => false])
|
||||
@props(['backLabel', 'backTitle' => 'Back to the main menu', 'depth' => 0, 'name' => null, 'navOnly' => false])
|
||||
@php
|
||||
// The main sidebar and the mobile drawer replace their menu with this one (see components/navbar.blade.php).
|
||||
registerMainNavContext($depth, $backLabel, $backTitle);
|
||||
registerMainNavContext($depth, $backLabel, $backTitle, $name);
|
||||
@endphp
|
||||
{{-- A page menu, rendered twice: in the page (CSS hides it), and teleported into the
|
||||
main sidebar. The slot must not contain Livewire components (they would render twice).
|
||||
|
||||
@@ -184,6 +184,7 @@
|
||||
// components/main-nav-menu.blade.php). Each one teleports itself into #main-nav-context-{depth}
|
||||
// (the desktop sidebar); the mobile drawer moves it into its own slot while it shows (see init).
|
||||
$navContext = request()->attributes->get('mainNavContext', []);
|
||||
$navContextName = collect($navContext)->pluck('name')->filter()->last() ?? 'Resource menu';
|
||||
@endphp
|
||||
{{-- On a resource page the deepest resource menu replaces the main menu. Back shows the
|
||||
menu one depth lower, and then the main menu (or its submenu), without leaving the page. --}}
|
||||
@@ -262,6 +263,20 @@
|
||||
@endforeach
|
||||
<li x-show="navLevel === -1 && !submenu" @if ($activeSubmenu || $navContext) x-cloak @endif class="contents">
|
||||
<ul role="list" class="flex flex-col gap-y-0.5" :class="navSwap && 'nav-swap-' + navSwap">
|
||||
@if ($navContext)
|
||||
{{-- On a resource page the main menu opens the deepest resource menu again. --}}
|
||||
<li class="mb-1">
|
||||
<button type="button" @click="navLevel = {{ array_key_last($navContext) }}; navSwap = 'forward'"
|
||||
title="Back to the {{ $navContextName }} menu" aria-label="Back to the {{ $navContextName }} menu"
|
||||
class="menu-item menu-back bg-transparent! hover:bg-neutral-100! dark:hover:bg-white/[0.06]!" :class="collapsed && 'lg:justify-center lg:px-0'">
|
||||
<span class="flex-1 truncate pl-6 text-center font-medium text-black dark:text-fg"
|
||||
:class="collapsed && 'lg:hidden'">{{ $navContextName }}</span>
|
||||
<span class="menu-back-icon flex shrink-0 items-center justify-center">
|
||||
<x-reicon name="chevron-down" class="size-3 -rotate-90 text-coollabs dark:text-fg-dim" />
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
@endif
|
||||
@foreach ($navSections as $sectionLabel => $sectionItems)
|
||||
{{-- The first section needs no title. --}}
|
||||
@unless ($loop->first)
|
||||
|
||||
@@ -228,7 +228,7 @@
|
||||
|
||||
@php
|
||||
// The main sidebar and the mobile drawer show this menu (see components/navbar.blade.php).
|
||||
registerMainNavContext(0, 'Servers', 'Back to the main menu');
|
||||
registerMainNavContext(0, 'Servers', 'Back to the main menu', $server->name);
|
||||
@endphp
|
||||
|
||||
{{-- Rendered twice: in the page (CSS hides it; it keeps the command palette items), and teleported into the main sidebar.
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
->filter(fn ($items) => $items->isNotEmpty());
|
||||
@endphp
|
||||
|
||||
<x-main-nav-menu back-label="Dashboard" :nav-only="$navOnly"
|
||||
<x-main-nav-menu back-label="Dashboard" :name="$service->name" :nav-only="$navOnly"
|
||||
data-settings-search-items="{{ json_encode(settingsSearchItems($groupedItems, $serviceRouteParameters)) }}">
|
||||
<nav aria-label="Service settings"
|
||||
class="grid grid-cols-1 gap-0.5">
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
])->filter();
|
||||
@endphp
|
||||
|
||||
<x-main-nav-menu back-label="Destinations" back-title="Back to Integrations"
|
||||
<x-main-nav-menu back-label="Destinations" back-title="Back to Integrations" :name="$destination->name"
|
||||
data-settings-search-items="{{ json_encode(settingsSearchItems(['Destination' => $destinationMenuItems], $destinationRouteParameters)) }}">
|
||||
<nav aria-label="Destination settings"
|
||||
class="grid grid-cols-1 gap-0.5">
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
@if ($showSettingsSidebar)
|
||||
<section class="application-settings-workspace mt-4 w-full max-w-none lg:mt-0">
|
||||
<div class="grid min-w-0 gap-8 xl:grid-cols-[210px_minmax(0,1fr)] xl:gap-8">
|
||||
<x-main-nav-menu back-label="Sources" back-title="Back to Integrations"
|
||||
<x-main-nav-menu back-label="Sources" back-title="Back to Integrations" :name="$github_app->name ?: 'GitHub App'"
|
||||
data-settings-search-items="{{ json_encode(settingsSearchItems(['GitHub App' => $settingsMenuItems], $githubAppRouteParameters)) }}">
|
||||
<nav aria-label="GitHub App settings"
|
||||
class="grid grid-cols-1 gap-0.5">
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
@if ($showSettingsSidebar)
|
||||
<section class="application-settings-workspace mt-4 w-full max-w-none lg:mt-0">
|
||||
<div class="grid min-w-0 gap-8 xl:grid-cols-[210px_minmax(0,1fr)] xl:gap-8">
|
||||
<x-main-nav-menu back-label="S3 Storage" back-title="Back to Integrations"
|
||||
<x-main-nav-menu back-label="S3 Storage" back-title="Back to Integrations" :name="$storage->name"
|
||||
data-settings-search-items="{{ json_encode(settingsSearchItems(['S3 storage' => $settingsMenuItems], $storageRouteParameters)) }}">
|
||||
<nav aria-label="S3 storage settings"
|
||||
class="grid grid-cols-1 gap-0.5">
|
||||
|
||||
@@ -58,7 +58,7 @@ test('an application page teleports its menu into the main sidebar ', function (
|
||||
->toContain('x-teleport="#main-nav-context-0"')
|
||||
->toContain('application-settings-navigation in-main-nav')
|
||||
->toMatch('#<button type="button" @click="navLevel = -1; navSwap = \'back\'"\s+title="Back to the main menu"#')
|
||||
->not->toContain('Back to the Navbar Menu App menu')
|
||||
->toContain('Back to the Navbar Menu App menu')
|
||||
->not->toContain('id="main-nav-context-1"')
|
||||
->and(substr_count($html, 'id="main-nav-context-0"'))->toBe(1);
|
||||
});
|
||||
@@ -144,7 +144,7 @@ test('a database backup page keeps the database menu one back away in the main s
|
||||
->toContain('x-teleport="#main-nav-context-1"')
|
||||
->toMatch('#@click="navLevel = -1; navSwap = \'back\'"\s+title="Back to the main menu"#')
|
||||
->toMatch('#@click="navLevel = 0; navSwap = \'back\'"\s+title="Back to the database menu"#')
|
||||
->not->toContain('Back to the orders-db menu')
|
||||
->toContain('Back to the orders-db menu')
|
||||
->and(substr_count($html, 'aria-label="Database settings"'))->toBe(1)
|
||||
->and(substr_count($html, 'aria-label="Backup settings"'))->toBe(2);
|
||||
});
|
||||
Reference in new issue
Block a user