feat: clean up legacy tenant environment context
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m43s
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m43s
This commit is contained in:
parent
9b097f97f9
commit
c3c4f9aaf1
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Concerns;
|
||||
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
trait CleansAdminTenantQueryParameter
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $parameters
|
||||
*/
|
||||
public static function getUrl(array $parameters = [], bool $isAbsolute = true, ?string $panel = null, ?Model $tenant = null): string
|
||||
{
|
||||
$panelId = $panel ?? Filament::getCurrentOrDefaultPanel()?->getId() ?? 'admin';
|
||||
|
||||
if ($panelId === 'admin') {
|
||||
unset($parameters['tenant']);
|
||||
|
||||
return parent::getUrl($parameters, $isAbsolute, $panelId, null);
|
||||
}
|
||||
|
||||
return parent::getUrl($parameters, $isAbsolute, $panelId, $tenant);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Concerns;
|
||||
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
trait CleansAdminTenantResourceQueryParameter
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $parameters
|
||||
*/
|
||||
public static function getUrl(?string $name = null, array $parameters = [], bool $isAbsolute = true, ?string $panel = null, ?Model $tenant = null, bool $shouldGuessMissingParameters = false): string
|
||||
{
|
||||
$panelId = $panel ?? Filament::getCurrentOrDefaultPanel()?->getId() ?? 'admin';
|
||||
|
||||
if ($panelId === 'admin') {
|
||||
unset($parameters['tenant']);
|
||||
|
||||
return parent::getUrl($name, $parameters, $isAbsolute, $panelId, null, $shouldGuessMissingParameters);
|
||||
}
|
||||
|
||||
return parent::getUrl($name, $parameters, $isAbsolute, $panelId, $tenant, $shouldGuessMissingParameters);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Concerns;
|
||||
|
||||
use App\Models\ManagedEnvironment;
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
trait UsesAdminEnvironmentFilterQueryParameter
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $parameters
|
||||
*/
|
||||
public static function getUrl(array $parameters = [], bool $isAbsolute = true, ?string $panel = null, ?Model $tenant = null): string
|
||||
{
|
||||
$panelId = $panel ?? Filament::getCurrentOrDefaultPanel()?->getId() ?? 'admin';
|
||||
|
||||
if ($panelId !== 'admin') {
|
||||
return parent::getUrl($parameters, $isAbsolute, $panelId, $tenant);
|
||||
}
|
||||
|
||||
$environment = $tenant instanceof ManagedEnvironment ? $tenant : null;
|
||||
$parameterTenant = $parameters['tenant'] ?? null;
|
||||
|
||||
if (! $environment instanceof ManagedEnvironment && $parameterTenant instanceof ManagedEnvironment) {
|
||||
$environment = $parameterTenant;
|
||||
}
|
||||
|
||||
unset($parameters['tenant']);
|
||||
|
||||
$url = parent::getUrl($parameters, $isAbsolute, $panelId, null);
|
||||
|
||||
return $environment instanceof ManagedEnvironment
|
||||
? static::withEnvironmentId($url, $environment)
|
||||
: $url;
|
||||
}
|
||||
|
||||
private static function withEnvironmentId(string $url, ManagedEnvironment $environment): string
|
||||
{
|
||||
$parts = parse_url($url);
|
||||
|
||||
if (! is_array($parts)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$query = [];
|
||||
parse_str((string) ($parts['query'] ?? ''), $query);
|
||||
$query['environment_id'] = (int) $environment->getKey();
|
||||
unset($query['tenant'], $query['tenant_id'], $query['managed_environment_id'], $query['tenant_scope'], $query['environment']);
|
||||
|
||||
$parts['query'] = http_build_query($query, '', '&', PHP_QUERY_RFC3986);
|
||||
|
||||
$rebuilt = '';
|
||||
|
||||
if (isset($parts['scheme'])) {
|
||||
$rebuilt .= $parts['scheme'].'://';
|
||||
}
|
||||
|
||||
if (isset($parts['host'])) {
|
||||
$rebuilt .= $parts['host'];
|
||||
}
|
||||
|
||||
if (isset($parts['port'])) {
|
||||
$rebuilt .= ':'.$parts['port'];
|
||||
}
|
||||
|
||||
$rebuilt .= $parts['path'] ?? '';
|
||||
|
||||
if (($parts['query'] ?? '') !== '') {
|
||||
$rebuilt .= '?'.$parts['query'];
|
||||
}
|
||||
|
||||
if (isset($parts['fragment'])) {
|
||||
$rebuilt .= '#'.$parts['fragment'];
|
||||
}
|
||||
|
||||
return $rebuilt;
|
||||
}
|
||||
}
|
||||
@ -10,7 +10,7 @@
|
||||
use Filament\Panel;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
trait WorkspaceScopedTenantRoutes
|
||||
trait WorkspaceScopedEnvironmentRoutes
|
||||
{
|
||||
public static function getSlug(?Panel $panel = null): string
|
||||
{
|
||||
@ -28,7 +28,7 @@ public static function getUrl(?string $name = null, array $parameters = [], bool
|
||||
return parent::getUrl($name, $parameters, $isAbsolute, $panelId, $tenant, $shouldGuessMissingParameters);
|
||||
}
|
||||
|
||||
$resolvedTenant = static::resolveWorkspaceScopedTenant($parameters, $tenant);
|
||||
$resolvedTenant = static::resolveWorkspaceScopedEnvironment($parameters, $tenant);
|
||||
|
||||
if (! $resolvedTenant instanceof ManagedEnvironment) {
|
||||
return url('/admin');
|
||||
@ -49,7 +49,7 @@ public static function getUrl(?string $name = null, array $parameters = [], bool
|
||||
|
||||
protected static function workspaceScopedSlug(string $slug, ?Panel $panel = null): string
|
||||
{
|
||||
if (! static::shouldUseWorkspaceScopedTenantRoutes($panel)) {
|
||||
if (! static::shouldUseWorkspaceScopedEnvironmentRoutes($panel)) {
|
||||
return $slug;
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ protected static function workspaceScopedSlug(string $slug, ?Panel $panel = null
|
||||
: $prefix.ltrim($slug, '/');
|
||||
}
|
||||
|
||||
protected static function shouldUseWorkspaceScopedTenantRoutes(?Panel $panel = null): bool
|
||||
protected static function shouldUseWorkspaceScopedEnvironmentRoutes(?Panel $panel = null): bool
|
||||
{
|
||||
$panelId = $panel?->getId() ?? Filament::getCurrentOrDefaultPanel()?->getId() ?? 'admin';
|
||||
|
||||
@ -70,7 +70,7 @@ protected static function shouldUseWorkspaceScopedTenantRoutes(?Panel $panel = n
|
||||
/**
|
||||
* @param array<string, mixed> $parameters
|
||||
*/
|
||||
protected static function resolveWorkspaceScopedTenant(array $parameters, ?Model $tenant = null): ?ManagedEnvironment
|
||||
protected static function resolveWorkspaceScopedEnvironment(array $parameters, ?Model $tenant = null): ?ManagedEnvironment
|
||||
{
|
||||
$parameterTenant = $parameters['tenant'] ?? $parameters['environment'] ?? null;
|
||||
|
||||
@ -85,7 +85,7 @@ protected static function resolveWorkspaceScopedTenant(array $parameters, ?Model
|
||||
$record = $parameters['record'] ?? null;
|
||||
|
||||
if ($record instanceof Model) {
|
||||
$relationshipName = static::workspaceScopedTenantRelationshipName();
|
||||
$relationshipName = static::workspaceScopedEnvironmentRelationshipName();
|
||||
|
||||
if (method_exists($record, $relationshipName)) {
|
||||
$recordTenant = $record->getRelationValue($relationshipName);
|
||||
@ -139,7 +139,7 @@ protected static function resolveWorkspaceScopedWorkspace(ManagedEnvironment $te
|
||||
return $tenant->workspace()->first();
|
||||
}
|
||||
|
||||
protected static function workspaceScopedTenantRelationshipName(): string
|
||||
protected static function workspaceScopedEnvironmentRelationshipName(): string
|
||||
{
|
||||
$relationshipName = property_exists(static::class, 'tenantOwnershipRelationshipName')
|
||||
? static::$tenantOwnershipRelationshipName
|
||||
@ -5,11 +5,12 @@
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\UsesAdminEnvironmentFilterQueryParameter;
|
||||
use App\Filament\Resources\BaselineProfileResource;
|
||||
use App\Filament\Resources\FindingResource;
|
||||
use App\Models\BaselineProfile;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\User;
|
||||
use App\Services\Auth\CapabilityResolver;
|
||||
use App\Services\Baselines\BaselineCompareService;
|
||||
@ -17,16 +18,16 @@
|
||||
use App\Support\Baselines\BaselineCaptureMode;
|
||||
use App\Support\Baselines\BaselineCompareEvidenceGapDetails;
|
||||
use App\Support\Baselines\BaselineCompareStats;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
use App\Support\Baselines\TenantGovernanceAggregate;
|
||||
use App\Support\Baselines\TenantGovernanceAggregateResolver;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OperationRunType;
|
||||
use App\Support\OpsUx\OperationUxPresenter;
|
||||
use App\Support\OpsUx\OpsUxBrowserEvents;
|
||||
use App\Support\ReasonTranslation\ReasonPresenter;
|
||||
use App\Support\Rbac\UiEnforcement;
|
||||
use App\Support\ReasonTranslation\ReasonPresenter;
|
||||
use App\Support\Ui\ActionSurface\ActionSurfaceDeclaration;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot;
|
||||
@ -39,6 +40,7 @@
|
||||
class BaselineCompareLanding extends Page
|
||||
{
|
||||
use ResolvesPanelTenantContext;
|
||||
use UsesAdminEnvironmentFilterQueryParameter;
|
||||
|
||||
protected const MONITORING_PAGE_STATE_CONTRACT = [
|
||||
'surfaceKey' => 'baseline_compare_landing',
|
||||
|
||||
@ -126,7 +126,7 @@ public function selectEnvironment(int $tenantId): void
|
||||
|
||||
$this->persistLastTenant($user, $tenant);
|
||||
|
||||
if (! $workspaceContext->rememberTenantContext($tenant, request())) {
|
||||
if (! $workspaceContext->rememberEnvironmentContext($tenant, request())) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
use App\Models\Workspace;
|
||||
use App\Services\Auth\WorkspaceCapabilityResolver;
|
||||
use App\Services\Findings\FindingAssignmentHygieneService;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\Filament\TablePaginationProfiles;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
use App\Support\OperateHub\OperateHubShell;
|
||||
@ -78,7 +78,7 @@ public function mount(): void
|
||||
$this->reasonFilter = $this->resolveRequestedReasonFilter();
|
||||
$this->authorizePageAccess();
|
||||
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
[],
|
||||
request(),
|
||||
@ -486,14 +486,14 @@ private function filteredTenant(): ?ManagedEnvironment
|
||||
|
||||
private function activeVisibleTenant(): ?ManagedEnvironment
|
||||
{
|
||||
$activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
$activeEnvironment = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
|
||||
if (! $activeTenant instanceof ManagedEnvironment) {
|
||||
if (! $activeEnvironment instanceof ManagedEnvironment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->visibleTenants() as $tenant) {
|
||||
if ($tenant->is($activeTenant)) {
|
||||
if ($tenant->is($activeEnvironment)) {
|
||||
return $tenant;
|
||||
}
|
||||
}
|
||||
@ -509,9 +509,9 @@ private function tenantPrefilterSource(): string
|
||||
return 'none';
|
||||
}
|
||||
|
||||
$activeTenant = $this->activeVisibleTenant();
|
||||
$activeEnvironment = $this->activeVisibleTenant();
|
||||
|
||||
if ($activeTenant instanceof ManagedEnvironment && $activeTenant->is($tenant)) {
|
||||
if ($activeEnvironment instanceof ManagedEnvironment && $activeEnvironment->is($tenant)) {
|
||||
return 'active_tenant_context';
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\Filament\TablePaginationProfiles;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
use App\Support\OperateHub\OperateHubShell;
|
||||
@ -92,7 +92,7 @@ public function mount(): void
|
||||
$this->queueView = $this->resolveRequestedQueueView();
|
||||
$this->authorizePageAccess();
|
||||
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
[],
|
||||
request(),
|
||||
@ -494,12 +494,12 @@ private function filteredQueueQuery(
|
||||
|
||||
return $query
|
||||
->orderByRaw(
|
||||
"case
|
||||
'case
|
||||
when due_at is not null and due_at < ? then 0
|
||||
when status = ? then 1
|
||||
when status = ? then 2
|
||||
else 3
|
||||
end asc",
|
||||
end asc',
|
||||
[now(), Finding::STATUS_REOPENED, Finding::STATUS_NEW],
|
||||
)
|
||||
->orderByRaw('case when due_at is null then 1 else 0 end asc')
|
||||
@ -605,14 +605,14 @@ private function filteredTenant(): ?ManagedEnvironment
|
||||
|
||||
private function activeVisibleTenant(): ?ManagedEnvironment
|
||||
{
|
||||
$activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
$activeEnvironment = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
|
||||
if (! $activeTenant instanceof ManagedEnvironment) {
|
||||
if (! $activeEnvironment instanceof ManagedEnvironment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->visibleTenants() as $tenant) {
|
||||
if ($tenant->is($activeTenant)) {
|
||||
if ($tenant->is($activeEnvironment)) {
|
||||
return $tenant;
|
||||
}
|
||||
}
|
||||
@ -628,9 +628,9 @@ private function tenantPrefilterSource(): string
|
||||
return 'none';
|
||||
}
|
||||
|
||||
$activeTenant = $this->activeVisibleTenant();
|
||||
$activeEnvironment = $this->activeVisibleTenant();
|
||||
|
||||
if ($activeTenant instanceof ManagedEnvironment && $activeTenant->is($tenant)) {
|
||||
if ($activeEnvironment instanceof ManagedEnvironment && $activeEnvironment->is($tenant)) {
|
||||
return 'active_tenant_context';
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\Filament\TablePaginationProfiles;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
use App\Support\OperateHub\OperateHubShell;
|
||||
@ -84,7 +84,7 @@ public function mount(): void
|
||||
{
|
||||
$this->authorizePageAccess();
|
||||
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
['overdue', 'reopened', 'high_severity'],
|
||||
request(),
|
||||
@ -270,9 +270,9 @@ public function emptyState(): array
|
||||
];
|
||||
}
|
||||
|
||||
$activeTenant = $this->activeVisibleTenant();
|
||||
$activeEnvironment = $this->activeVisibleTenant();
|
||||
|
||||
if ($activeTenant instanceof ManagedEnvironment) {
|
||||
if ($activeEnvironment instanceof ManagedEnvironment) {
|
||||
return [
|
||||
'title' => 'No visible assigned findings right now',
|
||||
'body' => 'Nothing currently assigned to you needs attention in the visible environment scope. You can still open environment findings for broader context.',
|
||||
@ -280,7 +280,7 @@ public function emptyState(): array
|
||||
'action_name' => 'open_tenant_findings_empty',
|
||||
'action_label' => 'Open environment findings',
|
||||
'action_kind' => 'url',
|
||||
'action_url' => FindingResource::getUrl('index', tenant: $activeTenant),
|
||||
'action_url' => FindingResource::getUrl('index', tenant: $activeEnvironment),
|
||||
];
|
||||
}
|
||||
|
||||
@ -561,14 +561,14 @@ private function filteredTenant(): ?ManagedEnvironment
|
||||
|
||||
private function activeVisibleTenant(): ?ManagedEnvironment
|
||||
{
|
||||
$activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
$activeEnvironment = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
|
||||
if (! $activeTenant instanceof ManagedEnvironment) {
|
||||
if (! $activeEnvironment instanceof ManagedEnvironment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->visibleTenants() as $tenant) {
|
||||
if ($tenant->is($activeTenant)) {
|
||||
if ($tenant->is($activeEnvironment)) {
|
||||
return $tenant;
|
||||
}
|
||||
}
|
||||
@ -584,9 +584,9 @@ private function tenantPrefilterSource(): string
|
||||
return 'none';
|
||||
}
|
||||
|
||||
$activeTenant = $this->activeVisibleTenant();
|
||||
$activeEnvironment = $this->activeVisibleTenant();
|
||||
|
||||
if ($activeTenant instanceof ManagedEnvironment && $activeTenant->is($tenant)) {
|
||||
if ($activeEnvironment instanceof ManagedEnvironment && $activeEnvironment->is($tenant)) {
|
||||
return 'active_tenant_context';
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
namespace App\Filament\Pages\Governance;
|
||||
|
||||
use App\Filament\Concerns\CleansAdminTenantQueryParameter;
|
||||
use App\Filament\Concerns\ClearsWorkspaceHubEnvironmentFilterState;
|
||||
use App\Filament\Resources\FindingExceptionResource;
|
||||
use App\Models\FindingException;
|
||||
@ -40,6 +41,7 @@
|
||||
|
||||
class DecisionRegister extends Page implements HasTable
|
||||
{
|
||||
use CleansAdminTenantQueryParameter;
|
||||
use ClearsWorkspaceHubEnvironmentFilterState;
|
||||
use InteractsWithTable;
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
namespace App\Filament\Pages\Governance;
|
||||
|
||||
use App\Filament\Concerns\CleansAdminTenantQueryParameter;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
@ -29,6 +30,8 @@
|
||||
|
||||
class GovernanceInbox extends Page
|
||||
{
|
||||
use CleansAdminTenantQueryParameter;
|
||||
|
||||
protected static bool $isDiscovered = false;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-inbox-stack';
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
namespace App\Filament\Pages\Monitoring;
|
||||
|
||||
use App\Models\AuditLog as AuditLogModel;
|
||||
use App\Models\SupportAccessGrant;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\SupportAccessGrant;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
use App\Services\Auth\WorkspaceCapabilityResolver;
|
||||
@ -14,7 +14,7 @@
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\Filament\FilterOptionCatalog;
|
||||
use App\Support\Filament\FilterPresets;
|
||||
use App\Support\Filament\TablePaginationProfiles;
|
||||
@ -164,7 +164,7 @@ public function mount(): void
|
||||
$this->supportAccessOnly = request()->boolean('supportAccess');
|
||||
$requestedEventId = is_numeric(request()->query('event')) ? (int) request()->query('event') : null;
|
||||
|
||||
app(CanonicalAdminTenantFilterState::class)->sync($this->getTableFiltersSessionKey(), request: request());
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync($this->getTableFiltersSessionKey(), request: request());
|
||||
|
||||
$this->mountInteractsWithTable();
|
||||
|
||||
@ -616,14 +616,14 @@ private function tenantFilterOptions(): array
|
||||
|
||||
private function defaultTenantFilter(): ?string
|
||||
{
|
||||
$activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
$activeEnvironment = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
|
||||
if (! $activeTenant instanceof ManagedEnvironment) {
|
||||
if (! $activeEnvironment instanceof ManagedEnvironment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return array_key_exists((int) $activeTenant->getKey(), $this->authorizedTenants())
|
||||
? (string) $activeTenant->getKey()
|
||||
return array_key_exists((int) $activeEnvironment->getKey(), $this->authorizedTenants())
|
||||
? (string) $activeEnvironment->getKey()
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
namespace App\Filament\Pages\Monitoring;
|
||||
|
||||
use App\Filament\Concerns\CleansAdminTenantQueryParameter;
|
||||
use App\Filament\Concerns\ClearsWorkspaceHubEnvironmentFilterState;
|
||||
use App\Filament\Resources\FindingExceptionResource;
|
||||
use App\Filament\Resources\FindingResource;
|
||||
@ -17,7 +18,7 @@
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\Filament\FilterOptionCatalog;
|
||||
use App\Support\Filament\TablePaginationProfiles;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
@ -52,6 +53,7 @@
|
||||
|
||||
class FindingExceptionsQueue extends Page implements HasTable
|
||||
{
|
||||
use CleansAdminTenantQueryParameter;
|
||||
use ClearsWorkspaceHubEnvironmentFilterState;
|
||||
use InteractsWithTable;
|
||||
|
||||
@ -653,7 +655,7 @@ private function filteredTenant(): ?ManagedEnvironment
|
||||
|
||||
private function currentTenantFilterId(): ?int
|
||||
{
|
||||
$tenantFilter = app(CanonicalAdminTenantFilterState::class)->currentFilterValue(
|
||||
$tenantFilter = app(CanonicalAdminEnvironmentFilterState::class)->currentFilterValue(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
$this->tableFilters ?? [],
|
||||
request(),
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
use App\Models\Workspace;
|
||||
use App\Services\Auth\ManagedEnvironmentAccessScopeResolver;
|
||||
use App\Services\Auth\WorkspaceCapabilityResolver;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\ManagedEnvironmentLinks;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
use App\Support\Navigation\WorkspaceHubEnvironmentFilter;
|
||||
@ -231,7 +231,7 @@ protected function getHeaderActions(): array
|
||||
->disabled(),
|
||||
];
|
||||
|
||||
$activeTenant = $this->currentTenantFilterId() === null
|
||||
$activeEnvironment = $this->currentTenantFilterId() === null
|
||||
? $operateHubShell->activeEntitledTenant(request())
|
||||
: null;
|
||||
|
||||
@ -241,22 +241,22 @@ protected function getHeaderActions(): array
|
||||
->icon('heroicon-o-arrow-left')
|
||||
->color('gray')
|
||||
->url($navigationContext->backLinkUrl);
|
||||
} elseif ($activeTenant instanceof ManagedEnvironment) {
|
||||
} elseif ($activeEnvironment instanceof ManagedEnvironment) {
|
||||
$actions[] = Action::make('operate_hub_back_to_tenant_operations')
|
||||
->label('Back to '.$activeTenant->name)
|
||||
->label('Back to '.$activeEnvironment->name)
|
||||
->icon('heroicon-o-arrow-left')
|
||||
->color('gray')
|
||||
->url(ManagedEnvironmentLinks::viewUrl($activeTenant));
|
||||
->url(ManagedEnvironmentLinks::viewUrl($activeEnvironment));
|
||||
}
|
||||
|
||||
if ($activeTenant instanceof ManagedEnvironment) {
|
||||
if ($activeEnvironment instanceof ManagedEnvironment) {
|
||||
$actions[] = Action::make('operate_hub_show_all_tenants')
|
||||
->label(__('localization.shell.show_all_environments'))
|
||||
->color('gray')
|
||||
->action(function (): void {
|
||||
Filament::setTenant(null, true);
|
||||
|
||||
app(WorkspaceContext::class)->clearLastTenantId(request());
|
||||
app(WorkspaceContext::class)->clearLastEnvironmentId(request());
|
||||
|
||||
$this->removeTableFilter('managed_environment_id');
|
||||
|
||||
@ -283,7 +283,7 @@ public function landingHierarchySummary(): array
|
||||
$operateHubShell = app(OperateHubShell::class);
|
||||
$navigationContext = $this->navigationContext();
|
||||
$filteredTenant = $this->filteredTenant();
|
||||
$activeTenant = $filteredTenant instanceof ManagedEnvironment
|
||||
$activeEnvironment = $filteredTenant instanceof ManagedEnvironment
|
||||
? null
|
||||
: $operateHubShell->activeEntitledTenant(request());
|
||||
|
||||
@ -293,8 +293,8 @@ public function landingHierarchySummary(): array
|
||||
if ($navigationContext?->backLinkLabel !== null && $navigationContext->backLinkUrl !== null) {
|
||||
$returnLabel = $navigationContext->backLinkLabel;
|
||||
$returnBody = 'Return to the originating monitoring surface without competing with the current tab, filters, or row inspection flow.';
|
||||
} elseif ($activeTenant instanceof ManagedEnvironment) {
|
||||
$returnLabel = 'Back to '.$activeTenant->name;
|
||||
} elseif ($activeEnvironment instanceof ManagedEnvironment) {
|
||||
$returnLabel = 'Back to '.$activeEnvironment->name;
|
||||
$returnBody = 'Return to the tenant dashboard when you need tenant-specific context outside this workspace monitoring landing.';
|
||||
}
|
||||
|
||||
@ -302,13 +302,13 @@ public function landingHierarchySummary(): array
|
||||
'scope_label' => $operateHubShell->scopeLabel(request()),
|
||||
'scope_body' => $filteredTenant instanceof ManagedEnvironment
|
||||
? 'The landing is workspace-scoped and filtered by an explicit environment filter.'
|
||||
: ($activeTenant instanceof ManagedEnvironment
|
||||
: ($activeEnvironment instanceof ManagedEnvironment
|
||||
? 'The landing is currently narrowed to one environment inside the active workspace.'
|
||||
: 'The landing is currently showing workspace-wide monitoring across all entitled environments.'),
|
||||
'return_label' => $returnLabel,
|
||||
'return_body' => $returnBody,
|
||||
'scope_reset_label' => $activeTenant instanceof ManagedEnvironment ? __('localization.shell.show_all_environments') : null,
|
||||
'scope_reset_body' => $activeTenant instanceof ManagedEnvironment
|
||||
'scope_reset_label' => $activeEnvironment instanceof ManagedEnvironment ? __('localization.shell.show_all_environments') : null,
|
||||
'scope_reset_body' => $activeEnvironment instanceof ManagedEnvironment
|
||||
? 'Reset the landing back to workspace-wide monitoring when environment-specific context is no longer needed.'
|
||||
: null,
|
||||
'inspect_body' => 'Open a run from the table to enter the canonical monitoring detail viewer.',
|
||||
@ -534,7 +534,7 @@ private function operationsUrl(array $overrides = []): string
|
||||
|
||||
private function currentTenantFilterId(): ?int
|
||||
{
|
||||
$tenantFilter = app(CanonicalAdminTenantFilterState::class)->currentFilterValue(
|
||||
$tenantFilter = app(CanonicalAdminEnvironmentFilterState::class)->currentFilterValue(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
$this->tableFilters ?? [],
|
||||
request(),
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
namespace App\Filament\Pages\Operations;
|
||||
|
||||
use App\Filament\Resources\OperationRunResource;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\SupportRequest;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\User;
|
||||
use App\Services\Audit\WorkspaceAuditLogger;
|
||||
use App\Services\Auth\CapabilityResolver;
|
||||
@ -27,10 +27,10 @@
|
||||
use App\Support\OpsUx\RunDetailPolling;
|
||||
use App\Support\ProductTelemetry\ProductTelemetryRecorder;
|
||||
use App\Support\ProductTelemetry\ProductUsageEventCatalog;
|
||||
use App\Support\Rbac\UiEnforcement;
|
||||
use App\Support\ReasonTranslation\ReasonPresenter;
|
||||
use App\Support\RedactionIntegrity;
|
||||
use App\Support\RestoreSafety\RestoreSafetyCopy;
|
||||
use App\Support\Rbac\UiEnforcement;
|
||||
use App\Support\SupportDiagnostics\SupportDiagnosticBundleBuilder;
|
||||
use App\Support\SupportRequests\ExternalSupportDeskHandoffService;
|
||||
use App\Support\SupportRequests\SupportRequestSubmissionService;
|
||||
@ -46,15 +46,15 @@
|
||||
use Filament\Actions\ActionGroup;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Schemas\Components\EmbeddedSchema;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Schema;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
@ -108,7 +108,7 @@ protected function getHeaderActions(): array
|
||||
{
|
||||
$operateHubShell = app(OperateHubShell::class);
|
||||
$navigationContext = $this->navigationContext();
|
||||
$activeTenant = $operateHubShell->activeEntitledTenant(request());
|
||||
$activeEnvironment = $operateHubShell->activeEntitledTenant(request());
|
||||
$runTenantId = isset($this->run) ? (int) ($this->run->managed_environment_id ?? 0) : 0;
|
||||
|
||||
$actions = [
|
||||
@ -123,11 +123,11 @@ protected function getHeaderActions(): array
|
||||
->label($navigationContext->backLinkLabel)
|
||||
->color('gray')
|
||||
->url($navigationContext->backLinkUrl);
|
||||
} elseif ($activeTenant instanceof ManagedEnvironment && (int) $activeTenant->getKey() === $runTenantId) {
|
||||
} elseif ($activeEnvironment instanceof ManagedEnvironment && (int) $activeEnvironment->getKey() === $runTenantId) {
|
||||
$actions[] = Action::make('operate_hub_back_to_tenant_run_detail')
|
||||
->label('← Back to '.$activeTenant->name)
|
||||
->label('← Back to '.$activeEnvironment->name)
|
||||
->color('gray')
|
||||
->url(ManagedEnvironmentLinks::viewUrl($activeTenant));
|
||||
->url(ManagedEnvironmentLinks::viewUrl($activeEnvironment));
|
||||
} else {
|
||||
$actions[] = Action::make('operate_hub_back_to_operations')
|
||||
->label('Back to Operations')
|
||||
@ -135,7 +135,7 @@ protected function getHeaderActions(): array
|
||||
->url(fn (): string => OperationRunLinks::index());
|
||||
}
|
||||
|
||||
if ($activeTenant instanceof ManagedEnvironment) {
|
||||
if ($activeEnvironment instanceof ManagedEnvironment) {
|
||||
$actions[] = Action::make('operate_hub_show_all_operations')
|
||||
->label('Show all operations')
|
||||
->color('gray')
|
||||
@ -201,7 +201,7 @@ public function monitoringDetailSummary(): array
|
||||
{
|
||||
$operateHubShell = app(OperateHubShell::class);
|
||||
$navigationContext = $this->navigationContext();
|
||||
$activeTenant = $operateHubShell->activeEntitledTenant(request());
|
||||
$activeEnvironment = $operateHubShell->activeEntitledTenant(request());
|
||||
$runTenantId = isset($this->run) ? (int) ($this->run->managed_environment_id ?? 0) : 0;
|
||||
|
||||
$navigationLabel = 'Back to Operations';
|
||||
@ -210,8 +210,8 @@ public function monitoringDetailSummary(): array
|
||||
if ($navigationContext?->backLinkLabel !== null && $navigationContext->backLinkUrl !== null) {
|
||||
$navigationLabel = $navigationContext->backLinkLabel;
|
||||
$navigationBody = 'Return to the originating surface while keeping refresh and follow-up work separate from navigation.';
|
||||
} elseif ($activeTenant instanceof ManagedEnvironment && (int) $activeTenant->getKey() === $runTenantId) {
|
||||
$navigationLabel = 'Back to '.$activeTenant->name;
|
||||
} elseif ($activeEnvironment instanceof ManagedEnvironment && (int) $activeEnvironment->getKey() === $runTenantId) {
|
||||
$navigationLabel = 'Back to '.$activeEnvironment->name;
|
||||
$navigationBody = 'Return to the active tenant dashboard, then widen back to the workspace view only when you need broader monitoring context.';
|
||||
}
|
||||
|
||||
@ -727,15 +727,15 @@ public function canonicalContextBanner(): ?array
|
||||
return null;
|
||||
}
|
||||
|
||||
$activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
$activeEnvironment = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
$runTenant = $this->run->tenant;
|
||||
|
||||
if (! $runTenant instanceof ManagedEnvironment) {
|
||||
return [
|
||||
'tone' => 'slate',
|
||||
'title' => 'Workspace-level operation',
|
||||
'body' => $activeTenant instanceof ManagedEnvironment
|
||||
? 'This canonical workspace view is not tied to the current environment context ('.$activeTenant->name.').'
|
||||
'body' => $activeEnvironment instanceof ManagedEnvironment
|
||||
? 'This canonical workspace view is not tied to the current environment context ('.$activeEnvironment->name.').'
|
||||
: 'This canonical workspace view is not tied to any environment.',
|
||||
];
|
||||
}
|
||||
@ -744,9 +744,9 @@ public function canonicalContextBanner(): ?array
|
||||
$tone = 'sky';
|
||||
$title = null;
|
||||
|
||||
if ($activeTenant instanceof ManagedEnvironment && ! $activeTenant->is($runTenant)) {
|
||||
if ($activeEnvironment instanceof ManagedEnvironment && ! $activeEnvironment->is($runTenant)) {
|
||||
$title = 'Current environment context differs from this operation';
|
||||
array_unshift($messages, 'Current environment context: '.$activeTenant->name.'.');
|
||||
array_unshift($messages, 'Current environment context: '.$activeEnvironment->name.'.');
|
||||
$messages[] = 'This canonical workspace view remains valid without switching environment context.';
|
||||
}
|
||||
|
||||
@ -760,7 +760,7 @@ public function canonicalContextBanner(): ?array
|
||||
if ($referencedTenant->contextNote !== null) {
|
||||
$messages[] = $referencedTenant->contextNote;
|
||||
}
|
||||
} elseif (! $activeTenant instanceof ManagedEnvironment) {
|
||||
} elseif (! $activeEnvironment instanceof ManagedEnvironment) {
|
||||
$title ??= 'Canonical workspace view';
|
||||
$messages[] = 'No environment context is currently selected.';
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
namespace App\Filament\Pages\Reviews;
|
||||
|
||||
use App\Filament\Concerns\CleansAdminTenantQueryParameter;
|
||||
use App\Filament\Concerns\ClearsWorkspaceHubEnvironmentFilterState;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\EnvironmentReview;
|
||||
@ -50,6 +51,7 @@
|
||||
|
||||
class CustomerReviewWorkspace extends Page implements HasTable
|
||||
{
|
||||
use CleansAdminTenantQueryParameter;
|
||||
use ClearsWorkspaceHubEnvironmentFilterState;
|
||||
use InteractsWithTable;
|
||||
|
||||
@ -99,7 +101,7 @@ public function getTitle(): string
|
||||
return __('localization.review.customer_review_workspace');
|
||||
}
|
||||
|
||||
public static function tenantPrefilterUrl(ManagedEnvironment $tenant): string
|
||||
public static function environmentFilterUrl(ManagedEnvironment $tenant): string
|
||||
{
|
||||
return static::getUrl(panel: 'admin').'?'.http_build_query([
|
||||
'environment_id' => (int) $tenant->getKey(),
|
||||
@ -573,7 +575,7 @@ private function latestReviewUrl(ManagedEnvironment $tenant): ?string
|
||||
static fn (mixed $value): bool => $value !== null && $value !== '',
|
||||
);
|
||||
|
||||
return $this->appendQuery(EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant), $query);
|
||||
return $this->appendQuery(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant), $query);
|
||||
}
|
||||
|
||||
private function reviewPackDownloadUrl(EnvironmentReview $review, ManagedEnvironment $tenant): ?string
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
namespace App\Filament\Pages\Reviews;
|
||||
|
||||
use App\Filament\Concerns\CleansAdminTenantQueryParameter;
|
||||
use App\Filament\Concerns\ClearsWorkspaceHubEnvironmentFilterState;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\EnvironmentReview;
|
||||
@ -45,6 +46,7 @@
|
||||
|
||||
class ReviewRegister extends Page implements HasTable
|
||||
{
|
||||
use CleansAdminTenantQueryParameter;
|
||||
use ClearsWorkspaceHubEnvironmentFilterState;
|
||||
use InteractsWithTable;
|
||||
|
||||
@ -111,7 +113,7 @@ public function table(Table $table): Table
|
||||
->persistFiltersInSession()
|
||||
->persistSearchInSession()
|
||||
->persistSortInSession()
|
||||
->recordUrl(fn (EnvironmentReview $record): string => EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $record], $record->tenant))
|
||||
->recordUrl(fn (EnvironmentReview $record): string => EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $record], $record->tenant))
|
||||
->columns([
|
||||
TextColumn::make('tenant.name')->label('Environment')->searchable(),
|
||||
TextColumn::make('status')
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
|
||||
namespace App\Filament\Pages\Workspaces;
|
||||
|
||||
use BackedEnum;
|
||||
use App\Exceptions\Onboarding\OnboardingDraftConflictException;
|
||||
use App\Exceptions\Onboarding\OnboardingDraftImmutableException;
|
||||
use App\Filament\Resources\ManagedEnvironmentResource;
|
||||
@ -13,24 +12,22 @@
|
||||
use App\Jobs\ProviderComplianceSnapshotJob;
|
||||
use App\Jobs\ProviderConnectionHealthCheckJob;
|
||||
use App\Jobs\ProviderInventorySyncJob;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ProviderConnection;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\ManagedEnvironmentOnboardingSession;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ProviderConnection;
|
||||
use App\Models\User;
|
||||
use App\Models\VerificationCheckAcknowledgement;
|
||||
use App\Models\Workspace;
|
||||
use App\Services\Audit\WorkspaceAuditLogger;
|
||||
use App\Services\Auth\ManagedEnvironmentMembershipManager;
|
||||
use App\Services\Entitlements\WorkspaceCommercialLifecycleResolver;
|
||||
use App\Services\Intune\AuditLogger;
|
||||
use App\Services\Intune\ManagedEnvironmentRequiredPermissionsViewModelBuilder;
|
||||
use App\Services\Onboarding\OnboardingDraftMutationService;
|
||||
use App\Services\Onboarding\OnboardingDraftResolver;
|
||||
use App\Services\Onboarding\OnboardingDraftStageResolver;
|
||||
use App\Services\Onboarding\OnboardingLifecycleService;
|
||||
use App\Services\Entitlements\WorkspaceCommercialLifecycleResolver;
|
||||
use App\Services\Entitlements\WorkspaceEntitlementResolver;
|
||||
use App\Services\OperationRunService;
|
||||
use App\Services\Providers\ProviderConnectionMutationService;
|
||||
use App\Services\Providers\ProviderOperationRegistry;
|
||||
use App\Services\Providers\ProviderOperationStartGate;
|
||||
@ -50,17 +47,16 @@
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OperationRunOutcome;
|
||||
use App\Support\OperationRunStatus;
|
||||
use App\Support\OpsUx\OperationUxPresenter;
|
||||
use App\Support\OpsUx\ProviderOperationStartResultPresenter;
|
||||
use App\Support\OpsUx\OpsUxBrowserEvents;
|
||||
use App\Support\OpsUx\ProviderOperationStartResultPresenter;
|
||||
use App\Support\ProductKnowledge\ContextualHelpResolver;
|
||||
use App\Support\Providers\ProviderConnectionType;
|
||||
use App\Support\Providers\ProviderConsentStatus;
|
||||
use App\Support\Providers\ProviderReasonCodes;
|
||||
use App\Support\Providers\ProviderVerificationStatus;
|
||||
use App\Support\Providers\TargetScope\ProviderConnectionSurfaceSummary;
|
||||
use App\Support\Providers\TargetScope\ProviderConnectionTargetScopeDescriptor;
|
||||
use App\Support\Providers\TargetScope\ProviderConnectionTargetScopeNormalizer;
|
||||
use App\Support\Providers\ProviderVerificationStatus;
|
||||
use App\Support\Tenants\TenantInteractionLane;
|
||||
use App\Support\Tenants\TenantLifecyclePresentation;
|
||||
use App\Support\Tenants\TenantOperabilityQuestion;
|
||||
@ -68,6 +64,7 @@
|
||||
use App\Support\Verification\VerificationCheckStatus;
|
||||
use App\Support\Verification\VerificationReportOverall;
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use BackedEnum;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\CheckboxList;
|
||||
use Filament\Forms\Components\Radio;
|
||||
@ -233,7 +230,7 @@ private function canViewLinkedEnvironment(): bool
|
||||
|
||||
return app(TenantOperabilityService::class)->outcomeFor(
|
||||
tenant: $tenant,
|
||||
question: TenantOperabilityQuestion::TenantBoundViewability,
|
||||
question: TenantOperabilityQuestion::EnvironmentBoundViewability,
|
||||
actor: $user,
|
||||
workspaceId: (int) $this->workspace->getKey(),
|
||||
lane: TenantInteractionLane::AdministrativeManagement,
|
||||
@ -1108,7 +1105,7 @@ private function readinessSupportingEvidenceSchema(array $payload, string $keyPr
|
||||
$actions[] = Action::make($keyPrefix.'_required_permissions_assist')
|
||||
->label('View required permissions')
|
||||
->color('gray')
|
||||
->url($requiredPermissionsUrl);
|
||||
->url($requiredPermissionsUrl);
|
||||
}
|
||||
|
||||
if ($actions === []) {
|
||||
@ -1206,7 +1203,7 @@ private function readinessPermissionDiagnosticsSchema(array $payload, string $ke
|
||||
* draft: array{id: int, environment_name: string, stage_label: string, draft_status_label: string, started_by: string, updated_by: string, last_updated_human: string},
|
||||
* checkpoint: array{current_checkpoint: string|null, current_checkpoint_label: string|null, last_completed_checkpoint: string|null, lifecycle_state: string, lifecycle_label: string},
|
||||
* provider_summary: array<string, mixed>|null,
|
||||
* verification: array{status: string, status_label: string, run_id: int|null, run_url: string|null, is_active: bool, has_report: bool, matches_selected_connection: bool|null, overall: string|null},
|
||||
* verification: array{status: string, status_label: string, run_id: int|null, run_url: string|null, is_active: bool, has_report: bool, matches_selected_connection: bool|null, overall: string|null},
|
||||
* verification_assist: array{is_visible: bool, reason: string},
|
||||
* permissions: array{overall: string|null, counts: array<string, int>, freshness: array{last_refreshed_at: string|null, is_stale: bool}, capability_groups: array<int, array<string, mixed>>, primary_capability_group: array<string, mixed>|null, missing_permissions: array{application: list<string>, delegated: list<string>}, required_permissions_url: string|null}|null,
|
||||
* freshness: array{connection_recently_updated: bool, verification_mismatch: bool, permission_last_refreshed_at: string|null, permission_data_is_stale: bool, note: string},
|
||||
@ -4195,7 +4192,7 @@ public function startBootstrap(array $operationTypes): void
|
||||
draft: $this->onboardingSession,
|
||||
actor: $user,
|
||||
expectedVersion: $this->expectedDraftVersion(),
|
||||
mutator: function (ManagedEnvironmentOnboardingSession $draft) use ($tenant, $connection, $types, $registry, $user, &$result): void {
|
||||
mutator: function (ManagedEnvironmentOnboardingSession $draft) use ($tenant, $connection, $types, $user, &$result): void {
|
||||
$nextOperationType = $this->nextBootstrapOperationType($draft, $types, (int) $connection->getKey());
|
||||
|
||||
if ($nextOperationType === null) {
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
namespace App\Filament\Resources\AlertDeliveryResource\Pages;
|
||||
|
||||
use App\Filament\Resources\AlertDeliveryResource;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
use App\Support\OperateHub\OperateHubShell;
|
||||
use Filament\Actions\Action;
|
||||
@ -17,7 +17,7 @@ class ListAlertDeliveries extends ListRecords
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
app(CanonicalAdminTenantFilterState::class)->sync($this->getTableFiltersSessionKey(), request: request());
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync($this->getTableFiltersSessionKey(), request: request());
|
||||
|
||||
parent::mount();
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
use App\Exceptions\InvalidPolicyTypeException;
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\BackupScheduleResource\Pages;
|
||||
use App\Filament\Resources\BackupScheduleResource\RelationManagers\BackupScheduleOperationRunsRelationManager;
|
||||
use App\Jobs\RunBackupScheduleJob;
|
||||
@ -43,7 +43,6 @@
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\CheckboxList;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
@ -70,7 +69,7 @@ class BackupScheduleResource extends Resource
|
||||
{
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = BackupSchedule::class;
|
||||
|
||||
|
||||
@ -3,11 +3,9 @@
|
||||
namespace App\Filament\Resources\BackupScheduleResource\Pages;
|
||||
|
||||
use App\Filament\Resources\BackupScheduleResource;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Support\BackupHealth\TenantBackupHealthAssessment;
|
||||
use App\Support\BackupHealth\TenantBackupHealthResolver;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use Filament\Facades\Filament;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
|
||||
@ -34,7 +32,7 @@ public function mountAction(string $name, array $arguments = [], array $context
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->syncCanonicalAdminTenantFilterState();
|
||||
$this->syncCanonicalAdminEnvironmentFilterState();
|
||||
|
||||
parent::mount();
|
||||
}
|
||||
@ -59,13 +57,13 @@ private function tableHasRecords(): bool
|
||||
return $this->getTableRecords()->count() > 0;
|
||||
}
|
||||
|
||||
private function syncCanonicalAdminTenantFilterState(): void
|
||||
private function syncCanonicalAdminEnvironmentFilterState(): void
|
||||
{
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
tenantSensitiveFilters: [],
|
||||
environmentSensitiveFilters: [],
|
||||
request: request(),
|
||||
tenantFilterName: null,
|
||||
environmentFilterName: null,
|
||||
);
|
||||
}
|
||||
|
||||
@ -75,9 +73,9 @@ public function getSubheading(): ?string
|
||||
return null;
|
||||
}
|
||||
|
||||
$tenant = BackupScheduleResource::panelTenantContext();
|
||||
$tenant = BackupScheduleResource::panelTenantContext();
|
||||
|
||||
if ($tenant === null) {
|
||||
if ($tenant === null) {
|
||||
return 'One or more enabled schedules need follow-up.';
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\BackupSetResource\Pages;
|
||||
use App\Filament\Resources\BackupSetResource\RelationManagers\BackupItemsRelationManager;
|
||||
use App\Jobs\BulkBackupSetDeleteJob;
|
||||
@ -45,7 +45,6 @@
|
||||
use Filament\Actions\ActionGroup;
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms;
|
||||
use Filament\Infolists;
|
||||
use Filament\Notifications\Notification;
|
||||
@ -64,7 +63,7 @@ class BackupSetResource extends Resource
|
||||
{
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = BackupSet::class;
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
use App\Filament\Resources\BackupSetResource;
|
||||
use App\Support\BackupHealth\TenantBackupHealthAssessment;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListBackupSets extends ListRecords
|
||||
@ -13,10 +13,10 @@ class ListBackupSets extends ListRecords
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
request: request(),
|
||||
tenantFilterName: null,
|
||||
environmentFilterName: null,
|
||||
);
|
||||
|
||||
parent::mount();
|
||||
|
||||
@ -4,13 +4,14 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Concerns\CleansAdminTenantResourceQueryParameter;
|
||||
use App\Filament\Pages\BaselineCompareMatrix;
|
||||
use App\Filament\Resources\BaselineProfileResource\Pages;
|
||||
use App\Models\BaselineProfile;
|
||||
use App\Models\BaselineSnapshot;
|
||||
use App\Models\BaselineTenantAssignment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
use App\Services\Audit\WorkspaceAuditLogger;
|
||||
@ -21,11 +22,11 @@
|
||||
use App\Support\Badges\BadgeCatalog;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Baselines\BaselineScope;
|
||||
use App\Support\Baselines\BaselineCaptureMode;
|
||||
use App\Support\Baselines\BaselineFullContentRolloutGate;
|
||||
use App\Support\Baselines\BaselineProfileStatus;
|
||||
use App\Support\Baselines\BaselineReasonCodes;
|
||||
use App\Support\Baselines\BaselineScope;
|
||||
use App\Support\Baselines\Compare\CompareStrategyRegistry;
|
||||
use App\Support\Filament\FilterOptionCatalog;
|
||||
use App\Support\Inventory\InventoryPolicyTypeMeta;
|
||||
@ -61,16 +62,18 @@
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Unique;
|
||||
use InvalidArgumentException;
|
||||
use UnitEnum;
|
||||
|
||||
class BaselineProfileResource extends Resource
|
||||
{
|
||||
use CleansAdminTenantResourceQueryParameter;
|
||||
|
||||
protected static bool $isDiscovered = false;
|
||||
|
||||
protected static bool $isScopedToTenant = false;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Concerns\CleansAdminTenantResourceQueryParameter;
|
||||
use App\Filament\Resources\BaselineSnapshotResource\Pages;
|
||||
use App\Models\BaselineProfile;
|
||||
use App\Models\BaselineSnapshot;
|
||||
@ -25,9 +26,9 @@
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceType;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\CompressedGovernanceOutcome;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthEnvelope;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\CompressedGovernanceOutcome;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\SurfaceCompressionContext;
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use BackedEnum;
|
||||
@ -44,6 +45,8 @@
|
||||
|
||||
class BaselineSnapshotResource extends Resource
|
||||
{
|
||||
use CleansAdminTenantResourceQueryParameter;
|
||||
|
||||
protected static bool $isDiscovered = false;
|
||||
|
||||
protected static bool $isScopedToTenant = false;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\ScopesGlobalSearchToTenant;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\EntraGroupResource\Pages;
|
||||
use App\Models\EntraGroup;
|
||||
use App\Models\ManagedEnvironment;
|
||||
@ -39,7 +39,7 @@ class EntraGroupResource extends Resource
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use ScopesGlobalSearchToTenant;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static bool $isScopedToTenant = false;
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
use App\Models\User;
|
||||
use App\Services\Directory\EntraGroupSyncService;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OpsUx\OpsUxBrowserEvents;
|
||||
use App\Support\OpsUx\ProviderOperationStartResultPresenter;
|
||||
@ -22,10 +22,10 @@ class ListEntraGroups extends ListRecords
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
request: request(),
|
||||
tenantFilterName: null,
|
||||
environmentFilterName: null,
|
||||
);
|
||||
|
||||
if (
|
||||
|
||||
@ -4,47 +4,46 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Exceptions\Entitlements\WorkspaceEntitlementBlockedException;
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
||||
use App\Filament\Resources\EnvironmentReviewResource\Pages;
|
||||
use App\Exceptions\Entitlements\WorkspaceEntitlementBlockedException;
|
||||
use App\Models\EvidenceSnapshot;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\EnvironmentReview;
|
||||
use App\Models\EnvironmentReviewSection;
|
||||
use App\Models\EvidenceSnapshot;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\User;
|
||||
use App\Services\ReviewPackService;
|
||||
use App\Services\EnvironmentReviews\EnvironmentReviewService;
|
||||
use App\Services\ReviewPackService;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Auth\UiTooltips as AuthUiTooltips;
|
||||
use App\Support\Badges\BadgeCatalog;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\EnvironmentReviewCompletenessState;
|
||||
use App\Support\EnvironmentReviewStatus;
|
||||
use App\Support\Findings\FindingOutcomeSemantics;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OperationRunType;
|
||||
use App\Support\OpsUx\OperationUxPresenter;
|
||||
use App\Support\Rbac\UiEnforcement;
|
||||
use App\Support\ReasonTranslation\ReasonPresenter;
|
||||
use App\Support\ReviewPackStatus;
|
||||
use App\Support\Rbac\UiEnforcement;
|
||||
use App\Support\EnvironmentReviewCompletenessState;
|
||||
use App\Support\EnvironmentReviewStatus;
|
||||
use App\Support\Ui\ActionSurface\ActionSurfaceDeclaration;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceInspectAffordance;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceType;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\CompressedGovernanceOutcome;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthEnvelope;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\CompressedGovernanceOutcome;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\SurfaceCompressionContext;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Infolists\Components\RepeatableEntry;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
@ -66,7 +65,7 @@ class EnvironmentReviewResource extends Resource
|
||||
{
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static bool $isDiscovered = false;
|
||||
|
||||
@ -317,7 +316,7 @@ public static function table(Table $table): Table
|
||||
->persistFiltersInSession()
|
||||
->persistSearchInSession()
|
||||
->persistSortInSession()
|
||||
->recordUrl(fn (EnvironmentReview $record): string => static::tenantScopedUrl('view', ['record' => $record], $record->tenant))
|
||||
->recordUrl(fn (EnvironmentReview $record): string => static::environmentScopedUrl('view', ['record' => $record], $record->tenant))
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('status')
|
||||
->badge()
|
||||
@ -464,7 +463,7 @@ public static function executeCreateReview(array $data): void
|
||||
->actions([
|
||||
Actions\Action::make('view_review')
|
||||
->label(__('localization.review.view_review'))
|
||||
->url(static::tenantScopedUrl('view', ['record' => $review], $tenant)),
|
||||
->url(static::environmentScopedUrl('view', ['record' => $review], $tenant)),
|
||||
])
|
||||
->send();
|
||||
|
||||
@ -613,11 +612,10 @@ public static function executeExport(EnvironmentReview $review): void
|
||||
/**
|
||||
* @param array<string, mixed> $parameters
|
||||
*/
|
||||
public static function tenantScopedUrl(
|
||||
public static function environmentScopedUrl(
|
||||
string $page = 'index',
|
||||
array $parameters = [],
|
||||
?ManagedEnvironment $tenant = null,
|
||||
?string $panel = null,
|
||||
): string {
|
||||
$panelId = 'admin';
|
||||
|
||||
@ -881,7 +879,7 @@ private static function summaryContextLinks(EnvironmentReview $record, bool $cus
|
||||
$links[] = [
|
||||
'title' => __('localization.review.customer_workspace'),
|
||||
'label' => __('localization.review.open_customer_workspace'),
|
||||
'url' => CustomerReviewWorkspace::tenantPrefilterUrl($record->tenant),
|
||||
'url' => CustomerReviewWorkspace::environmentFilterUrl($record->tenant),
|
||||
'description' => __('localization.review.customer_workspace_description'),
|
||||
];
|
||||
}
|
||||
|
||||
@ -6,19 +6,19 @@
|
||||
|
||||
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\EnvironmentReview;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\User;
|
||||
use App\Services\ReviewPackService;
|
||||
use App\Services\Audit\WorkspaceAuditLogger;
|
||||
use App\Services\EnvironmentReviews\EnvironmentReviewLifecycleService;
|
||||
use App\Services\EnvironmentReviews\EnvironmentReviewService;
|
||||
use App\Services\ReviewPackService;
|
||||
use App\Support\Audit\AuditActionId;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\EnvironmentReviewStatus;
|
||||
use App\Support\Rbac\UiEnforcement;
|
||||
use App\Support\ReviewPackStatus;
|
||||
use App\Support\EnvironmentReviewStatus;
|
||||
use App\Support\Ui\GovernanceActions\GovernanceActionCatalog;
|
||||
use Filament\Actions;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
@ -302,7 +302,7 @@ private function createNextReviewAction(): Actions\Action
|
||||
return;
|
||||
}
|
||||
|
||||
$this->redirect(EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $nextReview], $nextReview->tenant));
|
||||
$this->redirect(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $nextReview], $nextReview->tenant));
|
||||
}),
|
||||
)
|
||||
->requireCapability(Capabilities::ENVIRONMENT_REVIEW_MANAGE)
|
||||
|
||||
@ -6,10 +6,9 @@
|
||||
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
||||
use App\Filament\Resources\EvidenceSnapshotResource\Pages;
|
||||
use App\Filament\Resources\ReviewPackResource;
|
||||
use App\Models\EvidenceSnapshot;
|
||||
use App\Models\EvidenceSnapshotItem;
|
||||
use App\Models\ManagedEnvironment;
|
||||
@ -21,8 +20,8 @@
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Evidence\EvidenceCompletenessState;
|
||||
use App\Support\Evidence\EvidenceSnapshotStatus;
|
||||
use App\Support\Navigation\RelatedContextEntry;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
use App\Support\Navigation\RelatedContextEntry;
|
||||
use App\Support\OperationCatalog;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OperationRunOutcome;
|
||||
@ -35,13 +34,12 @@
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceType;
|
||||
use App\Support\Ui\GovernanceActions\GovernanceActionCatalog;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\CompressedGovernanceOutcome;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthEnvelope;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\CompressedGovernanceOutcome;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\SurfaceCompressionContext;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Infolists\Components\RepeatableEntry;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
@ -66,7 +64,7 @@ class EvidenceSnapshotResource extends Resource
|
||||
{
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = EvidenceSnapshot::class;
|
||||
|
||||
@ -311,7 +309,7 @@ public static function relatedContextEntries(EvidenceSnapshot $record): array
|
||||
label: 'Customer workspace',
|
||||
value: $record->tenant->name,
|
||||
secondaryValue: 'Open the customer-safe review workspace prefiltered to this tenant.',
|
||||
targetUrl: CustomerReviewWorkspace::tenantPrefilterUrl($record->tenant),
|
||||
targetUrl: CustomerReviewWorkspace::environmentFilterUrl($record->tenant),
|
||||
targetKind: 'canonical_page',
|
||||
priority: 30,
|
||||
actionLabel: 'Open customer workspace',
|
||||
|
||||
@ -6,9 +6,8 @@
|
||||
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\FindingExceptionResource\Pages;
|
||||
use App\Filament\Resources\FindingResource;
|
||||
use App\Models\FindingException;
|
||||
use App\Models\FindingExceptionEvidenceReference;
|
||||
use App\Models\ManagedEnvironment;
|
||||
@ -31,7 +30,6 @@
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot;
|
||||
use BackedEnum;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Select;
|
||||
@ -56,7 +54,7 @@ class FindingExceptionResource extends Resource
|
||||
{
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = FindingException::class;
|
||||
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\FindingResource\Pages;
|
||||
use App\Filament\Support\NormalizedDiffSurface;
|
||||
use App\Models\Finding;
|
||||
use App\Models\FindingException;
|
||||
use App\Models\PolicyVersion;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\PolicyVersion;
|
||||
use App\Models\User;
|
||||
use App\Services\Auth\ManagedEnvironmentAccessScopeResolver;
|
||||
use App\Services\Drift\DriftFindingDiffBuilder;
|
||||
@ -22,8 +22,8 @@
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Filament\FilterOptionCatalog;
|
||||
use App\Support\Filament\FilterPresets;
|
||||
use App\Support\Findings\FindingOutcomeSemantics;
|
||||
use App\Support\Filament\TablePaginationProfiles;
|
||||
use App\Support\Findings\FindingOutcomeSemantics;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
use App\Support\Navigation\CrossResourceNavigationMatrix;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
@ -69,7 +69,7 @@ class FindingResource extends Resource
|
||||
{
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = Finding::class;
|
||||
|
||||
@ -1229,7 +1229,7 @@ public static function table(Table $table): Table
|
||||
}
|
||||
}
|
||||
|
||||
$body = "Resolved {$resolvedCount} finding".($resolvedCount === 1 ? '' : 's')." pending verification.";
|
||||
$body = "Resolved {$resolvedCount} finding".($resolvedCount === 1 ? '' : 's').' pending verification.';
|
||||
if ($skippedCount > 0) {
|
||||
$body .= " Skipped {$skippedCount}.";
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
use App\Models\User;
|
||||
use App\Services\Findings\FindingWorkflowService;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\Rbac\UiEnforcement;
|
||||
use App\Support\Rbac\UiTooltips;
|
||||
use Filament\Actions;
|
||||
@ -49,7 +49,7 @@ public function mountAction(string $name, array $arguments = [], array $context
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->syncCanonicalAdminTenantFilterState();
|
||||
$this->syncCanonicalAdminEnvironmentFilterState();
|
||||
|
||||
parent::mount();
|
||||
$this->applyRequestedDashboardPrefilter();
|
||||
@ -264,13 +264,13 @@ protected function buildAllMatchingQuery(): Builder
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function syncCanonicalAdminTenantFilterState(): void
|
||||
private function syncCanonicalAdminEnvironmentFilterState(): void
|
||||
{
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
tenantSensitiveFilters: ['scope_key', 'run_ids'],
|
||||
environmentSensitiveFilters: ['scope_key', 'run_ids'],
|
||||
request: request(),
|
||||
tenantFilterName: null,
|
||||
environmentFilterName: null,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
use App\Filament\Clusters\Inventory\InventoryCluster;
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\InventoryItemResource\Pages;
|
||||
use App\Models\InventoryItem;
|
||||
use App\Models\ManagedEnvironment;
|
||||
@ -28,8 +28,8 @@
|
||||
use Closure;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Panel;
|
||||
use Filament\Infolists\Components\ViewEntry;
|
||||
use Filament\Panel;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
@ -37,15 +37,15 @@
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Str;
|
||||
use UnitEnum;
|
||||
|
||||
class InventoryItemResource extends Resource
|
||||
{
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = InventoryItem::class;
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
use App\Services\Inventory\InventorySyncService;
|
||||
use App\Services\OperationRunService;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use App\Support\Inventory\InventoryPolicyTypeMeta;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OperationRunType;
|
||||
@ -28,8 +28,8 @@
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Filament\Support\Enums\Size;
|
||||
use Filament\Support\Enums\Width;
|
||||
|
||||
class ListInventoryItems extends ListRecords
|
||||
{
|
||||
@ -41,16 +41,16 @@ class ListInventoryItems extends ListRecords
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
request: request(),
|
||||
tenantFilterName: null,
|
||||
environmentFilterName: null,
|
||||
);
|
||||
|
||||
$tenant = static::resolveTenantContextForCurrentPanel();
|
||||
|
||||
if ($tenant instanceof ManagedEnvironment) {
|
||||
app(WorkspaceContext::class)->rememberTenantContext($tenant, request());
|
||||
app(WorkspaceContext::class)->rememberEnvironmentContext($tenant, request());
|
||||
}
|
||||
|
||||
parent::mount();
|
||||
|
||||
@ -20,7 +20,7 @@ public function mount(int|string $record): void
|
||||
$tenant = static::resolveTenantContextForCurrentPanel();
|
||||
|
||||
if ($tenant instanceof ManagedEnvironment) {
|
||||
app(WorkspaceContext::class)->rememberTenantContext($tenant, request());
|
||||
app(WorkspaceContext::class)->rememberEnvironmentContext($tenant, request());
|
||||
}
|
||||
|
||||
parent::mount($record);
|
||||
|
||||
@ -191,19 +191,19 @@ public static function table(Table $table): Table
|
||||
->all();
|
||||
})
|
||||
->default(function (): ?string {
|
||||
$activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
$activeEnvironment = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
|
||||
if (! $activeTenant instanceof ManagedEnvironment) {
|
||||
if (! $activeEnvironment instanceof ManagedEnvironment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$workspaceId = app(WorkspaceContext::class)->currentWorkspaceId();
|
||||
|
||||
if ($workspaceId === null || (int) $activeTenant->workspace_id !== (int) $workspaceId) {
|
||||
if ($workspaceId === null || (int) $activeEnvironment->workspace_id !== (int) $workspaceId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (string) $activeTenant->getKey();
|
||||
return (string) $activeEnvironment->getKey();
|
||||
})
|
||||
->searchable(),
|
||||
Tables\Filters\SelectFilter::make('type')
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\ScopesGlobalSearchToTenant;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\PolicyResource\Pages;
|
||||
use App\Filament\Resources\PolicyResource\RelationManagers\VersionsRelationManager;
|
||||
use App\Filament\Support\NormalizedSettingsSurface;
|
||||
@ -13,8 +13,8 @@
|
||||
use App\Jobs\BulkPolicyExportJob;
|
||||
use App\Jobs\BulkPolicyUnignoreJob;
|
||||
use App\Jobs\SyncPoliciesJob;
|
||||
use App\Models\Policy;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\Policy;
|
||||
use App\Models\User;
|
||||
use App\Services\Auth\CapabilityResolver;
|
||||
use App\Services\Intune\PolicyNormalizer;
|
||||
@ -41,7 +41,6 @@
|
||||
use Filament\Actions\ActionGroup;
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Infolists\Components\ViewEntry;
|
||||
@ -63,7 +62,7 @@ class PolicyResource extends Resource
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use ScopesGlobalSearchToTenant;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = Policy::class;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
namespace App\Filament\Resources\PolicyResource\Pages;
|
||||
|
||||
use App\Filament\Resources\PolicyResource;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListPolicies extends ListRecords
|
||||
@ -12,7 +12,7 @@ class ListPolicies extends ListRecords
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->syncCanonicalAdminTenantFilterState();
|
||||
$this->syncCanonicalAdminEnvironmentFilterState();
|
||||
|
||||
parent::mount();
|
||||
}
|
||||
@ -31,13 +31,13 @@ protected function getTableEmptyStateActions(): array
|
||||
];
|
||||
}
|
||||
|
||||
private function syncCanonicalAdminTenantFilterState(): void
|
||||
private function syncCanonicalAdminEnvironmentFilterState(): void
|
||||
{
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
tenantSensitiveFilters: [],
|
||||
environmentSensitiveFilters: [],
|
||||
request: request(),
|
||||
tenantFilterName: null,
|
||||
environmentFilterName: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\ScopesGlobalSearchToTenant;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\PolicyVersionResource\Pages;
|
||||
use App\Filament\Support\NormalizedDiffSurface;
|
||||
use App\Filament\Support\NormalizedSettingsSurface;
|
||||
@ -14,8 +14,8 @@
|
||||
use App\Jobs\BulkPolicyVersionRestoreJob;
|
||||
use App\Models\BackupItem;
|
||||
use App\Models\BackupSet;
|
||||
use App\Models\PolicyVersion;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\PolicyVersion;
|
||||
use App\Models\User;
|
||||
use App\Services\Auth\CapabilityResolver;
|
||||
use App\Services\Intune\AuditLogger;
|
||||
@ -49,7 +49,6 @@
|
||||
use Filament\Actions;
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms;
|
||||
use Filament\Infolists;
|
||||
use Filament\Notifications\Notification;
|
||||
@ -71,7 +70,7 @@ class PolicyVersionResource extends Resource
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use ScopesGlobalSearchToTenant;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = PolicyVersion::class;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
namespace App\Filament\Resources\PolicyVersionResource\Pages;
|
||||
|
||||
use App\Filament\Resources\PolicyVersionResource;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListPolicyVersions extends ListRecords
|
||||
@ -12,10 +12,10 @@ class ListPolicyVersions extends ListRecords
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
request: request(),
|
||||
tenantFilterName: null,
|
||||
environmentFilterName: null,
|
||||
);
|
||||
|
||||
parent::mount();
|
||||
|
||||
@ -203,20 +203,6 @@ public static function resolveRequestedEnvironment(): ?ManagedEnvironment
|
||||
|
||||
public static function resolveContextTenantExternalId(): ?string
|
||||
{
|
||||
$workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request());
|
||||
$contextTenantId = app(WorkspaceContext::class)->lastTenantId(request());
|
||||
|
||||
if ($workspaceId !== null && $contextTenantId !== null) {
|
||||
$tenant = ManagedEnvironment::query()
|
||||
->whereKey($contextTenantId)
|
||||
->where('workspace_id', (int) $workspaceId)
|
||||
->first();
|
||||
|
||||
if ($tenant instanceof ManagedEnvironment) {
|
||||
return (string) $tenant->slug;
|
||||
}
|
||||
}
|
||||
|
||||
$tenant = static::resolveTenantContextForCurrentPanel();
|
||||
|
||||
if ($tenant instanceof ManagedEnvironment) {
|
||||
@ -228,7 +214,7 @@ public static function resolveContextTenantExternalId(): ?string
|
||||
|
||||
public static function resolveTenantForCreate(): ?ManagedEnvironment
|
||||
{
|
||||
$tenantExternalId = static::resolveRequestedTenantExternalId() ?? static::resolveContextTenantExternalId();
|
||||
$tenantExternalId = static::resolveRequestedTenantExternalId();
|
||||
|
||||
if (! is_string($tenantExternalId) || $tenantExternalId === '') {
|
||||
return null;
|
||||
@ -1676,11 +1662,6 @@ public static function getUrl(?string $name = null, array $parameters = [], bool
|
||||
$tenantExternalId = null;
|
||||
$isIndexUrl = $name === null || $name === 'index';
|
||||
|
||||
if (array_key_exists('tenant', $parameters)) {
|
||||
$tenantExternalId = static::normalizeTenantExternalId($parameters['tenant']);
|
||||
unset($parameters['tenant']);
|
||||
}
|
||||
|
||||
if ($tenantExternalId === null && $tenant instanceof ManagedEnvironment) {
|
||||
$tenantExternalId = (string) $tenant->slug;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
use App\Exceptions\Hardening\ProviderAccessHardeningRequired;
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\RestoreRunResource\Pages;
|
||||
use App\Jobs\BulkRestoreRunDeleteJob;
|
||||
use App\Jobs\BulkRestoreRunForceDeleteJob;
|
||||
@ -15,9 +15,9 @@
|
||||
use App\Models\BackupItem;
|
||||
use App\Models\BackupSet;
|
||||
use App\Models\EntraGroup;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\RestoreRun;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
use App\Rules\SkipOrUuidRule;
|
||||
@ -32,21 +32,21 @@
|
||||
use App\Services\Operations\BulkSelectionIdentity;
|
||||
use App\Services\Providers\ProviderOperationStartGate;
|
||||
use App\Services\Providers\ProviderOperationStartResult;
|
||||
use App\Support\Audit\AuditActionId;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\BackupQuality\BackupQualityResolver;
|
||||
use App\Support\Audit\AuditActionId;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Filament\FilterOptionCatalog;
|
||||
use App\Support\Filament\FilterPresets;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
use App\Support\OperationalControls\OperationalControlBlockedException;
|
||||
use App\Support\OperationalControls\OperationalControlEvaluator;
|
||||
use App\Support\OperationCatalog;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OpsUx\OperationUxPresenter;
|
||||
use App\Support\OpsUx\OpsUxBrowserEvents;
|
||||
use App\Support\OpsUx\ProviderOperationStartResultPresenter;
|
||||
use App\Support\OperationalControls\OperationalControlBlockedException;
|
||||
use App\Support\OperationalControls\OperationalControlEvaluator;
|
||||
use App\Support\Rbac\UiEnforcement;
|
||||
use App\Support\RestoreRunIdempotency;
|
||||
use App\Support\RestoreRunStatus;
|
||||
@ -63,7 +63,6 @@
|
||||
use Filament\Actions\ActionGroup;
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms;
|
||||
use Filament\Infolists;
|
||||
use Filament\Notifications\Notification;
|
||||
@ -80,7 +79,6 @@
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
@ -90,7 +88,7 @@ class RestoreRunResource extends Resource
|
||||
{
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = RestoreRun::class;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
namespace App\Filament\Resources\RestoreRunResource\Pages;
|
||||
|
||||
use App\Filament\Resources\RestoreRunResource;
|
||||
use App\Support\Filament\CanonicalAdminTenantFilterState;
|
||||
use App\Support\Filament\CanonicalAdminEnvironmentFilterState;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
|
||||
@ -30,10 +30,10 @@ public function mountAction(string $name, array $arguments = [], array $context
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
app(CanonicalAdminTenantFilterState::class)->sync(
|
||||
app(CanonicalAdminEnvironmentFilterState::class)->sync(
|
||||
$this->getTableFiltersSessionKey(),
|
||||
request: request(),
|
||||
tenantFilterName: null,
|
||||
environmentFilterName: null,
|
||||
);
|
||||
|
||||
parent::mount();
|
||||
|
||||
@ -2,20 +2,19 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Exceptions\Entitlements\WorkspaceEntitlementBlockedException;
|
||||
use App\Exceptions\ReviewPackEvidenceResolutionException;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
||||
use App\Filament\Resources\EvidenceSnapshotResource as TenantEvidenceSnapshotResource;
|
||||
use App\Filament\Resources\ReviewPackResource\Pages;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\User;
|
||||
use App\Services\ReviewPackService;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Auth\UiTooltips as AuthUiTooltips;
|
||||
use App\Support\Badges\BadgeCatalog;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
@ -28,13 +27,12 @@
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot;
|
||||
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceType;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\CompressedGovernanceOutcome;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthEnvelope;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\CompressedGovernanceOutcome;
|
||||
use App\Support\Ui\GovernanceArtifactTruth\SurfaceCompressionContext;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Infolists\Components\ViewEntry;
|
||||
@ -52,7 +50,7 @@
|
||||
class ReviewPackResource extends Resource
|
||||
{
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
protected static ?string $model = ReviewPack::class;
|
||||
|
||||
@ -204,14 +202,14 @@ public static function infolist(Schema $schema): Schema
|
||||
->label('ManagedEnvironment review')
|
||||
->formatStateUsing(fn (?int $state): string => $state ? '#'.$state : '—')
|
||||
->url(fn (ReviewPack $record): ?string => $record->environmentReview && $record->tenant
|
||||
? EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $record->environmentReview], $record->tenant)
|
||||
? EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $record->environmentReview], $record->tenant)
|
||||
: null)
|
||||
->placeholder('—'),
|
||||
TextEntry::make('customer_workspace')
|
||||
->label('Customer workspace')
|
||||
->state(fn (): string => 'Open workspace')
|
||||
->url(fn (ReviewPack $record): ?string => $record->tenant instanceof ManagedEnvironment
|
||||
? CustomerReviewWorkspace::tenantPrefilterUrl($record->tenant)
|
||||
? CustomerReviewWorkspace::environmentFilterUrl($record->tenant)
|
||||
: null)
|
||||
->placeholder('—'),
|
||||
TextEntry::make('summary.review_status')
|
||||
|
||||
@ -6,10 +6,10 @@
|
||||
|
||||
use App\Filament\Concerns\InteractsWithTenantOwnedRecords;
|
||||
use App\Filament\Concerns\ResolvesPanelTenantContext;
|
||||
use App\Filament\Concerns\WorkspaceScopedTenantRoutes;
|
||||
use App\Filament\Concerns\WorkspaceScopedEnvironmentRoutes;
|
||||
use App\Filament\Resources\StoredReportResource\Pages;
|
||||
use App\Models\StoredReport;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\StoredReport;
|
||||
use App\Models\User;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
@ -45,7 +45,7 @@ class StoredReportResource extends Resource
|
||||
{
|
||||
use InteractsWithTenantOwnedRecords;
|
||||
use ResolvesPanelTenantContext;
|
||||
use WorkspaceScopedTenantRoutes;
|
||||
use WorkspaceScopedEnvironmentRoutes;
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
|
||||
use App\Exceptions\Entitlements\WorkspaceEntitlementBlockedException;
|
||||
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\User;
|
||||
use App\Services\ReviewPackService;
|
||||
use App\Support\Auth\Capabilities;
|
||||
@ -193,7 +193,7 @@ protected function getViewData(): array
|
||||
'generationBlocked' => $generationBlocked,
|
||||
'generationBlockReason' => $generationBlockReason,
|
||||
'generationWarningReason' => $generationWarningReason,
|
||||
'customerWorkspaceUrl' => $canView ? CustomerReviewWorkspace::tenantPrefilterUrl($tenant) : null,
|
||||
'customerWorkspaceUrl' => $canView ? CustomerReviewWorkspace::environmentFilterUrl($tenant) : null,
|
||||
'downloadUrl' => null,
|
||||
'failedReason' => null,
|
||||
'reviewUrl' => null,
|
||||
@ -211,7 +211,7 @@ protected function getViewData(): array
|
||||
|
||||
$reviewUrl = null;
|
||||
if ($latestPack->environmentReview && $canView) {
|
||||
$reviewUrl = \App\Filament\Resources\EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $latestPack->environmentReview], $tenant);
|
||||
$reviewUrl = \App\Filament\Resources\EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $latestPack->environmentReview], $tenant);
|
||||
}
|
||||
|
||||
$failedReason = null;
|
||||
@ -245,7 +245,7 @@ protected function getViewData(): array
|
||||
'generationBlocked' => $generationBlocked,
|
||||
'generationBlockReason' => $generationBlockReason,
|
||||
'generationWarningReason' => $generationWarningReason,
|
||||
'customerWorkspaceUrl' => $canView ? CustomerReviewWorkspace::tenantPrefilterUrl($tenant) : null,
|
||||
'customerWorkspaceUrl' => $canView ? CustomerReviewWorkspace::environmentFilterUrl($tenant) : null,
|
||||
'downloadUrl' => $downloadUrl,
|
||||
'failedReason' => $failedReason,
|
||||
'failedReasonDetail' => $failedReasonDetail,
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
|
||||
namespace App\Filament\Widgets\Operations;
|
||||
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\User;
|
||||
use App\Services\Auth\ManagedEnvironmentAccessScopeResolver;
|
||||
use App\Support\OperateHub\OperateHubShell;
|
||||
@ -27,7 +27,7 @@ class OperationsKpiHeader extends StatsOverviewWidget
|
||||
|
||||
protected function getPollingInterval(): ?string
|
||||
{
|
||||
$tenant = $this->activeTenant();
|
||||
$tenant = $this->activeEnvironment();
|
||||
|
||||
if ($tenant instanceof ManagedEnvironment) {
|
||||
return ActiveRuns::existForTenant($tenant) ? '10s' : null;
|
||||
@ -119,7 +119,7 @@ protected function getStats(): array
|
||||
];
|
||||
}
|
||||
|
||||
private function activeTenant(): ?ManagedEnvironment
|
||||
private function activeEnvironment(): ?ManagedEnvironment
|
||||
{
|
||||
$tenant = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
|
||||
@ -128,7 +128,7 @@ private function activeTenant(): ?ManagedEnvironment
|
||||
|
||||
private function scopedOperationRunQuery(): ?Builder
|
||||
{
|
||||
$tenant = $this->activeTenant();
|
||||
$tenant = $this->activeEnvironment();
|
||||
|
||||
if ($tenant instanceof ManagedEnvironment) {
|
||||
return OperationRun::query()
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Support\Navigation\AdminSurfaceScope;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\Tenants\TenantPageCategory;
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@ -19,7 +19,7 @@ public function __invoke(Request $request): RedirectResponse
|
||||
|
||||
$workspaceContext = app(WorkspaceContext::class);
|
||||
|
||||
$workspaceContext->clearRememberedTenantContext($request);
|
||||
$workspaceContext->clearRememberedEnvironmentContext($request);
|
||||
|
||||
$previousUrl = url()->previous();
|
||||
|
||||
@ -30,11 +30,11 @@ public function __invoke(Request $request): RedirectResponse
|
||||
return redirect()->to(OperationRunLinks::index());
|
||||
}
|
||||
|
||||
if ($this->isTenantScopedEvidencePath($previousPath)) {
|
||||
if ($this->isEnvironmentScopedEvidencePath($previousPath)) {
|
||||
return redirect()->route('admin.evidence.overview');
|
||||
}
|
||||
|
||||
if (TenantPageCategory::fromPath($previousPath) === TenantPageCategory::TenantBound) {
|
||||
if (AdminSurfaceScope::fromPath($previousPath) === AdminSurfaceScope::EnvironmentBound) {
|
||||
$workspace = $workspaceContext->currentWorkspace($request);
|
||||
|
||||
if ($workspace !== null) {
|
||||
@ -51,7 +51,7 @@ public function __invoke(Request $request): RedirectResponse
|
||||
return redirect()->to((string) $previousUrl);
|
||||
}
|
||||
|
||||
private function isTenantScopedEvidencePath(string $previousPath): bool
|
||||
private function isEnvironmentScopedEvidencePath(string $previousPath): bool
|
||||
{
|
||||
if ($previousPath === '/admin/evidence') {
|
||||
return true;
|
||||
|
||||
@ -49,7 +49,7 @@ public function __invoke(Request $request, ManagedEnvironment $environment): Red
|
||||
|
||||
$workspaceContext->setCurrentWorkspace($workspace, $user, $request);
|
||||
|
||||
if (! $workspaceContext->rememberTenantContext($environment, $request)) {
|
||||
if (! $workspaceContext->rememberEnvironmentContext($environment, $request)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
use App\Models\User;
|
||||
use App\Models\UserTenantPreference;
|
||||
use App\Services\Tenants\TenantOperabilityService;
|
||||
use App\Support\ManagedEnvironmentLinks;
|
||||
use App\Support\Tenants\TenantInteractionLane;
|
||||
use App\Support\Tenants\TenantOperabilityQuestion;
|
||||
use App\Support\ManagedEnvironmentLinks;
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@ -63,7 +63,7 @@ public function __invoke(Request $request): RedirectResponse
|
||||
|
||||
$this->persistLastTenant($user, $tenant);
|
||||
|
||||
if (! app(WorkspaceContext::class)->rememberTenantContext($tenant, $request)) {
|
||||
if (! app(WorkspaceContext::class)->rememberEnvironmentContext($tenant, $request)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ public function __invoke(Request $request): RedirectResponse
|
||||
$prevWorkspaceId = $context->currentWorkspaceId($request);
|
||||
|
||||
$context->setCurrentWorkspace($workspace, $user, $request);
|
||||
$context->rememberedTenant($request);
|
||||
$context->rememberedEnvironment($request);
|
||||
Filament::setTenant(null, true);
|
||||
|
||||
/** @var WorkspaceAuditLogger $auditLogger */
|
||||
|
||||
@ -250,7 +250,7 @@ private function resolveCurrentTenant(): ManagedEnvironment
|
||||
$tenant = Filament::getTenant();
|
||||
|
||||
if (! $tenant instanceof ManagedEnvironment) {
|
||||
$tenant = app(WorkspaceContext::class)->rememberedTenant(request());
|
||||
$tenant = app(WorkspaceContext::class)->rememberedEnvironment(request());
|
||||
}
|
||||
|
||||
if (! $tenant instanceof ManagedEnvironment) {
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
use Filament\Models\Contracts\HasDefaultTenant;
|
||||
use Filament\Models\Contracts\HasTenants;
|
||||
use Filament\Panel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -194,10 +194,10 @@ public function getDefaultTenant(Panel $panel): ?Model
|
||||
|
||||
$operability = app(TenantOperabilityService::class);
|
||||
|
||||
$rememberedTenant = $workspaceContext->rememberedTenant(request());
|
||||
$rememberedEnvironment = $workspaceContext->rememberedEnvironment(request());
|
||||
|
||||
if ($rememberedTenant instanceof ManagedEnvironment && $this->canAccessTenant($rememberedTenant)) {
|
||||
return $rememberedTenant;
|
||||
if ($rememberedEnvironment instanceof ManagedEnvironment && $this->canAccessTenant($rememberedEnvironment)) {
|
||||
return $rememberedEnvironment;
|
||||
}
|
||||
|
||||
$tenantId = null;
|
||||
|
||||
@ -120,7 +120,7 @@ private function resolvedTenant(): ?ManagedEnvironment
|
||||
return null;
|
||||
}
|
||||
|
||||
$tenantId = app(WorkspaceContext::class)->lastTenantId(request());
|
||||
$tenantId = app(WorkspaceContext::class)->lastEnvironmentId(request());
|
||||
|
||||
if (! is_int($tenantId)) {
|
||||
return null;
|
||||
|
||||
@ -109,7 +109,7 @@ private function authorizeForDraft(
|
||||
|
||||
$viewability = app(TenantOperabilityService::class)->outcomeFor(
|
||||
tenant: $tenant,
|
||||
question: TenantOperabilityQuestion::TenantBoundViewability,
|
||||
question: TenantOperabilityQuestion::EnvironmentBoundViewability,
|
||||
actor: $user,
|
||||
workspaceId: (int) $workspace->getKey(),
|
||||
lane: TenantInteractionLane::AdministrativeManagement,
|
||||
|
||||
@ -240,11 +240,11 @@ private function resolveCreateTenant(Workspace $workspace): ?ManagedEnvironment
|
||||
$requestedEnvironmentId = request()->query('environment_id');
|
||||
|
||||
if (! is_numeric($requestedEnvironmentId)) {
|
||||
$lastTenantId = app(WorkspaceContext::class)->lastTenantId(request());
|
||||
$lastEnvironmentId = app(WorkspaceContext::class)->lastEnvironmentId(request());
|
||||
|
||||
if (is_int($lastTenantId)) {
|
||||
if (is_int($lastEnvironmentId)) {
|
||||
return ManagedEnvironment::query()
|
||||
->whereKey($lastTenantId)
|
||||
->whereKey($lastEnvironmentId)
|
||||
->where('workspace_id', (int) $workspace->getKey())
|
||||
->first();
|
||||
}
|
||||
|
||||
@ -2,35 +2,35 @@
|
||||
|
||||
namespace App\Providers\Filament;
|
||||
|
||||
use App\Filament\Clusters\Inventory\InventoryCluster;
|
||||
use App\Filament\Pages\Auth\Login;
|
||||
use App\Filament\Pages\BaselineCompareLanding;
|
||||
use App\Filament\Pages\ChooseEnvironment;
|
||||
use App\Filament\Pages\ChooseWorkspace;
|
||||
use App\Filament\Pages\CrossEnvironmentComparePage;
|
||||
use App\Filament\Pages\EnvironmentRequiredPermissions;
|
||||
use App\Filament\Pages\Findings\FindingsHygieneReport;
|
||||
use App\Filament\Pages\Findings\FindingsIntakeQueue;
|
||||
use App\Filament\Pages\Findings\MyFindingsInbox;
|
||||
use App\Filament\Pages\Governance\DecisionRegister;
|
||||
use App\Filament\Pages\Governance\GovernanceInbox;
|
||||
use App\Filament\Pages\Findings\MyFindingsInbox;
|
||||
use App\Filament\Pages\InventoryCoverage;
|
||||
use App\Filament\Pages\Monitoring\FindingExceptionsQueue;
|
||||
use App\Filament\Pages\NoAccess;
|
||||
use App\Filament\Pages\Reviews\ReviewRegister;
|
||||
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
||||
use App\Filament\Pages\Reviews\ReviewRegister;
|
||||
use App\Filament\Pages\Settings\WorkspaceSettings;
|
||||
use App\Filament\Pages\EnvironmentRequiredPermissions;
|
||||
use App\Filament\Pages\WorkspaceOverview;
|
||||
use App\Filament\Clusters\Inventory\InventoryCluster;
|
||||
use App\Filament\Resources\AlertDeliveryResource;
|
||||
use App\Filament\Resources\AlertDestinationResource;
|
||||
use App\Filament\Resources\AlertRuleResource;
|
||||
use App\Filament\Resources\BaselineProfileResource;
|
||||
use App\Filament\Resources\BaselineSnapshotResource;
|
||||
use App\Filament\Resources\EntraGroupResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\InventoryItemResource;
|
||||
use App\Filament\Resources\PolicyResource;
|
||||
use App\Filament\Resources\ProviderConnectionResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\Workspaces\WorkspaceResource;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
@ -39,14 +39,14 @@
|
||||
use App\Services\Auth\WorkspaceRoleCapabilityMap;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Filament\PanelThemeAsset;
|
||||
use App\Support\Navigation\AdminSurfaceScope;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
use App\Support\Navigation\WorkspaceHubRegistry;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\Tenants\TenantPageCategory;
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use Filament\FontProviders\LocalFontProvider;
|
||||
use Filament\Http\Middleware\Authenticate;
|
||||
use Filament\Http\Middleware\AuthenticateSession;
|
||||
use Filament\FontProviders\LocalFontProvider;
|
||||
use Filament\Http\Middleware\DisableBladeIconComponents;
|
||||
use Filament\Http\Middleware\DispatchServingFilamentEvent;
|
||||
use Filament\Navigation\NavigationItem;
|
||||
@ -189,7 +189,7 @@ public function panel(Panel $panel): Panel
|
||||
)
|
||||
->renderHook(
|
||||
PanelsRenderHook::PAGE_START,
|
||||
fn (): string => TenantPageCategory::fromRequest(request()) === TenantPageCategory::OnboardingWorkflow
|
||||
fn (): string => AdminSurfaceScope::fromRequest(request()) === AdminSurfaceScope::OnboardingWorkflow
|
||||
|| request()->routeIs('admin.workspace.managed-environments.index', 'filament.admin.pages.choose-environment')
|
||||
? ''
|
||||
: ((bool) config('tenantpilot.bulk_operations.progress_widget_enabled', true)
|
||||
@ -242,7 +242,7 @@ public function panel(Panel $panel): Panel
|
||||
SubstituteBindings::class,
|
||||
'ensure-correct-guard:web',
|
||||
'ensure-workspace-selected',
|
||||
'ensure-filament-tenant-selected',
|
||||
'ensure-environment-context-selected',
|
||||
DisableBladeIconComponents::class,
|
||||
DispatchServingFilamentEvent::class,
|
||||
])
|
||||
|
||||
@ -106,7 +106,7 @@ public function evaluate(TenantOperabilityContext $context, TenantOperabilityQue
|
||||
lifecycle: $lifecycle,
|
||||
lane: $context->lane,
|
||||
reasonCode: TenantOperabilityReasonCode::MissingCapability,
|
||||
discoverable: $question === TenantOperabilityQuestion::AdministrativeDiscoverability || $question === TenantOperabilityQuestion::TenantBoundViewability,
|
||||
discoverable: $question === TenantOperabilityQuestion::AdministrativeDiscoverability || $question === TenantOperabilityQuestion::EnvironmentBoundViewability,
|
||||
requiredCapability: $context->requiredCapability,
|
||||
metadata: $this->metadata($context),
|
||||
);
|
||||
@ -169,7 +169,7 @@ public function evaluate(TenantOperabilityContext $context, TenantOperabilityQue
|
||||
return match ($question) {
|
||||
TenantOperabilityQuestion::SelectorEligibility => $this->selectorEligibilityOutcome($context, $lifecycle),
|
||||
TenantOperabilityQuestion::RememberedContextValidity => $this->rememberedContextOutcome($context, $lifecycle),
|
||||
TenantOperabilityQuestion::TenantBoundViewability => $this->tenantBoundViewabilityOutcome($context, $lifecycle),
|
||||
TenantOperabilityQuestion::EnvironmentBoundViewability => $this->tenantBoundViewabilityOutcome($context, $lifecycle),
|
||||
TenantOperabilityQuestion::CanonicalLinkedRecordViewability => $this->canonicalViewabilityOutcome($context, $lifecycle),
|
||||
TenantOperabilityQuestion::ArchiveEligibility => $this->archiveEligibilityOutcome($context, $lifecycle),
|
||||
TenantOperabilityQuestion::RestoreEligibility => $this->restoreEligibilityOutcome($context, $lifecycle),
|
||||
@ -375,11 +375,11 @@ private function rememberedContextOutcome(TenantOperabilityContext $context, Ten
|
||||
private function tenantBoundViewabilityOutcome(TenantOperabilityContext $context, TenantLifecycle $lifecycle): TenantOperabilityOutcome
|
||||
{
|
||||
if ($context->lane !== TenantInteractionLane::AdministrativeManagement) {
|
||||
return $this->wrongLaneOutcome($context, TenantOperabilityQuestion::TenantBoundViewability, $lifecycle);
|
||||
return $this->wrongLaneOutcome($context, TenantOperabilityQuestion::EnvironmentBoundViewability, $lifecycle);
|
||||
}
|
||||
|
||||
return TenantOperabilityOutcome::allow(
|
||||
question: TenantOperabilityQuestion::TenantBoundViewability,
|
||||
question: TenantOperabilityQuestion::EnvironmentBoundViewability,
|
||||
lifecycle: $lifecycle,
|
||||
lane: $context->lane,
|
||||
discoverable: true,
|
||||
|
||||
@ -181,7 +181,7 @@ public function removeTenantFromWorkspace(ManagedEnvironment $tenant, User $acto
|
||||
'is_current' => false,
|
||||
])->save();
|
||||
|
||||
app(WorkspaceContext::class)->clearRememberedTenantContext();
|
||||
app(WorkspaceContext::class)->clearRememberedEnvironmentContext();
|
||||
|
||||
$this->auditLogger->logTenantLifecycleAction(
|
||||
tenant: $tenant,
|
||||
|
||||
@ -6,18 +6,18 @@
|
||||
|
||||
use App\Models\Finding;
|
||||
use App\Models\FindingException;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\ManagedEnvironmentOnboardingSession;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\PlatformUser;
|
||||
use App\Models\ProductUsageEvent;
|
||||
use App\Models\ProviderConnection;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\ManagedEnvironmentOnboardingSession;
|
||||
use App\Models\Workspace;
|
||||
use App\Support\Auth\PlatformCapabilities;
|
||||
use App\Support\Onboarding\OnboardingLifecycleState;
|
||||
use App\Support\OperationRunOutcome;
|
||||
use App\Support\OperationRunStatus;
|
||||
use App\Support\Auth\PlatformCapabilities;
|
||||
use App\Support\ProductTelemetry\ProductUsageEventCatalog;
|
||||
use App\Support\Providers\ProviderConsentStatus;
|
||||
use App\Support\Providers\ProviderVerificationStatus;
|
||||
@ -68,7 +68,7 @@ public function summaries(SystemConsoleWindow|string|null $window = null, ?Carbo
|
||||
->map(static fn (mixed $workspaceId): int => (int) $workspaceId)
|
||||
->all();
|
||||
|
||||
$activeTenants = ManagedEnvironment::query()
|
||||
$activeEnvironments = ManagedEnvironment::query()
|
||||
->whereIn('workspace_id', $workspaceIds)
|
||||
->whereNull('deleted_at')
|
||||
->where('lifecycle_status', '!=', ManagedEnvironment::STATUS_ARCHIVED)
|
||||
@ -76,7 +76,7 @@ public function summaries(SystemConsoleWindow|string|null $window = null, ?Carbo
|
||||
->orderBy('id')
|
||||
->get(['id', 'workspace_id', 'slug', 'name', 'lifecycle_status']);
|
||||
|
||||
$tenantsByWorkspace = $activeTenants->groupBy(static fn (ManagedEnvironment $tenant): int => (int) $tenant->workspace_id);
|
||||
$tenantsByWorkspace = $activeEnvironments->groupBy(static fn (ManagedEnvironment $tenant): int => (int) $tenant->workspace_id);
|
||||
|
||||
$latestOnboardingSessions = ManagedEnvironmentOnboardingSession::query()
|
||||
->whereIn('workspace_id', $workspaceIds)
|
||||
|
||||
@ -8,36 +8,35 @@
|
||||
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
||||
use App\Filament\Resources\BackupScheduleResource;
|
||||
use App\Filament\Resources\BackupSetResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\EvidenceSnapshotResource;
|
||||
use App\Filament\Resources\FindingExceptionResource;
|
||||
use App\Filament\Resources\FindingResource;
|
||||
use App\Filament\Resources\ReviewPackResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\EnvironmentReview;
|
||||
use App\Models\EvidenceSnapshot;
|
||||
use App\Models\Finding;
|
||||
use App\Models\FindingException;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ProviderConnection;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\EnvironmentReview;
|
||||
use App\Models\User;
|
||||
use App\Services\Intune\ManagedEnvironmentRequiredPermissionsViewModelBuilder;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\BackupHealth\BackupHealthActionTarget;
|
||||
use App\Support\BackupHealth\TenantBackupHealthAssessment;
|
||||
use App\Support\BackupHealth\TenantBackupHealthResolver;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\Badges\BadgeRenderer;
|
||||
use App\Support\Baselines\TenantGovernanceAggregate;
|
||||
use App\Support\Baselines\TenantGovernanceAggregateResolver;
|
||||
use App\Support\Links\RequiredPermissionsLinks;
|
||||
use App\Support\OperationCatalog;
|
||||
use App\Support\OperationRunOutcome;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OperationRunOutcome;
|
||||
use App\Support\OpsUx\ActiveRuns;
|
||||
use App\Support\OpsUx\OperationUxPresenter;
|
||||
use App\Support\RestoreSafety\RestoreResultAttention;
|
||||
use App\Support\RestoreSafety\RestoreSafetyResolver;
|
||||
use App\Support\Tenants\TenantRecoveryTriagePresentation;
|
||||
use App\Support\Verification\VerificationReportOverall;
|
||||
@ -1084,8 +1083,7 @@ private function metricCard(
|
||||
string $icon,
|
||||
array $action,
|
||||
?array $chart = null,
|
||||
): array
|
||||
{
|
||||
): array {
|
||||
return array_merge([
|
||||
'key' => $key,
|
||||
'label' => $label,
|
||||
@ -1165,8 +1163,8 @@ private function environmentReviewAction(ManagedEnvironment $tenant, ?User $user
|
||||
|
||||
if ($canOpen) {
|
||||
$url = $review instanceof EnvironmentReview
|
||||
? EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant)
|
||||
: EnvironmentReviewResource::tenantScopedUrl('index', tenant: $tenant);
|
||||
? EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant)
|
||||
: EnvironmentReviewResource::environmentScopedUrl('index', tenant: $tenant);
|
||||
}
|
||||
|
||||
return $this->actionPayload(
|
||||
@ -1185,7 +1183,7 @@ private function continueReviewAction(ManagedEnvironment $tenant, ?User $user, E
|
||||
|
||||
return $this->actionPayload(
|
||||
label: $this->overviewText('action_continue_review'),
|
||||
url: $canContinue ? EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant) : null,
|
||||
url: $canContinue ? EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant) : null,
|
||||
helperText: $canContinue ? null : $this->overviewText('helper_continue_review_requires_manage'),
|
||||
);
|
||||
}
|
||||
@ -1234,7 +1232,7 @@ private function customerWorkspaceAction(ManagedEnvironment $tenant, ?User $user
|
||||
if ($canOpenWorkspace) {
|
||||
$url = $reviewPack instanceof ReviewPack && $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)
|
||||
? ReviewPackResource::getUrl('view', ['record' => $reviewPack], tenant: $tenant)
|
||||
: CustomerReviewWorkspace::tenantPrefilterUrl($tenant);
|
||||
: CustomerReviewWorkspace::environmentFilterUrl($tenant);
|
||||
}
|
||||
|
||||
return $this->actionPayload(
|
||||
@ -1986,4 +1984,4 @@ private function overviewText(string $key, array $replace = []): string
|
||||
{
|
||||
return (string) __('localization.dashboard.overview.'.$key, $replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,9 +12,9 @@
|
||||
use Illuminate\Session\Store;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
final class CanonicalAdminTenantFilterState
|
||||
final class CanonicalAdminEnvironmentFilterState
|
||||
{
|
||||
private const STATE_PREFIX = 'filament.admin_tenant_filter_state';
|
||||
private const STATE_PREFIX = 'filament.admin_environment_filter_state';
|
||||
|
||||
public function __construct(
|
||||
private readonly OperateHubShell $operateHubShell,
|
||||
@ -25,20 +25,20 @@ public function currentFilterValue(
|
||||
string $filtersSessionKey,
|
||||
?array $tableFilters = null,
|
||||
?Request $request = null,
|
||||
?string $tenantFilterName = 'managed_environment_id',
|
||||
?string $environmentFilterName = 'managed_environment_id',
|
||||
): ?string {
|
||||
if ($tenantFilterName === null) {
|
||||
if ($environmentFilterName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$tableFilterValue = data_get($tableFilters ?? [], "{$tenantFilterName}.value");
|
||||
$tableFilterValue = data_get($tableFilters ?? [], "{$environmentFilterName}.value");
|
||||
|
||||
if (is_scalar($tableFilterValue) && (string) $tableFilterValue !== '') {
|
||||
return (string) $tableFilterValue;
|
||||
}
|
||||
|
||||
$persistedFilters = $this->session($request)->get($filtersSessionKey, []);
|
||||
$persistedValue = data_get(is_array($persistedFilters) ? $persistedFilters : [], "{$tenantFilterName}.value");
|
||||
$persistedValue = data_get(is_array($persistedFilters) ? $persistedFilters : [], "{$environmentFilterName}.value");
|
||||
|
||||
if (! is_scalar($persistedValue) || (string) $persistedValue === '') {
|
||||
return null;
|
||||
@ -48,14 +48,14 @@ public function currentFilterValue(
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, string> $tenantSensitiveFilters
|
||||
* @param array<int, string> $environmentSensitiveFilters
|
||||
*/
|
||||
public function sync(
|
||||
string $filtersSessionKey,
|
||||
array $tenantSensitiveFilters = [],
|
||||
array $environmentSensitiveFilters = [],
|
||||
?Request $request = null,
|
||||
?string $tenantFilterName = 'managed_environment_id',
|
||||
string $tenantAttribute = 'id',
|
||||
?string $environmentFilterName = 'managed_environment_id',
|
||||
string $environmentAttribute = 'id',
|
||||
): void {
|
||||
$session = $this->session($request);
|
||||
|
||||
@ -73,27 +73,27 @@ public function sync(
|
||||
);
|
||||
}
|
||||
|
||||
$activeTenant = $this->operateHubShell->activeEntitledTenant($request);
|
||||
$resolvedTenantId = $activeTenant instanceof ManagedEnvironment ? (string) $activeTenant->getKey() : null;
|
||||
$activeEnvironment = $this->operateHubShell->activeEntitledTenant($request);
|
||||
$resolvedEnvironmentId = $activeEnvironment instanceof ManagedEnvironment ? (string) $activeEnvironment->getKey() : null;
|
||||
$stateKey = $this->stateKey($filtersSessionKey);
|
||||
$previousTenantId = $session->get($stateKey);
|
||||
$previousEnvironmentId = $session->get($stateKey);
|
||||
|
||||
if ($previousTenantId !== $resolvedTenantId) {
|
||||
foreach ($tenantSensitiveFilters as $filterName) {
|
||||
if ($previousEnvironmentId !== $resolvedEnvironmentId) {
|
||||
foreach ($environmentSensitiveFilters as $filterName) {
|
||||
Arr::forget($persistedFilters, $filterName);
|
||||
}
|
||||
}
|
||||
|
||||
if ($tenantFilterName !== null) {
|
||||
$tenantFilterValue = match ($tenantAttribute) {
|
||||
'external_id' => $activeTenant?->external_id,
|
||||
default => $resolvedTenantId,
|
||||
if ($environmentFilterName !== null) {
|
||||
$environmentFilterValue = match ($environmentAttribute) {
|
||||
'external_id' => $activeEnvironment?->external_id,
|
||||
default => $resolvedEnvironmentId,
|
||||
};
|
||||
|
||||
if ($tenantFilterValue !== null) {
|
||||
data_set($persistedFilters, "{$tenantFilterName}.value", $tenantFilterValue);
|
||||
if ($environmentFilterValue !== null) {
|
||||
data_set($persistedFilters, "{$environmentFilterName}.value", $environmentFilterValue);
|
||||
} else {
|
||||
Arr::forget($persistedFilters, $tenantFilterName);
|
||||
Arr::forget($persistedFilters, $environmentFilterName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ public function sync(
|
||||
$session->put($filtersSessionKey, $persistedFilters);
|
||||
}
|
||||
|
||||
$session->put($stateKey, $resolvedTenantId);
|
||||
$session->put($stateKey, $resolvedEnvironmentId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -9,24 +9,23 @@
|
||||
use App\Filament\Pages\Monitoring\FindingExceptionsQueue;
|
||||
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
||||
use App\Filament\Resources\AlertDeliveryResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\FindingExceptionResource;
|
||||
use App\Filament\Resources\FindingResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\AlertDelivery;
|
||||
use App\Models\Finding;
|
||||
use App\Models\FindingException;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\ManagedEnvironmentTriageReview;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
use App\Services\EnvironmentReviews\EnvironmentReviewRegisterService;
|
||||
use App\Support\Auth\Capabilities;
|
||||
use App\Support\BackupHealth\TenantBackupHealthResolver;
|
||||
use App\Support\Navigation\CanonicalNavigationContext;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\PortfolioTriage\PortfolioArrivalContextToken;
|
||||
use App\Support\PortfolioTriage\ManagedEnvironmentTriageReviewStateResolver;
|
||||
use App\Support\PortfolioTriage\PortfolioArrivalContextToken;
|
||||
use App\Support\RestoreSafety\RestoreSafetyResolver;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
@ -550,7 +549,7 @@ private function reviewFollowUpSection(
|
||||
'summary' => $this->reviewSummary($followUpCount, $changedCount),
|
||||
'dominant_action_label' => 'Open customer review workspace',
|
||||
'dominant_action_url' => $selectedTenant instanceof ManagedEnvironment
|
||||
? $this->appendQuery(CustomerReviewWorkspace::tenantPrefilterUrl($selectedTenant), $navigationContext?->toQuery() ?? [])
|
||||
? $this->appendQuery(CustomerReviewWorkspace::environmentFilterUrl($selectedTenant), $navigationContext?->toQuery() ?? [])
|
||||
: $this->appendQuery(CustomerReviewWorkspace::getUrl(panel: 'admin'), $navigationContext?->toQuery() ?? []),
|
||||
'entries' => array_slice($rawEntries, 0, self::PREVIEW_LIMIT),
|
||||
'empty_state' => $selectedTenant instanceof ManagedEnvironment
|
||||
@ -609,12 +608,12 @@ private function orderedIntakeFindingsQuery(\Illuminate\Database\Eloquent\Builde
|
||||
{
|
||||
return $query
|
||||
->orderByRaw(
|
||||
"case
|
||||
'case
|
||||
when due_at is not null and due_at < ? then 0
|
||||
when status = ? then 1
|
||||
when status = ? then 2
|
||||
else 3
|
||||
end asc",
|
||||
end asc',
|
||||
[now(), Finding::STATUS_REOPENED, Finding::STATUS_NEW],
|
||||
)
|
||||
->orderByRaw('case when due_at is null then 1 else 0 end asc')
|
||||
@ -724,13 +723,13 @@ private function orderedFindingExceptionsQuery(\Illuminate\Database\Eloquent\Bui
|
||||
{
|
||||
return $query
|
||||
->orderByRaw(
|
||||
"case
|
||||
'case
|
||||
when status = ? then 0
|
||||
when current_validity_state = ? then 1
|
||||
when current_validity_state = ? then 2
|
||||
when current_validity_state = ? then 3
|
||||
else 4
|
||||
end asc",
|
||||
end asc',
|
||||
[
|
||||
FindingException::STATUS_PENDING,
|
||||
FindingException::VALIDITY_EXPIRED,
|
||||
@ -909,8 +908,8 @@ private function reviewEntry(
|
||||
: null,
|
||||
]));
|
||||
$destinationUrl = $latestPublishedReview !== null
|
||||
? EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $latestPublishedReview], $tenant)
|
||||
: CustomerReviewWorkspace::tenantPrefilterUrl($tenant);
|
||||
? EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $latestPublishedReview], $tenant)
|
||||
: CustomerReviewWorkspace::environmentFilterUrl($tenant);
|
||||
|
||||
return [
|
||||
'family_key' => 'review_follow_up',
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\User;
|
||||
use App\Support\Navigation\AdminSurfaceScope;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
use App\Support\Navigation\WorkspaceHubRegistry;
|
||||
use App\Support\Navigation\WorkspaceSidebarNavigation;
|
||||
use App\Support\OperateHub\OperateHubShell;
|
||||
use App\Support\Tenants\TenantPageCategory;
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use Closure;
|
||||
use Filament\Facades\Filament;
|
||||
@ -16,7 +16,7 @@
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class EnsureFilamentTenantSelected
|
||||
class EnsureEnvironmentContextSelected
|
||||
{
|
||||
/**
|
||||
* @param Closure(Request): Response $next
|
||||
@ -100,7 +100,7 @@ public function handle(Request $request, Closure $next): Response
|
||||
return redirect()->route('filament.admin.pages.choose-environment');
|
||||
}
|
||||
|
||||
if ($resolvedContext->pageCategory === TenantPageCategory::TenantBound && ! $resolvedContext->hasTenant()) {
|
||||
if ($resolvedContext->pageCategory === AdminSurfaceScope::EnvironmentBound && ! $resolvedContext->hasTenant()) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ public function handle(Request $request, Closure $next): Response
|
||||
$resolvedContext->hasTenant()
|
||||
&& (
|
||||
! $this->isWorkspaceScopedPageWithTenant($path)
|
||||
&& $resolvedContext->pageCategory === TenantPageCategory::TenantBound
|
||||
&& $resolvedContext->pageCategory === AdminSurfaceScope::EnvironmentBound
|
||||
)
|
||||
) {
|
||||
Filament::setTenant($resolvedContext->tenant, true);
|
||||
@ -175,7 +175,7 @@ private function isLivewireUpdatePath(string $path): bool
|
||||
|
||||
private function isCanonicalWorkspaceRecordViewerPath(string $path): bool
|
||||
{
|
||||
return TenantPageCategory::fromPath($path) === TenantPageCategory::CanonicalWorkspaceRecordViewer;
|
||||
return AdminSurfaceScope::fromPath($path) === AdminSurfaceScope::CanonicalWorkspaceRecordViewer;
|
||||
}
|
||||
|
||||
private function requestHasExplicitTenantHint(Request $request): bool
|
||||
@ -2,18 +2,18 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Support\Tenants;
|
||||
namespace App\Support\Navigation;
|
||||
|
||||
use App\Support\Navigation\WorkspaceHubRegistry;
|
||||
use App\Support\Tenants\TenantInteractionLane;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
enum TenantPageCategory: string
|
||||
enum AdminSurfaceScope: string
|
||||
{
|
||||
case WorkspaceWideSurface = 'workspace_wide_surface';
|
||||
case WorkspaceScoped = 'workspace_scoped';
|
||||
case WorkspaceChooserException = 'workspace_chooser_exception';
|
||||
case TenantBound = 'tenant_bound';
|
||||
case TenantScopedEvidence = 'tenant_scoped_evidence';
|
||||
case EnvironmentBound = 'environment_bound';
|
||||
case EnvironmentScopedEvidence = 'environment_scoped_evidence';
|
||||
case OnboardingWorkflow = 'onboarding_workflow';
|
||||
case CanonicalWorkspaceRecordViewer = 'canonical_workspace_record_viewer';
|
||||
|
||||
@ -46,7 +46,7 @@ public static function fromPath(string $path): self
|
||||
str_starts_with($normalizedPath, '/admin/evidence/')
|
||||
&& ! str_starts_with($normalizedPath, '/admin/evidence/overview')
|
||||
) {
|
||||
return self::TenantScopedEvidence;
|
||||
return self::EnvironmentScopedEvidence;
|
||||
}
|
||||
|
||||
if (preg_match('#^/admin/onboarding(?:/[^/]+)?$#', $normalizedPath) === 1) {
|
||||
@ -54,13 +54,13 @@ public static function fromPath(string $path): self
|
||||
}
|
||||
|
||||
if (preg_match('#^/admin/workspaces/[^/]+/environments/[^/]+(?:/|$)#', $normalizedPath) === 1) {
|
||||
return self::TenantBound;
|
||||
return self::EnvironmentBound;
|
||||
}
|
||||
|
||||
return self::WorkspaceScoped;
|
||||
}
|
||||
|
||||
public function allowsQueryTenantHints(): bool
|
||||
public function allowsQueryEnvironmentHints(): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::WorkspaceWideSurface, self::WorkspaceScoped, self::OnboardingWorkflow => true,
|
||||
@ -68,7 +68,7 @@ public function allowsQueryTenantHints(): bool
|
||||
};
|
||||
}
|
||||
|
||||
public function allowsRememberedTenantRestore(): bool
|
||||
public function allowsRememberedEnvironmentRestore(): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::WorkspaceScoped, self::OnboardingWorkflow, self::CanonicalWorkspaceRecordViewer => true,
|
||||
@ -76,7 +76,7 @@ public function allowsRememberedTenantRestore(): bool
|
||||
};
|
||||
}
|
||||
|
||||
public function allowsTenantlessState(): bool
|
||||
public function allowsEnvironmentlessState(): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::WorkspaceWideSurface,
|
||||
@ -88,7 +88,7 @@ public function allowsTenantlessState(): bool
|
||||
};
|
||||
}
|
||||
|
||||
public function forcesTenantlessShellContext(): bool
|
||||
public function forcesEnvironmentlessShellContext(): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::WorkspaceWideSurface,
|
||||
@ -98,17 +98,17 @@ public function forcesTenantlessShellContext(): bool
|
||||
};
|
||||
}
|
||||
|
||||
public function requiresExplicitTenant(): bool
|
||||
public function requiresExplicitEnvironment(): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::TenantBound, self::TenantScopedEvidence => true,
|
||||
self::EnvironmentBound, self::EnvironmentScopedEvidence => true,
|
||||
default => false,
|
||||
};
|
||||
}
|
||||
|
||||
public function lane(): TenantInteractionLane
|
||||
{
|
||||
return TenantInteractionLane::fromPageCategory($this);
|
||||
return TenantInteractionLane::fromSurfaceScope($this);
|
||||
}
|
||||
|
||||
private static function isWorkspaceWideSurfacePath(string $normalizedPath): bool
|
||||
@ -4,7 +4,6 @@
|
||||
|
||||
namespace App\Support\Navigation;
|
||||
|
||||
use App\Support\Tenants\TenantPageCategory;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
final class NavigationScope
|
||||
@ -17,8 +16,8 @@ public static function isWorkspaceSurface(?Request $request = null): bool
|
||||
public static function isEnvironmentSurface(?Request $request = null): bool
|
||||
{
|
||||
return in_array(self::pageCategory($request), [
|
||||
TenantPageCategory::TenantBound,
|
||||
TenantPageCategory::TenantScopedEvidence,
|
||||
AdminSurfaceScope::EnvironmentBound,
|
||||
AdminSurfaceScope::EnvironmentScopedEvidence,
|
||||
], true);
|
||||
}
|
||||
|
||||
@ -27,9 +26,9 @@ public static function shouldRegisterEnvironmentNavigation(?Request $request = n
|
||||
return self::isEnvironmentSurface($request);
|
||||
}
|
||||
|
||||
public static function pageCategory(?Request $request = null): TenantPageCategory
|
||||
public static function pageCategory(?Request $request = null): AdminSurfaceScope
|
||||
{
|
||||
return TenantPageCategory::fromPath(self::effectivePath($request));
|
||||
return AdminSurfaceScope::fromPath(self::effectivePath($request));
|
||||
}
|
||||
|
||||
private static function effectivePath(?Request $request = null): string
|
||||
|
||||
@ -20,11 +20,11 @@
|
||||
use App\Models\BaselineSnapshotItem;
|
||||
use App\Models\Finding;
|
||||
use App\Models\FindingException;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\Policy;
|
||||
use App\Models\PolicyVersion;
|
||||
use App\Models\RestoreRun;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
use App\Services\Auth\CapabilityResolver;
|
||||
@ -39,7 +39,6 @@
|
||||
use App\Support\Ui\DerivedState\DerivedStateFamily;
|
||||
use App\Support\Ui\DerivedState\DerivedStateKey;
|
||||
use App\Support\Ui\DerivedState\RequestScopedDerivedStateStore;
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
@ -367,7 +366,7 @@ private function memoizedEntries(
|
||||
context: [
|
||||
'source_type' => $sourceType,
|
||||
'surface' => $surface,
|
||||
'active_tenant_id' => $this->activeTenantId(),
|
||||
'active_tenant_id' => $this->activeEnvironmentId(),
|
||||
'route_name' => request()?->route()?->getName(),
|
||||
'user_id' => auth()->id(),
|
||||
],
|
||||
@ -631,7 +630,7 @@ private function snapshotPolicyVersionEntry(NavigationMatrixRule $rule, Baseline
|
||||
return $this->policyVersionEntry(
|
||||
rule: $rule,
|
||||
policyVersionId: is_numeric($policyVersionId) ? (int) $policyVersionId : null,
|
||||
tenantId: $this->activeTenantId(),
|
||||
tenantId: $this->activeEnvironmentId(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -1094,7 +1093,7 @@ private function contextForOperationRun(OperationRun $run): CanonicalNavigationC
|
||||
);
|
||||
}
|
||||
|
||||
private function activeTenantId(): ?int
|
||||
private function activeEnvironmentId(): ?int
|
||||
{
|
||||
$tenant = app(OperateHubShell::class)->activeEntitledTenant(request());
|
||||
|
||||
|
||||
@ -10,9 +10,9 @@
|
||||
use App\Services\Auth\CapabilityResolver;
|
||||
use App\Services\Tenants\TenantOperabilityService;
|
||||
use App\Support\ManagedEnvironmentLinks;
|
||||
use App\Support\Navigation\AdminSurfaceScope;
|
||||
use App\Support\Navigation\WorkspaceHubRegistry;
|
||||
use App\Support\Tenants\TenantOperabilityQuestion;
|
||||
use App\Support\Tenants\TenantPageCategory;
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Facades\Filament;
|
||||
@ -30,10 +30,10 @@ public function __construct(
|
||||
|
||||
public function scopeLabel(?Request $request = null): string
|
||||
{
|
||||
$activeTenant = $this->activeEntitledTenant($request);
|
||||
$activeEnvironment = $this->activeEntitledTenant($request);
|
||||
|
||||
if ($activeTenant instanceof ManagedEnvironment) {
|
||||
return __('localization.shell.environment_scope').': '.$activeTenant->name;
|
||||
if ($activeEnvironment instanceof ManagedEnvironment) {
|
||||
return __('localization.shell.environment_scope').': '.$activeEnvironment->name;
|
||||
}
|
||||
|
||||
return __('localization.shell.all_environments');
|
||||
@ -44,12 +44,12 @@ public function scopeLabel(?Request $request = null): string
|
||||
*/
|
||||
public function returnAffordance(?Request $request = null): ?array
|
||||
{
|
||||
$activeTenant = $this->activeEntitledTenant($request);
|
||||
$activeEnvironment = $this->activeEntitledTenant($request);
|
||||
|
||||
if ($activeTenant instanceof ManagedEnvironment) {
|
||||
if ($activeEnvironment instanceof ManagedEnvironment) {
|
||||
return [
|
||||
'label' => 'Back to '.$activeTenant->name,
|
||||
'url' => ManagedEnvironmentLinks::viewUrl($activeTenant),
|
||||
'label' => 'Back to '.$activeEnvironment->name,
|
||||
'url' => ManagedEnvironmentLinks::viewUrl($activeEnvironment),
|
||||
];
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo
|
||||
pageCategory: $pageCategory,
|
||||
state: 'missing_workspace',
|
||||
displayMode: 'recovery',
|
||||
recoveryAction: $pageCategory === TenantPageCategory::WorkspaceChooserException ? 'none' : 'redirect_choose_workspace',
|
||||
recoveryAction: $pageCategory === AdminSurfaceScope::WorkspaceChooserException ? 'none' : 'redirect_choose_workspace',
|
||||
recoveryDestination: '/admin/choose-workspace',
|
||||
recoveryReason: 'missing_workspace',
|
||||
);
|
||||
@ -157,7 +157,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo
|
||||
|
||||
$recoveryReason = $routeTenant['reason'];
|
||||
|
||||
if ($pageCategory === TenantPageCategory::TenantBound && $recoveryReason !== null) {
|
||||
if ($pageCategory === AdminSurfaceScope::EnvironmentBound && $recoveryReason !== null) {
|
||||
return new ResolvedShellContext(
|
||||
workspace: $workspace,
|
||||
tenant: null,
|
||||
@ -170,7 +170,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo
|
||||
);
|
||||
}
|
||||
|
||||
if ($pageCategory->forcesTenantlessShellContext()) {
|
||||
if ($pageCategory->forcesEnvironmentlessShellContext()) {
|
||||
return new ResolvedShellContext(
|
||||
workspace: $workspace,
|
||||
tenant: null,
|
||||
@ -225,13 +225,13 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo
|
||||
);
|
||||
}
|
||||
|
||||
if ($pageCategory->allowsRememberedTenantRestore()) {
|
||||
$rememberedTenant = $this->workspaceContext->rememberedTenant($request);
|
||||
if ($pageCategory->allowsRememberedEnvironmentRestore()) {
|
||||
$rememberedEnvironment = $this->workspaceContext->rememberedEnvironment($request);
|
||||
|
||||
if ($rememberedTenant instanceof ManagedEnvironment) {
|
||||
if ($rememberedEnvironment instanceof ManagedEnvironment) {
|
||||
return new ResolvedShellContext(
|
||||
workspace: $workspace,
|
||||
tenant: $rememberedTenant,
|
||||
tenant: $rememberedEnvironment,
|
||||
pageCategory: $pageCategory,
|
||||
state: 'tenant_scoped',
|
||||
displayMode: 'tenant_scoped',
|
||||
@ -241,7 +241,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo
|
||||
}
|
||||
}
|
||||
|
||||
if ($pageCategory->requiresExplicitTenant()) {
|
||||
if ($pageCategory->requiresExplicitEnvironment()) {
|
||||
return new ResolvedShellContext(
|
||||
workspace: $workspace,
|
||||
tenant: null,
|
||||
@ -249,10 +249,10 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo
|
||||
state: 'missing_tenant',
|
||||
displayMode: 'recovery',
|
||||
workspaceSource: $workspaceSource,
|
||||
recoveryAction: $pageCategory === TenantPageCategory::TenantScopedEvidence
|
||||
recoveryAction: $pageCategory === AdminSurfaceScope::EnvironmentScopedEvidence
|
||||
? 'redirect_evidence_overview'
|
||||
: 'abort_not_found',
|
||||
recoveryDestination: $pageCategory === TenantPageCategory::TenantScopedEvidence
|
||||
recoveryDestination: $pageCategory === AdminSurfaceScope::EnvironmentScopedEvidence
|
||||
? '/admin/evidence/overview'
|
||||
: null,
|
||||
recoveryReason: $recoveryReason ?? 'missing_tenant',
|
||||
@ -272,7 +272,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo
|
||||
|
||||
private function resolveValidatedFilamentTenant(
|
||||
?Request $request = null,
|
||||
?TenantPageCategory $pageCategory = null,
|
||||
?AdminSurfaceScope $pageCategory = null,
|
||||
?Workspace $workspace = null,
|
||||
): ?ManagedEnvironment {
|
||||
$tenant = Filament::getTenant();
|
||||
@ -297,7 +297,7 @@ private function resolveValidatedRouteTenant(
|
||||
?ManagedEnvironment $tenant,
|
||||
Workspace $workspace,
|
||||
?Request $request = null,
|
||||
?TenantPageCategory $pageCategory = null,
|
||||
?AdminSurfaceScope $pageCategory = null,
|
||||
): array {
|
||||
$pageCategory ??= $this->pageCategory($request);
|
||||
|
||||
@ -316,22 +316,22 @@ private function resolveValidatedRouteTenant(
|
||||
|
||||
private function resolveWorkspaceForPageCategory(
|
||||
?ManagedEnvironment $tenant,
|
||||
TenantPageCategory $pageCategory,
|
||||
AdminSurfaceScope $pageCategory,
|
||||
?Request $request = null,
|
||||
): ?Workspace {
|
||||
return match ($pageCategory) {
|
||||
TenantPageCategory::TenantScopedEvidence => $this->workspaceContext->currentWorkspace($request),
|
||||
TenantPageCategory::TenantBound => $this->workspaceContext->currentWorkspaceOrTenantWorkspace($tenant, $request),
|
||||
default => $this->workspaceContext->currentWorkspaceOrTenantWorkspace($tenant, $request),
|
||||
AdminSurfaceScope::EnvironmentScopedEvidence => $this->workspaceContext->currentWorkspace($request),
|
||||
AdminSurfaceScope::EnvironmentBound => $this->workspaceContext->currentWorkspaceOrEnvironmentWorkspace($tenant, $request),
|
||||
default => $this->workspaceContext->currentWorkspaceOrEnvironmentWorkspace($tenant, $request),
|
||||
};
|
||||
}
|
||||
|
||||
private function resolveValidatedQueryHintTenant(
|
||||
?Request $request,
|
||||
Workspace $workspace,
|
||||
TenantPageCategory $pageCategory,
|
||||
AdminSurfaceScope $pageCategory,
|
||||
): array {
|
||||
if (! $pageCategory->allowsQueryTenantHints()) {
|
||||
if (! $pageCategory->allowsQueryEnvironmentHints()) {
|
||||
return ['tenant' => null, 'reason' => null];
|
||||
}
|
||||
|
||||
@ -350,7 +350,7 @@ private function resolveValidatedQueryHintTenant(
|
||||
return ['tenant' => $queryTenant, 'reason' => null];
|
||||
}
|
||||
|
||||
private function resolveRouteTenantCandidate(?Request $request = null, ?TenantPageCategory $pageCategory = null): ?ManagedEnvironment
|
||||
private function resolveRouteTenantCandidate(?Request $request = null, ?AdminSurfaceScope $pageCategory = null): ?ManagedEnvironment
|
||||
{
|
||||
$route = $request?->route();
|
||||
$pageCategory ??= $this->pageCategory($request);
|
||||
@ -445,7 +445,7 @@ private function tenantValidationReason(
|
||||
ManagedEnvironment $tenant,
|
||||
Workspace $workspace,
|
||||
?Request $request = null,
|
||||
?TenantPageCategory $pageCategory = null,
|
||||
?AdminSurfaceScope $pageCategory = null,
|
||||
): ?string {
|
||||
$pageCategory ??= $this->pageCategory($request);
|
||||
|
||||
@ -463,8 +463,8 @@ private function tenantValidationReason(
|
||||
return 'not_member';
|
||||
}
|
||||
|
||||
$question = $pageCategory === TenantPageCategory::TenantBound
|
||||
? TenantOperabilityQuestion::TenantBoundViewability
|
||||
$question = $pageCategory === AdminSurfaceScope::EnvironmentBound
|
||||
? TenantOperabilityQuestion::EnvironmentBoundViewability
|
||||
: TenantOperabilityQuestion::AdministrativeDiscoverability;
|
||||
|
||||
$allowed = $this->tenantOperabilityService->outcomeFor(
|
||||
@ -480,13 +480,13 @@ private function tenantValidationReason(
|
||||
return null;
|
||||
}
|
||||
|
||||
return $pageCategory === TenantPageCategory::TenantBound
|
||||
return $pageCategory === AdminSurfaceScope::EnvironmentBound
|
||||
? 'inaccessible'
|
||||
: 'not_operable';
|
||||
}
|
||||
|
||||
private function pageCategory(?Request $request = null): TenantPageCategory
|
||||
private function pageCategory(?Request $request = null): AdminSurfaceScope
|
||||
{
|
||||
return TenantPageCategory::fromRequest($request);
|
||||
return AdminSurfaceScope::fromRequest($request);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,14 +6,14 @@
|
||||
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\Workspace;
|
||||
use App\Support\Tenants\TenantPageCategory;
|
||||
use App\Support\Navigation\AdminSurfaceScope;
|
||||
|
||||
final readonly class ResolvedShellContext
|
||||
{
|
||||
public function __construct(
|
||||
public ?Workspace $workspace,
|
||||
public ?ManagedEnvironment $tenant,
|
||||
public TenantPageCategory $pageCategory,
|
||||
public AdminSurfaceScope $pageCategory,
|
||||
public string $state,
|
||||
public string $displayMode,
|
||||
public string $workspaceSource = 'none',
|
||||
|
||||
@ -237,7 +237,7 @@ public static function related(OperationRun $run, ?ManagedEnvironment $tenant):
|
||||
->first();
|
||||
|
||||
if ($review instanceof EnvironmentReview) {
|
||||
$links['ManagedEnvironment Review'] = EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant);
|
||||
$links['ManagedEnvironment Review'] = EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,18 +4,18 @@
|
||||
|
||||
namespace App\Support\SupportDiagnostics;
|
||||
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\FindingResource;
|
||||
use App\Filament\Resources\ProviderConnectionResource;
|
||||
use App\Filament\Resources\ReviewPackResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\AuditLog;
|
||||
use App\Models\EnvironmentReview;
|
||||
use App\Models\Finding;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ProviderConnection;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\StoredReport;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\EnvironmentReview;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
use App\Support\Ai\AiDataClassification;
|
||||
@ -741,7 +741,7 @@ private function environmentReviewSection(?EnvironmentReview $review, ?ManagedEn
|
||||
label: 'ManagedEnvironment review #'.$review->getKey(),
|
||||
actionLabel: 'Open environment review',
|
||||
url: $tenant instanceof ManagedEnvironment
|
||||
? EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant)
|
||||
? EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant)
|
||||
: null,
|
||||
freshnessAt: $review->generated_at,
|
||||
),
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
|
||||
namespace App\Support\Tenants;
|
||||
|
||||
use App\Support\Navigation\AdminSurfaceScope;
|
||||
|
||||
enum TenantInteractionLane: string
|
||||
{
|
||||
case StandardActiveOperating = 'standard_active_operating';
|
||||
@ -11,16 +13,16 @@ enum TenantInteractionLane: string
|
||||
case AdministrativeManagement = 'administrative_management';
|
||||
case CanonicalWorkspaceRecord = 'canonical_workspace_record';
|
||||
|
||||
public static function fromPageCategory(TenantPageCategory $pageCategory): self
|
||||
public static function fromSurfaceScope(AdminSurfaceScope $pageCategory): self
|
||||
{
|
||||
return match ($pageCategory) {
|
||||
TenantPageCategory::OnboardingWorkflow => self::OnboardingWorkflow,
|
||||
TenantPageCategory::TenantBound,
|
||||
TenantPageCategory::TenantScopedEvidence => self::AdministrativeManagement,
|
||||
TenantPageCategory::CanonicalWorkspaceRecordViewer => self::CanonicalWorkspaceRecord,
|
||||
TenantPageCategory::WorkspaceWideSurface,
|
||||
TenantPageCategory::WorkspaceScoped,
|
||||
TenantPageCategory::WorkspaceChooserException => self::StandardActiveOperating,
|
||||
AdminSurfaceScope::OnboardingWorkflow => self::OnboardingWorkflow,
|
||||
AdminSurfaceScope::EnvironmentBound,
|
||||
AdminSurfaceScope::EnvironmentScopedEvidence => self::AdministrativeManagement,
|
||||
AdminSurfaceScope::CanonicalWorkspaceRecordViewer => self::CanonicalWorkspaceRecord,
|
||||
AdminSurfaceScope::WorkspaceWideSurface,
|
||||
AdminSurfaceScope::WorkspaceScoped,
|
||||
AdminSurfaceScope::WorkspaceChooserException => self::StandardActiveOperating,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ public function supportsQuestion(TenantOperabilityQuestion $question, TenantInte
|
||||
return match ($question) {
|
||||
TenantOperabilityQuestion::SelectorEligibility,
|
||||
TenantOperabilityQuestion::RememberedContextValidity => $lane === TenantInteractionLane::StandardActiveOperating && $this->isSelectableInStandardLane(),
|
||||
TenantOperabilityQuestion::TenantBoundViewability => $lane === TenantInteractionLane::AdministrativeManagement,
|
||||
TenantOperabilityQuestion::EnvironmentBoundViewability => $lane === TenantInteractionLane::AdministrativeManagement,
|
||||
TenantOperabilityQuestion::CanonicalLinkedRecordViewability => $lane === TenantInteractionLane::CanonicalWorkspaceRecord,
|
||||
TenantOperabilityQuestion::ArchiveEligibility => $lane === TenantInteractionLane::AdministrativeManagement && $this->canArchive(),
|
||||
TenantOperabilityQuestion::RestoreEligibility => $lane === TenantInteractionLane::AdministrativeManagement && $this->canRestore(),
|
||||
|
||||
@ -100,7 +100,7 @@ public static function invalid(?string $normalizedValue = null): self
|
||||
badgeIcon: 'heroicon-m-exclamation-triangle',
|
||||
badgeIconColor: 'danger',
|
||||
shortDescription: 'Lifecycle data is invalid and requires review.',
|
||||
longDescription: 'The stored tenant lifecycle value is not canonical. Review the source data before treating this tenant as draft, onboarding, active, or archived.',
|
||||
longDescription: 'The stored environment lifecycle value is not canonical. Review the source data before treating this tenant as draft, onboarding, active, or archived.',
|
||||
isInvalidFallback: true,
|
||||
lifecycle: null,
|
||||
);
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\ManagedEnvironmentOnboardingSession;
|
||||
use App\Models\User;
|
||||
use App\Support\Navigation\AdminSurfaceScope;
|
||||
|
||||
final readonly class TenantOperabilityContext
|
||||
{
|
||||
@ -15,7 +16,7 @@ public function __construct(
|
||||
public ?User $actor,
|
||||
public ?int $workspaceId,
|
||||
public TenantInteractionLane $lane,
|
||||
public ?TenantPageCategory $pageCategory = null,
|
||||
public ?AdminSurfaceScope $pageCategory = null,
|
||||
public ?string $linkedRecordType = null,
|
||||
public ?int $linkedRecordId = null,
|
||||
public ?ManagedEnvironmentOnboardingSession $onboardingDraft = null,
|
||||
@ -28,7 +29,7 @@ public static function forTenant(
|
||||
?User $actor = null,
|
||||
?int $workspaceId = null,
|
||||
TenantInteractionLane $lane = TenantInteractionLane::AdministrativeManagement,
|
||||
?TenantPageCategory $pageCategory = null,
|
||||
?AdminSurfaceScope $pageCategory = null,
|
||||
?ManagedEnvironmentOnboardingSession $onboardingDraft = null,
|
||||
?string $requiredCapability = null,
|
||||
?ManagedEnvironment $selectedTenant = null,
|
||||
|
||||
@ -8,7 +8,7 @@ enum TenantOperabilityQuestion: string
|
||||
{
|
||||
case SelectorEligibility = 'selector_eligibility';
|
||||
case RememberedContextValidity = 'remembered_context_validity';
|
||||
case TenantBoundViewability = 'tenant_bound_viewability';
|
||||
case EnvironmentBoundViewability = 'environment_bound_viewability';
|
||||
case CanonicalLinkedRecordViewability = 'canonical_linked_record_viewability';
|
||||
case ArchiveEligibility = 'archive_eligibility';
|
||||
case RestoreEligibility = 'restore_eligibility';
|
||||
|
||||
@ -55,7 +55,7 @@ public function shortExplanation(): string
|
||||
self::TenantAlreadyArchived => 'The tenant is already archived, so there is nothing else to do for this action.',
|
||||
self::OnboardingNotResumable => 'This onboarding session can no longer be resumed from the current lifecycle state.',
|
||||
self::CanonicalViewFollowupOnly => 'This canonical workspace view is informational only and cannot complete tenant follow-up directly.',
|
||||
self::RememberedContextStale => 'The remembered tenant context is no longer valid for the current tenant selector state.',
|
||||
self::RememberedContextStale => 'The remembered environment context is no longer valid for the current tenant selector state.',
|
||||
self::WorkspaceClosed => 'This workspace is closed and cannot be used for active tenant context or new tenant operations until it is reopened.',
|
||||
self::TenantRemovedFromWorkspace => 'This tenant was removed from the workspace and cannot be selected or used for new tenant operations until it is restored.',
|
||||
};
|
||||
|
||||
@ -5,20 +5,22 @@
|
||||
namespace App\Support\Ui\GovernanceArtifactTruth;
|
||||
|
||||
use App\Filament\Resources\BaselineSnapshotResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\EvidenceSnapshotResource;
|
||||
use App\Filament\Resources\ReviewPackResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\BaselineSnapshot;
|
||||
use App\Models\EnvironmentReview;
|
||||
use App\Models\EvidenceSnapshot;
|
||||
use App\Models\FindingExceptionDecision;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\StoredReport;
|
||||
use App\Models\EnvironmentReview;
|
||||
use App\Services\Baselines\BaselineSnapshotTruthResolver;
|
||||
use App\Services\Baselines\SnapshotRendering\FidelityState;
|
||||
use App\Support\Badges\BadgeCatalog;
|
||||
use App\Support\Badges\BadgeDomain;
|
||||
use App\Support\EnvironmentReviewCompletenessState;
|
||||
use App\Support\EnvironmentReviewStatus;
|
||||
use App\Support\Evidence\EvidenceCompletenessState;
|
||||
use App\Support\OperationCatalog;
|
||||
use App\Support\OperationRunLinks;
|
||||
@ -28,8 +30,6 @@
|
||||
use App\Support\ReasonTranslation\ReasonPresenter;
|
||||
use App\Support\ReasonTranslation\ReasonResolutionEnvelope;
|
||||
use App\Support\ReviewPackStatus;
|
||||
use App\Support\EnvironmentReviewCompletenessState;
|
||||
use App\Support\EnvironmentReviewStatus;
|
||||
use App\Support\Ui\DerivedState\DerivedStateFamily;
|
||||
use App\Support\Ui\DerivedState\DerivedStateKey;
|
||||
use App\Support\Ui\DerivedState\RequestScopedDerivedStateStore;
|
||||
@ -600,7 +600,7 @@ private function buildEnvironmentReviewEnvelope(EnvironmentReview $review): Arti
|
||||
|
||||
if ($publishBlockers !== [] && $review->tenant !== null) {
|
||||
$nextActionUrl = $this->panelSafeTenantArtifactUrl(
|
||||
fn (): string => EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $review], $review->tenant)
|
||||
fn (): string => EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $review->tenant)
|
||||
);
|
||||
} elseif (($freshnessState === 'stale' || $contentState === 'partial') && $review->tenant !== null && $review->evidenceSnapshot !== null) {
|
||||
$nextActionUrl = $this->panelSafeTenantArtifactUrl(
|
||||
@ -642,7 +642,7 @@ private function buildEnvironmentReviewEnvelope(EnvironmentReview $review): Arti
|
||||
relatedRunId: $review->operation_run_id !== null ? (int) $review->operation_run_id : null,
|
||||
relatedArtifactUrl: $review->tenant !== null
|
||||
? $this->panelSafeTenantArtifactUrl(
|
||||
fn (): string => EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $review], $review->tenant)
|
||||
fn (): string => EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $review->tenant)
|
||||
)
|
||||
: null,
|
||||
includePublicationDimension: true,
|
||||
@ -785,7 +785,7 @@ private function buildReviewPackEnvelope(ReviewPack $pack): ArtifactTruthEnvelop
|
||||
|
||||
if ($sourceReview instanceof EnvironmentReview && $pack->tenant !== null) {
|
||||
$nextActionUrl = $this->panelSafeTenantArtifactUrl(
|
||||
fn (): string => EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $sourceReview], $pack->tenant)
|
||||
fn (): string => EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $sourceReview], $pack->tenant)
|
||||
);
|
||||
} elseif (($freshnessState === 'stale' || $contentState === 'partial') && $pack->tenant !== null && $pack->evidenceSnapshot !== null) {
|
||||
$nextActionUrl = $this->panelSafeTenantArtifactUrl(
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use App\Filament\Resources\BackupScheduleResource;
|
||||
use App\Filament\Resources\BackupSetResource;
|
||||
use App\Filament\Resources\EntraGroupResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\EvidenceSnapshotResource;
|
||||
use App\Filament\Resources\FindingExceptionResource;
|
||||
use App\Filament\Resources\FindingResource;
|
||||
@ -15,10 +16,10 @@
|
||||
use App\Filament\Resources\PolicyVersionResource;
|
||||
use App\Filament\Resources\RestoreRunResource;
|
||||
use App\Filament\Resources\StoredReportResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\BackupSchedule;
|
||||
use App\Models\BackupSet;
|
||||
use App\Models\EntraGroup;
|
||||
use App\Models\EnvironmentReview;
|
||||
use App\Models\EvidenceSnapshot;
|
||||
use App\Models\Finding;
|
||||
use App\Models\FindingException;
|
||||
@ -27,7 +28,6 @@
|
||||
use App\Models\PolicyVersion;
|
||||
use App\Models\RestoreRun;
|
||||
use App\Models\StoredReport;
|
||||
use App\Models\EnvironmentReview;
|
||||
|
||||
final class TenantOwnedModelFamilies
|
||||
{
|
||||
@ -251,7 +251,7 @@ public static function scopeExceptions(): array
|
||||
'why_excepted' => 'Workspace-admin tenant-default surface referencing tenant-owned data without being part of the mandatory first-slice canon.',
|
||||
'still_required_checks' => [
|
||||
'workspace membership',
|
||||
'remembered tenant entitlement',
|
||||
'remembered environment entitlement',
|
||||
'capability gating on the destination action',
|
||||
],
|
||||
],
|
||||
|
||||
@ -18,7 +18,7 @@ final class WorkspaceContext
|
||||
|
||||
public const INTENDED_URL_SESSION_KEY = 'workspace_intended_url';
|
||||
|
||||
public const LAST_TENANT_IDS_SESSION_KEY = 'workspace_last_tenant_ids';
|
||||
public const LAST_ENVIRONMENT_IDS_SESSION_KEY = 'workspace_last_environment_ids';
|
||||
|
||||
public function __construct(
|
||||
private WorkspaceResolver $resolver,
|
||||
@ -55,7 +55,7 @@ public function currentWorkspace(?Request $request = null): ?Workspace
|
||||
return $workspace;
|
||||
}
|
||||
|
||||
public function currentWorkspaceOrTenantWorkspace(?ManagedEnvironment $tenant = null, ?Request $request = null): ?Workspace
|
||||
public function currentWorkspaceOrEnvironmentWorkspace(?ManagedEnvironment $tenant = null, ?Request $request = null): ?Workspace
|
||||
{
|
||||
$workspace = $this->currentWorkspace($request);
|
||||
|
||||
@ -96,19 +96,19 @@ public function setCurrentWorkspace(Workspace $workspace, ?User $user = null, ?R
|
||||
}
|
||||
}
|
||||
|
||||
public function rememberLastTenantId(int $workspaceId, int $tenantId, ?Request $request = null): void
|
||||
public function rememberLastEnvironmentId(int $workspaceId, int $tenantId, ?Request $request = null): void
|
||||
{
|
||||
$session = ($request && $request->hasSession()) ? $request->session() : session();
|
||||
|
||||
$map = $session->get(self::LAST_TENANT_IDS_SESSION_KEY, []);
|
||||
$map = $session->get(self::LAST_ENVIRONMENT_IDS_SESSION_KEY, []);
|
||||
$map = is_array($map) ? $map : [];
|
||||
|
||||
$map[(string) $workspaceId] = $tenantId;
|
||||
|
||||
$session->put(self::LAST_TENANT_IDS_SESSION_KEY, $map);
|
||||
$session->put(self::LAST_ENVIRONMENT_IDS_SESSION_KEY, $map);
|
||||
}
|
||||
|
||||
public function rememberTenantContext(ManagedEnvironment $tenant, ?Request $request = null): bool
|
||||
public function rememberEnvironmentContext(ManagedEnvironment $tenant, ?Request $request = null): bool
|
||||
{
|
||||
$workspaceId = $this->currentWorkspaceId($request);
|
||||
|
||||
@ -125,23 +125,23 @@ public function rememberTenantContext(ManagedEnvironment $tenant, ?Request $requ
|
||||
);
|
||||
|
||||
if (! $outcome->allowed) {
|
||||
$this->clearLastTenantId($request);
|
||||
$this->clearLastEnvironmentId($request);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->userCanAccessTenant($tenant, $request)) {
|
||||
$this->clearRememberedTenantContext($request);
|
||||
$this->clearRememberedEnvironmentContext($request);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->rememberLastTenantId($workspaceId, (int) $tenant->getKey(), $request);
|
||||
$this->rememberLastEnvironmentId($workspaceId, (int) $tenant->getKey(), $request);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function lastTenantId(?Request $request = null): ?int
|
||||
public function lastEnvironmentId(?Request $request = null): ?int
|
||||
{
|
||||
$workspaceId = $this->currentWorkspaceId($request);
|
||||
|
||||
@ -151,7 +151,7 @@ public function lastTenantId(?Request $request = null): ?int
|
||||
|
||||
$session = ($request && $request->hasSession()) ? $request->session() : session();
|
||||
|
||||
$map = $session->get(self::LAST_TENANT_IDS_SESSION_KEY, []);
|
||||
$map = $session->get(self::LAST_ENVIRONMENT_IDS_SESSION_KEY, []);
|
||||
$map = is_array($map) ? $map : [];
|
||||
|
||||
$id = $map[(string) $workspaceId] ?? null;
|
||||
@ -159,7 +159,7 @@ public function lastTenantId(?Request $request = null): ?int
|
||||
return is_int($id) ? $id : (is_numeric($id) ? (int) $id : null);
|
||||
}
|
||||
|
||||
public function clearLastTenantId(?Request $request = null): void
|
||||
public function clearLastEnvironmentId(?Request $request = null): void
|
||||
{
|
||||
$workspaceId = $this->currentWorkspaceId($request);
|
||||
|
||||
@ -169,20 +169,20 @@ public function clearLastTenantId(?Request $request = null): void
|
||||
|
||||
$session = ($request && $request->hasSession()) ? $request->session() : session();
|
||||
|
||||
$map = $session->get(self::LAST_TENANT_IDS_SESSION_KEY, []);
|
||||
$map = $session->get(self::LAST_ENVIRONMENT_IDS_SESSION_KEY, []);
|
||||
$map = is_array($map) ? $map : [];
|
||||
|
||||
unset($map[(string) $workspaceId]);
|
||||
|
||||
$session->put(self::LAST_TENANT_IDS_SESSION_KEY, $map);
|
||||
$session->put(self::LAST_ENVIRONMENT_IDS_SESSION_KEY, $map);
|
||||
}
|
||||
|
||||
public function clearRememberedTenantContext(?Request $request = null): void
|
||||
public function clearRememberedEnvironmentContext(?Request $request = null): void
|
||||
{
|
||||
$this->clearLastTenantId($request);
|
||||
$this->clearLastEnvironmentId($request);
|
||||
}
|
||||
|
||||
public function rememberedTenant(?Request $request = null): ?ManagedEnvironment
|
||||
public function rememberedEnvironment(?Request $request = null): ?ManagedEnvironment
|
||||
{
|
||||
$workspaceId = $this->currentWorkspaceId($request);
|
||||
|
||||
@ -190,31 +190,31 @@ public function rememberedTenant(?Request $request = null): ?ManagedEnvironment
|
||||
return null;
|
||||
}
|
||||
|
||||
$rememberedTenantId = $this->lastTenantId($request);
|
||||
$rememberedEnvironmentId = $this->lastEnvironmentId($request);
|
||||
|
||||
if ($rememberedTenantId === null) {
|
||||
if ($rememberedEnvironmentId === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$tenant = ManagedEnvironment::query()
|
||||
->withTrashed()
|
||||
->whereKey($rememberedTenantId)
|
||||
->whereKey($rememberedEnvironmentId)
|
||||
->first();
|
||||
|
||||
if (! $tenant instanceof ManagedEnvironment) {
|
||||
$this->clearRememberedTenantContext($request);
|
||||
$this->clearRememberedEnvironmentContext($request);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((int) $tenant->workspace_id !== $workspaceId) {
|
||||
$this->clearRememberedTenantContext($request);
|
||||
$this->clearRememberedEnvironmentContext($request);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->userCanAccessTenant($tenant, $request)) {
|
||||
$this->clearRememberedTenantContext($request);
|
||||
$this->clearRememberedEnvironmentContext($request);
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -228,7 +228,7 @@ public function rememberedTenant(?Request $request = null): ?ManagedEnvironment
|
||||
);
|
||||
|
||||
if (! $outcome->allowed) {
|
||||
$this->clearRememberedTenantContext($request);
|
||||
$this->clearRememberedEnvironmentContext($request);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
|
||||
use App\Http\Middleware\ApplyResolvedLocale;
|
||||
use App\Http\Middleware\SuppressDebugbarForSmokeRequests;
|
||||
use App\Http\Middleware\UseSystemSessionCookieForLivewireRequests;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
->withRouting(
|
||||
@ -35,7 +34,7 @@
|
||||
'ensure-platform-capability' => \App\Http\Middleware\EnsurePlatformCapability::class,
|
||||
'ensure-workspace-member' => \App\Http\Middleware\EnsureWorkspaceMember::class,
|
||||
'ensure-workspace-selected' => \App\Http\Middleware\EnsureWorkspaceSelected::class,
|
||||
'ensure-filament-tenant-selected' => \App\Support\Middleware\EnsureFilamentTenantSelected::class,
|
||||
'ensure-environment-context-selected' => \App\Support\Middleware\EnsureEnvironmentContextSelected::class,
|
||||
]);
|
||||
|
||||
$middleware->prependToPriorityList(
|
||||
|
||||
@ -15,32 +15,32 @@
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
$tenants = collect();
|
||||
$environments = collect();
|
||||
if ($user instanceof User && $workspace) {
|
||||
$tenants = collect($user->getTenants(Filament::getCurrentOrDefaultPanel()))
|
||||
->filter(fn ($tenant): bool => $tenant instanceof ManagedEnvironment && (int) $tenant->workspace_id === (int) $workspace->getKey())
|
||||
$environments = collect($user->getTenants(Filament::getCurrentOrDefaultPanel()))
|
||||
->filter(fn ($environment): bool => $environment instanceof ManagedEnvironment && (int) $environment->workspace_id === (int) $workspace->getKey())
|
||||
->values();
|
||||
}
|
||||
|
||||
$currentTenant = $resolvedContext->tenant;
|
||||
$currentTenantId = $currentTenant instanceof ManagedEnvironment ? (int) $currentTenant->getKey() : null;
|
||||
$currentTenantName = $currentTenant instanceof ManagedEnvironment ? $currentTenant->getFilamentName() : null;
|
||||
$currentEnvironment = $resolvedContext->tenant;
|
||||
$currentEnvironmentId = $currentEnvironment instanceof ManagedEnvironment ? (int) $currentEnvironment->getKey() : null;
|
||||
$currentEnvironmentName = $currentEnvironment instanceof ManagedEnvironment ? $currentEnvironment->getFilamentName() : null;
|
||||
|
||||
$lastTenantId = $workspaceContext->lastTenantId(request());
|
||||
$canClearEnvironmentContext = $currentTenant instanceof ManagedEnvironment || $lastTenantId !== null;
|
||||
$lastEnvironmentId = $workspaceContext->lastEnvironmentId(request());
|
||||
$canClearEnvironmentContext = $currentEnvironment instanceof ManagedEnvironment || $lastEnvironmentId !== null;
|
||||
@endphp
|
||||
|
||||
@php
|
||||
$tenantLabel = $currentTenantName ?? __('localization.shell.no_environment_selected');
|
||||
$environmentLabel = $currentEnvironmentName ?? __('localization.shell.no_environment_selected');
|
||||
$workspaceLabel = $workspace?->name ?? __('localization.shell.choose_workspace');
|
||||
$hasActiveTenant = $currentTenantName !== null;
|
||||
$hasActiveEnvironment = $currentEnvironmentName !== null;
|
||||
$managedEnvironmentsUrl = $workspace
|
||||
? route('admin.workspace.managed-environments.index', ['workspace' => $workspace])
|
||||
: route('admin.onboarding');
|
||||
$workspaceUrl = $workspace
|
||||
? route('admin.home')
|
||||
: ChooseWorkspace::getUrl(panel: 'admin');
|
||||
$tenantTriggerLabel = $workspace ? $tenantLabel : __('localization.shell.choose_workspace');
|
||||
$environmentTriggerLabel = $workspace ? $environmentLabel : __('localization.shell.choose_workspace');
|
||||
$localePlane = 'admin';
|
||||
@endphp
|
||||
|
||||
@ -59,7 +59,7 @@ class="inline-flex items-center gap-1.5 rounded-l-lg px-2.5 py-1.5 font-medium t
|
||||
<x-filament::icon icon="heroicon-m-chevron-right" class="h-3 w-3 shrink-0 text-gray-300 dark:text-gray-600" />
|
||||
@endif
|
||||
|
||||
{{-- Dropdown trigger: tenant label + chevron --}}
|
||||
{{-- Dropdown trigger: environment label + chevron --}}
|
||||
<x-filament::dropdown placement="bottom-start" teleport width="xs">
|
||||
<x-slot name="trigger">
|
||||
<button
|
||||
@ -67,8 +67,8 @@ class="inline-flex items-center gap-1.5 rounded-l-lg px-2.5 py-1.5 font-medium t
|
||||
aria-label="{{ $workspace ? __('localization.shell.environment_scope') : __('localization.shell.select_environment') }}"
|
||||
class="inline-flex items-center gap-1.5 rounded-r-lg px-2 py-1.5 transition hover:bg-gray-50 dark:hover:bg-white/10"
|
||||
>
|
||||
<span class="{{ $workspace && $hasActiveTenant ? 'font-medium text-primary-600 dark:text-primary-400' : 'text-gray-500 dark:text-gray-400' }}">
|
||||
{{ $tenantTriggerLabel }}
|
||||
<span class="{{ $workspace && $hasActiveEnvironment ? 'font-medium text-primary-600 dark:text-primary-400' : 'text-gray-500 dark:text-gray-400' }}">
|
||||
{{ $environmentTriggerLabel }}
|
||||
</span>
|
||||
|
||||
<x-filament::icon icon="heroicon-m-chevron-down" class="h-3.5 w-3.5 text-gray-400 dark:text-gray-500" />
|
||||
@ -121,7 +121,7 @@ class="flex items-center gap-2 rounded-lg px-3 py-2 text-sm text-gray-700 transi
|
||||
@if ($workspace)
|
||||
<div class="border-t border-gray-200 dark:border-white/10"></div>
|
||||
|
||||
{{-- ManagedEnvironment section --}}
|
||||
{{-- Managed Environment section --}}
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-xs font-semibold uppercase tracking-wider text-gray-400 dark:text-gray-500">
|
||||
@ -129,11 +129,11 @@ class="flex items-center gap-2 rounded-lg px-3 py-2 text-sm text-gray-700 transi
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($resolvedContext->pageCategory->requiresExplicitTenant() && $hasActiveTenant)
|
||||
@if ($resolvedContext->pageCategory->requiresExplicitEnvironment() && $hasActiveEnvironment)
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center gap-2 rounded-lg bg-primary-50 px-3 py-2 dark:bg-primary-950/30">
|
||||
<x-filament::icon icon="heroicon-o-building-office-2" class="h-4 w-4 text-primary-600 dark:text-primary-400" />
|
||||
<span class="text-sm font-medium text-primary-700 dark:text-primary-300">{{ $currentTenantName }}</span>
|
||||
<span class="text-sm font-medium text-primary-700 dark:text-primary-300">{{ $currentEnvironmentName }}</span>
|
||||
<a
|
||||
href="{{ ChooseEnvironment::getUrl(panel: 'admin') }}"
|
||||
class="ml-auto text-xs font-medium text-primary-600 hover:text-primary-500 dark:text-primary-400 dark:hover:text-primary-300"
|
||||
@ -153,7 +153,7 @@ class="ml-auto text-xs font-medium text-primary-600 hover:text-primary-500 dark:
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
@if ($tenants->isEmpty())
|
||||
@if ($environments->isEmpty())
|
||||
<div class="space-y-2 rounded-lg border border-dashed border-gray-300 px-3 py-3 text-center text-xs text-gray-500 dark:border-gray-600 dark:text-gray-400">
|
||||
<div>{{ __('localization.shell.no_active_environments') }}</div>
|
||||
<a href="{{ $managedEnvironmentsUrl }}" class="inline-flex items-center gap-1 text-primary-600 hover:text-primary-500 dark:text-primary-400 dark:hover:text-primary-300">
|
||||
@ -162,7 +162,7 @@ class="ml-auto text-xs font-medium text-primary-600 hover:text-primary-500 dark:
|
||||
</a>
|
||||
</div>
|
||||
@else
|
||||
@if (! $hasActiveTenant)
|
||||
@if (! $hasActiveEnvironment)
|
||||
<div class="rounded-lg bg-gray-50 px-3 py-2 text-xs text-gray-600 dark:bg-white/5 dark:text-gray-400">
|
||||
{{ __('localization.shell.workspace_wide_available_without_environment') }}
|
||||
</div>
|
||||
@ -176,19 +176,19 @@ class="fi-input fi-text-input w-full"
|
||||
/>
|
||||
|
||||
<div class="max-h-48 overflow-auto rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
@foreach ($tenants as $tenant)
|
||||
@foreach ($environments as $environment)
|
||||
@php
|
||||
$isActive = $currentTenantId !== null && (int) $tenant->getKey() === $currentTenantId;
|
||||
$isActive = $currentEnvironmentId !== null && (int) $environment->getKey() === $currentEnvironmentId;
|
||||
@endphp
|
||||
|
||||
<form method="POST" action="{{ route('admin.select-environment') }}">
|
||||
@csrf
|
||||
<input type="hidden" name="managed_environment_id" value="{{ (int) $tenant->getKey() }}" />
|
||||
<input type="hidden" name="managed_environment_id" value="{{ (int) $environment->getKey() }}" />
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition {{ $isActive ? 'bg-primary-50 font-medium text-primary-700 dark:bg-primary-950/30 dark:text-primary-300' : 'text-gray-700 hover:bg-gray-50 dark:text-gray-300 dark:hover:bg-white/5' }}"
|
||||
data-search="{{ (string) str($tenant->getFilamentName())->lower() }}"
|
||||
data-search="{{ (string) str($environment->getFilamentName())->lower() }}"
|
||||
x-show="query === '' || ($el.dataset.search ?? '').includes(query.toLowerCase())"
|
||||
>
|
||||
@if ($isActive)
|
||||
@ -197,7 +197,7 @@ class="flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition {{
|
||||
<x-filament::icon icon="heroicon-o-building-office-2" class="h-4 w-4 shrink-0 text-gray-400 dark:text-gray-500" />
|
||||
@endif
|
||||
|
||||
{{ $tenant->getFilamentName() }}
|
||||
{{ $environment->getFilamentName() }}
|
||||
</button>
|
||||
</form>
|
||||
@endforeach
|
||||
|
||||
@ -5,24 +5,23 @@
|
||||
use App\Http\Controllers\Auth\EntraController;
|
||||
use App\Http\Controllers\ClearEnvironmentContextController;
|
||||
use App\Http\Controllers\LocalizationController;
|
||||
use App\Http\Controllers\ManagedEnvironmentOnboardingController;
|
||||
use App\Http\Controllers\OpenFindingExceptionsQueueController;
|
||||
use App\Http\Controllers\RbacDelegatedAuthController;
|
||||
use App\Http\Controllers\ReviewPackDownloadController;
|
||||
use App\Http\Controllers\SelectEnvironmentController;
|
||||
use App\Http\Controllers\SwitchWorkspaceController;
|
||||
use App\Http\Controllers\ManagedEnvironmentOnboardingController;
|
||||
use App\Http\Middleware\SuppressDebugbarForSmokeRequests;
|
||||
use App\Models\ProviderConnection;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\ManagedEnvironmentOnboardingSession;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
use App\Services\Onboarding\OnboardingDraftResolver;
|
||||
use App\Services\Tenants\TenantOperabilityService;
|
||||
use App\Support\Auth\WorkspaceRole;
|
||||
use App\Support\ManagedEnvironmentLinks;
|
||||
use App\Services\Tenants\TenantOperabilityService;
|
||||
use App\Support\Navigation\AdminSurfaceScope;
|
||||
use App\Support\Tenants\TenantOperabilityQuestion;
|
||||
use App\Support\Tenants\TenantPageCategory;
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use App\Support\Workspaces\WorkspaceResolver;
|
||||
use Filament\Http\Middleware\Authenticate as FilamentAuthenticate;
|
||||
@ -268,7 +267,7 @@
|
||||
$workspaceContext->setCurrentWorkspace($workspace, $user, $request);
|
||||
|
||||
if ($tenant instanceof ManagedEnvironment) {
|
||||
$workspaceContext->rememberTenantContext($tenant, $request);
|
||||
$workspaceContext->rememberEnvironmentContext($tenant, $request);
|
||||
} else {
|
||||
$workspaceContext->clearRememberedTenantContext($request);
|
||||
}
|
||||
@ -377,10 +376,10 @@
|
||||
|
||||
$allowed = app(TenantOperabilityService::class)->outcomeFor(
|
||||
tenant: $tenant,
|
||||
question: TenantOperabilityQuestion::TenantBoundViewability,
|
||||
question: TenantOperabilityQuestion::EnvironmentBoundViewability,
|
||||
actor: $user,
|
||||
workspaceId: $workspaceId,
|
||||
lane: TenantPageCategory::TenantBound->lane(),
|
||||
lane: AdminSurfaceScope::EnvironmentBound->lane(),
|
||||
)->allowed;
|
||||
|
||||
abort_unless($allowed, 404);
|
||||
@ -394,7 +393,7 @@
|
||||
DispatchServingFilamentEvent::class,
|
||||
FilamentAuthenticate::class,
|
||||
'ensure-workspace-member',
|
||||
'ensure-filament-tenant-selected',
|
||||
'ensure-environment-context-selected',
|
||||
])
|
||||
->prefix('/admin/workspaces/{workspace}')
|
||||
->group(function (): void {
|
||||
@ -470,7 +469,7 @@
|
||||
DispatchServingFilamentEvent::class,
|
||||
FilamentAuthenticate::class,
|
||||
'ensure-workspace-selected',
|
||||
'ensure-filament-tenant-selected',
|
||||
'ensure-environment-context-selected',
|
||||
])
|
||||
->get('/admin/audit-log', \App\Filament\Pages\Monitoring\AuditLog::class)
|
||||
->name('admin.monitoring.audit-log');
|
||||
@ -507,7 +506,7 @@
|
||||
DispatchServingFilamentEvent::class,
|
||||
FilamentAuthenticate::class,
|
||||
'ensure-workspace-member',
|
||||
'ensure-filament-tenant-selected',
|
||||
'ensure-environment-context-selected',
|
||||
])
|
||||
->get('/admin/workspaces/{workspace}/environments/{environment:slug}', \App\Filament\Pages\EnvironmentDashboard::class)
|
||||
->name('admin.workspace.environments.show');
|
||||
@ -520,7 +519,7 @@
|
||||
DispatchServingFilamentEvent::class,
|
||||
FilamentAuthenticate::class,
|
||||
'ensure-workspace-member',
|
||||
'ensure-filament-tenant-selected',
|
||||
'ensure-environment-context-selected',
|
||||
])
|
||||
->get('/admin/workspaces/{workspace}/environments/{environment:slug}/diagnostics', \App\Filament\Pages\EnvironmentDiagnostics::class)
|
||||
->name('admin.workspace.environments.diagnostics');
|
||||
@ -533,7 +532,7 @@
|
||||
DispatchServingFilamentEvent::class,
|
||||
FilamentAuthenticate::class,
|
||||
'ensure-workspace-member',
|
||||
'ensure-filament-tenant-selected',
|
||||
'ensure-environment-context-selected',
|
||||
])
|
||||
->get('/admin/workspaces/{workspace}/environments/{environment:slug}/access-scopes', \App\Filament\Resources\ManagedEnvironmentResource\Pages\ManageEnvironmentAccessScopes::class)
|
||||
->name('admin.workspace.environments.access-scopes');
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
@ -72,12 +72,12 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $tenantPublished->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $tenantPublished->workspace_id => (int) $tenantPublished->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
visit(EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $publishedReview], $tenantPublished))
|
||||
visit(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $publishedReview], $tenantPublished))
|
||||
->waitForText('Verwandter Kontext')
|
||||
->assertSee('Kunden-Workspace öffnen')
|
||||
->assertNoJavaScriptErrors()
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\EvidenceSnapshotResource;
|
||||
use App\Filament\Resources\ReviewPackResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Support\EnvironmentReviewCompletenessState;
|
||||
use App\Support\EnvironmentReviewStatus;
|
||||
@ -90,7 +90,7 @@
|
||||
->assertSee('Stale')
|
||||
->assertSee('Refresh the stale evidence before relying on this snapshot');
|
||||
|
||||
visit(EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $partialReview], $partialTenant))
|
||||
visit(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $partialReview], $partialTenant))
|
||||
->waitForText('Outcome summary')
|
||||
->assertNoJavaScriptErrors()
|
||||
->assertSee('Internal only')
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
$this->actingAs($fixture['user'])->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $fixture['workspace']->getKey(),
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $fixture['workspace']->getKey() => (int) $fixture['visibleTenant']->getKey(),
|
||||
],
|
||||
]);
|
||||
@ -97,7 +97,7 @@
|
||||
|
||||
$this->actingAs($viewer)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $fixture['workspace']->getKey(),
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $fixture['workspace']->getKey() => (int) $fixture['visibleTenant']->getKey(),
|
||||
],
|
||||
]);
|
||||
@ -134,7 +134,7 @@
|
||||
|
||||
$this->actingAs($fixture['user'])->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $fixture['workspace']->getKey(),
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $fixture['workspace']->getKey() => (int) $fixture['visibleTenant']->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
@ -6,12 +6,12 @@
|
||||
use App\Filament\Resources\BackupSetResource;
|
||||
use App\Filament\Resources\BaselineProfileResource;
|
||||
use App\Filament\Resources\BaselineSnapshotResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\EvidenceSnapshotResource;
|
||||
use App\Filament\Resources\FindingExceptionResource;
|
||||
use App\Filament\Resources\ManagedEnvironmentResource;
|
||||
use App\Filament\Resources\PolicyVersionResource;
|
||||
use App\Filament\Resources\ReviewPackResource;
|
||||
use App\Filament\Resources\ManagedEnvironmentResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\Workspaces\WorkspaceResource;
|
||||
use App\Models\AlertDestination;
|
||||
use App\Models\BackupSet;
|
||||
@ -20,11 +20,11 @@
|
||||
use App\Models\BaselineSnapshotItem;
|
||||
use App\Models\EvidenceSnapshot;
|
||||
use App\Models\Finding;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\Policy;
|
||||
use App\Models\PolicyVersion;
|
||||
use App\Models\ReviewPack;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Models\User;
|
||||
use App\Services\Findings\FindingExceptionService;
|
||||
use App\Support\Evidence\EvidenceCompletenessState;
|
||||
@ -157,7 +157,7 @@ function spec192ApprovedFindingException(ManagedEnvironment $tenant, User $reque
|
||||
->assertSee('Open finding')
|
||||
->assertSee('Renew exception');
|
||||
|
||||
visit(EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant))
|
||||
visit(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant))
|
||||
->waitForText('Related context')
|
||||
->assertNoJavaScriptErrors()
|
||||
->assertScript("document.querySelectorAll('[data-supporting-group-kind]').length === 0", true)
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Filament\Pages\Monitoring\FindingExceptionsQueue;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\EvidenceSnapshotResource;
|
||||
use App\Filament\Resources\FindingExceptionResource;
|
||||
use App\Filament\Resources\ManagedEnvironmentResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\EvidenceSnapshot;
|
||||
use App\Models\Finding;
|
||||
use App\Models\FindingException;
|
||||
@ -17,13 +17,13 @@
|
||||
use App\Models\User;
|
||||
use App\Services\Findings\FindingExceptionService;
|
||||
use App\Support\Auth\PlatformCapabilities;
|
||||
use App\Support\EnvironmentReviewCompletenessState;
|
||||
use App\Support\EnvironmentReviewStatus;
|
||||
use App\Support\Evidence\EvidenceCompletenessState;
|
||||
use App\Support\Evidence\EvidenceSnapshotStatus;
|
||||
use App\Support\OperationRunOutcome;
|
||||
use App\Support\OperationRunStatus;
|
||||
use App\Support\System\SystemOperationRunLinks;
|
||||
use App\Support\EnvironmentReviewCompletenessState;
|
||||
use App\Support\EnvironmentReviewStatus;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
pest()->browser()->timeout(20_000);
|
||||
@ -194,7 +194,7 @@ function spec194RelativeRedirect(string $redirect): string
|
||||
->assertSee('Renew exception')
|
||||
->assertSee('Revoke exception');
|
||||
|
||||
visit(EnvironmentReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant))
|
||||
visit(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant))
|
||||
->waitForText('Related context')
|
||||
->assertNoJavaScriptErrors()
|
||||
->assertNoConsoleLogs()
|
||||
|
||||
@ -88,7 +88,7 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
||||
],
|
||||
]);
|
||||
@ -154,7 +154,7 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Filament\Resources\EvidenceSnapshotResource;
|
||||
use App\Filament\Resources\FindingResource;
|
||||
use App\Filament\Resources\InventoryItemResource;
|
||||
use App\Filament\Resources\StoredReportResource;
|
||||
use App\Filament\Resources\EnvironmentReviewResource;
|
||||
use App\Models\Finding;
|
||||
use App\Models\InventoryItem;
|
||||
use App\Models\StoredReport;
|
||||
@ -41,7 +41,7 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(),
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $workspace->getKey() => (int) $environment->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
|
||||
session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [
|
||||
session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
|
||||
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
||||
]);
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id,
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $environment->workspace_id => (int) $environment->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
@ -24,13 +24,13 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(),
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $workspace->getKey() => (int) $environment->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey());
|
||||
session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [
|
||||
session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
|
||||
(string) $workspace->getKey() => (int) $environment->getKey(),
|
||||
]);
|
||||
|
||||
|
||||
@ -32,13 +32,13 @@
|
||||
|
||||
$this->actingAs($user)->withSession([
|
||||
WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(),
|
||||
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
||||
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
||||
(string) $workspace->getKey() => (int) $environmentA->getKey(),
|
||||
],
|
||||
]);
|
||||
|
||||
session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey());
|
||||
session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [
|
||||
session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
|
||||
(string) $workspace->getKey() => (int) $environmentA->getKey(),
|
||||
]);
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
'wide_text' => $environmentB->name,
|
||||
],
|
||||
'customer review workspace' => [
|
||||
'filtered_url' => CustomerReviewWorkspace::tenantPrefilterUrl($environmentA),
|
||||
'filtered_url' => CustomerReviewWorkspace::environmentFilterUrl($environmentA),
|
||||
'clean_url' => CustomerReviewWorkspace::getUrl(panel: 'admin'),
|
||||
'wide_text' => $environmentB->name,
|
||||
],
|
||||
@ -148,7 +148,7 @@
|
||||
FindingExceptionsQueue::getUrl(panel: 'admin', parameters: [
|
||||
'environment_id' => (int) $environmentA->getKey(),
|
||||
]),
|
||||
CustomerReviewWorkspace::tenantPrefilterUrl($environmentA),
|
||||
CustomerReviewWorkspace::environmentFilterUrl($environmentA),
|
||||
route('admin.evidence.overview', [
|
||||
'environment_id' => (int) $environmentA->getKey(),
|
||||
]),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user