fix: channels
feat: database backup is realtime now
This commit is contained in:
		
							
								
								
									
										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
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            new PrivateChannel("custom.{$this->userId}"),
 | 
			
		||||
            new PrivateChannel("user.{$this->userId}"),
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ class ServiceStatusChanged implements ShouldBroadcast
 | 
			
		||||
    public function broadcastOn(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            new PrivateChannel("custom.{$this->userId}"),
 | 
			
		||||
            new PrivateChannel("user.{$this->userId}"),
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ class TestEvent implements ShouldBroadcast
 | 
			
		||||
    public function broadcastOn(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            new PrivateChannel("custom.{$this->teamId}"),
 | 
			
		||||
            new PrivateChannel("team.{$this->teamId}"),
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -79,6 +79,10 @@ class Controller extends BaseController
 | 
			
		||||
        if (isInstanceAdmin()) {
 | 
			
		||||
            $settings = InstanceSettings::get();
 | 
			
		||||
            $database = StandalonePostgresql::whereName('coolify-db')->first();
 | 
			
		||||
            if ($database->status !== 'running') {
 | 
			
		||||
                $database->status = 'running';
 | 
			
		||||
                $database->save();
 | 
			
		||||
            }
 | 
			
		||||
            if ($database) {
 | 
			
		||||
                $s3s = S3Storage::whereTeamId(0)->get();
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
namespace App\Jobs;
 | 
			
		||||
 | 
			
		||||
use App\Actions\Database\StopDatabase;
 | 
			
		||||
use App\Events\BackupCreated;
 | 
			
		||||
use App\Models\S3Storage;
 | 
			
		||||
use App\Models\ScheduledDatabaseBackup;
 | 
			
		||||
use App\Models\ScheduledDatabaseBackupExecution;
 | 
			
		||||
@@ -74,6 +75,7 @@ class DatabaseBackupJob implements ShouldQueue, ShouldBeEncrypted
 | 
			
		||||
    public function handle(): void
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            BackupCreated::dispatch($this->team->id);
 | 
			
		||||
            // Check if team is exists
 | 
			
		||||
            if (is_null($this->team)) {
 | 
			
		||||
                $this->backup->update(['status' => 'failed']);
 | 
			
		||||
@@ -307,6 +309,8 @@ class DatabaseBackupJob implements ShouldQueue, ShouldBeEncrypted
 | 
			
		||||
        } catch (\Throwable $e) {
 | 
			
		||||
            send_internal_notification('DatabaseBackupJob failed with: ' . $e->getMessage());
 | 
			
		||||
            throw $e;
 | 
			
		||||
        } finally {
 | 
			
		||||
            BackupCreated::dispatch($this->team->id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private function backup_standalone_mongodb(string $databaseWithCollections): void
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,15 @@ class BackupExecutions extends Component
 | 
			
		||||
    public $backup;
 | 
			
		||||
    public $executions;
 | 
			
		||||
    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)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ class Heading extends Component
 | 
			
		||||
    {
 | 
			
		||||
        $userId = auth()->user()->id;
 | 
			
		||||
        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;
 | 
			
		||||
        return [
 | 
			
		||||
            "echo-private:custom.{$userId},ServiceStatusChanged" => 'checkStatus',
 | 
			
		||||
            "echo-private:user.{$userId},ServiceStatusChanged" => 'checkStatus',
 | 
			
		||||
            "refreshStacks",
 | 
			
		||||
            "checkStatus",
 | 
			
		||||
        ];
 | 
			
		||||
 
 | 
			
		||||
@@ -8,12 +8,12 @@ class Sponsorship extends Component
 | 
			
		||||
{
 | 
			
		||||
    public function getListeners()
 | 
			
		||||
    {
 | 
			
		||||
        $userId = auth()->user()->id;
 | 
			
		||||
        $teamId = auth()->user()->currentTeam()->id;
 | 
			
		||||
        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!');
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -22,9 +22,9 @@
 | 
			
		||||
                if (window.Echo) {
 | 
			
		||||
                    if (window.Echo.connector.pusher.connection.state !== 'connected') {
 | 
			
		||||
                        checkNumber++;
 | 
			
		||||
                        if (checkNumber > 5) {
 | 
			
		||||
                        if (checkNumber > 2) {
 | 
			
		||||
                            clearInterval(checkPusherInterval);
 | 
			
		||||
                            Livewire.emit('error', errorMessage);
 | 
			
		||||
                            window.Livewire.dispatch('error', errorMessage);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        console.log('Coolify is now connected to the new realtime service introduced in beta.154.');
 | 
			
		||||
@@ -32,7 +32,7 @@
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    clearInterval(checkPusherInterval);
 | 
			
		||||
                    Livewire.emit('error', errorMessage);
 | 
			
		||||
                    window.Livewire.dispatch('error', errorMessage);
 | 
			
		||||
                }
 | 
			
		||||
            }, 2000);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,7 @@
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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', () => {
 | 
			
		||||
                window.Livewire.on('reloadWindow', (timeout) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,15 @@
 | 
			
		||||
<div class="flex flex-col-reverse gap-2">
 | 
			
		||||
    @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([
 | 
			
		||||
                'border-green-500' => data_get($execution, 'status') === 'success',
 | 
			
		||||
                '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>Status: {{ data_get($execution, 'status') }}</div>
 | 
			
		||||
            <div>Started At: {{ data_get($execution, 'created_at') }}</div>
 | 
			
		||||
@@ -21,18 +26,11 @@
 | 
			
		||||
                    <x-forms.button class=" hover:bg-coolgray-400"
 | 
			
		||||
                        wire:click="download({{ data_get($execution, 'id') }})">Download</x-forms.button>
 | 
			
		||||
                @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>
 | 
			
		||||
        </form>
 | 
			
		||||
    @empty
 | 
			
		||||
        <div>No executions found.</div>
 | 
			
		||||
    @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>
 | 
			
		||||
 
 | 
			
		||||
@@ -45,11 +45,11 @@
 | 
			
		||||
    @endif
 | 
			
		||||
    <script>
 | 
			
		||||
        function checkProxy() {
 | 
			
		||||
            Livewire.emit('checkProxy')
 | 
			
		||||
            window.Livewire.dispatch('checkProxy')
 | 
			
		||||
        }
 | 
			
		||||
        Livewire.on('proxyChecked', () => {
 | 
			
		||||
            startProxy.showModal();
 | 
			
		||||
            Livewire.emit('startProxy');
 | 
			
		||||
            window.Livewire.dispatch('startProxy');
 | 
			
		||||
        })
 | 
			
		||||
    </script>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,16 @@ use App\Models\Application;
 | 
			
		||||
use App\Models\User;
 | 
			
		||||
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)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
Broadcast::channel('user.{userId}', function (User $user) {
 | 
			
		||||
    if ($user->id === auth()->user()->id) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user