mirror of
https://github.com/coollabsio/coolify.git
synced 2026-03-11 08:55:47 +00:00
Refactor deployment index view for improved layout and functionality
- Rearranged the table header to display 'Application' and 'Environment' in a more logical order. - Made the 'Application' and 'Environment' sections clickable, linking to their respective configuration and resource pages. - Removed unnecessary status time display and streamlined the deployment information presentation. - Enhanced the overall structure for better readability and user experience.
This commit is contained in:
parent
0621a1ad92
commit
09f8992af1
2 changed files with 102 additions and 50 deletions
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Livewire\Deployment;
|
||||
|
||||
use App\Enums\ApplicationDeploymentStatus;
|
||||
use App\Models\Application;
|
||||
use App\Models\ApplicationDeploymentQueue;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\GitlabApp;
|
||||
|
|
@ -22,6 +23,8 @@ class Index extends Component
|
|||
|
||||
public ?int $selectedServerId = null;
|
||||
|
||||
public ?string $selectedApplicationId = null;
|
||||
|
||||
public ?int $selectedSourceId = null;
|
||||
|
||||
public ?string $selectedSourceType = null;
|
||||
|
|
@ -33,6 +36,7 @@ class Index extends Component
|
|||
protected $queryString = [
|
||||
'selectedProjectId' => ['except' => ''],
|
||||
'selectedServerId' => ['except' => ''],
|
||||
'selectedApplicationId' => ['except' => ''],
|
||||
'selectedSourceId' => ['except' => ''],
|
||||
'selectedSourceType' => ['except' => ''],
|
||||
'selectedStatus' => ['except' => ''],
|
||||
|
|
@ -70,6 +74,11 @@ class Index extends Component
|
|||
$query->where('application_deployment_queues.server_id', $this->selectedServerId);
|
||||
}
|
||||
|
||||
// Filter by application
|
||||
if ($this->selectedApplicationId) {
|
||||
$query->where('applications.uuid', $this->selectedApplicationId);
|
||||
}
|
||||
|
||||
// Filter by source
|
||||
if ($this->selectedSourceId && $this->selectedSourceType) {
|
||||
$query->where('applications.source_id', $this->selectedSourceId)
|
||||
|
|
@ -99,6 +108,11 @@ class Index extends Component
|
|||
$this->resetPage();
|
||||
}
|
||||
|
||||
public function updatedSelectedApplicationId()
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
public function updatedSelectedSourceId()
|
||||
{
|
||||
$this->resetPage();
|
||||
|
|
@ -113,6 +127,7 @@ class Index extends Component
|
|||
{
|
||||
$this->selectedProjectId = null;
|
||||
$this->selectedServerId = null;
|
||||
$this->selectedApplicationId = null;
|
||||
$this->selectedSourceId = null;
|
||||
$this->selectedSourceType = null;
|
||||
$this->selectedStatus = null;
|
||||
|
|
@ -150,6 +165,27 @@ class Index extends Component
|
|||
->toArray();
|
||||
}
|
||||
|
||||
// Get applications that have deployments (only show applications with actual deployments)
|
||||
// Uses same join pattern as loadDeployments() to avoid type mismatch
|
||||
$applicationUuids = ApplicationDeploymentQueue::query()
|
||||
->join('applications', function ($join) {
|
||||
$join->on(DB::raw('CAST(application_deployment_queues.application_id AS INTEGER)'), '=', 'applications.id');
|
||||
})
|
||||
->join('environments', 'applications.environment_id', '=', 'environments.id')
|
||||
->join('projects', 'environments.project_id', '=', 'projects.id')
|
||||
->where('projects.team_id', $teamId)
|
||||
->whereNull('applications.deleted_at')
|
||||
->distinct('applications.uuid')
|
||||
->pluck('applications.uuid')
|
||||
->toArray();
|
||||
|
||||
$applications = [];
|
||||
if (! empty($applicationUuids)) {
|
||||
$applications = Application::whereIn('uuid', $applicationUuids)
|
||||
->pluck('name', 'uuid')
|
||||
->toArray();
|
||||
}
|
||||
|
||||
// Get sources (GitHub/GitLab apps) from applications with deployments
|
||||
// Applications use polymorphic relationships for sources, so we need to handle
|
||||
// both GithubApp and GitlabApp types
|
||||
|
|
@ -224,6 +260,7 @@ class Index extends Component
|
|||
return [
|
||||
'projects' => $projects,
|
||||
'servers' => $servers,
|
||||
'applications' => $applications,
|
||||
'sources' => $sources,
|
||||
'statuses' => $statuses,
|
||||
];
|
||||
|
|
@ -239,6 +276,11 @@ class Index extends Component
|
|||
return count($this->getFilterOptionsProperty()['servers']) > 1;
|
||||
}
|
||||
|
||||
public function getShouldShowApplicationFilterProperty(): bool
|
||||
{
|
||||
return count($this->getFilterOptionsProperty()['applications']) > 1;
|
||||
}
|
||||
|
||||
public function getShouldShowSourceFilterProperty(): bool
|
||||
{
|
||||
return count($this->getFilterOptionsProperty()['sources']) > 1;
|
||||
|
|
@ -327,6 +369,7 @@ class Index extends Component
|
|||
'isPolling' => $this->isPolling,
|
||||
'shouldShowProjectFilter' => $this->shouldShowProjectFilter,
|
||||
'shouldShowServerFilter' => $this->shouldShowServerFilter,
|
||||
'shouldShowApplicationFilter' => $this->shouldShowApplicationFilter,
|
||||
'shouldShowSourceFilter' => $this->shouldShowSourceFilter,
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,26 @@
|
|||
</x-dropdown>
|
||||
@endif
|
||||
|
||||
@if ($shouldShowApplicationFilter)
|
||||
<x-dropdown>
|
||||
<x-slot:title>
|
||||
{{ $selectedApplicationId ? ($filterOptions['applications'][$selectedApplicationId] ?? 'All Applications') : 'All Applications' }}
|
||||
</x-slot:title>
|
||||
<div class="flex flex-col">
|
||||
<button wire:click="$set('selectedApplicationId', null)"
|
||||
class="dropdown-item {{ !$selectedApplicationId ? 'bg-neutral-100 dark:bg-coolgray-100' : '' }}">
|
||||
All Applications
|
||||
</button>
|
||||
@foreach ($filterOptions['applications'] as $uuid => $name)
|
||||
<button wire:click="$set('selectedApplicationId', '{{ $uuid }}')"
|
||||
class="dropdown-item {{ $selectedApplicationId === $uuid ? 'bg-neutral-100 dark:bg-coolgray-100' : '' }}">
|
||||
{{ $name }}
|
||||
</button>
|
||||
@endforeach
|
||||
</div>
|
||||
</x-dropdown>
|
||||
@endif
|
||||
|
||||
@if ($shouldShowSourceFilter)
|
||||
<x-dropdown>
|
||||
<x-slot:title>
|
||||
|
|
@ -94,7 +114,7 @@
|
|||
</div>
|
||||
</x-dropdown>
|
||||
|
||||
@if ($selectedProjectId || $selectedServerId || $selectedSourceId || $selectedStatus)
|
||||
@if ($selectedProjectId || $selectedServerId || $selectedApplicationId || $selectedSourceId || $selectedStatus)
|
||||
<button wire:click="clearFilters"
|
||||
class="px-3 py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white">
|
||||
Clear filters
|
||||
|
|
@ -107,11 +127,10 @@
|
|||
{{-- Table Header --}}
|
||||
<div class="flex items-center gap-4 px-4 py-2 border-b border-neutral-300 dark:border-coolgray-200 bg-neutral-50 dark:bg-coolgray-200 text-xs font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">
|
||||
<div class="w-20 flex-shrink-0">ID</div>
|
||||
<div class="w-32 flex-shrink-0">Environment</div>
|
||||
<div class="w-40 flex-shrink-0">Status</div>
|
||||
<div class="flex-1 min-w-0">Application</div>
|
||||
<div class="min-w-0 flex-1">Commit</div>
|
||||
<div class="w-48 flex-shrink-0 text-right">Created</div>
|
||||
<div class="flex-1 min-w-0">Application</div>
|
||||
<div class="w-32 flex-shrink-0">Environment</div>
|
||||
</div>
|
||||
|
||||
@forelse ($deployments as $deployment)
|
||||
|
|
@ -124,8 +143,6 @@
|
|||
// Format deployment ID for display (first 9 characters)
|
||||
$shortId = substr($deployment->deployment_uuid, 0, 9);
|
||||
$status = $deployment->status;
|
||||
$statusUpdatedAt = $deployment->updated_at;
|
||||
$statusTimeAgo = $statusUpdatedAt->diffForHumans(['short' => true]);
|
||||
|
||||
// Determine if deployment is actively running (needs polling/logs)
|
||||
$isActive = in_array($status, ['in_progress', 'queued']);
|
||||
|
|
@ -173,26 +190,6 @@
|
|||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Environment Badge -- Clickable to environment page --}}
|
||||
<div class="flex items-center gap-2 w-32 flex-shrink-0 whitespace-nowrap">
|
||||
@if ($environment && $project)
|
||||
<a href="{{ route('project.resource.index', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_uuid' => $environment->uuid
|
||||
]) }}"
|
||||
class="px-2 py-0.5 text-xs font-medium rounded bg-neutral-100 dark:bg-coolgray-100 text-gray-700 dark:text-gray-300 whitespace-nowrap hover:bg-neutral-200 dark:hover:bg-coolgray-200 transition-colors">
|
||||
{{ ucfirst($environment->name) }}
|
||||
</a>
|
||||
@if ($isCurrent)
|
||||
<span class="w-2 h-2 rounded-full bg-blue-500 flex-shrink-0" title="Current deployment"></span>
|
||||
@endif
|
||||
@elseif ($environment)
|
||||
<span class="px-2 py-0.5 text-xs font-medium rounded bg-neutral-100 dark:bg-coolgray-100 text-gray-700 dark:text-gray-300 whitespace-nowrap">
|
||||
{{ ucfirst($environment->name) }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Status -- Not clickable --}}
|
||||
<div class="flex items-center gap-2 w-40 flex-shrink-0 whitespace-nowrap">
|
||||
@if ($isActive)
|
||||
|
|
@ -203,27 +200,6 @@
|
|||
<span class="text-sm font-medium {{ $statusConfig['textColor'] }} whitespace-nowrap">
|
||||
{{ $statusConfig['text'] }}
|
||||
</span>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">
|
||||
{{ $statusTimeAgo }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{{-- Application Info -- Clickable to application configuration page --}}
|
||||
<div class="flex items-center gap-2 flex-1 min-w-0">
|
||||
@if ($project && $environment && $application)
|
||||
<a href="{{ route('project.application.configuration', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_uuid' => $environment->uuid,
|
||||
'application_uuid' => $application->uuid
|
||||
]) }}"
|
||||
class="font-medium text-sm dark:text-white truncate hover:text-gray-900 dark:hover:text-gray-200 hover:underline">
|
||||
{{ $application->name }}
|
||||
</a>
|
||||
@else
|
||||
<span class="font-medium text-sm dark:text-white truncate">
|
||||
{{ $application->name }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Commit Info -- Clickable to GitHub commit page --}}
|
||||
|
|
@ -249,9 +225,42 @@
|
|||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Metadata -- Not clickable --}}
|
||||
<div class="flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400 w-48 flex-shrink-0 justify-end whitespace-nowrap">
|
||||
<span class="whitespace-nowrap">{{ $deployment->created_at->diffForHumans(['short' => true]) }}</span>
|
||||
{{-- Application Info -- Clickable to application configuration page --}}
|
||||
<div class="flex items-center gap-2 flex-1 min-w-0">
|
||||
@if ($project && $environment && $application)
|
||||
<a href="{{ route('project.application.configuration', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_uuid' => $environment->uuid,
|
||||
'application_uuid' => $application->uuid
|
||||
]) }}"
|
||||
class="font-medium text-sm dark:text-white truncate hover:text-gray-900 dark:hover:text-gray-200 hover:underline">
|
||||
{{ $application->name }}
|
||||
</a>
|
||||
@else
|
||||
<span class="font-medium text-sm dark:text-white truncate">
|
||||
{{ $application->name }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Environment Badge -- Clickable to environment page --}}
|
||||
<div class="flex items-center gap-2 w-32 flex-shrink-0 whitespace-nowrap">
|
||||
@if ($environment && $project)
|
||||
<a href="{{ route('project.resource.index', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_uuid' => $environment->uuid
|
||||
]) }}"
|
||||
class="px-2 py-0.5 text-xs font-medium rounded bg-neutral-100 dark:bg-coolgray-100 text-gray-700 dark:text-gray-300 whitespace-nowrap hover:bg-neutral-200 dark:hover:bg-coolgray-200 transition-colors">
|
||||
{{ ucfirst($environment->name) }}
|
||||
</a>
|
||||
@if ($isCurrent)
|
||||
<span class="w-2 h-2 rounded-full bg-blue-500 flex-shrink-0" title="Current deployment"></span>
|
||||
@endif
|
||||
@elseif ($environment)
|
||||
<span class="px-2 py-0.5 text-xs font-medium rounded bg-neutral-100 dark:bg-coolgray-100 text-gray-700 dark:text-gray-300 whitespace-nowrap">
|
||||
{{ ucfirst($environment->name) }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Expand/Collapse Button for Logs --}}
|
||||
|
|
|
|||
Loading…
Reference in a new issue