## Summary - enforce the canonical workspace/environment scope contract for workspace hubs and environment-owned surfaces - replace first-party Operations deep links that leaked Filament `tableFilters[...]` internals with stable product-level query behavior - add the sidebar scope indicator and split environment-page navigation into explicit `Workspace-wide` and `Workspace admin` groups - remove redundant tenantless `All environments` scope badges from workspace-wide pages while preserving explicit environment filter affordances - include the Spec 338 artifacts, guard tests, and browser smoke coverage for the new contract ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Navigation/Spec338EnvironmentSidebarSeparationTest.php tests/Feature/Navigation/Spec338OperationRunLinksQueryContractTest.php tests/Feature/Navigation/Spec338SidebarScopeIndicatorTest.php tests/Feature/Filament/PanelNavigationSegregationTest.php` - `cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec338ScopeContractSmokeTest.php --compact` ## Notes - Livewire v4 compliance unchanged - Filament provider registration remains in `bootstrap/providers.php` - no destructive action behavior changed - no migrations, env var changes, or new Filament asset registration Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #409
82 lines
2.4 KiB
PHP
82 lines
2.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Filament\Clusters\Monitoring;
|
|
|
|
use App\Models\Workspace;
|
|
use App\Support\Navigation\WorkspaceHubEnvironmentFilter;
|
|
use App\Support\Navigation\WorkspaceHubFilterStateResetter;
|
|
use App\Support\Navigation\WorkspaceHubNavigation;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use BackedEnum;
|
|
use Filament\Clusters\Cluster;
|
|
use Filament\Facades\Filament;
|
|
use Filament\Pages\Enums\SubNavigationPosition;
|
|
use UnitEnum;
|
|
|
|
class AlertsCluster extends Cluster
|
|
{
|
|
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-bell-alert';
|
|
|
|
protected static string|UnitEnum|null $navigationGroup = 'Monitoring';
|
|
|
|
protected static ?int $navigationSort = 20;
|
|
|
|
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Start;
|
|
|
|
public static function shouldRegisterNavigation(): bool
|
|
{
|
|
return Filament::getCurrentPanel()?->getId() === 'admin';
|
|
}
|
|
|
|
public static function getNavigationGroup(): string
|
|
{
|
|
return WorkspaceHubNavigation::workspaceWideGroup(__('localization.navigation.monitoring'));
|
|
}
|
|
|
|
public static function getNavigationUrl(): string
|
|
{
|
|
return WorkspaceHubNavigation::environmentFilteredUrl(parent::getNavigationUrl());
|
|
}
|
|
|
|
public function mount(): void
|
|
{
|
|
app(WorkspaceHubFilterStateResetter::class)->neutralizeEnvironmentLikeQueryState(request());
|
|
|
|
$environmentFilterQuery = $this->environmentFilterQuery();
|
|
|
|
foreach ($this->getCachedSubNavigation() as $navigationGroup) {
|
|
foreach ($navigationGroup->getItems() as $navigationItem) {
|
|
$url = $navigationItem->getUrl();
|
|
|
|
if (is_string($url) && $url !== '' && $environmentFilterQuery !== []) {
|
|
$url = url()->query($url, $environmentFilterQuery);
|
|
}
|
|
|
|
redirect($url);
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array<string, int>
|
|
*/
|
|
private function environmentFilterQuery(): array
|
|
{
|
|
$workspace = app(WorkspaceContext::class)->currentWorkspace(request());
|
|
|
|
if (! $workspace instanceof Workspace) {
|
|
return [];
|
|
}
|
|
|
|
$filter = WorkspaceHubEnvironmentFilter::fromRequest(request(), $workspace);
|
|
|
|
return $filter instanceof WorkspaceHubEnvironmentFilter
|
|
? $filter->queryParameters()
|
|
: [];
|
|
}
|
|
}
|