From 327b7769f3bdd9bacd54dfba745509be925881e1 Mon Sep 17 00:00:00 2001
From: Andras Bacsai <andras.bacsai@gmail.com>
Date: Wed, 31 May 2023 14:24:20 +0200
Subject: [PATCH] deployments

---
 .../Project/Application/Deployments.php       | 24 +++++-
 app/Models/Application.php                    |  5 +-
 .../project/application/deployments.blade.php | 74 ++++++++++++++-----
 3 files changed, 80 insertions(+), 23 deletions(-)

diff --git a/app/Http/Livewire/Project/Application/Deployments.php b/app/Http/Livewire/Project/Application/Deployments.php
index 1c16d82c5..3ab123635 100644
--- a/app/Http/Livewire/Project/Application/Deployments.php
+++ b/app/Http/Livewire/Project/Application/Deployments.php
@@ -10,16 +10,32 @@ class Deployments extends Component
     public int $application_id;
     public $deployments = [];
     public string $current_url;
+    public int $skip = 0;
+    public int $default_take = 8;
+    public bool $show_next = true;
+
     public function mount()
     {
         $this->current_url = url()->current();
     }
-    public function reloadDeployments()
+    public function reload_deployments()
     {
-        $this->loadDeployments();
+        $this->load_deployments();
     }
-    public function loadDeployments()
+    public function load_deployments(int|null $take = null)
     {
-        $this->deployments = Application::find($this->application_id)->deployments();
+        ray('Take' . $take);
+        if ($take) {
+            ray('Take is not null');
+            $this->skip = $this->skip + $take;
+        }
+
+        $take = $this->default_take;
+        $this->deployments = Application::find($this->application_id)->deployments($this->skip, $take);
+
+        if (count($this->deployments) !== 0 && count($this->deployments) < $take) {
+            $this->show_next = false;
+            return;
+        }
     }
 }
diff --git a/app/Models/Application.php b/app/Models/Application.php
index e3dbe0706..46f7956a1 100644
--- a/app/Models/Application.php
+++ b/app/Models/Application.php
@@ -144,9 +144,10 @@ class Application extends BaseModel
         return $this->morphMany(LocalPersistentVolume::class, 'resource');
     }
 
-    public function deployments()
+    public function deployments(int $skip = 0, int $take = 10)
     {
-        return ApplicationDeploymentQueue::where('application_id', $this->id)->orderBy('created_at', 'desc')->get();
+        ray('Skip ' . $skip . ' Take ' . $take);
+        return ApplicationDeploymentQueue::where('application_id', $this->id)->orderBy('created_at', 'desc')->skip($skip)->take($take)->get();
     }
     public function get_deployment(string $deployment_uuid)
     {
diff --git a/resources/views/livewire/project/application/deployments.blade.php b/resources/views/livewire/project/application/deployments.blade.php
index bcb74b296..d8f7ae2c8 100644
--- a/resources/views/livewire/project/application/deployments.blade.php
+++ b/resources/views/livewire/project/application/deployments.blade.php
@@ -1,7 +1,15 @@
- <div class="flex flex-col gap-2 pt-2" wire:init='loadDeployments' wire:poll.5000ms='reloadDeployments'>
-     <div wire:loading wire:target='loadDeployments'>
-         <x-loading />
+ <div class="flex flex-col gap-2 pt-2 " wire:init='load_deployments'
+     @if ($skip == 0) wire:poll.5000ms='reload_deployments' @endif>
+     <div>
+         <h3>Actions</h3>
+         @if ($show_next)
+             <x-forms.button isHighlighted wire:click="load_deployments({{ $default_take }})">Load More
+                 Deployments</x-forms.button>
+         @else
+             <x-forms.button disabled>No More Deployments</x-forms.button>
+         @endif
      </div>
+     <h3>Deployments</h3>
      @foreach ($deployments as $deployment)
          <a @class([
              'bg-coolgray-200 p-2 border-l border-dashed transition-colors hover:no-underline',
@@ -19,6 +27,10 @@
      @endif
      class="hover:no-underline">
      <div class="flex flex-col justify-start">
+         <div>
+             {{ $deployment->deployment_uuid }} <span class="text-sm text-warning">></span>
+             {{ $deployment->status }}
+         </div>
          @if (data_get($deployment, 'pull_request_id'))
              <div>
                  Pull Request #{{ data_get($deployment, 'pull_request_id') }}
@@ -27,29 +39,57 @@
                  @endif
              </div>
          @elseif (data_get($deployment, 'is_webhook'))
-             <div>Webhook (commit
+             <div>Webhook (sha
                  @if (data_get($deployment, 'commit'))
                      {{ data_get($deployment, 'commit') }})
                  @else
                      HEAD)
                  @endif
              </div>
-         @else
-             <div>Commit:
-                 @if (data_get($deployment, 'commit'))
-                     {{ data_get($deployment, 'commit') }}
-                 @else
-                     HEAD
-                 @endif
-             </div>
          @endif
-         <div>
-             {{ $deployment->status }}
-         </div>
-         <div>
-             {{ $deployment->created_at }}
+
+         <div class="flex flex-col" x-data="elapsedTime('{{ $deployment->deployment_uuid }}', '{{ $deployment->status }}', '{{ $deployment->created_at }}', '{{ $deployment->updated_at }}')">
+             <div>Finished <span x-text="measure_since_started()">0s</span> in <span class="font-bold text-white"
+                     x-text="measure_finished_time()">0s</span></div>
          </div>
      </div>
      </a>
      @endforeach
+
+     <script src="https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js"></script>
+     <script src="https://cdn.jsdelivr.net/npm/dayjs@1/plugin/utc.js"></script>
+     <script src="https://cdn.jsdelivr.net/npm/dayjs@1/plugin/relativeTime.js"></script>
+     <script>
+         document.addEventListener('alpine:init', () => {
+             let timers = {};
+
+             dayjs.extend(window.dayjs_plugin_utc);
+             dayjs.extend(window.dayjs_plugin_relativeTime);
+
+             Alpine.data('elapsedTime', (uuid, status, created_at, updated_at) => ({
+                 finished_time: '0s',
+                 started_time: '0s',
+                 init() {
+                     if (timers[uuid]) {
+                         clearInterval(timers[uuid]);
+                     }
+                     if (status === 'in_progress') {
+                         timers[uuid] = setInterval(() => {
+                             this.finished_time = dayjs().diff(dayjs.utc(created_at),
+                                 'second') + 's'
+                         }, 1000);
+                     } else {
+                         let seconds = dayjs.utc(updated_at).diff(dayjs.utc(created_at), 'second')
+                         this.finished_time = seconds + 's';
+                     }
+                 },
+                 measure_finished_time() {
+                     return this.finished_time;
+                 },
+                 measure_since_started() {
+                     return dayjs.utc(created_at).fromNow();
+                 }
+             }))
+         })
+     </script>
  </div>