From ce7da1ff6604c82e46408fea66a0217a2ee0312f Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Thu, 29 Jan 2026 11:17:41 +0100 Subject: [PATCH] Read Dokploy environments for composes --- .../Widgets/DokployPlatformHealth.php | 185 +++++++++++------- .../widgets/dokploy-platform-health.blade.php | 15 ++ .../DokployPlatformHealthWidgetTest.php | 47 +++-- 3 files changed, 157 insertions(+), 90 deletions(-) diff --git a/app/Filament/Widgets/DokployPlatformHealth.php b/app/Filament/Widgets/DokployPlatformHealth.php index 6a6923a..973c9a0 100644 --- a/app/Filament/Widgets/DokployPlatformHealth.php +++ b/app/Filament/Widgets/DokployPlatformHealth.php @@ -72,10 +72,10 @@ class DokployPlatformHealth extends Widget continue; } - $applicationsPayload = Arr::get($project, 'applications', []); - $applications = $this->formatApplications(is_array($applicationsPayload) ? $applicationsPayload : [], $client); - $composes = $this->formatProjectComposes($project, $client); - $services = $this->formatProjectServices($project); + $environments = $this->extractEnvironments($project); + $applications = $this->formatEnvironmentApplications($environments, $client); + $composes = $this->formatEnvironmentComposes($environments, $client); + $services = $this->formatEnvironmentServices($environments); $results[] = [ 'label' => ucfirst((string) $label), @@ -147,10 +147,116 @@ class DokployPlatformHealth extends Widget return $results; } - protected function formatApplications(array $applications, DokployClient $client): array + protected function extractEnvironments(array $project): array + { + $environments = Arr::get($project, 'environments', []); + + if (is_array($environments) && ! empty($environments)) { + return $environments; + } + + return [[ + 'name' => Arr::get($project, 'name'), + 'applications' => Arr::get($project, 'applications', []), + 'compose' => Arr::get($project, 'compose', []), + 'mysql' => Arr::get($project, 'mysql', []), + 'postgres' => Arr::get($project, 'postgres', []), + 'mariadb' => Arr::get($project, 'mariadb', []), + 'mongo' => Arr::get($project, 'mongo', []), + 'redis' => Arr::get($project, 'redis', []), + ]]; + } + + protected function formatEnvironmentApplications(array $environments, DokployClient $client): array + { + return collect($environments) + ->flatMap(function (array $environment) use ($client) { + $applications = Arr::get($environment, 'applications', []); + $environmentName = Arr::get($environment, 'name'); + + return $this->formatApplications(is_array($applications) ? $applications : [], $client, $environmentName); + }) + ->values() + ->all(); + } + + protected function formatEnvironmentComposes(array $environments, DokployClient $client): array + { + return collect($environments) + ->flatMap(function (array $environment) use ($client) { + $composes = Arr::get($environment, 'compose', []); + $environmentName = Arr::get($environment, 'name'); + + return collect(is_array($composes) ? $composes : []) + ->map(function (array $compose) use ($client, $environmentName) { + $composeId = Arr::get($compose, 'composeId') ?? Arr::get($compose, 'id'); + $statusPayload = []; + $deployments = []; + + if ($composeId) { + try { + $statusPayload = $client->composeStatus($composeId); + $deployments = $client->composeDeployments($composeId, 1); + } catch (\Throwable $exception) { + $statusPayload = []; + $deployments = []; + } + } + + $composeDetails = Arr::get($statusPayload, 'compose', []); + + return [ + 'id' => $composeId, + 'name' => Arr::get($compose, 'name') + ?? Arr::get($compose, 'appName') + ?? Arr::get($composeDetails, 'name') + ?? Arr::get($composeDetails, 'appName') + ?? $composeId, + 'status' => Arr::get($compose, 'composeStatus') + ?? Arr::get($compose, 'status') + ?? Arr::get($composeDetails, 'composeStatus') + ?? Arr::get($composeDetails, 'status') + ?? 'unknown', + 'environment' => $environmentName, + 'last_deploy' => Arr::get($deployments, '0.createdAt') + ?? Arr::get($deployments, '0.created_at') + ?? Arr::get($compose, 'updatedAt') + ?? Arr::get($composeDetails, 'updatedAt'), + 'services' => $this->formatServices(Arr::get($statusPayload, 'services', [])), + ]; + }) + ->filter(fn (array $compose) => filled($compose['name'])) + ->values() + ->all(); + }) + ->values() + ->all(); + } + + protected function formatEnvironmentServices(array $environments): array + { + return collect($environments) + ->flatMap(function (array $environment) { + $environmentName = Arr::get($environment, 'name'); + + return collect([ + ...$this->normalizeServiceList((array) Arr::get($environment, 'compose', []), 'compose', 'composeId', 'composeStatus', $environmentName), + ...$this->normalizeServiceList((array) Arr::get($environment, 'mysql', []), 'mysql', 'mysqlId', 'applicationStatus', $environmentName), + ...$this->normalizeServiceList((array) Arr::get($environment, 'postgres', []), 'postgres', 'postgresId', 'applicationStatus', $environmentName), + ...$this->normalizeServiceList((array) Arr::get($environment, 'mariadb', []), 'mariadb', 'mariadbId', 'applicationStatus', $environmentName), + ...$this->normalizeServiceList((array) Arr::get($environment, 'mongo', []), 'mongo', 'mongoId', 'applicationStatus', $environmentName), + ...$this->normalizeServiceList((array) Arr::get($environment, 'redis', []), 'redis', 'redisId', 'applicationStatus', $environmentName), + ]); + }) + ->filter(fn (array $service) => filled($service['name'])) + ->values() + ->all(); + } + + protected function formatApplications(array $applications, DokployClient $client, ?string $environment = null): array { return collect($applications) - ->map(function (array $application) use ($client) { + ->map(function (array $application) use ($client, $environment) { $applicationId = $this->extractApplicationId($application); $statusPayload = []; @@ -194,6 +300,7 @@ class DokployPlatformHealth extends Widget 'server' => Arr::get($application, 'serverName') ?? Arr::get($applicationDetails, 'serverName') ?? Arr::get($application, 'server'), + 'environment' => $environment, 'last_deploy' => Arr::get($application, 'lastDeploymentAt') ?? Arr::get($applicationDetails, 'lastDeploymentAt') ?? Arr::get($application, 'updatedAt') @@ -214,71 +321,10 @@ class DokployPlatformHealth extends Widget ?? Arr::get($application, 'id'); } - protected function formatProjectServices(array $project): array - { - return collect([ - ...$this->normalizeServiceList((array) Arr::get($project, 'compose', []), 'compose', 'composeId', 'composeStatus'), - ...$this->normalizeServiceList((array) Arr::get($project, 'mysql', []), 'mysql', 'mysqlId', 'applicationStatus'), - ...$this->normalizeServiceList((array) Arr::get($project, 'postgres', []), 'postgres', 'postgresId', 'applicationStatus'), - ...$this->normalizeServiceList((array) Arr::get($project, 'mariadb', []), 'mariadb', 'mariadbId', 'applicationStatus'), - ...$this->normalizeServiceList((array) Arr::get($project, 'mongo', []), 'mongo', 'mongoId', 'applicationStatus'), - ...$this->normalizeServiceList((array) Arr::get($project, 'redis', []), 'redis', 'redisId', 'applicationStatus'), - ]) - ->filter(fn (array $service) => filled($service['name'])) - ->values() - ->all(); - } - - protected function formatProjectComposes(array $project, DokployClient $client): array - { - $composes = (array) Arr::get($project, 'compose', []); - - return collect($composes) - ->map(function (array $compose) use ($client) { - $composeId = Arr::get($compose, 'composeId') ?? Arr::get($compose, 'id'); - $statusPayload = []; - $deployments = []; - - if ($composeId) { - try { - $statusPayload = $client->composeStatus($composeId); - $deployments = $client->composeDeployments($composeId, 1); - } catch (\Throwable $exception) { - $statusPayload = []; - $deployments = []; - } - } - - $composeDetails = Arr::get($statusPayload, 'compose', []); - - return [ - 'id' => $composeId, - 'name' => Arr::get($compose, 'name') - ?? Arr::get($compose, 'appName') - ?? Arr::get($composeDetails, 'name') - ?? Arr::get($composeDetails, 'appName') - ?? $composeId, - 'status' => Arr::get($compose, 'composeStatus') - ?? Arr::get($compose, 'status') - ?? Arr::get($composeDetails, 'composeStatus') - ?? Arr::get($composeDetails, 'status') - ?? 'unknown', - 'last_deploy' => Arr::get($deployments, '0.createdAt') - ?? Arr::get($deployments, '0.created_at') - ?? Arr::get($compose, 'updatedAt') - ?? Arr::get($composeDetails, 'updatedAt'), - 'services' => $this->formatServices(Arr::get($statusPayload, 'services', [])), - ]; - }) - ->filter(fn (array $compose) => filled($compose['name'])) - ->values() - ->all(); - } - - protected function normalizeServiceList(array $services, string $type, string $idKey, string $statusKey): array + protected function normalizeServiceList(array $services, string $type, string $idKey, string $statusKey, ?string $environment = null): array { return collect($services) - ->map(function (array $service) use ($type, $idKey, $statusKey) { + ->map(function (array $service) use ($type, $idKey, $statusKey, $environment) { return [ 'type' => $type, 'id' => Arr::get($service, $idKey) ?? Arr::get($service, 'id'), @@ -286,6 +332,7 @@ class DokployPlatformHealth extends Widget 'status' => Arr::get($service, $statusKey) ?? Arr::get($service, 'status') ?? Arr::get($service, 'composeStatus', 'unknown'), 'version' => Arr::get($service, 'dockerImage') ?? Arr::get($service, 'image'), 'external_port' => Arr::get($service, 'externalPort'), + 'environment' => $environment, ]; }) ->values() diff --git a/resources/views/filament/widgets/dokploy-platform-health.blade.php b/resources/views/filament/widgets/dokploy-platform-health.blade.php index 1538525..d210e2a 100644 --- a/resources/views/filament/widgets/dokploy-platform-health.blade.php +++ b/resources/views/filament/widgets/dokploy-platform-health.blade.php @@ -118,6 +118,11 @@ {{ $application['id'] }} @endif + @if(!empty($application['environment'])) + + Env: {{ $application['environment'] }} + + @endif @if(!empty($application['repository'])) {{ $application['repository'] }} @@ -184,6 +189,11 @@ {{ $compose['id'] }} @endif + @if(!empty($compose['environment'])) + + Env: {{ $compose['environment'] }} + + @endif Last deploy: {{ $compose['last_deploy'] ? \Illuminate\Support\Carbon::parse($compose['last_deploy'])->diffForHumans() : '—' }} @@ -235,6 +245,11 @@ {{ $service['id'] }} @endif + @if(!empty($service['environment'])) + + Env: {{ $service['environment'] }} + + @endif @if(!empty($service['version'])) {{ $service['version'] }} diff --git a/tests/Feature/DokployPlatformHealthWidgetTest.php b/tests/Feature/DokployPlatformHealthWidgetTest.php index b880338..da970b0 100644 --- a/tests/Feature/DokployPlatformHealthWidgetTest.php +++ b/tests/Feature/DokployPlatformHealthWidgetTest.php @@ -31,28 +31,33 @@ class DokployPlatformHealthWidgetTest extends TestCase 'name' => 'Core', 'description' => 'Main stack', 'updatedAt' => now()->toIso8601String(), - 'applications' => [ + 'environments' => [ [ - 'applicationId' => 'app_1', - 'name' => 'API', - 'applicationStatus' => 'running', - 'repository' => 'repo/api', - 'branch' => 'main', - ], - ], - 'compose' => [ - [ - 'composeId' => 'cmp_1', - 'name' => 'Main Compose', - 'composeStatus' => 'done', - ], - ], - 'redis' => [ - [ - 'redisId' => 'redis_1', - 'name' => 'Redis', - 'applicationStatus' => 'done', - 'externalPort' => 6379, + 'name' => 'production', + 'applications' => [ + [ + 'applicationId' => 'app_1', + 'name' => 'API', + 'applicationStatus' => 'running', + 'repository' => 'repo/api', + 'branch' => 'main', + ], + ], + 'compose' => [ + [ + 'composeId' => 'cmp_1', + 'name' => 'Main Compose', + 'composeStatus' => 'done', + ], + ], + 'redis' => [ + [ + 'redisId' => 'redis_1', + 'name' => 'Redis', + 'applicationStatus' => 'done', + 'externalPort' => 6379, + ], + ], ], ], ]);