Backup
This commit is contained in:
parent
29b14379e7
commit
b07058f742
44
examples/ServerManager/UI/LoadingIndicator.php
Normal file
44
examples/ServerManager/UI/LoadingIndicator.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ServerManager\UI;
|
||||||
|
|
||||||
|
use PHPNative\Tailwind\Data\Icon as IconName;
|
||||||
|
use PHPNative\Ui\Widget\Container;
|
||||||
|
use PHPNative\Ui\Widget\Icon;
|
||||||
|
use PHPNative\Ui\Widget\Label;
|
||||||
|
|
||||||
|
class LoadingIndicator extends Container
|
||||||
|
{
|
||||||
|
private Icon $icon;
|
||||||
|
private Label $label;
|
||||||
|
private bool $loading = false;
|
||||||
|
|
||||||
|
public function __construct(string $style = '')
|
||||||
|
{
|
||||||
|
parent::__construct('flex flex-row items-center gap-1 px-2 ' . $style);
|
||||||
|
|
||||||
|
$this->icon = new Icon(IconName::sync, 14, 'text-blue-600');
|
||||||
|
$this->label = new Label('Laden...', 'text-xs text-gray-700');
|
||||||
|
|
||||||
|
$this->addComponent($this->icon);
|
||||||
|
$this->addComponent($this->label);
|
||||||
|
|
||||||
|
$this->setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLoading(bool $loading): void
|
||||||
|
{
|
||||||
|
if ($this->loading === $loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->loading = $loading;
|
||||||
|
$this->setVisible($loading);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isLoading(): bool
|
||||||
|
{
|
||||||
|
return $this->loading;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -12,6 +12,7 @@ use PHPNative\Ui\Widget\TabContainer;
|
|||||||
use PHPNative\Ui\Widget\Table;
|
use PHPNative\Ui\Widget\Table;
|
||||||
use PHPNative\Ui\Widget\TextInput;
|
use PHPNative\Ui\Widget\TextInput;
|
||||||
use ServerManager\Services\HetznerService;
|
use ServerManager\Services\HetznerService;
|
||||||
|
use ServerManager\UI\LoadingIndicator;
|
||||||
|
|
||||||
class ServerListTab
|
class ServerListTab
|
||||||
{
|
{
|
||||||
@ -32,6 +33,7 @@ class ServerListTab
|
|||||||
private Label $detailType;
|
private Label $detailType;
|
||||||
private Label $detailIpv4;
|
private Label $detailIpv4;
|
||||||
private Container $detailDomainsContainer;
|
private Container $detailDomainsContainer;
|
||||||
|
private LoadingIndicator $loadingIndicator;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string &$apiKey,
|
string &$apiKey,
|
||||||
@ -49,6 +51,9 @@ class ServerListTab
|
|||||||
// Left side: Table with search and refresh
|
// Left side: Table with search and refresh
|
||||||
$leftSide = new Container('flex flex-col gap-2 flex-1');
|
$leftSide = new Container('flex flex-col gap-2 flex-1');
|
||||||
|
|
||||||
|
// Header row with refresh button and loading indicator on the right
|
||||||
|
$headerRow = new Container('flex flex-row items-center gap-2');
|
||||||
|
|
||||||
// Refresh button
|
// Refresh button
|
||||||
$this->refreshButton = new Button(
|
$this->refreshButton = new Button(
|
||||||
'Server aktualisieren',
|
'Server aktualisieren',
|
||||||
@ -58,7 +63,13 @@ class ServerListTab
|
|||||||
);
|
);
|
||||||
$refreshIcon = new Icon(IconName::sync, 16, 'text-white');
|
$refreshIcon = new Icon(IconName::sync, 16, 'text-white');
|
||||||
$this->refreshButton->setIcon($refreshIcon);
|
$this->refreshButton->setIcon($refreshIcon);
|
||||||
$leftSide->addComponent($this->refreshButton);
|
$headerRow->addComponent($this->refreshButton);
|
||||||
|
|
||||||
|
// Loading indicator (top-right in the server tab header)
|
||||||
|
$this->loadingIndicator = new LoadingIndicator('ml-auto');
|
||||||
|
$headerRow->addComponent($this->loadingIndicator);
|
||||||
|
|
||||||
|
$leftSide->addComponent($headerRow);
|
||||||
|
|
||||||
// Search input
|
// Search input
|
||||||
$this->searchInput = new TextInput(
|
$this->searchInput = new TextInput(
|
||||||
@ -222,9 +233,11 @@ class ServerListTab
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Refresh button - use reference to apiKey & privateKey variable
|
// Refresh button - use TaskManager directly so we can control the loading indicator
|
||||||
$this->refreshButton->setOnClickAsync(
|
$this->refreshButton->setOnClick(function () use (&$currentApiKey, $serverListTab, &$currentPrivateKeyPath) {
|
||||||
function () use (&$currentApiKey) {
|
$serverListTab->loadingIndicator->setLoading(true);
|
||||||
|
|
||||||
|
$task = TaskManager::getInstance()->runAsync(function () use (&$currentApiKey) {
|
||||||
try {
|
try {
|
||||||
if (empty($currentApiKey)) {
|
if (empty($currentApiKey)) {
|
||||||
return ['error' => 'Kein API-Key konfiguriert'];
|
return ['error' => 'Kein API-Key konfiguriert'];
|
||||||
@ -253,8 +266,9 @@ class ServerListTab
|
|||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return ['error' => 'Exception: ' . $e->getMessage()];
|
return ['error' => 'Exception: ' . $e->getMessage()];
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
function ($result) use (&$serverListTab, &$currentPrivateKeyPath) {
|
|
||||||
|
$task->onComplete(function ($result) use (&$serverListTab, &$currentPrivateKeyPath) {
|
||||||
if (is_array($result)) {
|
if (is_array($result)) {
|
||||||
if (isset($result['error'])) {
|
if (isset($result['error'])) {
|
||||||
$serverListTab->statusLabel->setText('Fehler: ' . $result['error']);
|
$serverListTab->statusLabel->setText('Fehler: ' . $result['error']);
|
||||||
@ -275,12 +289,13 @@ class ServerListTab
|
|||||||
$ip = $row['ipv4'] ?? '';
|
$ip = $row['ipv4'] ?? '';
|
||||||
|
|
||||||
if (empty($ip) || empty($currentPrivateKeyPath) || !file_exists($currentPrivateKeyPath)) {
|
if (empty($ip) || empty($currentPrivateKeyPath) || !file_exists($currentPrivateKeyPath)) {
|
||||||
$serverListTab->currentServerData[$index]['docker_error'] = 'Kein gültiger Private-Key oder IP';
|
$serverListTab->currentServerData[$index]['docker_error'] =
|
||||||
|
'Kein gültiger Private-Key oder IP';
|
||||||
$serverListTab->currentServerData[$index]['docker_status'] = 'error';
|
$serverListTab->currentServerData[$index]['docker_status'] = 'error';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$task = TaskManager::getInstance()->runAsync(function () use (
|
$dockerTask = TaskManager::getInstance()->runAsync(function () use (
|
||||||
$ip,
|
$ip,
|
||||||
$currentPrivateKeyPath,
|
$currentPrivateKeyPath,
|
||||||
$index,
|
$index,
|
||||||
@ -337,7 +352,7 @@ class ServerListTab
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$task->onComplete(function ($dockerResult) use (&$serverListTab) {
|
$dockerTask->onComplete(function ($dockerResult) use (&$serverListTab) {
|
||||||
if (!is_array($dockerResult) || !isset($dockerResult['index'])) {
|
if (!is_array($dockerResult) || !isset($dockerResult['index'])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -380,7 +395,7 @@ class ServerListTab
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$task->onError(function ($error) use ($serverListTab, $index) {
|
$dockerTask->onError(function ($error) use (&$serverListTab, $index) {
|
||||||
$errorMsg = is_object($error) && method_exists($error, 'getMessage')
|
$errorMsg = is_object($error) && method_exists($error, 'getMessage')
|
||||||
? $error->getMessage()
|
? $error->getMessage()
|
||||||
: ((string) $error);
|
: ((string) $error);
|
||||||
@ -392,15 +407,20 @@ class ServerListTab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
function ($error) use (&$serverListTab) {
|
$serverListTab->loadingIndicator->setLoading(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$task->onError(function ($error) use (&$serverListTab) {
|
||||||
$errorMsg = is_object($error) && method_exists($error, 'getMessage')
|
$errorMsg = is_object($error) && method_exists($error, 'getMessage')
|
||||||
? $error->getMessage()
|
? $error->getMessage()
|
||||||
: ((string) $error);
|
: ((string) $error);
|
||||||
$serverListTab->statusLabel->setText('Async Fehler: ' . $errorMsg);
|
$serverListTab->statusLabel->setText('Async Fehler: ' . $errorMsg);
|
||||||
echo "Async error: {$errorMsg}\n";
|
echo "Async error: {$errorMsg}\n";
|
||||||
},
|
|
||||||
);
|
$serverListTab->loadingIndicator->setLoading(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getContainer(): Container
|
public function getContainer(): Container
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user