From eec61e45b4742352164ce62ff3f0852a035a9a12 Mon Sep 17 00:00:00 2001 From: Aditya Tripathi Date: Fri, 11 Sep 2026 09:10:20 +0000 Subject: [PATCH] feat(database): reopen the live start/restart log after closing it Extend the service reopen-deployment pattern to databases: - Track the running activity id (refreshed on the 10s poll, on broadcasts, and instantly when start/restart runs) - Add reopenDeployment() to re-attach the activity monitor and reopen the dialog - Show the shared x-deploying-indicator in the mobile status row + desktop HUD - Clicking Start/Restart while an operation runs reopens the log instead of launching a duplicate Applications already use a persistent deployment-log page, so they need no reopen affordance. --- app/Livewire/Project/Database/Heading.php | 58 +++++++++++++++++++ .../project/database/heading.blade.php | 17 ++++++ 2 files changed, 75 insertions(+) diff --git a/app/Livewire/Project/Database/Heading.php b/app/Livewire/Project/Database/Heading.php index 993200b578..9a7a8634aa 100644 --- a/app/Livewire/Project/Database/Heading.php +++ b/app/Livewire/Project/Database/Heading.php @@ -6,9 +6,11 @@ use App\Actions\Database\RestartDatabase; use App\Actions\Database\StartDatabase; use App\Actions\Database\StopDatabase; use App\Actions\Docker\GetContainersStatus; +use App\Enums\ProcessStatus; use App\Events\ServiceStatusChanged; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; +use Spatie\Activitylog\Models\Activity; class Heading extends Component { @@ -20,6 +22,10 @@ class Heading extends Component public $docker_cleanup = true; + public $isDeploymentProgress = false; + + public $runningActivityId = null; + public function getListeners() { $teamId = auth()->user()->currentTeam()->id; @@ -61,6 +67,8 @@ class Heading extends Component public function checkStatus() { + $this->checkDeployments(); + if ($this->database->destination->server->isFunctional()) { GetContainersStatus::dispatch($this->database->destination->server); } else { @@ -68,6 +76,52 @@ class Heading extends Component } } + public function checkDeployments() + { + try { + $activity = Activity::where('properties->type_uuid', $this->database->uuid)->latest()->first(); + $status = data_get($activity, 'properties.status'); + if ($status === ProcessStatus::QUEUED->value || $status === ProcessStatus::IN_PROGRESS->value) { + $this->isDeploymentProgress = true; + $this->runningActivityId = $activity->id; + } else { + $this->isDeploymentProgress = false; + $this->runningActivityId = null; + } + } catch (\Throwable) { + $this->isDeploymentProgress = false; + $this->runningActivityId = null; + } + + return $this->isDeploymentProgress; + } + + /** + * Re-attach the live log dialog to a start/restart that is already running, + * so the log reappears after the dialog was closed. + */ + public function reopenDeployment() + { + $this->authorize('view', $this->database); + + $this->checkDeployments(); + + if ($this->isDeploymentProgress && $this->runningActivityId) { + $this->dispatch('activityMonitor', $this->runningActivityId, ServiceStatusChanged::class); + $this->js("window.dispatchEvent(new CustomEvent('startdatabase'))"); + } else { + $this->dispatch('info', 'No operation is currently running.'); + } + } + + private function markDeploymentRunning($activity): void + { + if (is_object($activity)) { + $this->isDeploymentProgress = true; + $this->runningActivityId = $activity->id; + } + } + public function manualCheckStatus() { $this->checkStatus(); @@ -80,6 +134,8 @@ class Heading extends Component 'environment_uuid' => $this->database->environment->uuid, 'database_uuid' => $this->database->uuid, ]; + + $this->checkDeployments(); } public function stop() @@ -102,6 +158,7 @@ class Heading extends Component $activity = RestartDatabase::run($this->database); $this->auditDatabaseAction('ui.database.restarted'); + $this->markDeploymentRunning($activity); $this->js("window.dispatchEvent(new CustomEvent('startdatabase'))"); $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } catch (\Throwable $e) { @@ -116,6 +173,7 @@ class Heading extends Component $activity = StartDatabase::run($this->database); $this->auditDatabaseAction('ui.database.started'); + $this->markDeploymentRunning($activity); $this->js("window.dispatchEvent(new CustomEvent('startdatabase'))"); $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } catch (\Throwable $e) { diff --git a/resources/views/livewire/project/database/heading.blade.php b/resources/views/livewire/project/database/heading.blade.php index 769e7ecdb2..92c33bfb8b 100644 --- a/resources/views/livewire/project/database/heading.blade.php +++ b/resources/views/livewire/project/database/heading.blade.php @@ -66,6 +66,9 @@
+ @if ($isDeploymentProgress) + + @endif
@@ -107,6 +110,9 @@
+ @if ($isDeploymentProgress) + + @endif @if ($database->destination->server->isFunctional()) @can('manage', $database) @@ -170,6 +176,12 @@ @script