fix: DockerSecretsResolver - don't normalize absolute paths like /var/www/html/...
Some checks failed
Deploy Application / deploy (push) Has been cancelled
Some checks failed
Deploy Application / deploy (push) Has been cancelled
This commit is contained in:
@@ -12,6 +12,7 @@ use App\Framework\View\Contracts\StaticComponent;
|
||||
use App\Framework\View\Dom\ElementNode;
|
||||
use App\Framework\View\Dom\Node;
|
||||
use App\Framework\View\Dom\TextNode;
|
||||
use App\Framework\View\ValueObjects\UIDataAttribute;
|
||||
|
||||
#[ComponentName('admin-sidebar')]
|
||||
final readonly class AdminSidebar implements StaticComponent
|
||||
@@ -53,8 +54,9 @@ final readonly class AdminSidebar implements StaticComponent
|
||||
$header = $this->buildHeader();
|
||||
$navigation = $this->buildNavigation();
|
||||
$footer = $this->buildFooter();
|
||||
$resizeHandle = '<div class="admin-sidebar__resize-handle" aria-label="Resize sidebar"></div>';
|
||||
|
||||
return $header . $navigation . $footer;
|
||||
return $header . $navigation . $footer . $resizeHandle;
|
||||
}
|
||||
|
||||
private function buildHeader(): string
|
||||
@@ -92,23 +94,37 @@ final readonly class AdminSidebar implements StaticComponent
|
||||
|
||||
private function renderSection(NavigationSection $section): string
|
||||
{
|
||||
$html = '<div class="admin-nav__section">';
|
||||
$sectionId = $this->generateSectionId($section->name);
|
||||
// Use name attribute for exclusive accordion behavior
|
||||
$html = '<details class="admin-nav__section" name="admin-nav-sections" ' . UIDataAttribute::SECTION_ID->value() . '="' . $this->escape($sectionId) . '">';
|
||||
|
||||
if ($section->name !== '') {
|
||||
$html .= '<h2 class="admin-nav__section-title">' . htmlspecialchars($section->name) . '</h2>';
|
||||
$chevronIcon = '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>';
|
||||
$html .= '<summary class="admin-nav__section-toggle">';
|
||||
$html .= '<h2>' . htmlspecialchars($section->name) . '</h2>';
|
||||
$html .= $chevronIcon;
|
||||
$html .= '</summary>';
|
||||
}
|
||||
|
||||
$html .= '<ul class="admin-nav__list" role="list">';
|
||||
$html .= '<ul role="list">';
|
||||
|
||||
foreach ($section->items as $item) {
|
||||
$html .= $this->renderItem($item);
|
||||
}
|
||||
|
||||
$html .= '</ul></div>';
|
||||
$html .= '</ul></details>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a section ID from section name
|
||||
*/
|
||||
private function generateSectionId(string $name): string
|
||||
{
|
||||
return strtolower(preg_replace('/[^a-zA-Z0-9]+/', '-', trim($name)));
|
||||
}
|
||||
|
||||
private function renderItem(NavigationItem $item): string
|
||||
{
|
||||
$activeState = $item->isActive($this->currentPath)
|
||||
@@ -118,8 +134,8 @@ final readonly class AdminSidebar implements StaticComponent
|
||||
$iconHtml = $this->renderIcon($item->icon);
|
||||
|
||||
return <<<HTML
|
||||
<li class="admin-nav__item">
|
||||
<a href="{$this->escape($item->url)}" class="admin-nav__link" {$activeState}>
|
||||
<li>
|
||||
<a href="{$this->escape($item->url)}" {$activeState}>
|
||||
{$iconHtml}
|
||||
<span>{$this->escape($item->name)}</span>
|
||||
</a>
|
||||
@@ -137,7 +153,7 @@ final readonly class AdminSidebar implements StaticComponent
|
||||
$svgIcon = $this->getSvgIcon($icon);
|
||||
|
||||
if ($svgIcon !== null) {
|
||||
return '<svg class="admin-nav__icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">' . $svgIcon . '</svg>';
|
||||
return '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">' . $svgIcon . '</svg>';
|
||||
}
|
||||
|
||||
// Fallback to emoji or text
|
||||
@@ -183,19 +199,24 @@ final readonly class AdminSidebar implements StaticComponent
|
||||
private function buildFallbackNavigation(): string
|
||||
{
|
||||
// Fallback to old hardcoded navigation for backward compatibility
|
||||
$sectionId = $this->generateSectionId('Dashboard');
|
||||
$chevronIcon = '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>';
|
||||
return <<<HTML
|
||||
<nav class="admin-nav">
|
||||
<div class="admin-nav__section">
|
||||
<h2 class="admin-nav__section-title">Dashboard</h2>
|
||||
<ul class="admin-nav__list" role="list">
|
||||
<li class="admin-nav__item">
|
||||
<a href="/admin" class="admin-nav__link" {$this->getActiveState('/admin')}>
|
||||
<details class="admin-nav__section" name="admin-nav-sections" data-section-id="{$sectionId}">
|
||||
<summary class="admin-nav__section-toggle">
|
||||
<h2>Dashboard</h2>
|
||||
{$chevronIcon}
|
||||
</summary>
|
||||
<ul role="list">
|
||||
<li>
|
||||
<a href="/admin" {$this->getActiveState('/admin')}>
|
||||
<span class="admin-nav__icon">📊</span>
|
||||
<span>Overview</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</details>
|
||||
</nav>
|
||||
HTML;
|
||||
}
|
||||
@@ -239,20 +260,33 @@ final readonly class AdminSidebar implements StaticComponent
|
||||
if (is_array($menuData)) {
|
||||
try {
|
||||
return NavigationMenu::fromArray($menuData);
|
||||
} catch (\Exception) {
|
||||
} catch (\Exception $e) {
|
||||
error_log("AdminSidebar: Failed to parse navigation menu from array: " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle JSON string
|
||||
if (is_string($menuData)) {
|
||||
$decoded = json_decode($menuData, true);
|
||||
if (is_array($decoded)) {
|
||||
try {
|
||||
return NavigationMenu::fromArray($decoded);
|
||||
} catch (\Exception) {
|
||||
return null;
|
||||
}
|
||||
// Decode HTML entities first (template system escapes values in HTML attributes)
|
||||
$decodedJson = html_entity_decode($menuData, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
|
||||
$decoded = json_decode($decodedJson, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
error_log("AdminSidebar: JSON decode error: " . json_last_error_msg() . " - Data: " . substr($decodedJson, 0, 200));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!is_array($decoded)) {
|
||||
error_log("AdminSidebar: Decoded data is not an array: " . gettype($decoded));
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return NavigationMenu::fromArray($decoded);
|
||||
} catch (\Exception $e) {
|
||||
error_log("AdminSidebar: Failed to parse navigation menu from decoded JSON: " . $e->getMessage() . " - Data: " . json_encode($decoded));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user