This commit is contained in:
Thomas Peterson 2025-12-19 17:04:05 +01:00
parent 81d0f5a429
commit 2d8d343011

View File

@ -11,8 +11,8 @@ use PHPNative\Ui\Widget\Container;
use PHPNative\Ui\Widget\Icon; use PHPNative\Ui\Widget\Icon;
use PHPNative\Ui\Widget\Label; use PHPNative\Ui\Widget\Label;
use PHPNative\Ui\Widget\TabContainer; use PHPNative\Ui\Widget\TabContainer;
use PHPNative\Ui\Widget\Table;
use PHPNative\Ui\Widget\TextInput; use PHPNative\Ui\Widget\TextInput;
use PHPNative\Ui\Widget\VirtualListView;
use ServerManager\Services\HetznerService; use ServerManager\Services\HetznerService;
use ServerManager\UI\KanbanTab; use ServerManager\UI\KanbanTab;
use ServerManager\UI\LoadingIndicator; use ServerManager\UI\LoadingIndicator;
@ -22,7 +22,7 @@ class ServerListTab
private Settings $settings; private Settings $settings;
private null|KanbanTab $kanbanTab; private null|KanbanTab $kanbanTab;
private Container $tab; private Container $tab;
private Table $table; private VirtualListView $table;
private TextInput $searchInput; private TextInput $searchInput;
private Label $statusLabel; private Label $statusLabel;
private Button $refreshButton; private Button $refreshButton;
@ -108,9 +108,12 @@ class ServerListTab
); );
$leftSide->addComponent($this->searchInput); $leftSide->addComponent($this->searchInput);
// Table // Table container with header and virtual list
$this->table = new Table(style: ' flex-1'); $tableContainer = new Container('flex flex-col flex-1 border border-gray-300 rounded');
$this->table->setColumns([
// Table header
$headerContainer = new Container('flex flex-row w-full bg-gray-200 border-b-2 border-gray-400');
$columns = [
[ [
'key' => 'selected', 'key' => 'selected',
'title' => '', 'title' => '',
@ -131,13 +134,13 @@ class ServerListTab
[ [
'key' => 'docker_status', 'key' => 'docker_status',
'title' => 'Docker', 'title' => 'Docker',
'width' => 100, 'width' => 50,
'render' => [$this, 'renderDockerStatusCell'], 'render' => [$this, 'renderDockerStatusCell'],
], ],
[ [
'key' => 'docker_running', 'key' => 'docker_running',
'title' => 'Running', 'title' => 'R',
'width' => 100, 'width' => 50,
'render' => [$this, 'renderDockerRunningCell'], 'render' => [$this, 'renderDockerRunningCell'],
], ],
[ [
@ -150,25 +153,25 @@ class ServerListTab
[ [
'key' => 'root', 'key' => 'root',
'title' => 'Root', 'title' => 'Root',
'width' => 100, 'width' => 50,
'render' => [$this, 'renderRootCell'], 'render' => [$this, 'renderRootCell'],
], ],
[ [
'key' => 'data', 'key' => 'data',
'title' => 'Data', 'title' => 'Data',
'width' => 90, 'width' => 50,
'render' => [$this, 'renderDataCell'], 'render' => [$this, 'renderDataCell'],
], ],
[ [
'key' => 'needs_reboot', 'key' => 'needs_reboot',
'title' => 'Neustart', 'title' => 'Neustart',
'width' => 110, 'width' => 100,
'render' => [$this, 'renderNeedsRebootCell'], 'render' => [$this, 'renderNeedsRebootCell'],
], ],
[ [
'key' => 'updates_available', 'key' => 'updates_available',
'title' => 'Updates', 'title' => 'Updates',
'width' => 130, 'width' => 100,
'render' => [$this, 'renderUpdatesCell'], 'render' => [$this, 'renderUpdatesCell'],
], ],
[ [
@ -177,16 +180,40 @@ class ServerListTab
'width' => 180, 'width' => 180,
'render' => [$this, 'renderLastBackupCell'], 'render' => [$this, 'renderLastBackupCell'],
], ],
]); ];
// Build header cells
foreach ($columns as $column) {
$title = $column['title'] ?? '';
$width = $column['width'] ?? null;
$style = 'px-4 py-2 text-black font-bold border-r border-gray-300';
if ($width) {
$style .= ' w-' . ((int) ($width / 4));
} else {
$style .= ' flex-1';
}
$headerLabel = new Label($title, $style);
$headerContainer->addComponent($headerLabel);
}
$tableContainer->addComponent($headerContainer);
// Virtual List View (Performance-optimized)
$this->table = new VirtualListView('flex-1 bg-white');
$this->table->setColumns($columns);
// Load initial test data // Load initial test data
$this->currentServerData = HetznerService::generateTestData(); $this->currentServerData = HetznerService::generateTestData();
$this->table->setData($this->currentServerData); $this->table->setData($this->currentServerData);
$leftSide->addComponent($this->table); $tableContainer->addComponent($this->table);
$leftSide->addComponent($tableContainer);
// Right side: Detail panel // Right side: Detail panel
$detailPanel = new Container('flex flex-col gap-3 w-120 bg-white border-2 border-gray-300 rounded p-4 overflow-y-auto'); $detailPanel = new Container(
'flex flex-col gap-3 w-120 bg-white border-2 border-gray-300 rounded p-4 overflow-y-auto',
);
$detailTitle = new Label('Server Details', 'text-xl font-bold text-black mb-2'); $detailTitle = new Label('Server Details', 'text-xl font-bold text-black mb-2');
$detailPanel->addComponent($detailTitle); $detailPanel->addComponent($detailTitle);
@ -368,7 +395,7 @@ class ServerListTab
$searchTerm = strtolower(trim($value)); $searchTerm = strtolower(trim($value));
if (empty($searchTerm)) { if (empty($searchTerm)) {
$serverListTab->table->setData($serverListTab->currentServerData, true); $serverListTab->table->setData($serverListTab->currentServerData);
} else { } else {
$filteredData = array_filter($serverListTab->currentServerData, function ($row) use ($searchTerm) { $filteredData = array_filter($serverListTab->currentServerData, function ($row) use ($searchTerm) {
return ( return (
@ -378,7 +405,7 @@ class ServerListTab
})) }))
); );
}); });
$serverListTab->table->setData(array_values($filteredData), false); $serverListTab->table->setData(array_values($filteredData));
} }
}); });
@ -438,7 +465,7 @@ class ServerListTab
'last_backup' => 'unbekannt', 'last_backup' => 'unbekannt',
], $row), $result['servers']); ], $row), $result['servers']);
$serverListTab->table->setData($serverListTab->currentServerData, false); $serverListTab->table->setData($serverListTab->currentServerData);
$serverListTab->statusLabel->setText('Server geladen: ' . $result['count'] . ' gefunden'); $serverListTab->statusLabel->setText('Server geladen: ' . $result['count'] . ' gefunden');
// Kanban-Board aktualisieren, damit Servernamen in den Karten up-to-date sind // Kanban-Board aktualisieren, damit Servernamen in den Karten up-to-date sind
@ -732,7 +759,7 @@ class ServerListTab
$serverListTab->currentServerData[$i]['docker'] = $dockerResult['docker']; $serverListTab->currentServerData[$i]['docker'] = $dockerResult['docker'];
$searchTerm = $serverListTab->searchInput->getValue(); $searchTerm = $serverListTab->searchInput->getValue();
if (empty($searchTerm)) { if (empty($searchTerm)) {
$serverListTab->table->setData($serverListTab->currentServerData, true); $serverListTab->table->setData($serverListTab->currentServerData);
} else { } else {
$filteredData = array_filter( $filteredData = array_filter(
$serverListTab->currentServerData, $serverListTab->currentServerData,
@ -747,7 +774,7 @@ class ServerListTab
); );
}, },
); );
$serverListTab->table->setData(array_values($filteredData), true); $serverListTab->table->setData(array_values($filteredData));
} }
} }
@ -1035,7 +1062,7 @@ class ServerListTab
} }
$searchTerm = $serverListTab->searchInput->getValue(); $searchTerm = $serverListTab->searchInput->getValue();
if (empty($searchTerm)) { if (empty($searchTerm)) {
$serverListTab->table->setData($serverListTab->currentServerData, true); $serverListTab->table->setData($serverListTab->currentServerData);
} else { } else {
$filteredData = array_filter($serverListTab->currentServerData, function ($row) use ( $filteredData = array_filter($serverListTab->currentServerData, function ($row) use (
$searchTerm, $searchTerm,
@ -1047,7 +1074,7 @@ class ServerListTab
})) }))
); );
}); });
$serverListTab->table->setData(array_values($filteredData), false); $serverListTab->table->setData(array_values($filteredData));
} }
} }
@ -1472,7 +1499,7 @@ class ServerListTab
foreach ($serverListTab->currentServerData as $index => $row) { foreach ($serverListTab->currentServerData as $index => $row) {
if (($row['id'] ?? null) === $rowId) { if (($row['id'] ?? null) === $rowId) {
$serverListTab->currentServerData[$index]['selected'] = $checked; $serverListTab->currentServerData[$index]['selected'] = $checked;
$serverListTab->table->setData($serverListTab->currentServerData, true); $serverListTab->table->setData($serverListTab->currentServerData);
break; break;
} }
} }