admin widget zu dokploy geswitched, viele übersetzungen im Frontend vervollständigt und Anlässe-Seiten mit ChatGPT ausgebaut

This commit is contained in:
Codex Agent
2025-11-19 13:12:35 +01:00
parent 125c624588
commit d8f365ddd6
30 changed files with 2820 additions and 293 deletions

View File

@@ -34,16 +34,17 @@ class InfrastructureActionLogResource extends Resource
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('service_id')
->label('Service')
->label('Target')
->searchable()
->copyable()
->limit(30),
Tables\Columns\BadgeColumn::make('action')
->label('Action')
->colors([
'warning' => 'restart',
'info' => 'redeploy',
'gray' => 'logs',
'warning' => fn ($state) => in_array($state, ['compose.redeploy', 'redeploy'], true),
'success' => fn ($state) => in_array($state, ['compose.deploy', 'deploy'], true),
'danger' => fn ($state) => in_array($state, ['compose.stop', 'stop'], true),
'gray' => fn ($state) => $state === 'logs',
])
->sortable(),
Tables\Columns\TextColumn::make('status_code')

View File

@@ -19,7 +19,7 @@ class DokployDeployments extends Page
protected string $view = 'filament.super-admin.pages.dokploy-deployments';
public array $applications = [];
public array $composes = [];
public array $recentLogs = [];
@@ -28,43 +28,45 @@ class DokployDeployments extends Page
public function mount(DokployClient $client): void
{
$this->dokployWebUrl = config('dokploy.web_url');
$this->refreshApplications($client);
$this->refreshComposes($client);
$this->refreshLogs();
}
public function reload(string $applicationId): void
public function redeploy(string $composeId): void
{
$this->performAction($applicationId, 'reload');
$this->performAction($composeId, 'redeploy');
}
public function redeploy(string $applicationId): void
public function stop(string $composeId): void
{
$this->performAction($applicationId, 'redeploy');
$this->performAction($composeId, 'stop');
}
protected function performAction(string $applicationId, string $action): void
protected function performAction(string $composeId, string $action): void
{
$client = app(DokployClient::class);
if (! $this->isKnownApplication($applicationId)) {
if (! $this->isKnownCompose($composeId)) {
Notification::make()
->danger()
->title('Unknown service')
->body("The application ID {$applicationId} is not configured.")
->body("The compose ID {$composeId} is not configured.")
->send();
return;
}
try {
$action === 'reload'
? $client->reloadApplication($applicationId, auth()->user())
: $client->redeployApplication($applicationId, auth()->user());
match ($action) {
'redeploy' => $client->redeployCompose($composeId, auth()->user()),
'stop' => $client->stopCompose($composeId, auth()->user()),
default => throw new \RuntimeException("Unsupported action [{$action}]"),
};
Notification::make()
->success()
->title(ucfirst($action).' requested')
->body("Dokploy accepted the {$action} action for {$applicationId}.")
->body("Dokploy accepted the {$action} action for {$composeId}.")
->send();
} catch (\Throwable $exception) {
Notification::make()
@@ -74,35 +76,35 @@ class DokployDeployments extends Page
->send();
}
$this->refreshApplications($client);
$this->refreshComposes($client);
$this->refreshLogs();
}
protected function refreshApplications(DokployClient $client): void
protected function refreshComposes(DokployClient $client): void
{
$applicationMap = config('dokploy.applications', []);
$composeMap = config('dokploy.composes', []);
$results = [];
foreach ($applicationMap as $label => $id) {
foreach ($composeMap as $label => $id) {
try {
$status = $client->applicationStatus($id);
$application = Arr::get($status, 'application', []);
$status = $client->composeStatus($id);
$compose = Arr::get($status, 'compose', []);
$results[] = [
'label' => ucfirst($label),
'application_id' => $id,
'status' => Arr::get($application, 'applicationStatus', 'unknown'),
'compose_id' => $id,
'status' => Arr::get($compose, 'composeStatus', 'unknown'),
];
} catch (\Throwable $e) {
$results[] = [
'label' => ucfirst($label),
'application_id' => $id,
'compose_id' => $id,
'status' => 'error',
];
}
}
$this->applications = $results;
$this->composes = $results;
}
protected function refreshLogs(): void
@@ -122,8 +124,8 @@ class DokployDeployments extends Page
->toArray();
}
protected function isKnownApplication(string $applicationId): bool
protected function isKnownCompose(string $composeId): bool
{
return in_array($applicationId, array_values(config('dokploy.applications', [])), true);
return in_array($composeId, array_values(config('dokploy.composes', [])), true);
}
}

View File

@@ -15,49 +15,38 @@ class DokployPlatformHealth extends Widget
protected function getViewData(): array
{
return [
'applications' => $this->loadApplications(),
'composes' => $this->loadComposes(),
];
}
protected function loadApplications(): array
protected function loadComposes(): array
{
$client = app(DokployClient::class);
$applicationMap = config('dokploy.applications', []);
$composeMap = config('dokploy.composes', []);
$results = [];
foreach ($applicationMap as $label => $applicationId) {
foreach ($composeMap as $label => $composeId) {
try {
$status = $client->applicationStatus($applicationId);
$deployments = $client->recentDeployments($applicationId, 1);
$application = Arr::get($status, 'application', []);
$monitoring = Arr::get($status, 'monitoring', []);
$status = $client->composeStatus($composeId);
$deployments = $client->composeDeployments($composeId, 1);
$compose = Arr::get($status, 'compose', []);
$services = $this->formatServices(Arr::get($status, 'services', []));
$results[] = [
'label' => ucfirst($label),
'application_id' => $applicationId,
'app_name' => Arr::get($application, 'appName') ?? Arr::get($application, 'name'),
'status' => Arr::get($application, 'applicationStatus', 'unknown'),
'cpu' => $this->extractMetric($monitoring, [
'metrics.cpuPercent',
'metrics.cpu_percent',
'cpuPercent',
'cpu_percent',
]),
'memory' => $this->extractMetric($monitoring, [
'metrics.memoryPercent',
'metrics.memory_percent',
'memoryPercent',
'memory_percent',
]),
'compose_id' => $composeId,
'name' => Arr::get($compose, 'name') ?? Arr::get($compose, 'appName') ?? $composeId,
'status' => Arr::get($compose, 'composeStatus', 'unknown'),
'services' => $services,
'last_deploy' => Arr::get($deployments, '0.createdAt')
?? Arr::get($deployments, '0.created_at')
?? Arr::get($application, 'updatedAt')
?? Arr::get($application, 'lastDeploymentAt'),
?? Arr::get($compose, 'updatedAt')
?? Arr::get($compose, 'lastDeploymentAt'),
];
} catch (\Throwable $exception) {
$results[] = [
'label' => ucfirst($label),
'application_id' => $applicationId,
'compose_id' => $composeId,
'status' => 'unreachable',
'error' => $exception->getMessage(),
];
@@ -68,9 +57,9 @@ class DokployPlatformHealth extends Widget
return [
[
'label' => 'Dokploy',
'application_id' => '-',
'compose_id' => '-',
'status' => 'unconfigured',
'error' => 'Set DOKPLOY_APPLICATION_IDS in .env to enable monitoring.',
'error' => 'Set DOKPLOY_COMPOSE_IDS in .env to enable monitoring.',
],
];
}
@@ -78,14 +67,17 @@ class DokployPlatformHealth extends Widget
return $results;
}
protected function extractMetric(array $source, array $candidates): mixed
protected function formatServices(array $services): array
{
foreach ($candidates as $key) {
if (Arr::has($source, $key)) {
return Arr::get($source, $key);
}
}
return null;
return collect($services)
->map(function ($service) {
return [
'name' => Arr::get($service, 'serviceName') ?? Arr::get($service, 'name') ?? Arr::get($service, 'containerName'),
'status' => Arr::get($service, 'status') ?? Arr::get($service, 'state') ?? Arr::get($service, 'composeStatus', 'unknown'),
];
})
->filter(fn ($service) => filled($service['name']))
->values()
->all();
}
}