From 605fcbe61a828724735aae38553efa20ac39547e Mon Sep 17 00:00:00 2001 From: PalmarHealer Date: Fri, 31 Oct 2025 19:12:54 +0100 Subject: [PATCH] feat: Add mixed navigation type with admin-configurable defaults (#1850) --- app/Enums/CustomizationKey.php | 2 +- app/Filament/Admin/Pages/Settings.php | 9 +++++++++ app/Filament/Pages/Auth/EditProfile.php | 18 ++++++++++++------ app/Providers/Filament/PanelProvider.php | 12 ++++++++++-- config/panel.php | 1 + lang/en/admin/setting.php | 2 ++ lang/en/profile.php | 5 +++-- 7 files changed, 38 insertions(+), 11 deletions(-) diff --git a/app/Enums/CustomizationKey.php b/app/Enums/CustomizationKey.php index 16437edd1..c76aa8157 100644 --- a/app/Enums/CustomizationKey.php +++ b/app/Enums/CustomizationKey.php @@ -18,7 +18,7 @@ enum CustomizationKey: string self::ConsoleFont => 'monospace', self::ConsoleFontSize => 14, self::ConsoleGraphPeriod => 30, - self::TopNavigation => false, + self::TopNavigation => config('panel.filament.default-navigation', 'sidebar'), self::DashboardLayout => 'grid', }; } diff --git a/app/Filament/Admin/Pages/Settings.php b/app/Filament/Admin/Pages/Settings.php index 5bc42f0e9..bc9b0cf8a 100644 --- a/app/Filament/Admin/Pages/Settings.php +++ b/app/Filament/Admin/Pages/Settings.php @@ -203,6 +203,15 @@ class Settings extends Page implements HasSchemas ]) ->stateCast(new BooleanStateCast(false, true)) ->default(env('PANEL_USE_BINARY_PREFIX', config('panel.use_binary_prefix'))), + ToggleButtons::make('FILAMENT_DEFAULT_NAVIGATION') + ->label(trans('admin/setting.general.default_navigation')) + ->inline() + ->options([ + 'sidebar' => trans('admin/setting.general.sidebar'), + 'topbar' => trans('admin/setting.general.topbar'), + 'mixed' => trans('admin/setting.general.mixed'), + ]) + ->default(env('FILAMENT_DEFAULT_NAVIGATION', config('panel.filament.default-navigation'))), ToggleButtons::make('APP_2FA_REQUIRED') ->label(trans('admin/setting.general.2fa_requirement')) ->inline() diff --git a/app/Filament/Pages/Auth/EditProfile.php b/app/Filament/Pages/Auth/EditProfile.php index 487967123..e9a9fad87 100644 --- a/app/Filament/Pages/Auth/EditProfile.php +++ b/app/Filament/Pages/Auth/EditProfile.php @@ -34,7 +34,6 @@ use Filament\Schemas\Components\Actions; use Filament\Schemas\Components\Grid; use Filament\Schemas\Components\Group; use Filament\Schemas\Components\Section; -use Filament\Schemas\Components\StateCasts\BooleanStateCast; use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; use Filament\Schemas\Components\Utilities\Get; @@ -440,10 +439,10 @@ class EditProfile extends BaseEditProfile ->label(trans('profile.navigation')) ->inline() ->options([ - 1 => trans('profile.top'), - 0 => trans('profile.side'), - ]) - ->stateCast(new BooleanStateCast(false, true)), + 'sidebar' => trans('profile.sidebar'), + 'topbar' => trans('profile.topbar'), + 'mixed' => trans('profile.mixed'), + ]), ]), Section::make(trans('profile.console')) ->collapsible() @@ -583,7 +582,14 @@ class EditProfile extends BaseEditProfile $data['console_rows'] = (int) $this->getUser()->getCustomization(CustomizationKey::ConsoleRows); $data['console_graph_period'] = (int) $this->getUser()->getCustomization(CustomizationKey::ConsoleGraphPeriod); $data['dashboard_layout'] = $this->getUser()->getCustomization(CustomizationKey::DashboardLayout); - $data['top_navigation'] = (bool) $this->getUser()->getCustomization(CustomizationKey::TopNavigation); + + // Handle migration from boolean to string navigation types + $topNavigation = $this->getUser()->getCustomization(CustomizationKey::TopNavigation); + if (is_bool($topNavigation)) { + $data['top_navigation'] = $topNavigation ? 'topbar' : 'sidebar'; + } else { + $data['top_navigation'] = $topNavigation; + } return $data; } diff --git a/app/Providers/Filament/PanelProvider.php b/app/Providers/Filament/PanelProvider.php index 165364b8b..cdb0dde42 100644 --- a/app/Providers/Filament/PanelProvider.php +++ b/app/Providers/Filament/PanelProvider.php @@ -34,8 +34,16 @@ abstract class PanelProvider extends BasePanelProvider ->brandLogo(config('app.logo')) ->brandLogoHeight('2rem') ->favicon(config('app.favicon', '/pelican.ico')) - ->topNavigation(fn () => user()?->getCustomization(CustomizationKey::TopNavigation)) - ->topbar(fn () => user()?->getCustomization(CustomizationKey::TopNavigation)) + ->topNavigation(function () { + $navigationType = user()?->getCustomization(CustomizationKey::TopNavigation); + + return $navigationType === 'topbar' || $navigationType === true; + }) + ->topbar(function () { + $navigationType = user()?->getCustomization(CustomizationKey::TopNavigation); + + return $navigationType === 'topbar' || $navigationType === 'mixed' || $navigationType === true; + }) ->maxContentWidth(config('panel.filament.display-width', 'screen-2xl')) ->profile(EditProfile::class, false) ->userMenuItems([ diff --git a/config/panel.php b/config/panel.php index ddb6aed2c..70a0c2952 100644 --- a/config/panel.php +++ b/config/panel.php @@ -53,6 +53,7 @@ return [ 'display-width' => env('FILAMENT_WIDTH', 'screen-2xl'), 'avatar-provider' => env('FILAMENT_AVATAR_PROVIDER', 'gravatar'), 'uploadable-avatars' => env('FILAMENT_UPLOADABLE_AVATARS', false), + 'default-navigation' => env('FILAMENT_DEFAULT_NAVIGATION', 'sidebar'), ], 'use_binary_prefix' => env('PANEL_USE_BINARY_PREFIX', true), diff --git a/lang/en/admin/setting.php b/lang/en/admin/setting.php index ca4598b03..963143c10 100644 --- a/lang/en/admin/setting.php +++ b/lang/en/admin/setting.php @@ -20,8 +20,10 @@ return [ 'app_favicon_help' => 'Favicon should be placed in the public folder located in the root panel directory.', 'debug_mode' => 'Debug Mode', 'navigation' => 'Navigation', + 'default_navigation' => 'Default Navigation Type', 'sidebar' => 'Sidebar', 'topbar' => 'Topbar', + 'mixed' => 'Mixed', 'unit_prefix' => 'Unit Prefix', 'decimal_prefix' => 'Decimal Prefix (MB/GB)', 'binary_prefix' => 'Binary Prefix (MiB/GiB)', diff --git a/lang/en/profile.php b/lang/en/profile.php index 04d8bb7aa..f6a6095c1 100644 --- a/lang/en/profile.php +++ b/lang/en/profile.php @@ -61,8 +61,9 @@ return [ 'graph_period' => 'Graph Period', 'graph_period_helper' => 'The amount of data points, seconds, shown on the console graphs.', 'navigation' => 'Navigation Type', - 'top' => 'Topbar', - 'side' => 'Sidebar', + 'sidebar' => 'Sidebar', + 'topbar' => 'Topbar', + 'mixed' => 'Mixed', 'no_oauth' => 'No Accounts Linked', 'no_api_keys' => 'No API Keys', 'no_ssh_keys' => 'No SSH Keys',