mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-03 15:02:34 +00:00
Migrate to HTMX (#114)
Dropped Livewire Added HTMX Added Blade code lint Drop Mysql and Redis Migrate to SQLite
This commit is contained in:
@ -0,0 +1,27 @@
|
||||
@if ($status == \App\Enums\BackupFileStatus::CREATED)
|
||||
<x-status status="success">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\BackupFileStatus::CREATING)
|
||||
<x-status status="warning">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\BackupFileStatus::FAILED)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\BackupFileStatus::DELETING)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\BackupFileStatus::RESTORING)
|
||||
<x-status status="warning">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\BackupFileStatus::RESTORED)
|
||||
<x-status status="success">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\BackupFileStatus::RESTORE_FAILED)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
11
resources/views/databases/partials/backup-status.blade.php
Normal file
11
resources/views/databases/partials/backup-status.blade.php
Normal file
@ -0,0 +1,11 @@
|
||||
@if ($status == \App\Enums\BackupStatus::RUNNING)
|
||||
<x-status status="success">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\BackupStatus::DELETING)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\BackupStatus::FAILED)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
105
resources/views/databases/partials/create-backup-modal.blade.php
Normal file
105
resources/views/databases/partials/create-backup-modal.blade.php
Normal file
@ -0,0 +1,105 @@
|
||||
<x-primary-button x-on:click="$dispatch('open-modal', 'create-backup')">
|
||||
{{ __("Create Backup") }}
|
||||
</x-primary-button>
|
||||
<x-modal name="create-backup">
|
||||
<form
|
||||
id="create-backup-form"
|
||||
hx-post="{{ route("servers.databases.backups.store", ["server" => $server]) }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#create-backup-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-create-backup"
|
||||
class="p-6"
|
||||
>
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Create Backup") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="backup_database" :value="__('Database')" />
|
||||
<x-select-input id="backup_database" name="backup_database" class="mt-1 w-full">
|
||||
<option value="" selected disabled>{{ __("Select") }}</option>
|
||||
@foreach ($databases as $db)
|
||||
<option value="{{ $db->id }}" @if($db->id == old('backup_database')) selected @endif>
|
||||
{{ $db->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</x-select-input>
|
||||
@error("backup_database")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="backup_storage" :value="__('Storage')" />
|
||||
<x-select-input id="backup_storage" name="backup_storage" class="mt-1 w-full">
|
||||
<option value="" selected disabled>{{ __("Select") }}</option>
|
||||
@foreach (auth()->user()->storageProviders as $st)
|
||||
<option value="{{ $st->id }}" @if(old('backup_storage') == $st->id) selected @endif>
|
||||
{{ $st->profile }} - {{ $st->provider }}
|
||||
</option>
|
||||
@endforeach
|
||||
</x-select-input>
|
||||
@error("backup_storage")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="backup_interval" :value="__('Interval')" />
|
||||
<x-select-input id="backup_interval" name="backup_interval" class="mt-1 w-full">
|
||||
<option value="" selected disabled>{{ __("Select") }}</option>
|
||||
<option value="0 * * * *" @if(old('backup_interval') === '0 * * * *') selected @endif>
|
||||
{{ __("Hourly") }}
|
||||
</option>
|
||||
<option value="0 0 * * *" @if(old('backup_interval') === '0 0 * * *') selected @endif>
|
||||
{{ __("Daily") }}
|
||||
</option>
|
||||
<option value="0 0 * * 0" @if(old('backup_interval') === '0 0 * * 0') selected @endif>
|
||||
{{ __("Weekly") }}
|
||||
</option>
|
||||
<option value="0 0 1 * *" @if(old('backup_interval') === '0 0 1 * *') selected @endif>
|
||||
{{ __("Monthly") }}
|
||||
</option>
|
||||
<option value="custom">{{ __("Custom") }}</option>
|
||||
</x-select-input>
|
||||
@error("backup_interval")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
@if (old("backup_interval") === "custom")
|
||||
<div class="mt-6">
|
||||
<x-input-label for="backup_custom" :value="__('Custom interval (Cron)')" />
|
||||
<x-text-input
|
||||
id="backup_custom"
|
||||
name="backup_custom"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
placeholder="* * * * *"
|
||||
/>
|
||||
@error("backup_custom")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="backup_keep" :value="__('Backups to Keep')" />
|
||||
<x-text-input id="backup_keep" name="backup_keep" type="text" class="mt-1 w-full" />
|
||||
@error("backup_keep")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-create-backup" class="ml-3">
|
||||
{{ __("Create") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
@ -0,0 +1,109 @@
|
||||
<x-modal name="create-database">
|
||||
<form
|
||||
id="create-database-form"
|
||||
hx-post="{{ route("servers.databases.store", $server) }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#create-database-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-create-database"
|
||||
class="p-6"
|
||||
x-data="{ user: @js((bool) old("user", false)), remote: @js((bool) old("remote", false)) }"
|
||||
>
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Create Database") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="name" :value="__('Name')" />
|
||||
<x-text-input value="{{ old('name') }}" id="name" name="name" type="text" class="mt-1 w-full" />
|
||||
@error("name")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<label for="user" class="inline-flex items-center">
|
||||
<input
|
||||
id="user"
|
||||
name="user"
|
||||
type="checkbox"
|
||||
x-model="user"
|
||||
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800"
|
||||
/>
|
||||
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
{{ __("Create a user for this database") }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div x-show="user">
|
||||
<div class="mt-6">
|
||||
<x-input-label for="db-username" :value="__('Username')" />
|
||||
<x-text-input
|
||||
value="{{ old('username') }}"
|
||||
id="db-username"
|
||||
name="username"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("username")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="db-password" :value="__('Password')" />
|
||||
<x-text-input
|
||||
value="{{ old('password') }}"
|
||||
id="db-password"
|
||||
name="password"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("password")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<label for="db-remote" class="inline-flex items-center">
|
||||
<input
|
||||
id="db-remote"
|
||||
type="checkbox"
|
||||
x-model="remote"
|
||||
name="remote"
|
||||
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800"
|
||||
/>
|
||||
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
{{ __("Enable remote access") }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div x-show="remote">
|
||||
<div class="mt-6">
|
||||
<x-input-label for="db-host" :value="__('Host')" />
|
||||
<x-text-input value="{{ old('host') }}" id="db-host" name="host" type="text" class="mt-1 w-full" />
|
||||
<x-input-label
|
||||
for="db-host"
|
||||
:value="__('You might also need to open the database port in Firewall')"
|
||||
class="mt-1"
|
||||
/>
|
||||
@error("host")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-create-database" class="ml-3">
|
||||
{{ __("Create") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
@ -0,0 +1,84 @@
|
||||
<x-modal name="create-database-user">
|
||||
<form
|
||||
id="create-database-user-form"
|
||||
hx-post="{{ route("servers.databases.users.store", $server) }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#create-database-user-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-database-user-database"
|
||||
class="p-6"
|
||||
x-data="{ remote: @js((bool) old("remote", false)) }"
|
||||
>
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Create Database User") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="user-username" :value="__('Username')" />
|
||||
<x-text-input
|
||||
value="{{ old('username') }}"
|
||||
id="user-username"
|
||||
name="username"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("username")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="user-password" :value="__('Password')" />
|
||||
<x-text-input
|
||||
value="{{ old('password') }}"
|
||||
id="user-password"
|
||||
name="password"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("password")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<label for="user-remote" class="inline-flex items-center">
|
||||
<input
|
||||
id="user-remote"
|
||||
type="checkbox"
|
||||
x-model="remote"
|
||||
name="remote"
|
||||
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800"
|
||||
/>
|
||||
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
{{ __("Enable remote access") }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div x-show="remote">
|
||||
<div class="mt-6">
|
||||
<x-input-label for="user-host" :value="__('Host')" />
|
||||
<x-text-input value="{{ old('host') }}" id="user-host" name="host" type="text" class="mt-1 w-full" />
|
||||
<x-input-label
|
||||
for="user-host"
|
||||
:value="__('You might also need to open the database port in Firewall')"
|
||||
class="mt-1"
|
||||
/>
|
||||
@error("host")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-database-user-database" class="ml-3">
|
||||
{{ __("Create") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
@ -0,0 +1,94 @@
|
||||
<div x-data="{ restoreAction: '', deleteAction: '' }">
|
||||
<x-card-header>
|
||||
<x-slot name="title">{{ __("Backup Files") }}</x-slot>
|
||||
<x-slot name="description">
|
||||
{{ __("Here you can see your backup files") }}
|
||||
</x-slot>
|
||||
<x-slot name="aside">
|
||||
<div>
|
||||
<x-secondary-button :href="route('servers.databases', ['server' => $server])">
|
||||
{{ __("Back to Databases") }}
|
||||
</x-secondary-button>
|
||||
<x-primary-button
|
||||
class="ml-1"
|
||||
:href="route('servers.databases.backups.run', ['server' => $server, 'backup' => $backup])"
|
||||
>
|
||||
{{ __("Backup Now") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<x-live id="live-backup-files">
|
||||
@if (count($files) > 0)
|
||||
<x-table class="mt-5">
|
||||
<tr>
|
||||
<x-th>{{ __("Name") }}</x-th>
|
||||
<x-th>{{ __("Created") }}</x-th>
|
||||
{{-- <x-th>{{ __("Size") }}</x-th> --}}
|
||||
<x-th>{{ __("Status") }}</x-th>
|
||||
<x-th>{{ __("Restored") }}</x-th>
|
||||
<x-th>{{ __("Restored To") }}</x-th>
|
||||
<x-th></x-th>
|
||||
</tr>
|
||||
@foreach ($files as $file)
|
||||
<tr>
|
||||
<x-td>{{ $file->name }}</x-td>
|
||||
<x-td>
|
||||
<x-datetime :value="$file->created_at" />
|
||||
</x-td>
|
||||
{{-- <x-td>{{ $file->size }}</x-td> --}}
|
||||
<x-td>
|
||||
<div class="inline-flex">
|
||||
@include("databases.partials.backup-file-status", ["status" => $file->status])
|
||||
</div>
|
||||
</x-td>
|
||||
<x-td>
|
||||
@if ($file->restored_at)
|
||||
<x-datetime :value="$file->restored_at" />
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</x-td>
|
||||
<x-td>
|
||||
@if ($file->restored_to)
|
||||
{{ $file->restored_to }}
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</x-td>
|
||||
<x-td class="flex w-full justify-end">
|
||||
@if (in_array($file->status, [\App\Enums\BackupFileStatus::CREATED, \App\Enums\BackupFileStatus::RESTORED, \App\Enums\BackupFileStatus::RESTORE_FAILED]))
|
||||
<x-icon-button
|
||||
x-on:click="restoreAction = '{{ route('servers.databases.backups.files.restore', ['server' => $server, 'backup' => $backup, 'backupFile' => $file]) }}'; $dispatch('open-modal', 'restore-backup')"
|
||||
>
|
||||
<x-heroicon-o-arrow-path class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
@endif
|
||||
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('servers.databases.backups.files.destroy', ['server' => $server, 'backup' => $backup, 'backupFile' => $file]) }}'; $dispatch('open-modal', 'delete-backup-file')"
|
||||
>
|
||||
<x-heroicon-o-trash class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</x-td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</x-table>
|
||||
<div class="mt-5">
|
||||
{{ $files->withQueryString()->links() }}
|
||||
</div>
|
||||
@else
|
||||
<x-simple-card class="text-center">
|
||||
{{ __("You don't have any backups yet") }}
|
||||
</x-simple-card>
|
||||
@endif
|
||||
</x-live>
|
||||
@include("databases.partials.restore-backup-modal", ["databases" => $server->databases])
|
||||
<x-confirmation-modal
|
||||
name="delete-backup-file"
|
||||
:title="__('Confirm')"
|
||||
:description="__('Are you sure that you want to delete this file?')"
|
||||
method="delete"
|
||||
x-bind:action="deleteAction"
|
||||
/>
|
||||
</div>
|
@ -0,0 +1,61 @@
|
||||
<div x-data="{ deleteAction: '' }">
|
||||
<x-card-header>
|
||||
<x-slot name="title">{{ __("Backups") }}</x-slot>
|
||||
<x-slot name="description">
|
||||
{{ __("You can backup your databases into external storages") }}
|
||||
</x-slot>
|
||||
<x-slot name="aside">
|
||||
<div>
|
||||
@include("databases.partials.create-backup-modal")
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<x-live id="live-backups">
|
||||
@if (count($backups) > 0)
|
||||
<x-table>
|
||||
<tr>
|
||||
<x-th>{{ __("Database") }}</x-th>
|
||||
<x-th>{{ __("Created") }}</x-th>
|
||||
<x-th>{{ __("Status") }}</x-th>
|
||||
<x-th></x-th>
|
||||
</tr>
|
||||
@foreach ($backups as $backup)
|
||||
<tr>
|
||||
<x-td>{{ $backup->database->name }}</x-td>
|
||||
<x-td>
|
||||
<x-datetime :value="$backup->created_at" />
|
||||
</x-td>
|
||||
<x-td>
|
||||
<div class="inline-flex">
|
||||
@include("databases.partials.backup-status", ["status" => $backup->status])
|
||||
</div>
|
||||
</x-td>
|
||||
<x-td class="flex w-full justify-end">
|
||||
<x-icon-button
|
||||
:href="route('servers.databases.backups', ['server' => $server, 'backup' => $backup])"
|
||||
>
|
||||
<x-heroicon-o-circle-stack class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('servers.databases.backups.destroy', ['server' => $server, 'backup' => $backup]) }}'; $dispatch('open-modal', 'delete-backup')"
|
||||
>
|
||||
<x-heroicon-o-trash class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</x-td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</x-table>
|
||||
@else
|
||||
<x-simple-card class="text-center">
|
||||
{{ __("You don't have any backups yet") }}
|
||||
</x-simple-card>
|
||||
@endif
|
||||
</x-live>
|
||||
<x-confirmation-modal
|
||||
name="delete-backup"
|
||||
title="Confirm"
|
||||
description="Are you sure that you want to delete this backup?"
|
||||
method="delete"
|
||||
x-bind:action="deleteAction"
|
||||
/>
|
||||
</div>
|
59
resources/views/databases/partials/database-list.blade.php
Normal file
59
resources/views/databases/partials/database-list.blade.php
Normal file
@ -0,0 +1,59 @@
|
||||
<div x-data="{ deleteAction: '' }">
|
||||
<x-card-header>
|
||||
<x-slot name="title">{{ __("Databases") }}</x-slot>
|
||||
<x-slot name="description">
|
||||
{{ __("You can see and manage your databases here") }}
|
||||
</x-slot>
|
||||
<x-slot name="aside">
|
||||
<div>
|
||||
<x-primary-button x-data="" x-on:click.prevent="$dispatch('open-modal', 'create-database')">
|
||||
{{ __("Create Database") }}
|
||||
</x-primary-button>
|
||||
@include("databases.partials.create-database-modal")
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<x-live id="live-databases">
|
||||
@if (count($databases) > 0)
|
||||
<x-table>
|
||||
<tr>
|
||||
<x-th>{{ __("Name") }}</x-th>
|
||||
<x-th>{{ __("Created") }}</x-th>
|
||||
<x-th>{{ __("Status") }}</x-th>
|
||||
<x-th></x-th>
|
||||
</tr>
|
||||
@foreach ($databases as $database)
|
||||
<tr>
|
||||
<x-td>{{ $database->name }}</x-td>
|
||||
<x-td>
|
||||
<x-datetime :value="$database->created_at" />
|
||||
</x-td>
|
||||
<x-td>
|
||||
<div class="inline-flex">
|
||||
@include("databases.partials.database-status", ["status" => $database->status])
|
||||
</div>
|
||||
</x-td>
|
||||
<x-td class="flex w-full justify-end">
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('servers.databases.destroy', ['server' => $server, 'database' => $database]) }}'; $dispatch('open-modal', 'delete-database')"
|
||||
>
|
||||
<x-heroicon-o-trash class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</x-td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</x-table>
|
||||
@else
|
||||
<x-simple-card class="text-center">
|
||||
{{ __("You don't have any databases yet") }}
|
||||
</x-simple-card>
|
||||
@endif
|
||||
</x-live>
|
||||
<x-confirmation-modal
|
||||
name="delete-database"
|
||||
title="Confirm"
|
||||
description="Are you sure that you want to delete this database?"
|
||||
method="delete"
|
||||
x-bind:action="deleteAction"
|
||||
/>
|
||||
</div>
|
15
resources/views/databases/partials/database-status.blade.php
Normal file
15
resources/views/databases/partials/database-status.blade.php
Normal file
@ -0,0 +1,15 @@
|
||||
@if ($status == \App\Enums\DatabaseStatus::READY)
|
||||
<x-status status="success">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\DatabaseStatus::CREATING)
|
||||
<x-status status="warning">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\DatabaseStatus::DELETING)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\DatabaseStatus::FAILED)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
@ -0,0 +1,84 @@
|
||||
<div x-data="{
|
||||
deleteAction: '',
|
||||
linkAction: '',
|
||||
linkedDatabases: [],
|
||||
}">
|
||||
<x-card-header>
|
||||
<x-slot name="title">{{ __("Database Users") }}</x-slot>
|
||||
<x-slot name="description">
|
||||
{{ __("You can see and manage your database users here") }}
|
||||
</x-slot>
|
||||
<x-slot name="aside">
|
||||
<div>
|
||||
<x-primary-button x-data="" x-on:click.prevent="$dispatch('open-modal', 'create-database-user')">
|
||||
{{ __("Create Database User") }}
|
||||
</x-primary-button>
|
||||
@include("databases.partials.create-database-user-modal")
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<x-live id="live-database-users">
|
||||
@if (count($databaseUsers) > 0)
|
||||
<x-table>
|
||||
<tr>
|
||||
<x-th>{{ __("Username") }}</x-th>
|
||||
<x-th>{{ __("Created") }}</x-th>
|
||||
<x-th class="flex items-center">
|
||||
<x-heroicon-o-link class="mr-1 h-5 w-5" />
|
||||
{{ __("Linked Databases") }}
|
||||
</x-th>
|
||||
<x-th>{{ __("Status") }}</x-th>
|
||||
<x-th></x-th>
|
||||
</tr>
|
||||
@foreach ($databaseUsers as $databaseUser)
|
||||
<tr>
|
||||
<x-td>{{ $databaseUser->username }}</x-td>
|
||||
<x-td>
|
||||
<x-datetime :value="$databaseUser->created_at" />
|
||||
</x-td>
|
||||
<x-td>[{{ $databaseUser->databases ? implode(", ", $databaseUser->databases) : "-" }}]</x-td>
|
||||
<x-td>
|
||||
<div class="inline-flex">
|
||||
@include("databases.partials.database-user-status", ["status" => $databaseUser->status])
|
||||
</div>
|
||||
</x-td>
|
||||
<x-td class="flex w-full justify-end">
|
||||
<x-icon-button
|
||||
x-on:click="$dispatch('open-modal', 'database-user-password'); document.getElementById('txt-database-user-password').value = 'Loading...';"
|
||||
hx-post="{{ route('servers.databases.users.password', ['server' => $server, 'databaseUser' => $databaseUser]) }}"
|
||||
hx-target="#database-user-password-content"
|
||||
hx-select="#database-user-password-content"
|
||||
hx-swap="outerHTML"
|
||||
>
|
||||
<x-heroicon-o-lock-closed class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
<x-icon-button
|
||||
x-on:click="linkAction = '{{ route('servers.databases.users.link', ['server' => $server, 'databaseUser' => $databaseUser]) }}';linkedDatabases = {{ json_encode($databaseUser->databases) }}; $dispatch('open-modal', 'link-database-user');"
|
||||
>
|
||||
<x-heroicon-o-link class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('servers.databases.users.destroy', ['server' => $server, 'databaseUser' => $databaseUser]) }}'; $dispatch('open-modal', 'delete-database-user')"
|
||||
>
|
||||
<x-heroicon-o-trash class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</x-td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</x-table>
|
||||
@else
|
||||
<x-simple-card class="text-center">
|
||||
{{ __("You don't have any database users yet") }}
|
||||
</x-simple-card>
|
||||
@endif
|
||||
</x-live>
|
||||
<x-confirmation-modal
|
||||
name="delete-database-user"
|
||||
title="Confirm"
|
||||
description="Are you sure that you want to delete this user?"
|
||||
method="delete"
|
||||
x-bind:action="deleteAction"
|
||||
/>
|
||||
@include("databases.partials.database-user-password-modal")
|
||||
@include("databases.partials.link-database-user-modal")
|
||||
</div>
|
@ -0,0 +1,45 @@
|
||||
<x-modal name="database-user-password">
|
||||
<div id="database-user-password-content" class="p-6">
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("View Password") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label :value="__('Password')" />
|
||||
<x-text-input
|
||||
id="txt-database-user-password"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
disabled
|
||||
value="{{ session()->has('password') ? session()->get('password') : '' }}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Close") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button
|
||||
x-data="{ copied: false }"
|
||||
x-clipboard.raw="{{ session()->has('password') ? session()->get('password') : '' }}"
|
||||
class="ml-2"
|
||||
>
|
||||
<div x-show="copied" class="flex items-center">
|
||||
{{ __("Copied") }}
|
||||
</div>
|
||||
<div
|
||||
x-show="!copied"
|
||||
x-on:click="
|
||||
copied = true
|
||||
setTimeout(() => {
|
||||
copied = false
|
||||
}, 2000)
|
||||
"
|
||||
>
|
||||
{{ __("Copy") }}
|
||||
</div>
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</div>
|
||||
</x-modal>
|
@ -0,0 +1,15 @@
|
||||
@if ($status == \App\Enums\DatabaseUserStatus::READY)
|
||||
<x-status status="success">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\DatabaseUserStatus::CREATING)
|
||||
<x-status status="warning">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\DatabaseUserStatus::DELETING)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\DatabaseUserStatus::FAILED)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
@ -0,0 +1,52 @@
|
||||
<x-modal name="link-database-user">
|
||||
<div id="link-database-user-modal">
|
||||
<form
|
||||
id="link-database-user-form"
|
||||
:hx-post="linkAction"
|
||||
x-init="$watch('linkAction', () => htmx.process($el))"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#link-database-user-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-link-database-user"
|
||||
class="p-6"
|
||||
>
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Link User to Databases") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
@foreach ($databases as $database)
|
||||
<div class="mb-2">
|
||||
<label for="db-{{ $database->id }}" class="inline-flex items-center">
|
||||
<input
|
||||
id="db-{{ $database->id }}"
|
||||
value="{{ $database->name }}"
|
||||
x-model="linkedDatabases"
|
||||
type="checkbox"
|
||||
name="databases[]"
|
||||
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800"
|
||||
/>
|
||||
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
{{ $database->name }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
@error("databases")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Close") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-link-database-user" class="ml-2">
|
||||
{{ __("Save") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</x-modal>
|
@ -0,0 +1,41 @@
|
||||
<x-modal name="restore-backup">
|
||||
<form
|
||||
id="restore-backup-form"
|
||||
:hx-post="restoreAction"
|
||||
x-init="$watch('restoreAction', () => htmx.process($el))"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#restore-backup-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-restore"
|
||||
class="p-6"
|
||||
>
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Restore Backup") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="database" :value="__('Database')" />
|
||||
<x-select-input id="database" name="database" class="mt-1 w-full">
|
||||
<option value="" selected disabled>{{ __("Select") }}</option>
|
||||
@foreach ($databases as $db)
|
||||
<option value="{{ $db->id }}" @if(old('database') == $db->id) selected @endif>
|
||||
{{ $db->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</x-select-input>
|
||||
@error("database")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-restore" class="ml-3">
|
||||
{{ __("Restore") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
Reference in New Issue
Block a user