Files
michaelschiemer/src/Framework/Console/Layout/PageLayout.php
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

160 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Console\Layout;
use App\Framework\Console\Layout\Components\Footer;
use App\Framework\Console\Layout\Components\Header;
use App\Framework\Console\Layout\Components\Sidebar;
use App\Framework\Console\Layout\ValueObjects\LayoutOptions;
/**
* Page layout with header, main content, footer, and optional sidebar
*/
final class PageLayout extends LayoutContainer
{
private ?Header $header = null;
private ?Footer $footer = null;
private ?Sidebar $sidebar = null;
private array $sections = [];
private array $mainContent = [];
public function __construct(
?TerminalSize $customTerminalSize = null,
?LayoutOptions $options = null
) {
parent::__construct($customTerminalSize, $options);
}
/**
* Set header
*/
public function withHeader(string $title, ?string $subtitle = null, array $meta = []): self
{
$this->header = new Header($title, $subtitle, $this->theme, $meta);
return $this;
}
/**
* Set footer
*/
public function withFooter(string $content): self
{
$this->footer = new Footer($content, $this->theme);
return $this;
}
/**
* Set sidebar
*/
public function withSidebar(array $items, ?string $title = null): self
{
$this->sidebar = new Sidebar($items, $title, $this->theme);
return $this;
}
/**
* Add section to main content
*/
public function addSection(Section $section): self
{
$this->sections[] = $section;
return $this;
}
/**
* Add content line to main area
*/
public function addContent(string $content): self
{
$this->mainContent[] = $content;
return $this;
}
/**
* Render the page layout
*/
public function render(): string
{
$width = $this->getEffectiveWidth();
$output = [];
$hasSidebar = $this->sidebar !== null && $this->shouldShowSidebar();
// Header
if ($this->header !== null) {
$output[] = $this->header->render($width, $this->options->showBorders);
$output[] = '';
}
// Main content area
$mainContent = $this->renderMainContent($width, $hasSidebar);
if ($hasSidebar) {
// Split layout: sidebar + main content
$sidebarWidth = min(25, (int)($width * 0.25));
$mainWidth = $width - $sidebarWidth - 2; // Space between sidebar and main
$sidebarLines = explode("\n", $this->sidebar->render($sidebarWidth, $this->options->showBorders));
$mainLines = explode("\n", $mainContent);
$maxLines = max(count($sidebarLines), count($mainLines));
for ($i = 0; $i < $maxLines; $i++) {
$sidebarLine = $sidebarLines[$i] ?? str_repeat(' ', $sidebarWidth);
$mainLine = $mainLines[$i] ?? '';
$output[] = $sidebarLine . ' ' . $mainLine;
}
} else {
// Full width main content
$output[] = $mainContent;
}
// Footer
if ($this->footer !== null) {
$output[] = '';
$output[] = $this->footer->render($width, $this->options->showBorders);
}
return implode("\n", $output);
}
private function renderMainContent(int $width, bool $hasSidebar): string
{
$content = [];
// Render sections
foreach ($this->sections as $section) {
$content[] = $section->render($width, $this->options->showBorders);
$content[] = '';
}
// Render additional content
foreach ($this->mainContent as $line) {
$content[] = $line;
}
return implode("\n", $content);
}
private function shouldShowSidebar(): bool
{
if (!$this->isResponsive()) {
return true;
}
// Hide sidebar on small terminals
$breakpoint = $this->terminalSize->getBreakpoint();
return $breakpoint !== TerminalBreakpoint::EXTRA_SMALL && $breakpoint !== TerminalBreakpoint::SMALL;
}
/**
* Create page layout
*/
public static function create(?TerminalSize $terminalSize = null, ?LayoutOptions $options = null): self
{
return new self($terminalSize, $options);
}
}