coolify/resources/views/livewire/project/database/scheduled-backups.blade.php

233 lines
15 KiB
PHP
Raw Permalink Normal View History

<div x-data="{
search: '',
backups: @js($database->scheduledBackups->map(fn ($backup) => [
'name' => strtolower($database->name),
'frequency' => strtolower($backup->frequency),
's3_storage' => strtolower($backup->s3?->name ?? ''),
])->values()),
hasMatches() {
const query = this.search.toLowerCase();
return this.backups.some((backup) => backup.name.includes(query) || backup.frequency.includes(query) || backup.s3_storage.includes(query));
},
}">
2024-06-05 09:44:10 +00:00
<div class="flex flex-col gap-2">
@if ($database->is_migrated && blank($database->custom_type))
<div>
<div>Select the type of
database to enable automated backups.</div>
<div class="pb-4"> If your database is not listed, automated backups are not supported.</div>
<form wire:submit="setCustomType" class="flex gap-2 items-end">
<div class="w-96">
<x-forms.select label="Type" id="custom_type">
<option selected value="mysql">MySQL</option>
<option value="mariadb">MariaDB</option>
<option value="postgresql">PostgreSQL</option>
<option value="mongodb">MongoDB</option>
</x-forms.select>
</div>
<x-forms.button type="submit">Set</x-forms.button>
</form>
</div>
@else
<div class="max-w-md pb-4">
<x-forms.input id="null" type="search" x-model="search"
placeholder="Search by database name, frequency, or S3 storage..." />
</div>
<div x-cloak x-show="search !== '' && backups.length > 0 && !hasMatches()">
No scheduled backups match your search.
</div>
@forelse($database->scheduledBackups as $backup)
@if ($type == 'database')
<a x-show="search === '' || @js(strtolower($database->name)).includes(search.toLowerCase()) || @js(strtolower($backup->frequency)).includes(search.toLowerCase()) || @js(strtolower($backup->s3?->name ?? '')).includes(search.toLowerCase())" @class([
'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',
'border-blue-500/50 border-dashed' =>
$backup->latest_log &&
data_get($backup->latest_log, 'status') === 'running',
'border-error' =>
$backup->latest_log &&
data_get($backup->latest_log, 'status') === 'failed',
'border-success' =>
$backup->latest_log &&
data_get($backup->latest_log, 'status') === 'success',
'border-gray-200 dark:border-coolgray-300' => !$backup->latest_log,
]) {{ wireNavigate() }}
href="{{ route('project.database.backup.execution', [...$parameters, 'backup_uuid' => $backup->uuid]) }}">
@if ($backup->latest_log && data_get($backup->latest_log, 'status') === 'running')
<div class="absolute top-2 right-2">
<x-loading />
</div>
@endif
<div class="flex items-center gap-2 mb-2">
@if ($backup->latest_log)
<span @class([
'px-3 py-1 rounded-md text-xs font-medium tracking-wide shadow-xs',
'bg-blue-100/80 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300 dark:shadow-blue-900/5' =>
data_get($backup->latest_log, 'status') === 'running',
'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-200 dark:shadow-red-900/5' =>
data_get($backup->latest_log, 'status') === 'failed',
'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-200 dark:shadow-green-900/5' =>
data_get($backup->latest_log, 'status') === 'success',
])>
@php
$statusText = match (data_get($backup->latest_log, 'status')) {
'success' => 'Success',
'running' => 'In Progress',
'failed' => 'Failed',
default => ucfirst(data_get($backup->latest_log, 'status')),
};
@endphp
{{ $statusText }}
</span>
@else
<span
class="px-3 py-1 rounded-md text-xs font-medium tracking-wide shadow-xs bg-gray-100 text-gray-800 dark:bg-neutral-800 dark:text-gray-200">
No executions yet
</span>
@endif
<h3 class="font-semibold">{{ $backup->frequency }}</h3>
</div>
<div class="text-gray-600 dark:text-gray-400 text-sm">
@if ($backup->latest_log)
@if (data_get($backup->latest_log, 'status') === 'running')
<span
title="Started: {{ formatDateInServerTimezone(data_get($backup->latest_log, 'created_at'), $backup->server()) }}">
Running for
{{ calculateDuration(data_get($backup->latest_log, 'created_at'), now()) }}
</span>
@else
<span
title="Started: {{ formatDateInServerTimezone(data_get($backup->latest_log, 'created_at'), $backup->server()) }}&#10;Ended: {{ formatDateInServerTimezone(data_get($backup->latest_log, 'finished_at'), $backup->server()) }}">
{{ \Carbon\Carbon::parse(data_get($backup->latest_log, 'finished_at'))->diffForHumans() }}
({{ calculateDuration(data_get($backup->latest_log, 'created_at'), data_get($backup->latest_log, 'finished_at')) }})
{{ \Carbon\Carbon::parse(data_get($backup->latest_log, 'finished_at'))->format('M j, H:i') }}
</span>
@endif
@if (data_get($backup->latest_log, 'status') === 'success')
@php
$size = data_get($backup->latest_log, 'size', 0);
@endphp
@if ($size > 0)
Size: {{ formatBytes($size) }}
@endif
@endif
@if ($backup->save_s3)
S3: {{ $backup->s3?->name ?? 'Storage unavailable' }}
@endif
@else
Last Run: Never Total Executions: 0
@if ($backup->save_s3)
S3: {{ $backup->s3?->name ?? 'Storage unavailable' }}
@endif
@endif
</div>
</a>
@else
<a x-show="search === '' || @js(strtolower($database->name)).includes(search.toLowerCase()) || @js(strtolower($backup->frequency)).includes(search.toLowerCase()) || @js(strtolower($backup->s3?->name ?? '')).includes(search.toLowerCase())" @class([
'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',
'border-blue-500/50 border-dashed' =>
$backup->latest_log &&
data_get($backup->latest_log, 'status') === 'running',
'border-error' =>
$backup->latest_log &&
data_get($backup->latest_log, 'status') === 'failed',
'border-success' =>
$backup->latest_log &&
data_get($backup->latest_log, 'status') === 'success',
'border-gray-200 dark:border-coolgray-300' => !$backup->latest_log,
]) {{ wireNavigate() }}
href="{{ route('project.service.database.backup.show', [...$parameters, 'backup_uuid' => $backup->uuid]) }}">
@if ($backup->latest_log && data_get($backup->latest_log, 'status') === 'running')
<div class="absolute top-2 right-2">
<x-loading />
</div>
@endif
<div class="flex items-center gap-2 mb-2">
@if ($backup->latest_log)
<span @class([
'px-3 py-1 rounded-md text-xs font-medium tracking-wide shadow-xs',
'bg-blue-100/80 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300 dark:shadow-blue-900/5' =>
data_get($backup->latest_log, 'status') === 'running',
'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-200 dark:shadow-red-900/5' =>
data_get($backup->latest_log, 'status') === 'failed',
'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-200 dark:shadow-green-900/5' =>
data_get($backup->latest_log, 'status') === 'success',
])>
@php
$statusText = match (data_get($backup->latest_log, 'status')) {
'success' => 'Success',
'running' => 'In Progress',
'failed' => 'Failed',
default => ucfirst(data_get($backup->latest_log, 'status')),
};
@endphp
{{ $statusText }}
</span>
@else
<span
class="px-3 py-1 rounded-md text-xs font-medium tracking-wide shadow-xs bg-gray-100 text-gray-800 dark:bg-neutral-800 dark:text-gray-200">
No executions yet
</span>
@endif
<h3 class="font-semibold">{{ $backup->frequency }} Backup</h3>
</div>
<div class="text-gray-600 dark:text-gray-400 text-sm">
@if ($backup->latest_log)
@if (data_get($backup->latest_log, 'status') === 'running')
<span
title="Started: {{ formatDateInServerTimezone(data_get($backup->latest_log, 'created_at'), $backup->server()) }}">
Running for
{{ calculateDuration(data_get($backup->latest_log, 'created_at'), now()) }}
</span>
@else
<span
title="Started: {{ formatDateInServerTimezone(data_get($backup->latest_log, 'created_at'), $backup->server()) }}&#10;Ended: {{ formatDateInServerTimezone(data_get($backup->latest_log, 'finished_at'), $backup->server()) }}">
{{ \Carbon\Carbon::parse(data_get($backup->latest_log, 'finished_at'))->diffForHumans() }}
({{ calculateDuration(data_get($backup->latest_log, 'created_at'), data_get($backup->latest_log, 'finished_at')) }})
{{ \Carbon\Carbon::parse(data_get($backup->latest_log, 'finished_at'))->format('M j, H:i') }}
</span>
@endif
@if (data_get($backup->latest_log, 'status') === 'success')
@php
$size = data_get($backup->latest_log, 'size', 0);
@endphp
@if ($size > 0)
Size: {{ formatBytes($size) }}
@endif
@endif
@if ($backup->save_s3)
S3: {{ $backup->s3?->name ?? 'Storage unavailable' }}
@endif
<br>Total Executions: {{ $backup->executions()->count() }}
@php
$successCount = $backup->executions()->where('status', 'success')->count();
$totalCount = $backup->executions()->count();
$successRate = $totalCount > 0 ? round(($successCount / $totalCount) * 100) : 0;
@endphp
@if ($totalCount > 0)
Success Rate: <span @class([
'font-medium',
'text-green-600' => $successRate >= 80,
'text-warning-600' => $successRate >= 50 && $successRate < 80,
'text-red-600' => $successRate < 50,
])>{{ $successRate }}%</span>
({{ $successCount }}/{{ $totalCount }})
@endif
@else
Last Run: Never Total Executions: 0
@if ($backup->save_s3)
S3: {{ $backup->s3?->name ?? 'Storage unavailable' }}
@endif
@endif
2025-01-03 19:39:27 +00:00
</div>
</a>
@endif
@empty
<div>No scheduled backups configured.</div>
@endforelse
@endif
2023-11-07 11:11:47 +00:00
</div>
</div>