mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-04 10:42:23 +00:00
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.
This commit is contained in:
1 parent
a90be6aa93
commit
3bfeb14b7d
4 files changed
+40
-30
No files matched your search
@@ -213,7 +213,7 @@ class Logs extends Component
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* deployments: list<array{value: string, label: string, labelClass: string}>,
|
||||
* deployments: list<array{value: string, label: string, dot: string, state?: string}>,
|
||||
* services: list<array{value: string, label: string, dot: string, description?: string}>,
|
||||
* deployment: string,
|
||||
* service: string,
|
||||
|
||||
@@ -17,7 +17,7 @@ class RuntimeLogTargets
|
||||
/**
|
||||
* @param list<array{uuid: string, name: string, containers: list<array<string, mixed>>}> $servers
|
||||
* @return array{
|
||||
* deployments: list<array{value: string, label: string, labelClass: string}>,
|
||||
* deployments: list<array{value: string, label: string, dot: string, state?: string}>,
|
||||
* services: list<array{value: string, label: string, dot: string, description?: string, state?: string}>,
|
||||
* 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<string> $ids
|
||||
* @return list<array{value: string, label: string, labelClass: string}>
|
||||
* @param list<array{deployment: string, state: string}> $containers
|
||||
* @return list<array{value: string, label: string, dot: string, state?: string}>
|
||||
*/
|
||||
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<string> $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';
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
<span class="listbox-trigger-label flex items-center gap-2">
|
||||
<span x-show="selectedOption?.dot" class="size-1.5 shrink-0 rounded-full" :class="dotClass(selectedOption?.dot)"></span>
|
||||
<span class="min-w-0 truncate" :class="selectedOption?.labelClass" x-text="current">{{ $multiple ? $multipleLabel : '' }}</span>
|
||||
<span class="min-w-0 truncate" x-text="current">{{ $multiple ? $multipleLabel : '' }}</span>
|
||||
<span x-show="selectedOption?.state" class="shrink-0 text-xs text-neutral-500 dark:text-fg-dim" x-text="selectedOption?.state"></span>
|
||||
</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2"
|
||||
@@ -292,7 +292,7 @@
|
||||
<span x-show="option.dot" class="size-1.5 shrink-0 rounded-full" :class="dotClass(option.dot)"></span>
|
||||
<span class="flex min-w-0 flex-col items-start">
|
||||
<span class="flex min-w-0 items-baseline gap-2">
|
||||
<span class="truncate" :class="option.labelClass" x-text="option.label"></span>
|
||||
<span class="truncate" x-text="option.label"></span>
|
||||
<span x-show="option.state" x-text="option.state"
|
||||
class="shrink-0 text-xs text-neutral-500 dark:text-fg-dim"></span>
|
||||
</span>
|
||||
@@ -364,7 +364,7 @@
|
||||
<span x-show="option.dot" class="size-1.5 shrink-0 rounded-full" :class="dotClass(option.dot)"></span>
|
||||
<span class="flex min-w-0 flex-col items-start">
|
||||
<span class="flex min-w-0 items-baseline gap-2">
|
||||
<span class="truncate" :class="option.labelClass" x-text="option.label"></span>
|
||||
<span class="truncate" x-text="option.label"></span>
|
||||
<span x-show="option.state" x-text="option.state"
|
||||
class="shrink-0 text-xs text-neutral-500 dark:text-fg-dim"></span>
|
||||
</span>
|
||||
|
||||
@@ -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('')
|
||||
|
||||
Reference in new issue
Block a user