@use('Core\Access\Permission') @use('Core\Area\Cms\Models\User') @use('Core\Internal\Navigation\PanelMenu') @use('Core\Localization\Locales') @use('Illuminate\Support\Str') @use('Layout\Cms\Shell\CmsShellResolver') @use('Layout\Engine\A11yPreferences') @use('Services\Layout\Contracts\LayoutAreaScopes') @props([ 'title' => null, 'breadcrumbs' => [], 'robots' => 'noindex, nofollow', 'instance' => [], 'heading' => true, ]) @php /** Shell resolvido: identidade + regiões + posição da navegação (ADR-036). */ $shell = app(CmsShellResolver::class)->resolve(is_array($instance) ? $instance : []); $a11y = A11yPreferences::fromRequest(request()); $currentUser = auth()->user(); $currentUser = $currentUser instanceof User ? $currentUser : null; /** * O menu de usuário mostra o perfil (ADR-033): carregar **aqui** evita *lazy loading* na view * (`Model::preventLazyLoading`) e um segundo request por linha. */ $currentUser?->loadMissing('role'); /** Navegação do manifesto: agrupada, ordenada e filtrada por permissão (ADR-033/ADR-036). */ $panelMenu = $currentUser === null ? null : app(PanelMenu::class); $menu = $panelMenu === null ? [] : $panelMenu->fromManifest($currentUser); /** Lista plana (navegação rápida Ctrl+K): o Core fornece o índice; o shell só traduz. */ $paletteItems = []; /** * Índice de busca: **sem acento** e minúsculo — o teclado brasileiro digita `noticias` e * precisa achar `Notícias`. O filtro do cliente normaliza com a mesma regra (NFD + diacríticos). */ $searchIndex = static fn (string $text): string => mb_strtolower(Str::ascii($text)); foreach ($panelMenu?->flat($currentUser) ?? [] as $entry) { $paletteItems[] = [ 'title_key' => $entry['title'], 'context_key' => $entry['context'], 'url' => $entry['url'], 'search' => $searchIndex(trim(__($entry['title']).' '.($entry['context'] === null ? '' : __($entry['context'])))), ]; } $brand = $shell->brand(); $pageTitle = filled($title) ? $title.' · '.$brand : $brand; /** * Ação "Configurar layout da área" (P1.S4b/ADR-016): **uma** ação compartilhada, nunca uma * permissão por módulo. Só aparece quando a tela atual tem contrapartida viva no portal * (`noticias.cms.index` → `noticias`) e o usuário tem a permissão da superfície de layout — * Configurações/Menus/superfície de layout não a exibem, então nunca há link morto. */ $areaLayoutScope = null; if ($currentUser !== null && config('layout.area_action', true) && Permission::allows('Layout', Permission::EDIT, $currentUser)) { $areaLayoutScope = app(LayoutAreaScopes::class)->scopeFor(request()->route()?->getName()); } /** Breadcrumb sempre começa no painel: a tela atual nunca é o único item (duplica o `