From 3bfeb14b7d8af1dd1dda022a212cb19299bd16ba Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 23 Oct 2026 12:25:57 +0200 Subject: [PATCH] style(logs): show deployment status dots like the service menu Deployment options get the same status dot and Stopped caption as services instead of colored badges, so the listbox no longer needs labelClass. --- app/Livewire/Project/Shared/Logs.php | 2 +- app/Support/RuntimeLogTargets.php | 52 +++++++++++-------- .../views/components/forms/listbox.blade.php | 8 +-- tests/Unit/Support/RuntimeLogTargetsTest.php | 8 +-- 4 files changed, 40 insertions(+), 30 deletions(-) diff --git a/app/Livewire/Project/Shared/Logs.php b/app/Livewire/Project/Shared/Logs.php index 4c9b882dcf..1add0bb6a0 100644 --- a/app/Livewire/Project/Shared/Logs.php +++ b/app/Livewire/Project/Shared/Logs.php @@ -213,7 +213,7 @@ class Logs extends Component /** * @return array{ - * deployments: list, + * deployments: list, * services: list, * deployment: string, * service: string, diff --git a/app/Support/RuntimeLogTargets.php b/app/Support/RuntimeLogTargets.php index d8454098d2..45bdc42329 100644 --- a/app/Support/RuntimeLogTargets.php +++ b/app/Support/RuntimeLogTargets.php @@ -17,7 +17,7 @@ class RuntimeLogTargets /** * @param list>}> $servers * @return array{ - * deployments: list, + * deployments: list, * services: list, * deployment: string, * service: string, @@ -50,7 +50,7 @@ class RuntimeLogTargets $sources = self::sourcesFor($groups[$chosenKey]); return [ - 'deployments' => $groupDeployments ? self::deploymentOptions($deploymentIds) : [], + 'deployments' => $groupDeployments ? self::deploymentOptions($deploymentIds, $containers) : [], 'services' => self::serviceOptions($groups), 'deployment' => $chosenDeployment, 'service' => count($groups) > 1 ? $chosenKey : '', @@ -204,18 +204,37 @@ class RuntimeLogTargets } /** + * Deployments show the same status dot and caption as services, for all their containers. + * * @param list $ids - * @return list + * @param list $containers + * @return list */ - private static function deploymentOptions(array $ids): array + private static function deploymentOptions(array $ids, array $containers): array { - return array_map(fn (string $id): array => [ - 'value' => $id, - 'label' => $id === '0' ? 'Production' : 'PR #'.$id, - 'labelClass' => $id === '0' - ? 'deployment-badge deployment-badge-production' - : 'deployment-badge deployment-badge-preview', - ], $ids); + return array_map(function (string $id) use ($containers): array { + $states = array_column(array_filter( + $containers, + fn (array $container): bool => $container['deployment'] === $id, + ), 'state'); + + return self::statusOption($id, $id === '0' ? 'Production' : 'PR #'.$id, $states); + }, $ids); + } + + /** + * @param list $states + * @return array{value: string, label: string, dot: string, state?: string} + */ + private static function statusOption(string $value, string $label, array $states): array + { + $option = ['value' => $value, 'label' => $label, 'dot' => self::serviceDot($states)]; + $state = self::serviceStateLabel($states); + if ($state !== null) { + $option['state'] = $state; + } + + return $option; } /** @@ -261,16 +280,7 @@ class RuntimeLogTargets { $options = []; foreach ($groups as $key => $containers) { - $states = array_column($containers, 'state'); - $option = [ - 'value' => $key, - 'label' => $key, - 'dot' => self::serviceDot($states), - ]; - $state = self::serviceStateLabel($states); - if ($state !== null) { - $option['state'] = $state; - } + $option = self::statusOption($key, $key, array_column($containers, 'state')); if (count($containers) > 1) { $option['description'] = count($containers).' containers'; } diff --git a/resources/views/components/forms/listbox.blade.php b/resources/views/components/forms/listbox.blade.php index a7f1012835..06b68b3dbe 100644 --- a/resources/views/components/forms/listbox.blade.php +++ b/resources/views/components/forms/listbox.blade.php @@ -4,7 +4,7 @@ 'label' => null, 'helper' => null, 'required' => false, - 'options' => [], // list of ['value' => ..., 'label' => ..., 'description' => ?string, 'disabled' => bool, 'dot' => ?string, 'state' => ?string, 'labelClass' => ?string] + 'options' => [], // list of ['value' => ..., 'label' => ..., 'description' => ?string, 'disabled' => bool, 'dot' => ?string, 'state' => ?string] 'placeholder' => 'Select…', 'emptyText' => 'No options available.', 'live' => false, @@ -236,7 +236,7 @@ :aria-expanded="open" @if ($tooltip) :title="title" @endif> - {{ $multiple ? $multipleLabel : '' }} + {{ $multiple ? $multipleLabel : '' }} - + @@ -364,7 +364,7 @@ - + diff --git a/tests/Unit/Support/RuntimeLogTargetsTest.php b/tests/Unit/Support/RuntimeLogTargetsTest.php index a8fb7ca8cd..878bddbc12 100644 --- a/tests/Unit/Support/RuntimeLogTargetsTest.php +++ b/tests/Unit/Support/RuntimeLogTargetsTest.php @@ -29,16 +29,16 @@ function runtimeLogTargets(array $servers, string $deployment = '0', string $ser it('orders production ahead of newer previews and uses the top bar pills', function () { $targets = runtimeLogTargets([ runtimeLogServer('primary', 'Primary', [ - runtimeLogContainer('app-pr-7', 'coolify.pullRequestId=7,com.docker.compose.service=web'), + runtimeLogContainer('app-pr-7', 'coolify.pullRequestId=7,com.docker.compose.service=web', 'exited'), runtimeLogContainer('app', 'coolify.pullRequestId=0,com.docker.compose.service=web'), runtimeLogContainer('app-pr-42', 'coolify.pullRequestId=42,com.docker.compose.service=web'), ]), ]); expect($targets['deployments'])->toBe([ - ['value' => '0', 'label' => 'Production', 'labelClass' => 'deployment-badge deployment-badge-production'], - ['value' => '42', 'label' => 'PR #42', 'labelClass' => 'deployment-badge deployment-badge-preview'], - ['value' => '7', 'label' => 'PR #7', 'labelClass' => 'deployment-badge deployment-badge-preview'], + ['value' => '0', 'label' => 'Production', 'dot' => 'success'], + ['value' => '42', 'label' => 'PR #42', 'dot' => 'success'], + ['value' => '7', 'label' => 'PR #7', 'dot' => 'error', 'state' => 'Stopped'], ]) ->and($targets['deployment'])->toBe('0') ->and($targets['service'])->toBe('')