refactor: improve data formatting and UI
- move date and duration functions to a shared function - remove duplicate code - redesigned the deployment executions tab - added start and end times for backups, scheduled tasks, deployments and docker cleanup executions - calculated the duration for backups, scheduled tasks, deployments and Docker cleanup executions - redesigned status badges with colors to make it easier to see your current status - removed dependency on dayjs - fixed calculation of execution time was sometimes incorrect
This commit is contained in:
@@ -117,29 +117,6 @@ class BackupExecutions extends Component
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getServerTimezone()
|
|
||||||
{
|
|
||||||
$server = $this->server();
|
|
||||||
if (! $server) {
|
|
||||||
return 'UTC';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $server->settings->server_timezone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function formatDateInServerTimezone($date)
|
|
||||||
{
|
|
||||||
$serverTimezone = $this->getServerTimezone();
|
|
||||||
$dateObj = new \DateTime($date);
|
|
||||||
try {
|
|
||||||
$dateObj->setTimezone(new \DateTimeZone($serverTimezone));
|
|
||||||
} catch (\Exception) {
|
|
||||||
$dateObj->setTimezone(new \DateTimeZone('UTC'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $dateObj->format('Y-m-d H:i:s T');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.project.database.backup-executions', [
|
return view('livewire.project.database.backup-executions', [
|
||||||
|
|||||||
@@ -141,17 +141,4 @@ class Executions extends Component
|
|||||||
|
|
||||||
return $lines->count() > ($this->currentPage * $this->logsPerPage);
|
return $lines->count() > ($this->currentPage * $this->logsPerPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function formatDateInServerTimezone($date)
|
|
||||||
{
|
|
||||||
$serverTimezone = $this->serverTimezone;
|
|
||||||
$dateObj = new \DateTime($date);
|
|
||||||
try {
|
|
||||||
$dateObj->setTimezone(new \DateTimeZone($serverTimezone));
|
|
||||||
} catch (\Exception) {
|
|
||||||
$dateObj->setTimezone(new \DateTimeZone('UTC'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $dateObj->format('Y-m-d H:i:s T');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
42
bootstrap/helpers/timezone.php
Normal file
42
bootstrap/helpers/timezone.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function getServerTimezone($server = null)
|
||||||
|
{
|
||||||
|
if (! $server) {
|
||||||
|
return 'UTC';
|
||||||
|
}
|
||||||
|
|
||||||
|
return data_get($server, 'settings.server_timezone', 'UTC');
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDateInServerTimezone($date, $server = null)
|
||||||
|
{
|
||||||
|
$serverTimezone = getServerTimezone($server);
|
||||||
|
$dateObj = new \DateTime($date);
|
||||||
|
try {
|
||||||
|
$dateObj->setTimezone(new \DateTimeZone($serverTimezone));
|
||||||
|
} catch (\Exception) {
|
||||||
|
$dateObj->setTimezone(new \DateTimeZone('UTC'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dateObj->format('Y-m-d H:i:s T');
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateDuration($startDate, $endDate = null)
|
||||||
|
{
|
||||||
|
if (! $endDate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$start = new \DateTime($startDate);
|
||||||
|
$end = new \DateTime($endDate);
|
||||||
|
$interval = $start->diff($end);
|
||||||
|
|
||||||
|
if ($interval->days > 0) {
|
||||||
|
return $interval->format('%dd %Hh %Im %Ss');
|
||||||
|
} elseif ($interval->h > 0) {
|
||||||
|
return $interval->format('%Hh %Im %Ss');
|
||||||
|
} else {
|
||||||
|
return $interval->format('%Im %Ss');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,135 +32,96 @@
|
|||||||
@forelse ($deployments as $deployment)
|
@forelse ($deployments as $deployment)
|
||||||
<div @class([
|
<div @class([
|
||||||
'dark:bg-coolgray-100 p-2 border-l-2 transition-colors hover:no-underline box-without-bg-without-border bg-white flex-col cursor-pointer dark:hover:text-neutral-400 dark:hover:bg-coolgray-200',
|
'dark:bg-coolgray-100 p-2 border-l-2 transition-colors hover:no-underline box-without-bg-without-border bg-white flex-col cursor-pointer dark:hover:text-neutral-400 dark:hover:bg-coolgray-200',
|
||||||
'border-white border-dashed ' =>
|
'border-blue-500/50 border-dashed' => data_get($deployment, 'status') === 'in_progress',
|
||||||
data_get($deployment, 'status') === 'in_progress' ||
|
'border-purple-500/50 border-dashed' => data_get($deployment, 'status') === 'queued',
|
||||||
data_get($deployment, 'status') === 'cancelled-by-user',
|
'border-white border-dashed' => data_get($deployment, 'status') === 'cancelled-by-user',
|
||||||
'border-error border-dashed ' =>
|
'border-error' => data_get($deployment, 'status') === 'failed',
|
||||||
data_get($deployment, 'status') === 'failed',
|
|
||||||
'border-success' => data_get($deployment, 'status') === 'finished',
|
'border-success' => data_get($deployment, 'status') === 'finished',
|
||||||
])
|
])
|
||||||
x-on:click.stop="goto('{{ $current_url . '/' . data_get($deployment, 'deployment_uuid') }}')">
|
x-on:click.stop="goto('{{ $current_url . '/' . data_get($deployment, 'deployment_uuid') }}')">
|
||||||
<div class="flex flex-col justify-start">
|
<div class="flex flex-col justify-start">
|
||||||
<div class="flex gap-1">
|
<div class="flex items-center gap-2 mb-2">
|
||||||
{{ $deployment->created_at }} UTC
|
<span @class([
|
||||||
<span class=" dark:text-warning">></span>
|
'px-3 py-1 rounded-md text-xs font-medium tracking-wide shadow-sm',
|
||||||
{{ $deployment->status }}
|
'bg-blue-100/80 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300 dark:shadow-blue-900/5' => data_get($deployment, 'status') === 'in_progress',
|
||||||
|
'bg-purple-100/80 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300 dark:shadow-purple-900/5' => data_get($deployment, 'status') === 'queued',
|
||||||
|
'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-200 dark:shadow-red-900/5' => data_get($deployment, 'status') === 'failed',
|
||||||
|
'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-200 dark:shadow-green-900/5' => data_get($deployment, 'status') === 'finished',
|
||||||
|
'bg-gray-100 text-gray-700 dark:bg-gray-600/30 dark:text-gray-300 dark:shadow-gray-900/5' => data_get($deployment, 'status') === 'cancelled-by-user',
|
||||||
|
])>
|
||||||
|
@php
|
||||||
|
$statusText = match(data_get($deployment, 'status')) {
|
||||||
|
'finished' => 'Success',
|
||||||
|
'in_progress' => 'In Progress',
|
||||||
|
'cancelled-by-user' => 'Cancelled',
|
||||||
|
'queued' => 'Queued',
|
||||||
|
default => ucfirst(data_get($deployment, 'status'))
|
||||||
|
};
|
||||||
|
@endphp
|
||||||
|
{{ $statusText }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@if (data_get($deployment, 'is_webhook') || data_get($deployment, 'pull_request_id'))
|
@if(data_get($deployment, 'status') !== 'queued')
|
||||||
<div class="flex items-center gap-1">
|
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||||
@if (data_get($deployment, 'is_webhook'))
|
Started: {{ formatDateInServerTimezone(data_get($deployment, 'created_at'), data_get($application, 'destination.server')) }}
|
||||||
Webhook
|
@if($deployment->status !== 'in_progress')
|
||||||
@endif
|
<br>Ended: {{ formatDateInServerTimezone(data_get($deployment, 'updated_at'), data_get($application, 'destination.server')) }}
|
||||||
@if (data_get($deployment, 'pull_request_id'))
|
<br>Duration: {{ calculateDuration(data_get($deployment, 'created_at'), data_get($deployment, 'updated_at')) }}
|
||||||
@if (data_get($deployment, 'is_webhook'))
|
@else
|
||||||
|
|
<br>Running for: {{ calculateDuration(data_get($deployment, 'created_at'), now()) }}
|
||||||
@endif
|
|
||||||
Pull Request #{{ data_get($deployment, 'pull_request_id') }}
|
|
||||||
@endif
|
@endif
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="text-gray-600 dark:text-gray-400 text-sm mt-2">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
@if (data_get($deployment, 'commit'))
|
@if (data_get($deployment, 'commit'))
|
||||||
<div class="dark:hover:text-white"
|
<span>
|
||||||
x-on:click.stop="goto('{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}')">
|
Commit: <span class="dark:hover:text-white cursor-pointer underline"
|
||||||
<div class="text-xs underline">
|
x-on:click.stop="goto('{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}')">
|
||||||
@if ($deployment->commitMessage())
|
@if ($deployment->commitMessage())
|
||||||
({{ data_get_str($deployment, 'commit')->limit(7) }} -
|
{{ data_get_str($deployment, 'commit')->limit(7) }} - {{ $deployment->commitMessage() }}
|
||||||
{{ $deployment->commitMessage() }})
|
|
||||||
@else
|
@else
|
||||||
{{ data_get_str($deployment, 'commit')->limit(7) }}
|
{{ data_get_str($deployment, 'commit')->limit(7) }}
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
<span class="bg-gray-200/70 dark:bg-gray-600/20 px-2 py-0.5 rounded-md text-xs text-gray-800 dark:text-gray-100 border border-gray-400/30 dark:border-gray-500/30 font-medium backdrop-blur-sm">
|
||||||
@else
|
@if (data_get($deployment, 'is_webhook'))
|
||||||
<div class="flex items-center gap-1">
|
Webhook
|
||||||
@if (data_get($deployment, 'rollback') === true)
|
@if (data_get($deployment, 'pull_request_id'))
|
||||||
Rollback
|
| Pull Request #{{ data_get($deployment, 'pull_request_id') }}
|
||||||
@else
|
@endif
|
||||||
@if (data_get($deployment, 'is_api'))
|
@elseif (data_get($deployment, 'pull_request_id'))
|
||||||
|
Pull Request #{{ data_get($deployment, 'pull_request_id') }}
|
||||||
|
@elseif (data_get($deployment, 'rollback') === true)
|
||||||
|
Rollback
|
||||||
|
@elseif (data_get($deployment, 'is_api'))
|
||||||
API
|
API
|
||||||
@else
|
@else
|
||||||
Manual
|
Manual
|
||||||
@endif
|
@endif
|
||||||
@endif
|
</span>
|
||||||
@if (data_get($deployment, 'commit'))
|
|
||||||
<div class="dark:hover:text-white"
|
|
||||||
x-on:click.stop="goto('{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}')">
|
|
||||||
<div class="text-xs underline">
|
|
||||||
@if ($deployment->commitMessage())
|
|
||||||
({{ data_get_str($deployment, 'commit')->limit(7) }} -
|
|
||||||
{{ $deployment->commitMessage() }})
|
|
||||||
@else
|
|
||||||
{{ data_get_str($deployment, 'commit')->limit(7) }}
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
</div>
|
||||||
|
|
||||||
@if (data_get($deployment, 'server_name') && $application->additional_servers->count() > 0)
|
@if (data_get($deployment, 'server_name') && $application->additional_servers->count() > 0)
|
||||||
<div class="flex gap-1">
|
<div class="text-gray-600 dark:text-gray-400 text-sm mt-2">
|
||||||
Server: {{ data_get($deployment, 'server_name') }}
|
Server: {{ data_get($deployment, 'server_name') }}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col" x-data="elapsedTime('{{ $deployment->deployment_uuid }}', '{{ $deployment->status }}', '{{ $deployment->created_at }}', '{{ $deployment->updated_at }}')">
|
|
||||||
<div>
|
|
||||||
@if ($deployment->status !== 'in_progress')
|
|
||||||
Finished <span x-text="measure_since_started()">0s</span> ago in
|
|
||||||
<span class="font-bold" x-text="measure_finished_time()">0s</span>
|
|
||||||
@else
|
|
||||||
Running for <span class="font-bold" x-text="measure_since_started()">0s</span>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@empty
|
@empty
|
||||||
<div class="">No deployments found</div>
|
<div class="">No deployments found</div>
|
||||||
@endforelse
|
@endforelse
|
||||||
|
|
||||||
@if ($deployments_count > 0)
|
@if ($deployments_count > 0)
|
||||||
<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>
|
<script>
|
||||||
function goto(url) {
|
function goto(url) {
|
||||||
window.location.href = url;
|
window.location.href = url;
|
||||||
};
|
};
|
||||||
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: 'calculating...',
|
|
||||||
started_time: 'calculating...',
|
|
||||||
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() {
|
|
||||||
if (this.finished_time > 2000) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return this.finished_time;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
measure_since_started() {
|
|
||||||
return dayjs.utc(created_at).fromNow(true); // "true" prevents the "ago" suffix
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
</script>
|
</script>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,22 +7,40 @@
|
|||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
@forelse($executions as $execution)
|
@forelse($executions as $execution)
|
||||||
<div wire:key="{{ data_get($execution, 'id') }}" @class([
|
<div wire:key="{{ data_get($execution, 'id') }}" @class([
|
||||||
'flex flex-col border-l-2 transition-colors p-4 ',
|
'flex flex-col border-l-2 transition-colors p-4 bg-white dark:bg-coolgray-100 text-black dark:text-white',
|
||||||
'bg-white dark:bg-coolgray-100 ',
|
'border-blue-500/50 border-dashed' => data_get($execution, 'status') === 'running',
|
||||||
'text-black dark:text-white',
|
'border-error' => data_get($execution, 'status') === 'failed',
|
||||||
'border-green-500' => data_get($execution, 'status') === 'success',
|
'border-success' => data_get($execution, 'status') === 'success',
|
||||||
'border-red-500' => data_get($execution, 'status') === 'failed',
|
|
||||||
'border-yellow-500' => data_get($execution, 'status') === 'running',
|
|
||||||
])>
|
])>
|
||||||
@if (data_get($execution, 'status') === 'running')
|
@if (data_get($execution, 'status') === 'running')
|
||||||
<div class="absolute top-2 right-2">
|
<div class="absolute top-2 right-2">
|
||||||
<x-loading />
|
<x-loading />
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
<div class="text-gray-700 dark:text-gray-300 font-semibold mb-1">Status:
|
<div class="flex items-center gap-2 mb-2">
|
||||||
{{ data_get($execution, 'status') }}</div>
|
<span @class([
|
||||||
|
'px-3 py-1 rounded-md text-xs font-medium tracking-wide shadow-sm',
|
||||||
|
'bg-blue-100/80 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300 dark:shadow-blue-900/5' => data_get($execution, 'status') === 'running',
|
||||||
|
'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-200 dark:shadow-red-900/5' => data_get($execution, 'status') === 'failed',
|
||||||
|
'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-200 dark:shadow-green-900/5' => data_get($execution, 'status') === 'success',
|
||||||
|
])>
|
||||||
|
@php
|
||||||
|
$statusText = match(data_get($execution, 'status')) {
|
||||||
|
'success' => 'Success',
|
||||||
|
'running' => 'In Progress',
|
||||||
|
'failed' => 'Failed',
|
||||||
|
default => ucfirst(data_get($execution, 'status'))
|
||||||
|
};
|
||||||
|
@endphp
|
||||||
|
{{ $statusText }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||||
Started At: {{ $this->formatDateInServerTimezone(data_get($execution, 'created_at')) }}
|
Started: {{ formatDateInServerTimezone(data_get($execution, 'created_at'), $this->server()) }}
|
||||||
|
@if(data_get($execution, 'status') !== 'running')
|
||||||
|
<br>Ended: {{ formatDateInServerTimezone(data_get($execution, 'updated_at'), $this->server()) }}
|
||||||
|
<br>Duration: {{ calculateDuration(data_get($execution, 'created_at'), data_get($execution, 'updated_at')) }}
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||||
Database: {{ data_get($execution, 'database_name', 'N/A') }}
|
Database: {{ data_get($execution, 'database_name', 'N/A') }}
|
||||||
|
|||||||
@@ -14,25 +14,41 @@
|
|||||||
}">
|
}">
|
||||||
@forelse($executions as $execution)
|
@forelse($executions as $execution)
|
||||||
<a wire:click="selectTask({{ data_get($execution, 'id') }})" @class([
|
<a wire:click="selectTask({{ data_get($execution, 'id') }})" @class([
|
||||||
'flex flex-col border-l-2 transition-colors p-4 cursor-pointer',
|
'flex flex-col border-l-2 transition-colors p-4 cursor-pointer bg-white hover:bg-gray-100 dark:bg-coolgray-100 dark:hover:bg-coolgray-200 text-black dark:text-white',
|
||||||
'bg-white hover:bg-gray-100 dark:bg-coolgray-100 dark:hover:bg-coolgray-200',
|
'bg-gray-200 dark:bg-coolgray-200' => data_get($execution, 'id') == $selectedKey,
|
||||||
'text-black dark:text-white',
|
'border-blue-500/50 border-dashed' => data_get($execution, 'status') === 'running',
|
||||||
'bg-gray-200 dark:bg-coolgray-200' =>
|
'border-error' => data_get($execution, 'status') === 'failed',
|
||||||
data_get($execution, 'id') == $selectedKey,
|
'border-success' => data_get($execution, 'status') === 'success',
|
||||||
'border-green-500' => data_get($execution, 'status') === 'success',
|
|
||||||
'border-red-500' => data_get($execution, 'status') === 'failed',
|
|
||||||
'border-yellow-500' => data_get($execution, 'status') === 'running',
|
|
||||||
])>
|
])>
|
||||||
|
|
||||||
@if (data_get($execution, 'status') === 'running')
|
@if (data_get($execution, 'status') === 'running')
|
||||||
<div class="absolute top-2 right-2">
|
<div class="absolute top-2 right-2">
|
||||||
<x-loading />
|
<x-loading />
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
<div class="text-gray-700 dark:text-gray-300 font-semibold mb-1">Status: {{ data_get($execution, 'status') }}
|
<div class="flex items-center gap-2 mb-2">
|
||||||
|
<span @class([
|
||||||
|
'px-3 py-1 rounded-md text-xs font-medium tracking-wide shadow-sm',
|
||||||
|
'bg-blue-100/80 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300 dark:shadow-blue-900/5' => data_get($execution, 'status') === 'running',
|
||||||
|
'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-200 dark:shadow-red-900/5' => data_get($execution, 'status') === 'failed',
|
||||||
|
'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-200 dark:shadow-green-900/5' => data_get($execution, 'status') === 'success',
|
||||||
|
])>
|
||||||
|
@php
|
||||||
|
$statusText = match(data_get($execution, 'status')) {
|
||||||
|
'success' => 'Success',
|
||||||
|
'running' => 'In Progress',
|
||||||
|
'failed' => 'Failed',
|
||||||
|
default => ucfirst(data_get($execution, 'status'))
|
||||||
|
};
|
||||||
|
@endphp
|
||||||
|
{{ $statusText }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||||
Started At: {{ $this->formatDateInServerTimezone(data_get($execution, 'created_at', now())) }}
|
Started: {{ formatDateInServerTimezone(data_get($execution, 'created_at', now()), data_get($task, 'application.destination.server') ?? data_get($task, 'service.destination.server')) }}
|
||||||
|
@if(data_get($execution, 'status') !== 'running')
|
||||||
|
<br>Ended: {{ formatDateInServerTimezone(data_get($execution, 'updated_at'), data_get($task, 'application.destination.server') ?? data_get($task, 'service.destination.server')) }}
|
||||||
|
<br>Duration: {{ calculateDuration(data_get($execution, 'created_at'), data_get($execution, 'updated_at')) }}
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
@if (strlen($execution->message) > 0)
|
@if (strlen($execution->message) > 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user