mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-09 20:02:34 +02:00
Verify every dev-doc claim against src/ and fix factual drift: wrong method signatures/return types, wrong enum casing (BootContext cases are PascalCase), stale paths (M3u parsers are Composer deps under vendor/, MobileDetect is mobiledetect/mobiledetectlib v4.9.0 \Detection\MobileDetect, NotFoundException lives in XcVm\Core\Container\Psr), a fictional `stream:check` command/class, reversed migration-failure semantics ([FAIL] = not recorded, retried), inverted isStreamRunning/isStreamAlive descriptions, findProcessPIDs ANY-not-ALL, acquireCronLock has no shutdown callback, and nonexistent make targets. Split oversized pages and fix nav + cross-links: - modules.md -> module-authoring / module-lifecycle / module-extension-points - cli-tools.md -> cli-tools + database-migrations - streaming-subsystem.md -> + streaming-diagnostics - geoip-and-device-detection.md -> geoip-isp-and-geo-routing + device-detection-and-stb-locking Add development/core-wiring.md: how the core assembles itself at boot (container population, ServiceContainer reference, bootAll orchestration, CLI command auto-discovery, end-to-end Admin/CLI boot walkthroughs). Only docs/en + mkdocs.yml touched; docs/ru is regenerated before release.
125 lines
4.7 KiB
Markdown
125 lines
4.7 KiB
Markdown
# Navbar rendering in module panel
|
|
|
|
Technical documentation for building and rendering the navbar in the admin panel.
|
|
|
|
## Purpose
|
|
|
|
The navbar is built declaratively from a `NavbarItem` tree, not from hardcoded HTML menus.
|
|
|
|
Tree sources:
|
|
|
|
1. Core nodes from `CoreNavbarProvider::register()`.
|
|
2. Module nodes from `ModuleInterface::registerNavbar()`.
|
|
|
|
## Lifecycle
|
|
|
|
1. `ModuleLoader::bootAll()` calls `CoreNavbarProvider::register()`.
|
|
2. Then `registerNavbar()` is called for each loaded module.
|
|
3. In `Public/Views/admin/header.php`, the tree is rendered from `NavbarRegistry`.
|
|
|
|
## Rendering in header
|
|
|
|
Rendering is done by helper functions:
|
|
|
|
1. `_xc_nav_visible()` - visibility filtering for a node.
|
|
2. `_xc_nav_label()` - text label resolution.
|
|
3. `_xc_nav_children()` - recursive rendering of child items.
|
|
|
|
Top-level nodes come from `NavbarRegistry::getTopLevel()`, child nodes come from `NavbarRegistry::getChildren($key)`.
|
|
|
|
## Visibility rules
|
|
|
|
Checks are performed in `_xc_nav_visible()`:
|
|
|
|
1. `desktopOnly`: hides node on mobile.
|
|
2. `settingDisabled`: hides node when a setting flag is enabled.
|
|
3. `permissions`: OR-check via `Authorization::check('adv', $permission)`.
|
|
4. A group with `url='#'` is shown only if at least one child is visible.
|
|
5. `divider` is always passed through and rendered as separator.
|
|
|
|
## Rendering specifics
|
|
|
|
1. `divider` renders as separator without a link.
|
|
2. `submenuClass('megamenu')` enables two-column rendering for long lists.
|
|
3. `noMobileSubmenu` disables child submenu expansion on mobile.
|
|
|
|
## How a module adds a menu item
|
|
|
|
A module adds items only through `registerNavbar()`:
|
|
|
|
```php
|
|
public function registerNavbar(NavbarRegistry $registry): void {
|
|
NavbarRegistry::add((new NavbarItem('management.service_setup.my_module'))
|
|
->parent('management.service_setup')
|
|
->url('my_module')
|
|
->label('my_module')
|
|
->permissions(['my_module'])
|
|
->order(60));
|
|
|
|
NavbarRegistry::add((new NavbarItem('management.logs.my_module_log'))
|
|
->parent('management.logs')
|
|
->url('my_module_logs')
|
|
->label('', 'My Module Logs')
|
|
->permissions(['my_module'])
|
|
->order(170));
|
|
}
|
|
```
|
|
|
|
## NavbarItem builder API
|
|
|
|
`NavbarItem` is a fluent value object (`src/Core/Module/NavbarItem.php`) — chain setters off `new NavbarItem($key)`:
|
|
|
|
| Method | Purpose |
|
|
| --- | --- |
|
|
| `new NavbarItem($key)` | create a node; `$key` is its unique `section.group.item` id |
|
|
| `->parent($parentKey)` | attach under an existing node (omit for a top-level node) |
|
|
| `->url($url)` | target path; `'#'` makes it a non-navigating **group** header |
|
|
| `->label($key, $fallback = '')` | translation key, or `('', 'Literal')` for fixed text |
|
|
| `->icon($icon)` | icon CSS class for the item |
|
|
| `->permissions([...])` | OR-list of permission keys; node hidden unless the viewer has one |
|
|
| `->order($n)` | sort position within the parent |
|
|
| `->desktopOnly()` | hide on mobile |
|
|
| `->noMobileSubmenu()` | don't expand this node's submenu on mobile |
|
|
| `->submenuClass('megamenu')` | two-column rendering for long child lists |
|
|
| `->settingDisabled($settingKey)` | hide the node when that panel setting flag is truthy |
|
|
| `->makeDivider()` | render this node as a separator (no link) |
|
|
|
|
### Group node and divider
|
|
|
|
```php
|
|
public function registerNavbar(NavbarRegistry $registry): void {
|
|
// A group header (url('#')) — shown only if at least one child is visible
|
|
NavbarRegistry::add((new NavbarItem('management.my_group'))
|
|
->parent('management')
|
|
->url('#')
|
|
->label('my_group')
|
|
->order(50));
|
|
|
|
// A divider inside that group
|
|
NavbarRegistry::add((new NavbarItem('management.my_group.sep1'))
|
|
->parent('management.my_group')
|
|
->makeDivider()
|
|
->order(55));
|
|
}
|
|
```
|
|
|
|
> `settingDisabled('some_setting')` hides the node whenever that setting is truthy (gate a feature behind a toggle). Visibility is also **viewer-scoped**: the `permissions` OR-check runs against the current user via `Authorization::check('adv', …)`, so an admin and a reseller can see different subsets of the same tree.
|
|
|
|
## Practical rules for modules
|
|
|
|
1. Use unique `key` values in `section.group.item` format.
|
|
2. Set `parent` to an existing core tree node or your own already-added node.
|
|
3. Position items using `order` inside one parent.
|
|
4. Use `label('translation_key')` for translatable text.
|
|
5. Use `label('', 'Literal Text')` for fixed literal text.
|
|
6. If the module has no menu items, keep `registerNavbar()` empty.
|
|
|
|
## Related files
|
|
|
|
| File | Role |
|
|
| --- | --- |
|
|
| `src/Core/Module/NavbarRegistry.php` | Collects navbar items from providers |
|
|
| `src/Core/Module/NavbarItem.php` | Navbar item value object |
|
|
| `src/Core/Module/CoreNavbarProvider.php` | Built-in core menu items |
|
|
| `src/Public/Views/admin/header.php` | Renders the navbar tree |
|