fix: channels
feat: database backup is realtime now
This commit is contained in:
parent
63dff5961e
commit
3ffd3fc819
34
app/Events/BackupCreated.php
Normal file
34
app/Events/BackupCreated.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Events;
|
||||||
|
|
||||||
|
use Illuminate\Broadcasting\Channel;
|
||||||
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
|
use Illuminate\Broadcasting\PresenceChannel;
|
||||||
|
use Illuminate\Broadcasting\PrivateChannel;
|
||||||
|
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class BackupCreated implements ShouldBroadcast
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||||
|
public $teamId;
|
||||||
|
public function __construct($teamId = null)
|
||||||
|
{
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
$teamId = auth()->user()->currentTeam()->id ?? null;
|
||||||
|
}
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
throw new \Exception("Team id is null");
|
||||||
|
}
|
||||||
|
$this->teamId = $teamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function broadcastOn(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new PrivateChannel("team.{$this->teamId}"),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -28,7 +28,7 @@ class DatabaseStatusChanged implements ShouldBroadcast
|
|||||||
public function broadcastOn(): array
|
public function broadcastOn(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
new PrivateChannel("custom.{$this->userId}"),
|
new PrivateChannel("user.{$this->userId}"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ class ServiceStatusChanged implements ShouldBroadcast
|
|||||||
public function broadcastOn(): array
|
public function broadcastOn(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
new PrivateChannel("custom.{$this->userId}"),
|
new PrivateChannel("user.{$this->userId}"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class TestEvent implements ShouldBroadcast
|
|||||||
public function broadcastOn(): array
|
public function broadcastOn(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
new PrivateChannel("custom.{$this->teamId}"),
|
new PrivateChannel("team.{$this->teamId}"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,10 @@ class Controller extends BaseController
|
|||||||
if (isInstanceAdmin()) {
|
if (isInstanceAdmin()) {
|
||||||
$settings = InstanceSettings::get();
|
$settings = InstanceSettings::get();
|
||||||
$database = StandalonePostgresql::whereName('coolify-db')->first();
|
$database = StandalonePostgresql::whereName('coolify-db')->first();
|
||||||
|
if ($database->status !== 'running') {
|
||||||
|
$database->status = 'running';
|
||||||
|
$database->save();
|
||||||
|
}
|
||||||
if ($database) {
|
if ($database) {
|
||||||
$s3s = S3Storage::whereTeamId(0)->get();
|
$s3s = S3Storage::whereTeamId(0)->get();
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Jobs;
|
namespace App\Jobs;
|
||||||
|
|
||||||
use App\Actions\Database\StopDatabase;
|
use App\Actions\Database\StopDatabase;
|
||||||
|
use App\Events\BackupCreated;
|
||||||
use App\Models\S3Storage;
|
use App\Models\S3Storage;
|
||||||
use App\Models\ScheduledDatabaseBackup;
|
use App\Models\ScheduledDatabaseBackup;
|
||||||
use App\Models\ScheduledDatabaseBackupExecution;
|
use App\Models\ScheduledDatabaseBackupExecution;
|
||||||
@ -74,6 +75,7 @@ class DatabaseBackupJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
BackupCreated::dispatch($this->team->id);
|
||||||
// Check if team is exists
|
// Check if team is exists
|
||||||
if (is_null($this->team)) {
|
if (is_null($this->team)) {
|
||||||
$this->backup->update(['status' => 'failed']);
|
$this->backup->update(['status' => 'failed']);
|
||||||
@ -307,6 +309,8 @@ class DatabaseBackupJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
send_internal_notification('DatabaseBackupJob failed with: ' . $e->getMessage());
|
send_internal_notification('DatabaseBackupJob failed with: ' . $e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
|
} finally {
|
||||||
|
BackupCreated::dispatch($this->team->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private function backup_standalone_mongodb(string $databaseWithCollections): void
|
private function backup_standalone_mongodb(string $databaseWithCollections): void
|
||||||
|
@ -10,7 +10,15 @@ class BackupExecutions extends Component
|
|||||||
public $backup;
|
public $backup;
|
||||||
public $executions;
|
public $executions;
|
||||||
public $setDeletableBackup;
|
public $setDeletableBackup;
|
||||||
protected $listeners = ['refreshBackupExecutions', 'deleteBackup'];
|
public function getListeners()
|
||||||
|
{
|
||||||
|
$userId = auth()->user()->id;
|
||||||
|
return [
|
||||||
|
"echo-private:team.{$userId},BackupCreated" => 'refreshBackupExecutions',
|
||||||
|
"refreshBackupExecutions",
|
||||||
|
"deleteBackup"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function deleteBackup($exeuctionId)
|
public function deleteBackup($exeuctionId)
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,7 @@ class Heading extends Component
|
|||||||
{
|
{
|
||||||
$userId = auth()->user()->id;
|
$userId = auth()->user()->id;
|
||||||
return [
|
return [
|
||||||
"echo-private:custom.{$userId},DatabaseStatusChanged" => 'activityFinished',
|
"echo-private:user.{$userId},DatabaseStatusChanged" => 'activityFinished',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class Index extends Component
|
|||||||
{
|
{
|
||||||
$userId = auth()->user()->id;
|
$userId = auth()->user()->id;
|
||||||
return [
|
return [
|
||||||
"echo-private:custom.{$userId},ServiceStatusChanged" => 'checkStatus',
|
"echo-private:user.{$userId},ServiceStatusChanged" => 'checkStatus',
|
||||||
"refreshStacks",
|
"refreshStacks",
|
||||||
"checkStatus",
|
"checkStatus",
|
||||||
];
|
];
|
||||||
|
@ -8,12 +8,12 @@ class Sponsorship extends Component
|
|||||||
{
|
{
|
||||||
public function getListeners()
|
public function getListeners()
|
||||||
{
|
{
|
||||||
$userId = auth()->user()->id;
|
$teamId = auth()->user()->currentTeam()->id;
|
||||||
return [
|
return [
|
||||||
"echo-private:custom.{$userId},TestEvent" => 'testEvent',
|
"echo-private:team.{$teamId},TestEvent" => 'testEvent',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
public function testEvent($asd)
|
public function testEvent()
|
||||||
{
|
{
|
||||||
$this->dispatch('success', 'Realtime events configured!');
|
$this->dispatch('success', 'Realtime events configured!');
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
if (window.Echo) {
|
if (window.Echo) {
|
||||||
if (window.Echo.connector.pusher.connection.state !== 'connected') {
|
if (window.Echo.connector.pusher.connection.state !== 'connected') {
|
||||||
checkNumber++;
|
checkNumber++;
|
||||||
if (checkNumber > 5) {
|
if (checkNumber > 2) {
|
||||||
clearInterval(checkPusherInterval);
|
clearInterval(checkPusherInterval);
|
||||||
Livewire.emit('error', errorMessage);
|
window.Livewire.dispatch('error', errorMessage);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Coolify is now connected to the new realtime service introduced in beta.154.');
|
console.log('Coolify is now connected to the new realtime service introduced in beta.154.');
|
||||||
@ -32,7 +32,7 @@
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clearInterval(checkPusherInterval);
|
clearInterval(checkPusherInterval);
|
||||||
Livewire.emit('error', errorMessage);
|
window.Livewire.dispatch('error', errorMessage);
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function copyToClipboard(text) {
|
function copyToClipboard(text) {
|
||||||
navigator?.clipboard?.writeText(text) && window.Livewire.emit('success', 'Copied to clipboard.');
|
navigator?.clipboard?.writeText(text) && window.Livewire.dispatch('success', 'Copied to clipboard.');
|
||||||
}
|
}
|
||||||
document.addEventListener('livewire:init', () => {
|
document.addEventListener('livewire:init', () => {
|
||||||
window.Livewire.on('reloadWindow', (timeout) => {
|
window.Livewire.on('reloadWindow', (timeout) => {
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
<div class="flex flex-col-reverse gap-2">
|
<div class="flex flex-col-reverse gap-2">
|
||||||
@forelse($executions as $execution)
|
@forelse($executions as $execution)
|
||||||
<form wire:key="{{ data_get($execution, 'id') }}" class="flex flex-col p-2 border-dotted border-1 bg-coolgray-300"
|
<form wire:key="{{ data_get($execution, 'id') }}" class="relative flex flex-col p-4 border-dotted border-1 bg-coolgray-100"
|
||||||
@class([
|
@class([
|
||||||
'border-green-500' => data_get($execution, 'status') === 'success',
|
'border-green-500' => data_get($execution, 'status') === 'success',
|
||||||
'border-red-500' => data_get($execution, 'status') === 'failed',
|
'border-red-500' => data_get($execution, 'status') === 'failed',
|
||||||
])>
|
])>
|
||||||
|
@if (data_get($execution, 'status') === 'running')
|
||||||
|
<div class="absolute top-2 right-2">
|
||||||
|
<x-loading />
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
<div>Database: {{ data_get($execution, 'database_name', 'N/A') }}</div>
|
<div>Database: {{ data_get($execution, 'database_name', 'N/A') }}</div>
|
||||||
<div>Status: {{ data_get($execution, 'status') }}</div>
|
<div>Status: {{ data_get($execution, 'status') }}</div>
|
||||||
<div>Started At: {{ data_get($execution, 'created_at') }}</div>
|
<div>Started At: {{ data_get($execution, 'created_at') }}</div>
|
||||||
@ -21,18 +26,11 @@
|
|||||||
<x-forms.button class=" hover:bg-coolgray-400"
|
<x-forms.button class=" hover:bg-coolgray-400"
|
||||||
wire:click="download({{ data_get($execution, 'id') }})">Download</x-forms.button>
|
wire:click="download({{ data_get($execution, 'id') }})">Download</x-forms.button>
|
||||||
@endif
|
@endif
|
||||||
<x-forms.button isError onclick="sure({{ data_get($execution, 'id') }})">Delete</x-forms.button>
|
<x-forms.button isError wire:click="deleteBackup({{ data_get($execution, 'id') }})"
|
||||||
|
wire:confirm.prompt="Are you sure?\n\nType DELETE to confirm|DELETE">Delete</x-forms.button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@empty
|
@empty
|
||||||
<div>No executions found.</div>
|
<div>No executions found.</div>
|
||||||
@endforelse
|
@endforelse
|
||||||
<script>
|
|
||||||
function sure($id) {
|
|
||||||
const sure = confirm('Are you sure you want to delete this backup?');
|
|
||||||
if (sure) {
|
|
||||||
Livewire.emit('deleteBackup', $id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,11 +45,11 @@
|
|||||||
@endif
|
@endif
|
||||||
<script>
|
<script>
|
||||||
function checkProxy() {
|
function checkProxy() {
|
||||||
Livewire.emit('checkProxy')
|
window.Livewire.dispatch('checkProxy')
|
||||||
}
|
}
|
||||||
Livewire.on('proxyChecked', () => {
|
Livewire.on('proxyChecked', () => {
|
||||||
startProxy.showModal();
|
startProxy.showModal();
|
||||||
Livewire.emit('startProxy');
|
window.Livewire.dispatch('startProxy');
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,9 +15,16 @@ use App\Models\Application;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Broadcast;
|
use Illuminate\Support\Facades\Broadcast;
|
||||||
|
|
||||||
Broadcast::channel('custom.{teamId}', function (User $user, int $teamId) {
|
Broadcast::channel('team.{teamId}', function (User $user, int $teamId) {
|
||||||
if ($user->teams->pluck('id')->contains($teamId)) {
|
if ($user->teams->pluck('id')->contains($teamId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Broadcast::channel('user.{userId}', function (User $user) {
|
||||||
|
if ($user->id === auth()->user()->id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user