Foundation slice for Mantis #843 php/Mod/Admin + php/Website/Hub RFC: * php/Mod/Admin/Boot.php — search registry, menu registry, form component layer, HasRateLimiting concern, reusable form/view primitives under Mod/Admin/Forms * php/Website/Hub/Boot.php — host-aware Hub route naming for secondary domains * WorkspaceSwitcher and GlobalSearch global Hub Livewire components * Foundation routed slice in Hub/Routes/admin.php: dashboard shell, workspace listing, site settings (with WordPress/webhook connector), account usage, platform user list+detail * Foundation tests under php/tests/Feature/Mod/Admin/ 53 PHP files. php -l clean. Pest unrunnable in sandbox (no vendor/). Foundation slice only — composer.json kept off-limits so namespace stays under Core\Mod\Agentic\... rather than standalone Core\Admin package. Deferred: Profile, Settings, ServiceManager, ServicesAdmin, Honeypot, Entitlement\{Dashboard,FeatureManager,PackageManager}, PromptManager, WaitlistManager, Console, Databases, Deployments, Content, ContentManager, ContentEditor, ActivityLog, Analytics, AIServices, BoostPurchase. Lane was under-instructed by supervisor with stop-at framing — follow-up tickets needed for remainder. Co-authored-by: Codex <noreply@openai.com> Closes tasks.lthn.sh/view.php?id=843
122 lines
4 KiB
PHP
122 lines
4 KiB
PHP
<?php
|
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Core\Mod\Agentic\Website\Hub;
|
|
|
|
use Core\Events\AdminPanelBooting;
|
|
use Core\Events\DomainResolving;
|
|
use Core\Mod\Agentic\Mod\Admin\Menu\AdminMenuRegistry;
|
|
use Core\Mod\Agentic\Mod\Admin\Menu\Contracts\AdminMenuProvider;
|
|
use Core\Mod\Agentic\Website\Hub\Support\HubRouteNames;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Illuminate\Support\ServiceProvider;
|
|
|
|
class Boot extends ServiceProvider implements AdminMenuProvider
|
|
{
|
|
/**
|
|
* @var array<string>
|
|
*/
|
|
public static array $domains = [
|
|
'/^core\.(test|localhost)$/',
|
|
'/^hub\.core\.(test|localhost)$/',
|
|
];
|
|
|
|
/**
|
|
* @var array<class-string, string>
|
|
*/
|
|
public static array $listens = [
|
|
DomainResolving::class => 'onDomainResolving',
|
|
AdminPanelBooting::class => 'onAdminPanel',
|
|
];
|
|
|
|
public function onDomainResolving(DomainResolving $event): void
|
|
{
|
|
foreach (static::$domains as $pattern) {
|
|
if ($event->matches($pattern)) {
|
|
$event->register(static::class);
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function onAdminPanel(AdminPanelBooting $event): void
|
|
{
|
|
$event->views('hub', __DIR__.'/View/Blade');
|
|
$event->translations('hub', dirname(__DIR__, 2).'/Mod/Admin/Lang');
|
|
$event->livewire('hub.admin.workspace-switcher', View\Modal\Admin\WorkspaceSwitcher::class);
|
|
$event->livewire('hub.admin.global-search', View\Modal\Admin\GlobalSearch::class);
|
|
|
|
app(AdminMenuRegistry::class)->register($this);
|
|
|
|
$domain = request()->getHost();
|
|
$routePrefix = HubRouteNames::prefix($domain);
|
|
|
|
$event->routes(fn () => Route::prefix('hub')
|
|
->name($routePrefix)
|
|
->domain($domain)
|
|
->group(__DIR__.'/Routes/admin.php'));
|
|
}
|
|
|
|
public function adminMenuItems(): array
|
|
{
|
|
return [
|
|
[
|
|
'group' => 'dashboard',
|
|
'priority' => 10,
|
|
'item' => fn (): array => [
|
|
'label' => 'Dashboard',
|
|
'icon' => 'house',
|
|
'href' => HubRouteNames::url('dashboard', fallback: '/hub'),
|
|
'active' => request()->routeIs(HubRouteNames::name('dashboard')),
|
|
],
|
|
],
|
|
[
|
|
'group' => 'workspaces',
|
|
'priority' => 10,
|
|
'item' => fn (): array => [
|
|
'label' => 'Workspaces',
|
|
'icon' => 'folders',
|
|
'href' => HubRouteNames::url('sites', fallback: '/hub/workspaces'),
|
|
'active' => request()->routeIs(HubRouteNames::name('sites'))
|
|
|| request()->routeIs(HubRouteNames::name('sites.settings')),
|
|
],
|
|
],
|
|
[
|
|
'group' => 'settings',
|
|
'priority' => 30,
|
|
'item' => fn (): array => [
|
|
'label' => 'Usage',
|
|
'icon' => 'chart-pie',
|
|
'href' => HubRouteNames::url('account.usage', fallback: '/hub/account/usage'),
|
|
'active' => request()->routeIs(HubRouteNames::name('account.usage')),
|
|
],
|
|
],
|
|
[
|
|
'group' => 'admin',
|
|
'priority' => 10,
|
|
'admin' => true,
|
|
'item' => fn (): array => [
|
|
'label' => 'Platform',
|
|
'icon' => 'server',
|
|
'href' => HubRouteNames::url('platform', fallback: '/hub/platform'),
|
|
'active' => request()->routeIs(HubRouteNames::name('platform'))
|
|
|| request()->routeIs(HubRouteNames::name('platform.user')),
|
|
],
|
|
],
|
|
];
|
|
}
|
|
|
|
public function menuPermissions(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function canViewMenu(?object $user, ?object $workspace): bool
|
|
{
|
|
return $user !== null;
|
|
}
|
|
}
|