diff --git a/app/Actions/CoolifyTask/PrepareCoolifyTask.php b/app/Actions/CoolifyTask/PrepareCoolifyTask.php index 3b2f70014..b5b5a8853 100644 --- a/app/Actions/CoolifyTask/PrepareCoolifyTask.php +++ b/app/Actions/CoolifyTask/PrepareCoolifyTask.php @@ -39,7 +39,7 @@ class PrepareCoolifyTask public function __invoke(): Activity { - $job = new CoolifyTask($this->activity, ignore_errors: $this->remoteProcessArgs->ignore_errors); + $job = new CoolifyTask($this->activity, ignore_errors: $this->remoteProcessArgs->ignore_errors, call_event_on_finish: $this->remoteProcessArgs->call_event_on_finish); dispatch($job); $this->activity->refresh(); return $this->activity; diff --git a/app/Actions/CoolifyTask/RunRemoteProcess.php b/app/Actions/CoolifyTask/RunRemoteProcess.php index cdbf6813c..327d46c68 100644 --- a/app/Actions/CoolifyTask/RunRemoteProcess.php +++ b/app/Actions/CoolifyTask/RunRemoteProcess.php @@ -17,24 +17,24 @@ class RunRemoteProcess public bool $hide_from_output; - public bool $is_finished; - public bool $ignore_errors; + public $call_event_on_finish = null; + protected $time_start; protected $current_time; protected $last_write_at = 0; - protected $throttle_interval_ms = 500; + protected $throttle_interval_ms = 200; protected int $counter = 1; /** * Create a new job instance. */ - public function __construct(Activity $activity, bool $hide_from_output = false, bool $is_finished = false, bool $ignore_errors = false) + public function __construct(Activity $activity, bool $hide_from_output = false, bool $ignore_errors = false, $call_event_on_finish = null) { if ($activity->getExtraProperty('type') !== ActivityTypes::INLINE->value) { @@ -43,8 +43,8 @@ class RunRemoteProcess $this->activity = $activity; $this->hide_from_output = $hide_from_output; - $this->is_finished = $is_finished; $this->ignore_errors = $ignore_errors; + $this->call_event_on_finish = $call_event_on_finish; } public static function decodeOutput(?Activity $activity = null): string @@ -74,17 +74,29 @@ class RunRemoteProcess $this->time_start = hrtime(true); $status = ProcessStatus::IN_PROGRESS; - $processResult = Process::forever()->run($this->getCommand(), $this->handleOutput(...)); + $timeout = config('constants.ssh.command_timeout'); + $process = Process::timeout($timeout)->start($this->getCommand(), $this->handleOutput(...)); + $this->activity->properties = $this->activity->properties->merge([ + 'process_id' => $process->id(), + ]); + $processResult = $process->wait(); + // $processResult = Process::timeout($timeout)->run($this->getCommand(), $this->handleOutput(...)); if ($this->activity->properties->get('status') === ProcessStatus::ERROR->value) { $status = ProcessStatus::ERROR; } else { - if (($processResult->exitCode() == 0 && $this->is_finished) || $this->activity->properties->get('status') === ProcessStatus::FINISHED->value) { + if ($processResult->exitCode() == 0) { $status = ProcessStatus::FINISHED; } if ($processResult->exitCode() != 0 && !$this->ignore_errors) { $status = ProcessStatus::ERROR; } + // if (($processResult->exitCode() == 0 && $this->is_finished) || $this->activity->properties->get('status') === ProcessStatus::FINISHED->value) { + // $status = ProcessStatus::FINISHED; + // } + // if ($processResult->exitCode() != 0 && !$this->ignore_errors) { + // $status = ProcessStatus::ERROR; + // } } $this->activity->properties = $this->activity->properties->merge([ @@ -97,7 +109,15 @@ class RunRemoteProcess if ($processResult->exitCode() != 0 && !$this->ignore_errors) { throw new \RuntimeException($processResult->errorOutput(), $processResult->exitCode()); } - + if ($this->call_event_on_finish) { + try { + event(resolve("App\\Events\\$this->call_event_on_finish", [ + 'userId' => $this->activity->causer_id, + ])); + } catch (\Throwable $e) { + ray($e); + } + } return $processResult; } @@ -117,7 +137,6 @@ class RunRemoteProcess } $this->current_time = $this->elapsedTime(); $this->activity->description = $this->encodeOutput($type, $output); - if ($this->isAfterLastThrottle()) { // Let's write to database. DB::transaction(function () { diff --git a/app/Actions/Database/StartMariadb.php b/app/Actions/Database/StartMariadb.php index 21fcdb8a5..5ea86a551 100644 --- a/app/Actions/Database/StartMariadb.php +++ b/app/Actions/Database/StartMariadb.php @@ -105,7 +105,7 @@ class StartMariadb $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo '{$database->name} started.'"; - return remote_process($this->commands, $database->destination->server); + return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged'); } private function generate_local_persistent_volumes() diff --git a/app/Actions/Database/StartMongodb.php b/app/Actions/Database/StartMongodb.php index e0197a7bc..9ce35bbc2 100644 --- a/app/Actions/Database/StartMongodb.php +++ b/app/Actions/Database/StartMongodb.php @@ -121,7 +121,7 @@ class StartMongodb $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo '{$database->name} started.'"; - return remote_process($this->commands, $database->destination->server); + return remote_process($this->commands, $database->destination->server,callEventOnFinish: 'DatabaseStatusChanged'); } private function generate_local_persistent_volumes() diff --git a/app/Actions/Database/StartMysql.php b/app/Actions/Database/StartMysql.php index 76e8af619..d37821332 100644 --- a/app/Actions/Database/StartMysql.php +++ b/app/Actions/Database/StartMysql.php @@ -105,7 +105,7 @@ class StartMysql $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo '{$database->name} started.'"; - return remote_process($this->commands, $database->destination->server); + return remote_process($this->commands, $database->destination->server,callEventOnFinish: 'DatabaseStatusChanged'); } private function generate_local_persistent_volumes() diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index 97ae9da0e..99fb56ba4 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -131,7 +131,7 @@ class StartPostgresql $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo '{$database->name} started.'"; - return remote_process($this->commands, $database->destination->server); + return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged'); } private function generate_local_persistent_volumes() diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index fcb87b891..4e3773726 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -115,7 +115,7 @@ class StartRedis $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo '{$database->name} started.'"; - return remote_process($this->commands, $database->destination->server); + return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged'); } private function generate_local_persistent_volumes() diff --git a/app/Actions/Database/StopDatabase.php b/app/Actions/Database/StopDatabase.php index 4f6a8c6c2..e6316ecc9 100644 --- a/app/Actions/Database/StopDatabase.php +++ b/app/Actions/Database/StopDatabase.php @@ -2,6 +2,7 @@ namespace App\Actions\Database; +use App\Events\DatabaseStatusChanged; use App\Models\StandaloneMariadb; use App\Models\StandaloneMongodb; use App\Models\StandaloneMysql; diff --git a/app/Actions/Service/DeleteService.php b/app/Actions/Service/DeleteService.php new file mode 100644 index 000000000..e7cc049b1 --- /dev/null +++ b/app/Actions/Service/DeleteService.php @@ -0,0 +1,42 @@ +environment_variables()->delete(); + $commands = []; + foreach ($service->applications()->get() as $application) { + $storages = $application->persistentStorages()->get(); + foreach ($storages as $storage) { + $storagesToDelete->push($storage); + } + $application->delete(); + } + foreach ($service->databases()->get() as $database) { + $storages = $database->persistentStorages()->get(); + foreach ($storages as $storage) { + $storagesToDelete->push($storage); + } + $database->delete(); + } + foreach ($storagesToDelete as $storage) { + $commands[] = "docker volume rm -f $storage->name"; + } + $commands[] = "docker rm -f $service->uuid"; + + instant_remote_process($commands, $server, false); + + $service->forceDelete(); + } +} diff --git a/app/Actions/Service/StartService.php b/app/Actions/Service/StartService.php index 3cd23ef85..dc722aa83 100644 --- a/app/Actions/Service/StartService.php +++ b/app/Actions/Service/StartService.php @@ -16,19 +16,19 @@ class StartService $commands[] = "cd " . $service->workdir(); $commands[] = "echo 'Saved configuration files to {$service->workdir()}.'"; $commands[] = "echo 'Creating Docker network.'"; - $commands[] = "docker network create --attachable '{$service->uuid}' >/dev/null 2>&1 || true"; - $commands[] = "echo 'Starting service {$service->name} on {$service->server->name}.'"; + $commands[] = "docker network inspect $service->uuid >/dev/null 2>&1 || docker network create --attachable $service->uuid >/dev/null 2>&1 || true"; + $commands[] = "echo 'Starting service $service->name on {$service->server->name}.'"; $commands[] = "echo 'Pulling images.'"; $commands[] = "docker compose pull"; $commands[] = "echo 'Starting containers.'"; $commands[] = "docker compose up -d --remove-orphans --force-recreate --build"; $commands[] = "docker network connect $service->uuid coolify-proxy >/dev/null 2>&1 || true"; - $compose = data_get($service,'docker_compose',[]); - $serviceNames = data_get(Yaml::parse($compose),'services',[]); - foreach($serviceNames as $serviceName => $serviceConfig){ + $compose = data_get($service, 'docker_compose', []); + $serviceNames = data_get(Yaml::parse($compose), 'services', []); + foreach ($serviceNames as $serviceName => $serviceConfig) { $commands[] = "docker network connect --alias {$serviceName}-{$service->uuid} $network {$serviceName}-{$service->uuid} || true"; } - $activity = remote_process($commands, $service->server); + $activity = remote_process($commands, $service->server, type_uuid: $service->uuid, callEventOnFinish: 'ServiceStatusChanged'); return $activity; } } diff --git a/app/Data/CoolifyTaskArgs.php b/app/Data/CoolifyTaskArgs.php index f73fd6318..cc717561f 100644 --- a/app/Data/CoolifyTaskArgs.php +++ b/app/Data/CoolifyTaskArgs.php @@ -16,9 +16,11 @@ class CoolifyTaskArgs extends Data public string $command, public string $type, public ?string $type_uuid = null, + public ?int $process_id = null, public ?Model $model = null, public ?string $status = null , public bool $ignore_errors = false, + public $call_event_on_finish = null, ) { if(is_null($status)){ $this->status = ProcessStatus::QUEUED->value; diff --git a/app/Enums/ProcessStatus.php b/app/Enums/ProcessStatus.php index 889aca9f2..0031cabdd 100644 --- a/app/Enums/ProcessStatus.php +++ b/app/Enums/ProcessStatus.php @@ -8,5 +8,6 @@ enum ProcessStatus: string case IN_PROGRESS = 'in_progress'; case FINISHED = 'finished'; case ERROR = 'error'; + case KILLED = 'killed'; case CANCELLED = 'cancelled'; } diff --git a/app/Events/ApplicationStatusChanged.php b/app/Events/ApplicationStatusChanged.php new file mode 100644 index 000000000..4224d4a29 --- /dev/null +++ b/app/Events/ApplicationStatusChanged.php @@ -0,0 +1,34 @@ +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}"), + ]; + } +} diff --git a/app/Events/BackupCreated.php b/app/Events/BackupCreated.php new file mode 100644 index 000000000..41d0afcbc --- /dev/null +++ b/app/Events/BackupCreated.php @@ -0,0 +1,34 @@ +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}"), + ]; + } +} diff --git a/app/Events/DatabaseStatusChanged.php b/app/Events/DatabaseStatusChanged.php new file mode 100644 index 000000000..8f83406f4 --- /dev/null +++ b/app/Events/DatabaseStatusChanged.php @@ -0,0 +1,34 @@ +user()->id ?? null; + } + if (is_null($userId)) { + throw new \Exception("User id is null"); + } + $this->userId = $userId; + } + + public function broadcastOn(): array + { + return [ + new PrivateChannel("user.{$this->userId}"), + ]; + } +} diff --git a/app/Events/ServiceStatusChanged.php b/app/Events/ServiceStatusChanged.php new file mode 100644 index 000000000..3fe849190 --- /dev/null +++ b/app/Events/ServiceStatusChanged.php @@ -0,0 +1,34 @@ +user()->id ?? null; + } + if (is_null($userId)) { + throw new \Exception("User id is null"); + } + $this->userId = $userId; + } + + public function broadcastOn(): array + { + return [ + new PrivateChannel("user.{$this->userId}"), + ]; + } +} diff --git a/app/Events/TestEvent.php b/app/Events/TestEvent.php index 2a4c138f6..df677ba7a 100644 --- a/app/Events/TestEvent.php +++ b/app/Events/TestEvent.php @@ -22,7 +22,7 @@ class TestEvent implements ShouldBroadcast public function broadcastOn(): array { return [ - new PrivateChannel("custom.{$this->teamId}"), + new PrivateChannel("team.{$this->teamId}"), ]; } } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 7c1d186ff..ee0bc5160 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -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(); } diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 4e2fc5878..1e7d6b9cd 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -116,7 +116,6 @@ class ProjectController extends Controller }); } $service->parse(isNew: true); - return redirect()->route('project.service.configuration', [ 'service_uuid' => $service->uuid, 'environment_name' => $environment->name, diff --git a/app/Http/Livewire/Project/Application/Command.php b/app/Http/Livewire/Project/Application/Command.php deleted file mode 100644 index 5fea572ee..000000000 --- a/app/Http/Livewire/Project/Application/Command.php +++ /dev/null @@ -1,110 +0,0 @@ - 'required', - 'container' => 'required', - 'command' => 'required', - 'workDir' => 'nullable', - ]; - - public function mount() - { - $this->containers = collect(); - $this->parameters = get_route_parameters(); - if (data_get($this->parameters, 'application_uuid')) { - $this->type = 'application'; - $this->resource = Application::where('uuid', $this->parameters['application_uuid'])->firstOrFail(); - $this->server = $this->resource->destination->server; - $containers = getCurrentApplicationContainerStatus($this->server, $this->resource->id, 0); - if ($containers->count() > 0) { - $containers->each(function ($container) { - $this->containers->push(str_replace('/', '', $container['Names'])); - }); - } - } else if (data_get($this->parameters, 'database_uuid')) { - $this->type = 'database'; - $resource = StandalonePostgresql::where('uuid', $this->parameters['database_uuid'])->first(); - if (is_null($resource)) { - $resource = StandaloneRedis::where('uuid', $this->parameters['database_uuid'])->first(); - if (is_null($resource)) { - $resource = StandaloneMongodb::where('uuid', $this->parameters['database_uuid'])->first(); - if (is_null($resource)) { - $resource = StandaloneMysql::where('uuid', $this->parameters['database_uuid'])->first(); - if (is_null($resource)) { - $resource = StandaloneMariadb::where('uuid', $this->parameters['database_uuid'])->first(); - if (is_null($resource)) { - abort(404); - } - } - } - } - } - $this->resource = $resource; - $this->server = $this->resource->destination->server; - $this->container = $this->resource->uuid; - $this->containers->push($this->container); - } else if (data_get($this->parameters, 'service_uuid')) { - $this->type = 'service'; - $this->resource = Service::where('uuid', $this->parameters['service_uuid'])->firstOrFail(); - $this->resource->applications()->get()->each(function ($application) { - if (str(data_get($application, 'status'))->contains('running')) { - $this->containers->push(data_get($application, 'name') . '-' . data_get($this->resource, 'uuid')); - } - }); - $this->resource->databases()->get()->each(function ($database) { - if (str(data_get($database, 'status'))->contains('running')) { - $this->containers->push(data_get($database, 'name') . '-' . data_get($this->resource, 'uuid')); - } - }); - - $this->server = $this->resource->server; - } - if ($this->containers->count() > 1) { - $this->container = $this->containers->first(); - } - } - - public function runCommand() - { - $this->validate(); - try { - if (!empty($this->workDir)) { - $exec = "docker exec -w {$this->workDir} {$this->container} {$this->command}"; - } else { - $exec = "docker exec {$this->container} {$this->command}"; - } - $activity = remote_process([$exec], $this->server, ignore_errors: true); - $this->emit('newMonitorActivity', $activity->id); - } catch (\Throwable $e) { - return handleError($e, $this); - } - } - public function render() - { - return view('livewire.project.shared.execute-container-command'); - } -} diff --git a/app/Http/Livewire/Project/Service/Navbar.php b/app/Http/Livewire/Project/Service/Navbar.php deleted file mode 100644 index 1953605e6..000000000 --- a/app/Http/Livewire/Project/Service/Navbar.php +++ /dev/null @@ -1,41 +0,0 @@ -service->refresh(); - } - public function deploy() - { - $this->service->parse(); - $activity = StartService::run($this->service); - $this->emit('newMonitorActivity', $activity->id); - } - public function stop(bool $forceCleanup = false) - { - StopService::run($this->service); - $this->service->refresh(); - if ($forceCleanup) { - $this->emit('success', 'Force cleanup service successfully.'); - } else { - $this->emit('success', 'Service stopped successfully.'); - } - $this->emit('checkStatus'); - } -} diff --git a/app/Http/Livewire/Project/Shared/Danger.php b/app/Http/Livewire/Project/Shared/Danger.php deleted file mode 100644 index f2bef04d4..000000000 --- a/app/Http/Livewire/Project/Shared/Danger.php +++ /dev/null @@ -1,33 +0,0 @@ -modalId = new Cuid2(7); - $this->parameters = get_route_parameters(); - } - - public function delete() - { - try { - DeleteResourceJob::dispatchSync($this->resource); - return redirect()->route('project.resources', [ - 'project_uuid' => $this->parameters['project_uuid'], - 'environment_name' => $this->parameters['environment_name'] - ]); - } catch (\Throwable $e) { - return handleError($e, $this); - } - } -} diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 838bd7dd6..08c388084 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -4,6 +4,7 @@ namespace App\Jobs; use App\Enums\ApplicationDeploymentStatus; use App\Enums\ProxyTypes; +use App\Events\ApplicationStatusChanged; use App\Models\Application; use App\Models\ApplicationDeploymentQueue; use App\Models\ApplicationPreview; @@ -266,6 +267,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted "ignore_errors" => true, ] ); + ApplicationStatusChanged::dispatch(data_get($this->application,'environment.project.team.id')); } } private function push_to_docker_registry() @@ -451,6 +453,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted executeInDocker($this->deployment_uuid, "echo '{$this->docker_compose_base64}' | base64 -d > {$this->workdir}{$this->docker_compose_location}"), "hidden" => true ]); $this->save_environment_variables(); + // Build new container to limit downtime. + $this->build_by_compose_file(); $this->stop_running_container(force: true); $networkId = $this->application->uuid; @@ -1243,6 +1247,28 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); } } + private function build_by_compose_file() { + $this->application_deployment_queue->addLogEntry("Pulling & building required images."); + if ($this->application->build_pack === 'dockerimage') { + $this->application_deployment_queue->addLogEntry("Pulling latest images from the registry."); + $this->execute_remote_command( + [executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} pull"), "hidden" => true], + [executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} build"), "hidden" => true], + ); + } else { + if ($this->docker_compose_location) { + $this->execute_remote_command( + [executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} build"), "hidden" => true], + ); + } else { + $this->execute_remote_command( + [executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} build"), "hidden" => true], + ); + } + } + $this->application_deployment_queue->addLogEntry("New images built."); + } + private function start_by_compose_file() { if ($this->application->build_pack === 'dockerimage') { diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 090fd1896..5599c6de4 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -34,7 +34,7 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted public function __construct(public Server $server) { - if (isDev()) $this->handle(); + $this->handle(); } diff --git a/app/Jobs/CoolifyTask.php b/app/Jobs/CoolifyTask.php index 3ea32c27a..77d453ae2 100755 --- a/app/Jobs/CoolifyTask.php +++ b/app/Jobs/CoolifyTask.php @@ -21,6 +21,7 @@ class CoolifyTask implements ShouldQueue, ShouldBeEncrypted public function __construct( public Activity $activity, public bool $ignore_errors = false, + public $call_event_on_finish = null ) { } @@ -32,6 +33,7 @@ class CoolifyTask implements ShouldQueue, ShouldBeEncrypted $remote_process = resolve(RunRemoteProcess::class, [ 'activity' => $this->activity, 'ignore_errors' => $this->ignore_errors, + 'call_event_on_finish' => $this->call_event_on_finish ]); $remote_process(); diff --git a/app/Jobs/DatabaseBackupJob.php b/app/Jobs/DatabaseBackupJob.php index 02ddb7a5d..1ba855f4e 100644 --- a/app/Jobs/DatabaseBackupJob.php +++ b/app/Jobs/DatabaseBackupJob.php @@ -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 diff --git a/app/Jobs/DeleteResourceJob.php b/app/Jobs/DeleteResourceJob.php index 0393d9f56..f8df38a2a 100644 --- a/app/Jobs/DeleteResourceJob.php +++ b/app/Jobs/DeleteResourceJob.php @@ -4,7 +4,7 @@ namespace App\Jobs; use App\Actions\Application\StopApplication; use App\Actions\Database\StopDatabase; -use App\Actions\Service\StopService; +use App\Actions\Service\DeleteService; use App\Models\Application; use App\Models\Service; use App\Models\StandaloneMariadb; @@ -54,11 +54,13 @@ class DeleteResourceJob implements ShouldQueue, ShouldBeEncrypted case 'standalone-mariadb': StopDatabase::run($this->resource); break; - case 'service': - StopService::run($this->resource); - break; } - $this->resource->delete(); + if ($this->resource->type() === 'service') { + $this->resource->delete(); + DeleteService::dispatch($this->resource); + } else { + $this->resource->delete(); + } } catch (\Throwable $e) { send_internal_notification('ContainerStoppingJob failed with: ' . $e->getMessage()); throw $e; diff --git a/app/Http/Livewire/ActivityMonitor.php b/app/Livewire/ActivityMonitor.php similarity index 58% rename from app/Http/Livewire/ActivityMonitor.php rename to app/Livewire/ActivityMonitor.php index 9ce37f9b3..703899b65 100644 --- a/app/Http/Livewire/ActivityMonitor.php +++ b/app/Livewire/ActivityMonitor.php @@ -1,6 +1,6 @@ activity = Activity::query() - ->find($this->activityId); + $this->activity = Activity::find($this->activityId); } public function polling() { $this->hydrateActivity(); - $this->setStatus(ProcessStatus::IN_PROGRESS); + // $this->setStatus(ProcessStatus::IN_PROGRESS); $exit_code = data_get($this->activity, 'properties.exitCode'); if ($exit_code !== null) { if ($exit_code === 0) { - $this->setStatus(ProcessStatus::FINISHED); + // $this->setStatus(ProcessStatus::FINISHED); } else { - $this->setStatus(ProcessStatus::ERROR); + // $this->setStatus(ProcessStatus::ERROR); } $this->isPollingActive = false; - $this->emit('activityFinished'); + $this->dispatch('activityFinished'); } } - protected function setStatus($status) - { - $this->activity->properties = $this->activity->properties->merge([ - 'status' => $status, - ]); - $this->activity->save(); - } + // protected function setStatus($status) + // { + // $this->activity->properties = $this->activity->properties->merge([ + // 'status' => $status, + // ]); + // $this->activity->save(); + // } } diff --git a/app/Http/Livewire/Boarding/Index.php b/app/Livewire/Boarding/Index.php similarity index 95% rename from app/Http/Livewire/Boarding/Index.php rename to app/Livewire/Boarding/Index.php index 19c51d5ce..9c59f66ab 100644 --- a/app/Http/Livewire/Boarding/Index.php +++ b/app/Livewire/Boarding/Index.php @@ -1,6 +1,6 @@ selectedServerType === 'localhost') { $this->createdServer = Server::find(0); if (!$this->createdServer) { - return $this->emit('error', 'Localhost server is not found. Something went wrong during installation. Please try to reinstall or contact support.'); + return $this->dispatch('error', 'Localhost server is not found. Something went wrong during installation. Please try to reinstall or contact support.'); } $this->serverPublicKey = $this->createdServer->privateKey->publicKey(); return $this->validateServer('localhost'); @@ -110,7 +110,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== { $this->createdServer = Server::find($this->selectedExistingServer); if (!$this->createdServer) { - $this->emit('error', 'Server is not found.'); + $this->dispatch('error', 'Server is not found.'); $this->currentState = 'private-key'; return; } @@ -173,7 +173,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== $this->privateKey = formatPrivateKey($this->privateKey); $foundServer = Server::whereIp($this->remoteServerHost)->first(); if ($foundServer) { - return $this->emit('error', 'IP address is already in use by another team.'); + return $this->dispatch('error', 'IP address is already in use by another team.'); } $this->createdServer = Server::create([ 'name' => $this->remoteServerName, @@ -227,8 +227,8 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== try { $this->dockerInstallationStarted = true; $activity = InstallDocker::run($this->createdServer); - $this->emit('installDocker'); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('installDocker'); + $this->dispatch('newMonitorActivity', $activity->id); } catch (\Throwable $e) { $this->dockerInstallationStarted = false; return handleError(error: $e, livewire: $this); diff --git a/app/Http/Livewire/CheckLicense.php b/app/Livewire/CheckLicense.php similarity index 88% rename from app/Http/Livewire/CheckLicense.php rename to app/Livewire/CheckLicense.php index 3c2933bfc..b77cc6afe 100644 --- a/app/Http/Livewire/CheckLicense.php +++ b/app/Livewire/CheckLicense.php @@ -1,6 +1,6 @@ settings->resale_license) { try { CheckResaleLicense::run(); - $this->emit('reloadWindow'); + $this->dispatch('reloadWindow'); } catch (\Throwable $e) { session()->flash('error', 'Something went wrong. Please contact support.
Error: ' . $e->getMessage()); ray($e->getMessage()); - return redirect()->to('/settings/license'); + return $this->redirect('/settings/license', navigate: true); } } } diff --git a/app/Http/Livewire/Dashboard.php b/app/Livewire/Dashboard.php similarity index 96% rename from app/Http/Livewire/Dashboard.php rename to app/Livewire/Dashboard.php index 05bef207d..51d964a29 100644 --- a/app/Http/Livewire/Dashboard.php +++ b/app/Livewire/Dashboard.php @@ -1,6 +1,6 @@ destination->getMorphClass() === 'App\Models\StandaloneDocker') { if ($this->destination->attachedTo()) { - return $this->emit('error', 'You must delete all resources before deleting this destination.'); + return $this->dispatch('error', 'You must delete all resources before deleting this destination.'); } instant_remote_process(["docker network disconnect {$this->destination->network} coolify-proxy"], $this->destination->server, throwError: false); instant_remote_process(['docker network rm -f ' . $this->destination->network], $this->destination->server); } $this->destination->delete(); - return redirect()->route('dashboard'); + return $this->redirectRoute('dashboard', navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Destination/New/StandaloneDocker.php b/app/Livewire/Destination/New/StandaloneDocker.php similarity index 91% rename from app/Http/Livewire/Destination/New/StandaloneDocker.php rename to app/Livewire/Destination/New/StandaloneDocker.php index 75ceb1a0b..72516752a 100644 --- a/app/Http/Livewire/Destination/New/StandaloneDocker.php +++ b/app/Livewire/Destination/New/StandaloneDocker.php @@ -1,6 +1,6 @@ server->standaloneDockers()->where('network', $this->network)->first(); if ($found) { $this->createNetworkAndAttachToProxy(); - $this->emit('error', 'Network already added to this server.'); + $this->dispatch('error', 'Network already added to this server.'); return; } else { $docker = ModelsStandaloneDocker::create([ @@ -70,7 +70,7 @@ class StandaloneDocker extends Component ]); } $this->createNetworkAndAttachToProxy(); - return redirect()->route('destination.show', $docker->uuid); + return $this->redirectRoute('destination.show', $docker->uuid, navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Destination/Show.php b/app/Livewire/Destination/Show.php similarity index 89% rename from app/Http/Livewire/Destination/Show.php rename to app/Livewire/Destination/Show.php index d68537ac4..77495c83e 100644 --- a/app/Http/Livewire/Destination/Show.php +++ b/app/Livewire/Destination/Show.php @@ -1,6 +1,6 @@ contains('network', $network['Name']); }); if ($this->networks->count() === 0) { - $this->emit('success', 'No new networks found.'); + $this->dispatch('success', 'No new networks found.'); } } } diff --git a/app/Http/Livewire/Dev/Compose.php b/app/Livewire/Dev/Compose.php similarity index 95% rename from app/Http/Livewire/Dev/Compose.php rename to app/Livewire/Dev/Compose.php index d3a0ee4e5..ec2c4f54d 100644 --- a/app/Http/Livewire/Dev/Compose.php +++ b/app/Livewire/Dev/Compose.php @@ -1,6 +1,6 @@ user()->email); } - return redirect()->route('dashboard'); + return $this->redirectRoute('dashboard', navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Help.php b/app/Livewire/Help.php similarity index 90% rename from app/Http/Livewire/Help.php rename to app/Livewire/Help.php index 7cb2facef..5e0876f89 100644 --- a/app/Http/Livewire/Help.php +++ b/app/Livewire/Help.php @@ -1,6 +1,6 @@ subject("[HELP - {$subscriptionType}]: {$this->subject}"); send_user_an_email($mail, auth()->user()?->email, 'hi@coollabs.io'); - $this->emit('success', 'Your message has been sent successfully.
We will get in touch with you as soon as possible.'); + $this->dispatch('success', 'Your message has been sent successfully.
We will get in touch with you as soon as possible.'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Modal/EditCompose.php b/app/Livewire/Modal/EditCompose.php similarity index 73% rename from app/Http/Livewire/Modal/EditCompose.php rename to app/Livewire/Modal/EditCompose.php index 2ed129f9d..f2804e5ac 100644 --- a/app/Http/Livewire/Modal/EditCompose.php +++ b/app/Livewire/Modal/EditCompose.php @@ -1,9 +1,8 @@ emit('warning', "Saving new docker compose..."); - $this->emit('saveCompose', $this->service->docker_compose_raw); + $this->dispatch('warning', "Saving new docker compose..."); + $this->dispatch('saveCompose', $this->service->docker_compose_raw); $this->closeModal(); } } diff --git a/app/Http/Livewire/Notifications/DiscordSettings.php b/app/Livewire/Notifications/DiscordSettings.php similarity index 89% rename from app/Http/Livewire/Notifications/DiscordSettings.php rename to app/Livewire/Notifications/DiscordSettings.php index f39ea9175..cf8b116d4 100644 --- a/app/Http/Livewire/Notifications/DiscordSettings.php +++ b/app/Livewire/Notifications/DiscordSettings.php @@ -1,6 +1,6 @@ team->save(); refreshSession(); - $this->emit('success', 'Settings saved.'); + $this->dispatch('success', 'Settings saved.'); } public function sendTestNotification() { $this->team->notify(new Test()); - $this->emit('success', 'Test notification sent.'); + $this->dispatch('success', 'Test notification sent.'); } } diff --git a/app/Http/Livewire/Notifications/EmailSettings.php b/app/Livewire/Notifications/EmailSettings.php similarity index 90% rename from app/Http/Livewire/Notifications/EmailSettings.php rename to app/Livewire/Notifications/EmailSettings.php index 68c0b931b..f3b121851 100644 --- a/app/Http/Livewire/Notifications/EmailSettings.php +++ b/app/Livewire/Notifications/EmailSettings.php @@ -1,6 +1,6 @@ team->save(); refreshSession(); - $this->emit('success', 'Settings saved successfully.'); + $this->dispatch('success', 'Settings saved successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -71,7 +71,7 @@ class EmailSettings extends Component public function sendTestNotification() { $this->team->notify(new Test($this->emails)); - $this->emit('success', 'Test Email sent successfully.'); + $this->dispatch('success', 'Test Email sent successfully.'); } public function instantSaveInstance() { @@ -83,7 +83,7 @@ class EmailSettings extends Component $this->team->resend_enabled = false; $this->team->save(); refreshSession(); - $this->emit('success', 'Settings saved successfully.'); + $this->dispatch('success', 'Settings saved successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -113,7 +113,7 @@ class EmailSettings extends Component { $this->team->save(); refreshSession(); - $this->emit('success', 'Settings saved.'); + $this->dispatch('success', 'Settings saved.'); } public function submit() { @@ -131,7 +131,7 @@ class EmailSettings extends Component ]); $this->team->save(); refreshSession(); - $this->emit('success', 'Settings saved successfully.'); + $this->dispatch('success', 'Settings saved successfully.'); } catch (\Throwable $e) { $this->team->smtp_enabled = false; return handleError($e, $this); @@ -148,7 +148,7 @@ class EmailSettings extends Component ]); $this->team->save(); refreshSession(); - $this->emit('success', 'Settings saved successfully.'); + $this->dispatch('success', 'Settings saved successfully.'); } catch (\Throwable $e) { $this->team->resend_enabled = false; return handleError($e, $this); @@ -173,7 +173,7 @@ class EmailSettings extends Component ]); refreshSession(); $this->team = $team; - $this->emit('success', 'Settings saved.'); + $this->dispatch('success', 'Settings saved.'); return; } if ($settings->resend_enabled) { @@ -184,9 +184,9 @@ class EmailSettings extends Component ]); refreshSession(); $this->team = $team; - $this->emit('success', 'Settings saved.'); + $this->dispatch('success', 'Settings saved.'); return; } - $this->emit('error', 'Instance SMTP/Resend settings are not enabled.'); + $this->dispatch('error', 'Instance SMTP/Resend settings are not enabled.'); } } diff --git a/app/Http/Livewire/Notifications/TelegramSettings.php b/app/Livewire/Notifications/TelegramSettings.php similarity index 92% rename from app/Http/Livewire/Notifications/TelegramSettings.php rename to app/Livewire/Notifications/TelegramSettings.php index 1f4200076..08f1be005 100644 --- a/app/Http/Livewire/Notifications/TelegramSettings.php +++ b/app/Livewire/Notifications/TelegramSettings.php @@ -1,6 +1,6 @@ team->save(); refreshSession(); - $this->emit('success', 'Settings saved.'); + $this->dispatch('success', 'Settings saved.'); } public function sendTestNotification() { $this->team->notify(new Test()); - $this->emit('success', 'Test notification sent.'); + $this->dispatch('success', 'Test notification sent.'); } } diff --git a/app/Http/Livewire/PrivateKey/Change.php b/app/Livewire/PrivateKey/Change.php similarity index 82% rename from app/Http/Livewire/PrivateKey/Change.php rename to app/Livewire/PrivateKey/Change.php index 742212396..6dc7f3e8c 100644 --- a/app/Http/Livewire/PrivateKey/Change.php +++ b/app/Livewire/PrivateKey/Change.php @@ -1,6 +1,6 @@ private_key->isEmpty()) { $this->private_key->delete(); currentTeam()->privateKeys = PrivateKey::where('team_id', currentTeam()->id)->get(); - return redirect()->route('security.private-key.index'); + return $this->redirectRoute('security.private-key.index', navigate: true); } - $this->emit('error', 'This private key is in use and cannot be deleted. Please delete all servers, applications, and GitHub/GitLab apps that use this private key before deleting it.'); + $this->dispatch('error', 'This private key is in use and cannot be deleted. Please delete all servers, applications, and GitHub/GitLab apps that use this private key before deleting it.'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/PrivateKey/Create.php b/app/Livewire/PrivateKey/Create.php similarity index 89% rename from app/Http/Livewire/PrivateKey/Create.php rename to app/Livewire/PrivateKey/Create.php index 4dcaedbe2..430ea995e 100644 --- a/app/Http/Livewire/PrivateKey/Create.php +++ b/app/Livewire/PrivateKey/Create.php @@ -1,6 +1,6 @@ currentTeam()->id ]); if ($this->from === 'server') { - return redirect()->route('server.create'); + return $this->redirectRoute('server.create', navigate: true); } - return redirect()->route('security.private-key.show', ['private_key_uuid' => $private_key->uuid]); + return $this->redirectRoute('security.private-key.show', ['private_key_uuid' => $private_key->uuid], navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Profile/Form.php b/app/Livewire/Profile/Form.php similarity index 68% rename from app/Http/Livewire/Profile/Form.php rename to app/Livewire/Profile/Form.php index 728830702..3d395bf8f 100644 --- a/app/Http/Livewire/Profile/Form.php +++ b/app/Livewire/Profile/Form.php @@ -1,22 +1,17 @@ 'required', - ]; - protected $validationAttributes = [ - 'name' => 'name', - ]; + #[Validate('required')] + public string $name; public function mount() { @@ -30,9 +25,11 @@ class Form extends Component { try { $this->validate(); - User::where('id', $this->userId)->update([ + auth()->user()->update([ 'name' => $this->name, ]); + + $this->dispatch('success', 'Profile updated successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/AddEmpty.php b/app/Livewire/Project/AddEmpty.php similarity index 87% rename from app/Http/Livewire/Project/AddEmpty.php rename to app/Livewire/Project/AddEmpty.php index 0f6c9873e..edaca35f0 100644 --- a/app/Http/Livewire/Project/AddEmpty.php +++ b/app/Livewire/Project/AddEmpty.php @@ -1,6 +1,6 @@ $this->description, 'team_id' => currentTeam()->id, ]); - return redirect()->route('project.show', $project->uuid); + return $this->redirectRoute('project.show', $project->uuid, navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } finally { diff --git a/app/Http/Livewire/Project/AddEnvironment.php b/app/Livewire/Project/AddEnvironment.php similarity index 87% rename from app/Http/Livewire/Project/AddEnvironment.php rename to app/Livewire/Project/AddEnvironment.php index 334dd78f9..5696bc53c 100644 --- a/app/Http/Livewire/Project/AddEnvironment.php +++ b/app/Livewire/Project/AddEnvironment.php @@ -1,6 +1,6 @@ $this->project->id, ]); - return redirect()->route('project.resources', [ + return $this->redirectRoute('project.resources', [ 'project_uuid' => $this->project->uuid, 'environment_name' => $environment->name, - ]); + ], navigate: true); } catch (\Throwable $e) { handleError($e, $this); } finally { diff --git a/app/Http/Livewire/Project/Application/Advanced.php b/app/Livewire/Project/Application/Advanced.php similarity index 82% rename from app/Http/Livewire/Project/Application/Advanced.php rename to app/Livewire/Project/Application/Advanced.php index 656c55717..9ad485f85 100644 --- a/app/Http/Livewire/Project/Application/Advanced.php +++ b/app/Livewire/Project/Application/Advanced.php @@ -1,6 +1,6 @@ application->isLogDrainEnabled()) { if (!$this->application->destination->server->isLogDrainEnabled()) { $this->application->settings->is_log_drain_enabled = false; - $this->emit('error', 'Log drain is not enabled on this server.'); + $this->dispatch('error', 'Log drain is not enabled on this server.'); return; } } if ($this->application->settings->is_force_https_enabled) { - $this->emit('resetDefaultLabels', false); + $this->dispatch('resetDefaultLabels', false); } $this->application->settings->save(); - $this->emit('success', 'Settings saved.'); + $this->dispatch('success', 'Settings saved.'); } public function submit() { if ($this->application->settings->gpu_count && $this->application->settings->gpu_device_ids) { - $this->emit('error', 'You cannot set both GPU count and GPU device IDs.'); + $this->dispatch('error', 'You cannot set both GPU count and GPU device IDs.'); $this->application->settings->gpu_count = null; $this->application->settings->gpu_device_ids = null; $this->application->settings->save(); return; } $this->application->settings->save(); - $this->emit('success', 'Settings saved.'); + $this->dispatch('success', 'Settings saved.'); } public function render() { diff --git a/app/Http/Livewire/Project/Application/Configuration.php b/app/Livewire/Project/Application/Configuration.php similarity index 82% rename from app/Http/Livewire/Project/Application/Configuration.php rename to app/Livewire/Project/Application/Configuration.php index 51d964d37..0022d1693 100644 --- a/app/Http/Livewire/Project/Application/Configuration.php +++ b/app/Livewire/Project/Application/Configuration.php @@ -1,6 +1,6 @@ load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { - return redirect()->route('dashboard'); + return $this->redirectRoute('dashboard', navigate: true); } $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']); if (!$environment) { - return redirect()->route('dashboard'); + return $this->redirectRoute('dashboard', navigate: true); } $application = $environment->applications->where('uuid', request()->route('application_uuid'))->first(); if (!$application) { - return redirect()->route('dashboard'); + return $this->redirectRoute('dashboard', navigate: true); } $this->application = $application; $mainServer = $this->application->destination->server; diff --git a/app/Http/Livewire/Project/Application/DeploymentLogs.php b/app/Livewire/Project/Application/DeploymentLogs.php similarity index 88% rename from app/Http/Livewire/Project/Application/DeploymentLogs.php rename to app/Livewire/Project/Application/DeploymentLogs.php index ac3c4a6cf..d2d07035d 100644 --- a/app/Http/Livewire/Project/Application/DeploymentLogs.php +++ b/app/Livewire/Project/Application/DeploymentLogs.php @@ -1,6 +1,6 @@ emit('deploymentFinished'); + $this->dispatch('deploymentFinished'); $this->application_deployment_queue->refresh(); if (data_get($this->application_deployment_queue, 'status') == 'finished' || data_get($this->application_deployment_queue, 'status') == 'failed') { $this->isKeepAliveOn = false; diff --git a/app/Http/Livewire/Project/Application/DeploymentNavbar.php b/app/Livewire/Project/Application/DeploymentNavbar.php similarity index 97% rename from app/Http/Livewire/Project/Application/DeploymentNavbar.php rename to app/Livewire/Project/Application/DeploymentNavbar.php index 2cee34d11..aa5ea3a2d 100644 --- a/app/Http/Livewire/Project/Application/DeploymentNavbar.php +++ b/app/Livewire/Project/Application/DeploymentNavbar.php @@ -1,6 +1,6 @@ application->settings->is_debug_enabled = !$this->application->settings->is_debug_enabled; $this->application->settings->save(); $this->is_debug_enabled = $this->application->settings->is_debug_enabled; - $this->emit('refreshQueue'); + $this->dispatch('refreshQueue'); } public function cancel() diff --git a/app/Http/Livewire/Project/Application/Deployments.php b/app/Livewire/Project/Application/Deployments.php similarity index 97% rename from app/Http/Livewire/Project/Application/Deployments.php rename to app/Livewire/Project/Application/Deployments.php index 4f4d5ef67..241167a8f 100644 --- a/app/Http/Livewire/Project/Application/Deployments.php +++ b/app/Livewire/Project/Application/Deployments.php @@ -1,6 +1,6 @@ parsedServices = $this->application->parseCompose(); } catch (\Throwable $e) { - $this->emit('error', $e->getMessage()); + $this->dispatch('error', $e->getMessage()); } $this->parsedServiceDomains = $this->application->docker_compose_domains ? json_decode($this->application->docker_compose_domains, true) : []; @@ -121,7 +121,7 @@ class General extends Component public function instantSave() { $this->application->settings->save(); - $this->emit('success', 'Settings saved.'); + $this->dispatch('success', 'Settings saved.'); $this->application->refresh(); if ($this->ports_exposes !== $this->application->ports_exposes) { $this->resetDefaultLabels(false); @@ -134,7 +134,7 @@ class General extends Component return; } ['parsedServices' => $this->parsedServices, 'initialDockerComposeLocation' => $this->initialDockerComposeLocation, 'initialDockerComposePrLocation' => $this->initialDockerComposePrLocation] = $this->application->loadComposeFile($isInit); - $this->emit('success', 'Docker compose file loaded.'); + $this->dispatch('success', 'Docker compose file loaded.'); } catch (\Throwable $e) { $this->application->docker_compose_location = $this->initialDockerComposeLocation; $this->application->docker_compose_pr_location = $this->initialDockerComposePrLocation; @@ -151,7 +151,7 @@ class General extends Component $this->parsedServiceDomains[$serviceName]['domain'] = $domain; $this->application->docker_compose_domains = json_encode($this->parsedServiceDomains); $this->application->save(); - $this->emit('success', 'Domain generated.'); + $this->dispatch('success', 'Domain generated.'); } return $domain; } @@ -196,7 +196,7 @@ class General extends Component public function updatedApplicationFqdn() { $this->resetDefaultLabels(false); - $this->emit('success', 'Labels reseted to default!'); + $this->dispatch('success', 'Labels reseted to default!'); } public function submit($showToaster = true) { @@ -220,6 +220,7 @@ class General extends Component }); $this->application->fqdn = $domains->implode(','); } + if (data_get($this->application, 'dockerfile')) { $port = get_port_from_dockerfile($this->application->dockerfile); if ($port && !$this->application->ports_exposes) { @@ -241,7 +242,7 @@ class General extends Component $this->parsedServices = $this->application->parseCompose(); } $this->application->save(); - $showToaster && $this->emit('success', 'Application settings updated!'); + $showToaster && $this->dispatch('success', 'Application settings updated!'); } catch (\Throwable $e) { return handleError($e, $this); } finally { diff --git a/app/Http/Livewire/Project/Application/Heading.php b/app/Livewire/Project/Application/Heading.php similarity index 79% rename from app/Http/Livewire/Project/Application/Heading.php rename to app/Livewire/Project/Application/Heading.php index 3d5af34da..3db5fc9c4 100644 --- a/app/Http/Livewire/Project/Application/Heading.php +++ b/app/Livewire/Project/Application/Heading.php @@ -1,8 +1,9 @@ user()->currentTeam()->id; + return [ + "echo-private:team.{$teamId},ApplicationStatusChanged" => 'check_status', + ]; + } public function mount() { $this->parameters = get_route_parameters(); } - public function check_status() + public function check_status($showNotification = false) { if ($this->application->destination->server->isFunctional()) { dispatch(new ContainerStatusJob($this->application->destination->server)); @@ -32,6 +39,7 @@ class Heading extends Component } else { dispatch(new ServerStatusJob($this->application->destination->server)); } + if ($showNotification) $this->dispatch('success', 'Application status updated.'); } public function force_deploy_without_cache() @@ -42,7 +50,7 @@ class Heading extends Component public function deployNew() { if ($this->application->build_pack === 'dockercompose' && is_null($this->application->docker_compose_raw)) { - $this->emit('error', 'Please load a Compose file first.'); + $this->dispatch('error', 'Please load a Compose file first.'); return; } $this->setDeploymentUuid(); @@ -52,17 +60,17 @@ class Heading extends Component force_rebuild: false, is_new_deployment: true, ); - return redirect()->route('project.application.deployment', [ + return $this->redirectRoute('project.application.deployment', [ 'project_uuid' => $this->parameters['project_uuid'], 'application_uuid' => $this->parameters['application_uuid'], 'deployment_uuid' => $this->deploymentUuid, 'environment_name' => $this->parameters['environment_name'], - ]); + ], navigate: true); } public function deploy(bool $force_rebuild = false) { if ($this->application->build_pack === 'dockercompose' && is_null($this->application->docker_compose_raw)) { - $this->emit('error', 'Please load a Compose file first.'); + $this->dispatch('error', 'Please load a Compose file first.'); return; } $this->setDeploymentUuid(); @@ -71,12 +79,12 @@ class Heading extends Component deployment_uuid: $this->deploymentUuid, force_rebuild: $force_rebuild, ); - return redirect()->route('project.application.deployment', [ + $this->redirectRoute('project.application.deployment', [ 'project_uuid' => $this->parameters['project_uuid'], 'application_uuid' => $this->parameters['application_uuid'], 'deployment_uuid' => $this->deploymentUuid, 'environment_name' => $this->parameters['environment_name'], - ]); + ], navigate: true); } protected function setDeploymentUuid() @@ -101,12 +109,12 @@ class Heading extends Component restart_only: true, is_new_deployment: true, ); - return redirect()->route('project.application.deployment', [ + return $this->redirectRoute('project.application.deployment', [ 'project_uuid' => $this->parameters['project_uuid'], 'application_uuid' => $this->parameters['application_uuid'], 'deployment_uuid' => $this->deploymentUuid, 'environment_name' => $this->parameters['environment_name'], - ]); + ], navigate: true); } public function restart() { @@ -116,11 +124,11 @@ class Heading extends Component deployment_uuid: $this->deploymentUuid, restart_only: true, ); - return redirect()->route('project.application.deployment', [ + return $this->redirectRoute('project.application.deployment', [ 'project_uuid' => $this->parameters['project_uuid'], 'application_uuid' => $this->parameters['application_uuid'], 'deployment_uuid' => $this->deploymentUuid, 'environment_name' => $this->parameters['environment_name'], - ]); + ], navigate: true); } } diff --git a/app/Http/Livewire/Project/Application/Preview/Form.php b/app/Livewire/Project/Application/Preview/Form.php similarity index 91% rename from app/Http/Livewire/Project/Application/Preview/Form.php rename to app/Livewire/Project/Application/Preview/Form.php index fb71e5e47..0da8b1d76 100644 --- a/app/Http/Livewire/Project/Application/Preview/Form.php +++ b/app/Livewire/Project/Application/Preview/Form.php @@ -1,6 +1,6 @@ validate(); $this->application->preview_url_template = str_replace(' ', '', $this->application->preview_url_template); $this->application->save(); - $this->emit('success', 'Preview url template updated successfully.'); + $this->dispatch('success', 'Preview url template updated successfully.'); $this->generate_real_url(); } } diff --git a/app/Http/Livewire/Project/Application/Previews.php b/app/Livewire/Project/Application/Previews.php similarity index 95% rename from app/Http/Livewire/Project/Application/Previews.php rename to app/Livewire/Project/Application/Previews.php index effdd7f7c..0fc1acf5e 100644 --- a/app/Http/Livewire/Project/Application/Previews.php +++ b/app/Livewire/Project/Application/Previews.php @@ -1,6 +1,6 @@ route('project.application.deployment', [ + return $this->redirectRoute('project.application.deployment', [ 'project_uuid' => $this->parameters['project_uuid'], 'application_uuid' => $this->parameters['application_uuid'], 'deployment_uuid' => $this->deployment_uuid, 'environment_name' => $this->parameters['environment_name'], - ]); + ], navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/Application/Rollback.php b/app/Livewire/Project/Application/Rollback.php similarity index 92% rename from app/Http/Livewire/Project/Application/Rollback.php rename to app/Livewire/Project/Application/Rollback.php index 4c363421d..4c3630877 100644 --- a/app/Http/Livewire/Project/Application/Rollback.php +++ b/app/Livewire/Project/Application/Rollback.php @@ -1,6 +1,6 @@ route('project.application.deployment', [ + return $this->redirectRoute('project.application.deployment', [ 'project_uuid' => $this->parameters['project_uuid'], 'application_uuid' => $this->parameters['application_uuid'], 'deployment_uuid' => $deployment_uuid, 'environment_name' => $this->parameters['environment_name'], - ]); + ], navigate: true); } public function loadImages($showToast = false) @@ -66,7 +65,7 @@ class Rollback extends Component ]; })->toArray(); } - $showToast && $this->emit('success', 'Images loaded.'); + $showToast && $this->dispatch('success', 'Images loaded.'); return []; } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Http/Livewire/Project/Application/Source.php b/app/Livewire/Project/Application/Source.php similarity index 92% rename from app/Http/Livewire/Project/Application/Source.php rename to app/Livewire/Project/Application/Source.php index 801d533aa..c9907c8c4 100644 --- a/app/Http/Livewire/Project/Application/Source.php +++ b/app/Livewire/Project/Application/Source.php @@ -1,6 +1,6 @@ application->git_commit_sha = 'HEAD'; } $this->application->save(); - $this->emit('success', 'Application source updated!'); + $this->dispatch('success', 'Application source updated!'); } } diff --git a/app/Http/Livewire/Project/CloneProject.php b/app/Livewire/Project/CloneProject.php similarity index 98% rename from app/Http/Livewire/Project/CloneProject.php rename to app/Livewire/Project/CloneProject.php index 48852b7ce..3a6a1db6f 100644 --- a/app/Http/Livewire/Project/CloneProject.php +++ b/app/Livewire/Project/CloneProject.php @@ -1,6 +1,6 @@ parse(); } - return redirect()->route('project.resources', [ + return $this->redirectRoute('project.resources', [ 'project_uuid' => $newProject->uuid, 'environment_name' => $newEnvironment->name, - ]); + ], navigate: true); } catch (\Exception $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/Database/BackupEdit.php b/app/Livewire/Project/Database/BackupEdit.php similarity index 86% rename from app/Http/Livewire/Project/Database/BackupEdit.php rename to app/Livewire/Project/Database/BackupEdit.php index 813016dba..3a9a83dc4 100644 --- a/app/Http/Livewire/Project/Database/BackupEdit.php +++ b/app/Livewire/Project/Database/BackupEdit.php @@ -1,6 +1,6 @@ withoutQueryParameter('selectedBackupId'); $url = $url->withFragment('backups'); $url = $url->getPath() . "#{$url->getFragment()}"; - return redirect()->to($url); + return $this->redirect($url,navigate: true); } else { - redirect()->route('project.database.backups.all', $this->parameters); + return $this->redirectRoute('project.database.backups.all', $this->parameters); } } @@ -63,9 +63,9 @@ class BackupEdit extends Component $this->custom_validate(); $this->backup->save(); $this->backup->refresh(); - $this->emit('success', 'Backup updated successfully'); + $this->dispatch('success', 'Backup updated successfully'); } catch (\Throwable $e) { - $this->emit('error', $e->getMessage()); + $this->dispatch('error', $e->getMessage()); } } @@ -90,9 +90,9 @@ class BackupEdit extends Component } $this->backup->save(); $this->backup->refresh(); - $this->emit('success', 'Backup updated successfully'); + $this->dispatch('success', 'Backup updated successfully'); } catch (\Throwable $e) { - $this->emit('error', $e->getMessage()); + $this->dispatch('error', $e->getMessage()); } } } diff --git a/app/Http/Livewire/Project/Database/BackupExecutions.php b/app/Livewire/Project/Database/BackupExecutions.php similarity index 78% rename from app/Http/Livewire/Project/Database/BackupExecutions.php rename to app/Livewire/Project/Database/BackupExecutions.php index 41a1cfbd6..a41336bda 100644 --- a/app/Http/Livewire/Project/Database/BackupExecutions.php +++ b/app/Livewire/Project/Database/BackupExecutions.php @@ -1,6 +1,6 @@ user()->id; + return [ + "echo-private:team.{$userId},BackupCreated" => 'refreshBackupExecutions', + "refreshBackupExecutions", + "deleteBackup" + ]; + } public function deleteBackup($exeuctionId) { $execution = $this->backup->executions()->where('id', $exeuctionId)->first(); if (is_null($execution)) { - $this->emit('error', 'Backup execution not found.'); + $this->dispatch('error', 'Backup execution not found.'); return; } if ($execution->scheduledDatabaseBackup->database->getMorphClass() === 'App\Models\ServiceDatabase') { @@ -25,15 +33,15 @@ class BackupExecutions extends Component delete_backup_locally($execution->filename, $execution->scheduledDatabaseBackup->database->destination->server); } $execution->delete(); - $this->emit('success', 'Backup deleted successfully.'); - $this->emit('refreshBackupExecutions'); + $this->dispatch('success', 'Backup deleted successfully.'); + $this->dispatch('refreshBackupExecutions'); } public function download($exeuctionId) { try { $execution = $this->backup->executions()->where('id', $exeuctionId)->first(); if (is_null($execution)) { - $this->emit('error', 'Backup execution not found.'); + $this->dispatch('error', 'Backup execution not found.'); return; } $filename = data_get($execution, 'filename'); diff --git a/app/Http/Livewire/Project/Database/BackupNow.php b/app/Livewire/Project/Database/BackupNow.php similarity index 65% rename from app/Http/Livewire/Project/Database/BackupNow.php rename to app/Livewire/Project/Database/BackupNow.php index 35bd8318d..988f382a0 100644 --- a/app/Http/Livewire/Project/Database/BackupNow.php +++ b/app/Livewire/Project/Database/BackupNow.php @@ -1,6 +1,6 @@ backup )); - $this->emit('success', 'Backup queued. It will be available in a few minutes.'); + $this->dispatch('success', 'Backup queued. It will be available in a few minutes.'); } } diff --git a/app/Http/Livewire/Project/Database/CreateScheduledBackup.php b/app/Livewire/Project/Database/CreateScheduledBackup.php similarity index 89% rename from app/Http/Livewire/Project/Database/CreateScheduledBackup.php rename to app/Livewire/Project/Database/CreateScheduledBackup.php index a36266a6c..e58ea9df3 100644 --- a/app/Http/Livewire/Project/Database/CreateScheduledBackup.php +++ b/app/Livewire/Project/Database/CreateScheduledBackup.php @@ -1,6 +1,6 @@ validate(); $isValid = validate_cron_expression($this->frequency); if (!$isValid) { - $this->emit('error', 'Invalid Cron / Human expression.'); + $this->dispatch('error', 'Invalid Cron / Human expression.'); return; } $payload = [ @@ -57,9 +57,9 @@ class CreateScheduledBackup extends Component $databaseBackup = ScheduledDatabaseBackup::create($payload); if ($this->database->getMorphClass() === 'App\Models\ServiceDatabase') { - $this->emit('refreshScheduledBackups', $databaseBackup->id); + $this->dispatch('refreshScheduledBackups', $databaseBackup->id); } else { - $this->emit('refreshScheduledBackups'); + $this->dispatch('refreshScheduledBackups'); } } catch (\Throwable $e) { handleError($e, $this); diff --git a/app/Http/Livewire/Project/Database/Heading.php b/app/Livewire/Project/Database/Heading.php similarity index 67% rename from app/Http/Livewire/Project/Database/Heading.php rename to app/Livewire/Project/Database/Heading.php index 7b14e5368..76b36a5ba 100644 --- a/app/Http/Livewire/Project/Database/Heading.php +++ b/app/Livewire/Project/Database/Heading.php @@ -1,6 +1,6 @@ user()->id; + return [ + "echo-private:user.{$userId},DatabaseStatusChanged" => 'activityFinished', + ]; + } public function activityFinished() { $this->database->update([ 'started_at' => now(), ]); - $this->emit('refresh'); + $this->dispatch('refresh'); $this->check_status(); } - public function check_status() + public function check_status($showNotification = false) { dispatch_sync(new ContainerStatusJob($this->database->destination->server)); $this->database->refresh(); + if ($showNotification) $this->dispatch('success', 'Database status updated.'); } public function mount() @@ -50,19 +58,19 @@ class Heading extends Component { if ($this->database->type() === 'standalone-postgresql') { $activity = StartPostgresql::run($this->database); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('newMonitorActivity', $activity->id); } else if ($this->database->type() === 'standalone-redis') { $activity = StartRedis::run($this->database); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('newMonitorActivity', $activity->id); } else if ($this->database->type() === 'standalone-mongodb') { $activity = StartMongodb::run($this->database); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('newMonitorActivity', $activity->id); } else if ($this->database->type() === 'standalone-mysql') { $activity = StartMysql::run($this->database); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('newMonitorActivity', $activity->id); } else if ($this->database->type() === 'standalone-mariadb') { $activity = StartMariadb::run($this->database); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('newMonitorActivity', $activity->id); } } } diff --git a/app/Http/Livewire/Project/Database/InitScript.php b/app/Livewire/Project/Database/InitScript.php similarity index 84% rename from app/Http/Livewire/Project/Database/InitScript.php rename to app/Livewire/Project/Database/InitScript.php index a371bb33e..2014fba3b 100644 --- a/app/Http/Livewire/Project/Database/InitScript.php +++ b/app/Livewire/Project/Database/InitScript.php @@ -1,7 +1,8 @@ script['index'] = $this->index; $this->script['content'] = $this->content; $this->script['filename'] = $this->filename; - $this->emitUp('save_init_script', $this->script); + $this->dispatch('save_init_script', $this->script); } catch (Exception $e) { return handleError($e, $this); } @@ -42,6 +43,6 @@ class InitScript extends Component public function delete() { - $this->emitUp('delete_init_script', $this->script); + $this->dispatch('delete_init_script', $this->script); } } diff --git a/app/Http/Livewire/Project/Database/Mariadb/General.php b/app/Livewire/Project/Database/Mariadb/General.php similarity index 82% rename from app/Http/Livewire/Project/Database/Mariadb/General.php rename to app/Livewire/Project/Database/Mariadb/General.php index 455f1b4ca..305633cba 100644 --- a/app/Http/Livewire/Project/Database/Mariadb/General.php +++ b/app/Livewire/Project/Database/Mariadb/General.php @@ -1,6 +1,6 @@ database->destination->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; - $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); return; } $this->database->save(); - $this->emit('success', 'Database updated successfully.'); - $this->emit('success', 'You need to restart the service for the changes to take effect.'); + $this->dispatch('success', 'Database updated successfully.'); + $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); } catch (Exception $e) { return handleError($e, $this); } @@ -73,7 +73,7 @@ class General extends Component } $this->validate(); $this->database->save(); - $this->emit('success', 'Database updated successfully.'); + $this->dispatch('success', 'Database updated successfully.'); } catch (Exception $e) { return handleError($e, $this); } @@ -82,23 +82,23 @@ class General extends Component { try { if ($this->database->is_public && !$this->database->public_port) { - $this->emit('error', 'Public port is required.'); + $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; return; } if ($this->database->is_public) { if (!str($this->database->status)->startsWith('running')) { - $this->emit('error', 'Database must be started to be publicly accessible.'); + $this->dispatch('error', 'Database must be started to be publicly accessible.'); $this->database->is_public = false; return; } StartDatabaseProxy::run($this->database); $this->db_url_public = $this->database->getDbUrl(); - $this->emit('success', 'Database is now publicly accessible.'); + $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->db_url_public = null; - $this->emit('success', 'Database is no longer publicly accessible.'); + $this->dispatch('success', 'Database is no longer publicly accessible.'); } $this->database->save(); } catch (\Throwable $e) { diff --git a/app/Http/Livewire/Project/Database/Mongodb/General.php b/app/Livewire/Project/Database/Mongodb/General.php similarity index 82% rename from app/Http/Livewire/Project/Database/Mongodb/General.php rename to app/Livewire/Project/Database/Mongodb/General.php index 84669a019..70f54cc3f 100644 --- a/app/Http/Livewire/Project/Database/Mongodb/General.php +++ b/app/Livewire/Project/Database/Mongodb/General.php @@ -1,6 +1,6 @@ database->destination->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; - $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); return; } $this->database->save(); - $this->emit('success', 'Database updated successfully.'); - $this->emit('success', 'You need to restart the service for the changes to take effect.'); + $this->dispatch('success', 'Database updated successfully.'); + $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); } catch (Exception $e) { return handleError($e, $this); } @@ -75,7 +75,7 @@ class General extends Component } $this->validate(); $this->database->save(); - $this->emit('success', 'Database updated successfully.'); + $this->dispatch('success', 'Database updated successfully.'); } catch (Exception $e) { return handleError($e, $this); } @@ -84,23 +84,23 @@ class General extends Component { try { if ($this->database->is_public && !$this->database->public_port) { - $this->emit('error', 'Public port is required.'); + $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; return; } if ($this->database->is_public) { if (!str($this->database->status)->startsWith('running')) { - $this->emit('error', 'Database must be started to be publicly accessible.'); + $this->dispatch('error', 'Database must be started to be publicly accessible.'); $this->database->is_public = false; return; } StartDatabaseProxy::run($this->database); $this->db_url_public = $this->database->getDbUrl(); - $this->emit('success', 'Database is now publicly accessible.'); + $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->db_url_public = null; - $this->emit('success', 'Database is no longer publicly accessible.'); + $this->dispatch('success', 'Database is no longer publicly accessible.'); } $this->database->save(); } catch (\Throwable $e) { diff --git a/app/Http/Livewire/Project/Database/Mysql/General.php b/app/Livewire/Project/Database/Mysql/General.php similarity index 82% rename from app/Http/Livewire/Project/Database/Mysql/General.php rename to app/Livewire/Project/Database/Mysql/General.php index c63cea293..98b16a112 100644 --- a/app/Http/Livewire/Project/Database/Mysql/General.php +++ b/app/Livewire/Project/Database/Mysql/General.php @@ -1,6 +1,6 @@ database->destination->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; - $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); return; } $this->database->save(); - $this->emit('success', 'Database updated successfully.'); - $this->emit('success', 'You need to restart the service for the changes to take effect.'); + $this->dispatch('success', 'Database updated successfully.'); + $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); } catch (Exception $e) { return handleError($e, $this); } @@ -74,7 +74,7 @@ class General extends Component } $this->validate(); $this->database->save(); - $this->emit('success', 'Database updated successfully.'); + $this->dispatch('success', 'Database updated successfully.'); } catch (Exception $e) { return handleError($e, $this); } @@ -83,23 +83,23 @@ class General extends Component { try { if ($this->database->is_public && !$this->database->public_port) { - $this->emit('error', 'Public port is required.'); + $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; return; } if ($this->database->is_public) { if (!str($this->database->status)->startsWith('running')) { - $this->emit('error', 'Database must be started to be publicly accessible.'); + $this->dispatch('error', 'Database must be started to be publicly accessible.'); $this->database->is_public = false; return; } StartDatabaseProxy::run($this->database); $this->db_url_public = $this->database->getDbUrl(); - $this->emit('success', 'Database is now publicly accessible.'); + $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->db_url_public = null; - $this->emit('success', 'Database is no longer publicly accessible.'); + $this->dispatch('success', 'Database is no longer publicly accessible.'); } $this->database->save(); } catch (\Throwable $e) { diff --git a/app/Http/Livewire/Project/Database/Postgresql/General.php b/app/Livewire/Project/Database/Postgresql/General.php similarity index 84% rename from app/Http/Livewire/Project/Database/Postgresql/General.php rename to app/Livewire/Project/Database/Postgresql/General.php index 1804953ee..6fa5df97c 100644 --- a/app/Http/Livewire/Project/Database/Postgresql/General.php +++ b/app/Livewire/Project/Database/Postgresql/General.php @@ -1,6 +1,6 @@ database->destination->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; - $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); return; } $this->database->save(); - $this->emit('success', 'Database updated successfully.'); - $this->emit('success', 'You need to restart the service for the changes to take effect.'); + $this->dispatch('success', 'Database updated successfully.'); + $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); } catch (Exception $e) { return handleError($e, $this); } @@ -76,23 +76,23 @@ class General extends Component { try { if ($this->database->is_public && !$this->database->public_port) { - $this->emit('error', 'Public port is required.'); + $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; return; } if ($this->database->is_public) { if (!str($this->database->status)->startsWith('running')) { - $this->emit('error', 'Database must be started to be publicly accessible.'); + $this->dispatch('error', 'Database must be started to be publicly accessible.'); $this->database->is_public = false; return; } StartDatabaseProxy::run($this->database); $this->db_url_public = $this->database->getDbUrl(); - $this->emit('success', 'Database is now publicly accessible.'); + $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->db_url_public = null; - $this->emit('success', 'Database is no longer publicly accessible.'); + $this->dispatch('success', 'Database is no longer publicly accessible.'); } $this->database->save(); } catch (\Throwable $e) { @@ -105,7 +105,7 @@ class General extends Component $this->database->init_scripts = filter($this->database->init_scripts, fn ($s) => $s['filename'] !== $script['filename']); $this->database->init_scripts = array_merge($this->database->init_scripts, [$script]); $this->database->save(); - $this->emit('success', 'Init script saved successfully.'); + $this->dispatch('success', 'Init script saved successfully.'); } public function delete_init_script($script) @@ -116,7 +116,7 @@ class General extends Component $this->database->init_scripts = $collection->filter(fn ($s) => $s['filename'] !== $script['filename'])->toArray(); $this->database->save(); $this->refresh(); - $this->emit('success', 'Init script deleted successfully.'); + $this->dispatch('success', 'Init script deleted successfully.'); return; } } @@ -134,7 +134,7 @@ class General extends Component ]); $found = collect($this->database->init_scripts)->firstWhere('filename', $this->new_filename); if ($found) { - $this->emit('error', 'Filename already exists.'); + $this->dispatch('error', 'Filename already exists.'); return; } if (!isset($this->database->init_scripts)) { @@ -148,7 +148,7 @@ class General extends Component ] ]); $this->database->save(); - $this->emit('success', 'Init script added successfully.'); + $this->dispatch('success', 'Init script added successfully.'); $this->new_content = ''; $this->new_filename = ''; } @@ -161,7 +161,7 @@ class General extends Component } $this->validate(); $this->database->save(); - $this->emit('success', 'Database updated successfully.'); + $this->dispatch('success', 'Database updated successfully.'); } catch (Exception $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/Database/Redis/General.php b/app/Livewire/Project/Database/Redis/General.php similarity index 81% rename from app/Http/Livewire/Project/Database/Redis/General.php rename to app/Livewire/Project/Database/Redis/General.php index c2a28eef8..c328a6195 100644 --- a/app/Http/Livewire/Project/Database/Redis/General.php +++ b/app/Livewire/Project/Database/Redis/General.php @@ -1,6 +1,6 @@ database->destination->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; - $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); return; } $this->database->save(); - $this->emit('success', 'Database updated successfully.'); - $this->emit('success', 'You need to restart the service for the changes to take effect.'); + $this->dispatch('success', 'Database updated successfully.'); + $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); } catch (Exception $e) { return handleError($e, $this); } @@ -66,7 +66,7 @@ class General extends Component $this->database->redis_conf = null; } $this->database->save(); - $this->emit('success', 'Database updated successfully.'); + $this->dispatch('success', 'Database updated successfully.'); } catch (Exception $e) { return handleError($e, $this); } @@ -75,23 +75,23 @@ class General extends Component { try { if ($this->database->is_public && !$this->database->public_port) { - $this->emit('error', 'Public port is required.'); + $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; return; } if ($this->database->is_public) { if (!str($this->database->status)->startsWith('running')) { - $this->emit('error', 'Database must be started to be publicly accessible.'); + $this->dispatch('error', 'Database must be started to be publicly accessible.'); $this->database->is_public = false; return; } StartDatabaseProxy::run($this->database); $this->db_url_public = $this->database->getDbUrl(); - $this->emit('success', 'Database is now publicly accessible.'); + $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->db_url_public = null; - $this->emit('success', 'Database is no longer publicly accessible.'); + $this->dispatch('success', 'Database is no longer publicly accessible.'); } $this->database->save(); } catch (\Throwable $e) { diff --git a/app/Http/Livewire/Project/Database/ScheduledBackups.php b/app/Livewire/Project/Database/ScheduledBackups.php similarity index 92% rename from app/Http/Livewire/Project/Database/ScheduledBackups.php rename to app/Livewire/Project/Database/ScheduledBackups.php index ec20b1adb..2fc4d069e 100644 --- a/app/Http/Livewire/Project/Database/ScheduledBackups.php +++ b/app/Livewire/Project/Database/ScheduledBackups.php @@ -1,6 +1,6 @@ database->scheduledBackups->find($scheduled_backup_id)->delete(); - $this->emit('success', 'Scheduled backup deleted successfully.'); + $this->dispatch('success', 'Scheduled backup deleted successfully.'); $this->refreshScheduledBackups(); } diff --git a/app/Http/Livewire/Project/DeleteEnvironment.php b/app/Livewire/Project/DeleteEnvironment.php similarity index 67% rename from app/Http/Livewire/Project/DeleteEnvironment.php rename to app/Livewire/Project/DeleteEnvironment.php index 0b6254b3b..3b64df0c0 100644 --- a/app/Http/Livewire/Project/DeleteEnvironment.php +++ b/app/Livewire/Project/DeleteEnvironment.php @@ -1,6 +1,6 @@ environment_id); if ($environment->isEmpty()) { $environment->delete(); - return redirect()->route('project.show', ['project_uuid' => $this->parameters['project_uuid']]); + return $this->redirectRoute('project.show', ['project_uuid' => $this->parameters['project_uuid']], navigate: true); } - return $this->emit('error', 'Environment has defined resources, please delete them first.'); + return $this->dispatch('error', 'Environment has defined resources, please delete them first.'); } } diff --git a/app/Http/Livewire/Project/DeleteProject.php b/app/Livewire/Project/DeleteProject.php similarity index 72% rename from app/Http/Livewire/Project/DeleteProject.php rename to app/Livewire/Project/DeleteProject.php index 5bbfea17a..2c51509e1 100644 --- a/app/Http/Livewire/Project/DeleteProject.php +++ b/app/Livewire/Project/DeleteProject.php @@ -1,6 +1,6 @@ project_id); if ($project->applications->count() > 0) { - return $this->emit('error', 'Project has resources defined, please delete them first.'); + return $this->dispatch('error', 'Project has resources defined, please delete them first.'); } $project->delete(); - return redirect()->route('projects'); + return $this->redirectRoute('projects', navigate: true); } } diff --git a/app/Http/Livewire/Project/Edit.php b/app/Livewire/Project/Edit.php similarity index 86% rename from app/Http/Livewire/Project/Edit.php rename to app/Livewire/Project/Edit.php index 94b6979ae..d08aa3e59 100644 --- a/app/Http/Livewire/Project/Edit.php +++ b/app/Livewire/Project/Edit.php @@ -1,6 +1,6 @@ validate(); try { $this->project->save(); - $this->emit('saved'); + $this->dispatch('saved'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/New/DockerCompose.php b/app/Livewire/Project/New/DockerCompose.php similarity index 95% rename from app/Http/Livewire/Project/New/DockerCompose.php rename to app/Livewire/Project/New/DockerCompose.php index 280167bb1..70699a854 100644 --- a/app/Http/Livewire/Project/New/DockerCompose.php +++ b/app/Livewire/Project/New/DockerCompose.php @@ -1,6 +1,6 @@ parse(isNew: true); - return redirect()->route('project.service.configuration', [ + return $this->redirectRoute('project.service.configuration', [ 'service_uuid' => $service->uuid, 'environment_name' => $environment->name, 'project_uuid' => $project->uuid, ]); + } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/New/DockerImage.php b/app/Livewire/Project/New/DockerImage.php similarity index 94% rename from app/Http/Livewire/Project/New/DockerImage.php rename to app/Livewire/Project/New/DockerImage.php index 1081f3401..5479bca51 100644 --- a/app/Http/Livewire/Project/New/DockerImage.php +++ b/app/Livewire/Project/New/DockerImage.php @@ -1,6 +1,6 @@ 'docker-image-' . $application->uuid, 'fqdn' => $fqdn ]); - - redirect()->route('project.application.configuration', [ + return $this->redirectRoute('project.application.configuration', [ 'application_uuid' => $application->uuid, 'environment_name' => $environment->name, 'project_uuid' => $project->uuid, - ]); + ], navigate: true); } public function render() { diff --git a/app/Http/Livewire/Project/New/EmptyProject.php b/app/Livewire/Project/New/EmptyProject.php similarity index 62% rename from app/Http/Livewire/Project/New/EmptyProject.php rename to app/Livewire/Project/New/EmptyProject.php index 9dba4338b..559f774b5 100644 --- a/app/Http/Livewire/Project/New/EmptyProject.php +++ b/app/Livewire/Project/New/EmptyProject.php @@ -1,6 +1,6 @@ generate_random_name(), 'team_id' => currentTeam()->id, ]); - return redirect()->route('project.show', ['project_uuid' => $project->uuid, 'environment_name' => 'production']); + return $this->redirectRoute('project.show', ['project_uuid' => $project->uuid, 'environment_name' => 'production'], navigate: true); } } diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepository.php b/app/Livewire/Project/New/GithubPrivateRepository.php similarity index 94% rename from app/Http/Livewire/Project/New/GithubPrivateRepository.php rename to app/Livewire/Project/New/GithubPrivateRepository.php index 91e9a806a..376f7d646 100644 --- a/app/Http/Livewire/Project/New/GithubPrivateRepository.php +++ b/app/Livewire/Project/New/GithubPrivateRepository.php @@ -1,6 +1,6 @@ token)->get("{$this->github_app->api_url}/installation/repositories?per_page=100&page={$this->page}"); $json = $response->json(); if ($response->status() !== 200) { - return $this->emit('error', $json['message']); + return $this->dispatch('error', $json['message']); } if ($json['total_count'] === 0) { @@ -104,7 +104,7 @@ class GithubPrivateRepository extends Component $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/repos/{$this->selected_repository_owner}/{$this->selected_repository_repo}/branches?per_page=100&page={$this->page}"); $json = $response->json(); if ($response->status() !== 200) { - return $this->emit('error', $json['message']); + return $this->dispatch('error', $json['message']); } $this->total_branches_count = count($json); @@ -151,11 +151,11 @@ class GithubPrivateRepository extends Component $application->name = generate_application_name($this->selected_repository_owner . '/' . $this->selected_repository_repo, $this->selected_branch_name, $application->uuid); $application->save(); - redirect()->route('project.application.configuration', [ + return $this->redirectRoute('project.application.configuration', [ 'application_uuid' => $application->uuid, 'environment_name' => $environment->name, 'project_uuid' => $project->uuid, - ]); + ], navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } @@ -170,6 +170,6 @@ class GithubPrivateRepository extends Component $this->port = 3000; $this->publish_directory = null; } - $this->emit('success', 'Application settings updated!'); + $this->dispatch('success', 'Application settings updated!'); } } diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php b/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php similarity index 97% rename from app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php rename to app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php index e8974436a..6d270ef27 100644 --- a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php +++ b/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php @@ -1,6 +1,6 @@ name = generate_random_name($application->uuid); $application->save(); - return redirect()->route('project.application.configuration', [ - 'project_uuid' => $project->uuid, - 'environment_name' => $environment->name, + return $this->redirectRoute('project.application.configuration', [ 'application_uuid' => $application->uuid, - ]); + 'environment_name' => $environment->name, + 'project_uuid' => $project->uuid, + ], navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/New/PublicGitRepository.php b/app/Livewire/Project/New/PublicGitRepository.php similarity index 96% rename from app/Http/Livewire/Project/New/PublicGitRepository.php rename to app/Livewire/Project/New/PublicGitRepository.php index f1f4e9833..f7390ceaa 100644 --- a/app/Http/Livewire/Project/New/PublicGitRepository.php +++ b/app/Livewire/Project/New/PublicGitRepository.php @@ -1,6 +1,6 @@ port = 3000; $this->publish_directory = null; } - $this->emit('success', 'Application settings updated!'); + $this->dispatch('success', 'Application settings updated!'); } public function load_any_git() { @@ -184,11 +184,11 @@ class PublicGitRepository extends Component $application->fqdn = $fqdn; $application->save(); - return redirect()->route('project.application.configuration', [ - 'project_uuid' => $project->uuid, - 'environment_name' => $environment->name, + return $this->redirectRoute('project.application.configuration', [ 'application_uuid' => $application->uuid, - ]); + 'environment_name' => $environment->name, + 'project_uuid' => $project->uuid, + ], navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/New/Select.php b/app/Livewire/Project/New/Select.php similarity index 90% rename from app/Http/Livewire/Project/New/Select.php rename to app/Livewire/Project/New/Select.php index 13fbb8886..856a9b9a9 100644 --- a/app/Http/Livewire/Project/New/Select.php +++ b/app/Livewire/Project/New/Select.php @@ -1,6 +1,6 @@ search) $this->loadServices(); + $this->loadServices(); return view('livewire.project.new.select'); } public function updatedSelectedEnvironment() { - return redirect()->route('project.resources.new', [ + return $this->redirectRoute('project.resources.new', [ 'project_uuid' => $this->parameters['project_uuid'], 'environment_name' => $this->selectedEnvironment, - ]); + ], navigate: true); } // public function addExistingPostgresql() // { // try { // instantCommand("psql {$this->existingPostgresqlUrl} -c 'SELECT 1'"); - // $this->emit('success', 'Successfully connected to the database.'); + // $this->dispatch('success', 'Successfully connected to the database.'); // } catch (\Throwable $e) { // return handleError($e, $this); // } @@ -89,7 +89,7 @@ class Select extends Component $this->services = $this->allServices->filter(function ($service, $key) { return str_contains(strtolower($key), strtolower($this->search)); });; - $this->emit('success', 'Successfully loaded services.'); + $this->dispatch('success', 'Successfully loaded services.'); } } catch (\Throwable $e) { return handleError($e, $this); @@ -109,9 +109,6 @@ class Select extends Component if (count($this->servers) === 1) { $server = $this->servers->first(); $this->setServer($server); - if (count($server->destinations()) === 1) { - $this->setDestination($server->destinations()->first()->uuid); - } } if (!is_null($this->server)) { $foundServer = $this->servers->where('id', $this->server)->first(); @@ -133,7 +130,7 @@ class Select extends Component public function setDestination(string $destination_uuid) { $this->destination_uuid = $destination_uuid; - redirect()->route('project.resources.new', [ + return redirect()->route('project.resources.new', [ 'project_uuid' => $this->parameters['project_uuid'], 'environment_name' => $this->parameters['environment_name'], 'type' => $this->type, diff --git a/app/Http/Livewire/Project/New/SimpleDockerfile.php b/app/Livewire/Project/New/SimpleDockerfile.php similarity index 94% rename from app/Http/Livewire/Project/New/SimpleDockerfile.php rename to app/Livewire/Project/New/SimpleDockerfile.php index 07a9ec88a..7015af6ed 100644 --- a/app/Http/Livewire/Project/New/SimpleDockerfile.php +++ b/app/Livewire/Project/New/SimpleDockerfile.php @@ -1,6 +1,6 @@ $fqdn ]); - redirect()->route('project.application.configuration', [ + return $this->redirectRoute('project.application.configuration', [ 'application_uuid' => $application->uuid, 'environment_name' => $environment->name, 'project_uuid' => $project->uuid, - ]); + ], navigate: true); } } diff --git a/app/Http/Livewire/Project/Service/Application.php b/app/Livewire/Project/Service/Application.php similarity index 73% rename from app/Http/Livewire/Project/Service/Application.php rename to app/Livewire/Project/Service/Application.php index 622b1e0e2..1adacf555 100644 --- a/app/Http/Livewire/Project/Service/Application.php +++ b/app/Livewire/Project/Service/Application.php @@ -1,6 +1,6 @@ application->service->destination->server->isLogDrainEnabled()) { $this->application->is_log_drain_enabled = false; - $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); return; } $this->application->save(); - $this->emit('success', 'You need to restart the service for the changes to take effect.'); + $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); } public function delete() { try { $this->application->delete(); - $this->emit('success', 'Application deleted successfully.'); - return redirect()->route('project.service.configuration', $this->parameters); + $this->dispatch('success', 'Application deleted successfully.'); + return $this->redirectRoute('project.service.configuration', $this->parameters, navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } @@ -56,11 +56,11 @@ class Application extends Component $this->validate(); $this->application->save(); updateCompose($this->application); - $this->emit('success', 'Application saved successfully.'); + $this->dispatch('success', 'Application saved successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } finally { - $this->emit('generateDockerCompose'); + $this->dispatch('generateDockerCompose'); } } } diff --git a/app/Http/Livewire/Project/Service/Database.php b/app/Livewire/Project/Service/Database.php similarity index 77% rename from app/Http/Livewire/Project/Service/Database.php rename to app/Livewire/Project/Service/Database.php index 6bf6098ad..e7be1ff2e 100644 --- a/app/Http/Livewire/Project/Service/Database.php +++ b/app/Livewire/Project/Service/Database.php @@ -1,6 +1,6 @@ database->service->destination->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; - $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); return; } $this->submit(); - $this->emit('success', 'You need to restart the service for the changes to take effect.'); + $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); } public function instantSave() { if ($this->database->is_public && !$this->database->public_port) { - $this->emit('error', 'Public port is required.'); + $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; return; } if ($this->database->is_public) { if (!str($this->database->status)->startsWith('running')) { - $this->emit('error', 'Database must be started to be publicly accessible.'); + $this->dispatch('error', 'Database must be started to be publicly accessible.'); $this->database->is_public = false; return; } StartDatabaseProxy::run($this->database); $this->db_url_public = $this->database->getServiceDatabaseUrl(); - $this->emit('success', 'Database is now publicly accessible.'); + $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->db_url_public = null; - $this->emit('success', 'Database is no longer publicly accessible.'); + $this->dispatch('success', 'Database is no longer publicly accessible.'); } $this->submit(); } @@ -77,11 +77,11 @@ class Database extends Component $this->validate(); $this->database->save(); updateCompose($this->database); - $this->emit('success', 'Database saved successfully.'); + $this->dispatch('success', 'Database saved successfully.'); } catch (\Throwable $e) { ray($e); } finally { - $this->emit('generateDockerCompose'); + $this->dispatch('generateDockerCompose'); } } } diff --git a/app/Http/Livewire/Project/Service/FileStorage.php b/app/Livewire/Project/Service/FileStorage.php similarity index 94% rename from app/Http/Livewire/Project/Service/FileStorage.php rename to app/Livewire/Project/Service/FileStorage.php index 91ab8e659..ab7736c97 100644 --- a/app/Http/Livewire/Project/Service/FileStorage.php +++ b/app/Livewire/Project/Service/FileStorage.php @@ -1,6 +1,6 @@ fileStorage->save(); $this->fileStorage->saveStorageOnServer($this->service); - $this->emit('success', 'File updated successfully.'); + $this->dispatch('success', 'File updated successfully.'); } catch (\Throwable $e) { $this->fileStorage->setRawAttributes($original); $this->fileStorage->save(); diff --git a/app/Http/Livewire/Project/Service/Index.php b/app/Livewire/Project/Service/Index.php similarity index 74% rename from app/Http/Livewire/Project/Service/Index.php rename to app/Livewire/Project/Service/Index.php index af88fac87..e55dc610c 100644 --- a/app/Http/Livewire/Project/Service/Index.php +++ b/app/Livewire/Project/Service/Index.php @@ -1,6 +1,6 @@ user()->id; + return [ + "echo-private:user.{$userId},ServiceStatusChanged" => 'checkStatus', + "refreshStacks", + "checkStatus", + ]; + } public function render() { return view('livewire.project.service.index'); @@ -28,8 +36,9 @@ class Index extends Component } public function checkStatus() { - dispatch(new ContainerStatusJob($this->service->server)); + dispatch_sync(new ContainerStatusJob($this->service->server)); $this->refreshStacks(); + $this->dispatch('serviceStatusChanged'); } public function refreshStacks() { diff --git a/app/Http/Livewire/Project/Service/Modal.php b/app/Livewire/Project/Service/Modal.php similarity index 56% rename from app/Http/Livewire/Project/Service/Modal.php rename to app/Livewire/Project/Service/Modal.php index 7092070f6..653425835 100644 --- a/app/Http/Livewire/Project/Service/Modal.php +++ b/app/Livewire/Project/Service/Modal.php @@ -1,14 +1,11 @@ emit('checkStatus'); - } public function render() { return view('livewire.project.service.modal'); diff --git a/app/Livewire/Project/Service/Navbar.php b/app/Livewire/Project/Service/Navbar.php new file mode 100644 index 000000000..3e2c3485c --- /dev/null +++ b/app/Livewire/Project/Service/Navbar.php @@ -0,0 +1,72 @@ +type_uuid', $this->service->uuid)->latest()->first(); + $status = data_get($activity, 'properties.status'); + if ($status === 'queued' || $status === 'in_progress') { + $this->isDeploymentProgress = true; + } else { + $this->isDeploymentProgress = false; + } + } + public function getListeners() + { + return [ + "serviceStatusChanged" + ]; + } + public function serviceStatusChanged() + { + $this->service->refresh(); + } + public function render() + { + return view('livewire.project.service.navbar'); + } + public function check_status($showNotification = false) + { + dispatch_sync(new ContainerStatusJob($this->service->destination->server)); + $this->service->refresh(); + if ($showNotification) $this->dispatch('success', 'Service status updated.'); + } + public function deploy() + { + $this->checkDeployments(); + if ($this->isDeploymentProgress) { + $this->dispatch('error', 'There is a deployment in progress.'); + return; + } + $this->service->parse(); + $activity = StartService::run($this->service); + $this->dispatch('newMonitorActivity', $activity->id); + } + public function stop(bool $forceCleanup = false) + { + StopService::run($this->service); + $this->service->refresh(); + if ($forceCleanup) { + $this->dispatch('success', 'Force cleanup service successfully.'); + } else { + $this->dispatch('success', 'Service stopped successfully.'); + } + ServiceStatusChanged::dispatch(); + } +} diff --git a/app/Http/Livewire/Project/Service/Show.php b/app/Livewire/Project/Service/Show.php similarity index 97% rename from app/Http/Livewire/Project/Service/Show.php rename to app/Livewire/Project/Service/Show.php index 53f5033f4..272e0a399 100644 --- a/app/Http/Livewire/Project/Service/Show.php +++ b/app/Livewire/Project/Service/Show.php @@ -1,6 +1,6 @@ service->parse(); $this->service->refresh(); $this->service->saveComposeConfigs(); - $this->emit('refreshStacks'); - $this->emit('refreshEnvs'); - $this->emit('success', 'Service saved successfully.'); + $this->dispatch('refreshStacks'); + $this->dispatch('refreshEnvs'); + $this->dispatch('success', 'Service saved successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/Service/Storage.php b/app/Livewire/Project/Service/Storage.php similarity index 79% rename from app/Http/Livewire/Project/Service/Storage.php rename to app/Livewire/Project/Service/Storage.php index 2e3ef8f58..0accde787 100644 --- a/app/Http/Livewire/Project/Service/Storage.php +++ b/app/Livewire/Project/Service/Storage.php @@ -1,6 +1,6 @@ $this->resource->getMorphClass(), ]); $this->resource->refresh(); - $this->emit('success', 'Storage added successfully'); - $this->emit('clearAddStorage'); - $this->emit('refreshStorages'); + $this->dispatch('success', 'Storage added successfully'); + $this->dispatch('clearAddStorage'); + $this->dispatch('refreshStorages'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Livewire/Project/Shared/Danger.php b/app/Livewire/Project/Shared/Danger.php new file mode 100644 index 000000000..39dc38310 --- /dev/null +++ b/app/Livewire/Project/Shared/Danger.php @@ -0,0 +1,36 @@ +modalId = new Cuid2(7); + $parameters = get_route_parameters(); + $this->projectUuid = $parameters['project_uuid']; + $this->environmentName = $parameters['environment_name']; + } + + public function delete() + { + try { + DeleteResourceJob::dispatchSync($this->resource); + return $this->redirectRoute('project.resources', [ + 'project_uuid' => $this->projectUuid, + 'environment_name' => $this->environmentName + ], navigate: true); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } +} diff --git a/app/Http/Livewire/Project/Shared/Destination.php b/app/Livewire/Project/Shared/Destination.php similarity index 78% rename from app/Http/Livewire/Project/Shared/Destination.php rename to app/Livewire/Project/Shared/Destination.php index a946c013f..e6d2d5a33 100644 --- a/app/Http/Livewire/Project/Shared/Destination.php +++ b/app/Livewire/Project/Shared/Destination.php @@ -1,6 +1,6 @@ validate(); ray($this->key, $this->value, $this->is_build_time); - $this->emitUp('submit', [ + $this->dispatch('saveKey', [ 'key' => $this->key, 'value' => $this->value, 'is_build_time' => $this->is_build_time, diff --git a/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php b/app/Livewire/Project/Shared/EnvironmentVariable/All.php similarity index 91% rename from app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php rename to app/Livewire/Project/Shared/EnvironmentVariable/All.php index 3f8b73f7b..7002fb989 100644 --- a/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/All.php @@ -1,6 +1,6 @@ 'submit']; public function mount() { @@ -106,9 +106,9 @@ class All extends Component } } if ($isPreview) { - $this->emit('success', 'Preview environment variables updated successfully.'); + $this->dispatch('success', 'Preview environment variables updated successfully.'); } else { - $this->emit('success', 'Environment variables updated successfully.'); + $this->dispatch('success', 'Environment variables updated successfully.'); } $this->refreshEnvs(); } @@ -123,7 +123,7 @@ class All extends Component try { $found = $this->resource->environment_variables()->where('key', $data['key'])->first(); if ($found) { - $this->emit('error', 'Environment variable already exists.'); + $this->dispatch('error', 'Environment variable already exists.'); return; } $environment = new EnvironmentVariable(); @@ -145,7 +145,7 @@ class All extends Component } $environment->save(); $this->refreshEnvs(); - $this->emit('success', 'Environment variable added successfully.'); + $this->dispatch('success', 'Environment variable added successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php similarity index 86% rename from app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php rename to app/Livewire/Project/Shared/EnvironmentVariable/Show.php index eed0f7052..865ba9bcf 100644 --- a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php @@ -1,6 +1,6 @@ env->is_shown_once = true; $this->env->save(); $this->checkEnvs(); - $this->emit('refreshEnvs'); + $this->dispatch('refreshEnvs'); } public function instantSave() { @@ -59,13 +59,13 @@ class Show extends Component { $this->validate(); $this->env->save(); - $this->emit('success', 'Environment variable updated successfully.'); - $this->emit('refreshEnvs'); + $this->dispatch('success', 'Environment variable updated successfully.'); + $this->dispatch('refreshEnvs'); } public function delete() { $this->env->delete(); - $this->emit('refreshEnvs'); + $this->dispatch('refreshEnvs'); } } diff --git a/app/Http/Livewire/Project/Shared/ExecuteContainerCommand.php b/app/Livewire/Project/Shared/ExecuteContainerCommand.php similarity index 83% rename from app/Http/Livewire/Project/Shared/ExecuteContainerCommand.php rename to app/Livewire/Project/Shared/ExecuteContainerCommand.php index 3c73a7f52..a3a63c154 100644 --- a/app/Http/Livewire/Project/Shared/ExecuteContainerCommand.php +++ b/app/Livewire/Project/Shared/ExecuteContainerCommand.php @@ -1,6 +1,6 @@ getContainers(); + } protected $rules = [ 'server' => 'required', 'container' => 'required', @@ -33,8 +43,12 @@ class ExecuteContainerCommand extends Component public function mount() { - $this->containers = collect(); $this->parameters = get_route_parameters(); + $this->getContainers(); + } + public function getContainers() + { + $this->containers = collect(); if (data_get($this->parameters, 'application_uuid')) { $this->type = 'application'; $this->resource = Application::where('uuid', $this->parameters['application_uuid'])->firstOrFail(); @@ -66,7 +80,9 @@ class ExecuteContainerCommand extends Component $this->resource = $resource; $this->server = $this->resource->destination->server; $this->container = $this->resource->uuid; - $this->containers->push($this->container); + if (str(data_get($this,'resource.status'))->startsWith('running')) { + $this->containers->push($this->container); + } } else if (data_get($this->parameters, 'service_uuid')) { $this->type = 'service'; $this->resource = Service::where('uuid', $this->parameters['service_uuid'])->firstOrFail(); @@ -92,13 +108,16 @@ class ExecuteContainerCommand extends Component { $this->validate(); try { + // Wrap command to prevent escaped execution in the host. + $cmd = 'sh -c "' . str_replace('"', '\"', $this->command) . '"'; + if (!empty($this->workDir)) { - $exec = "docker exec -w {$this->workDir} {$this->container} {$this->command}"; + $exec = "docker exec -w {$this->workDir} {$this->container} {$cmd}"; } else { - $exec = "docker exec {$this->container} {$this->command}"; + $exec = "docker exec {$this->container} {$cmd}"; } $activity = remote_process([$exec], $this->server, ignore_errors: true); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('newMonitorActivity', $activity->id); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/Shared/GetLogs.php b/app/Livewire/Project/Shared/GetLogs.php similarity index 56% rename from app/Http/Livewire/Project/Shared/GetLogs.php rename to app/Livewire/Project/Shared/GetLogs.php index 933938f56..db2170b5f 100644 --- a/app/Http/Livewire/Project/Shared/GetLogs.php +++ b/app/Livewire/Project/Shared/GetLogs.php @@ -1,6 +1,6 @@ resource->getMorphClass() === 'App\Models\Application') { - $this->showTimeStamps = $this->resource->settings->is_include_timestamps; - } else { - if ($this->servicesubtype) { - $this->showTimeStamps = $this->servicesubtype->is_include_timestamps; + if (!is_null($this->resource)) { + if ($this->resource->getMorphClass() === 'App\Models\Application') { + $this->showTimeStamps = $this->resource->settings->is_include_timestamps; } else { - $this->showTimeStamps = $this->resource->is_include_timestamps; + if ($this->servicesubtype) { + $this->showTimeStamps = $this->servicesubtype->is_include_timestamps; + } else { + $this->showTimeStamps = $this->resource->is_include_timestamps; + } } } } @@ -45,21 +47,30 @@ class GetLogs extends Component } public function instantSave() { - if ($this->resource->getMorphClass() === 'App\Models\Application') { - $this->resource->settings->is_include_timestamps = $this->showTimeStamps; - $this->resource->settings->save(); - } else { - if ($this->servicesubtype) { - $this->servicesubtype->is_include_timestamps = $this->showTimeStamps; - $this->servicesubtype->save(); - } else { - $this->resource->is_include_timestamps = $this->showTimeStamps; - $this->resource->save(); + if (!is_null($this->resource)) { + if ($this->resource->getMorphClass() === 'App\Models\Application') { + $this->resource->settings->is_include_timestamps = $this->showTimeStamps; + $this->resource->settings->save(); + } + if ($this->resource->getMorphClass() === 'App\Models\Service') { + $serviceName = str($this->container)->beforeLast('-')->value(); + $subType = $this->resource->applications()->where('name', $serviceName)->first(); + if ($subType) { + $subType->is_include_timestamps = $this->showTimeStamps; + $subType->save(); + } else { + $subType = $this->resource->databases()->where('name', $serviceName)->first(); + if ($subType) { + $subType->is_include_timestamps = $this->showTimeStamps; + $subType->save(); + } + } } } } public function getLogs($refresh = false) { + if (!$refresh && $this->resource->getMorphClass() === 'App\Models\Service') return; if ($this->container) { if ($this->showTimeStamps) { $sshCommand = generateSshCommand($this->server, "docker logs -n {$this->numberOfLines} -t {$this->container}"); diff --git a/app/Http/Livewire/Project/Shared/HealthChecks.php b/app/Livewire/Project/Shared/HealthChecks.php similarity index 87% rename from app/Http/Livewire/Project/Shared/HealthChecks.php rename to app/Livewire/Project/Shared/HealthChecks.php index 1c783abec..3bf507cab 100644 --- a/app/Http/Livewire/Project/Shared/HealthChecks.php +++ b/app/Livewire/Project/Shared/HealthChecks.php @@ -1,6 +1,6 @@ resource->save(); - $this->emit('success', 'Health check updated.'); + $this->dispatch('success', 'Health check updated.'); } @@ -35,7 +35,7 @@ class HealthChecks extends Component try { $this->validate(); $this->resource->save(); - $this->emit('success', 'Health check updated.'); + $this->dispatch('success', 'Health check updated.'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/Shared/Logs.php b/app/Livewire/Project/Shared/Logs.php similarity index 79% rename from app/Http/Livewire/Project/Shared/Logs.php rename to app/Livewire/Project/Shared/Logs.php index 18b632ab4..f7c952b46 100644 --- a/app/Http/Livewire/Project/Shared/Logs.php +++ b/app/Livewire/Project/Shared/Logs.php @@ -1,6 +1,6 @@ status = $this->resource->status; $this->server = $this->resource->destination->server; $this->container = $this->resource->uuid; + if (str(data_get($this,'resource.status'))->startsWith('running')) { + $this->containers->push($this->container); + } } else if (data_get($this->parameters, 'service_uuid')) { $this->type = 'service'; $this->resource = Service::where('uuid', $this->parameters['service_uuid'])->firstOrFail(); - $service_name = data_get($this->parameters, 'service_name'); - $this->serviceSubType = $this->resource->applications()->where('name', $service_name)->first(); - if (!$this->serviceSubType) { - $this->serviceSubType = $this->resource->databases()->where('name', $service_name)->first(); - } - $this->status = $this->resource->status; + $this->resource->applications()->get()->each(function ($application) { + if (str(data_get($application, 'status'))->contains('running')) { + $this->containers->push(data_get($application, 'name') . '-' . data_get($this->resource, 'uuid')); + } + }); + $this->resource->databases()->get()->each(function ($database) { + if (str(data_get($database, 'status'))->contains('running')) { + $this->containers->push(data_get($database, 'name') . '-' . data_get($this->resource, 'uuid')); + } + }); + $this->server = $this->resource->server; - $this->container = data_get($this->parameters, 'service_name') . '-' . $this->resource->uuid; } } diff --git a/app/Http/Livewire/Project/Shared/ResourceLimits.php b/app/Livewire/Project/Shared/ResourceLimits.php similarity index 94% rename from app/Http/Livewire/Project/Shared/ResourceLimits.php rename to app/Livewire/Project/Shared/ResourceLimits.php index 5959cb9ac..692c5f741 100644 --- a/app/Http/Livewire/Project/Shared/ResourceLimits.php +++ b/app/Livewire/Project/Shared/ResourceLimits.php @@ -1,6 +1,6 @@ validate(); $this->resource->save(); - $this->emit('success', 'Resource limits updated successfully.'); + $this->dispatch('success', 'Resource limits updated successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Project/Shared/Storages/Add.php b/app/Livewire/Project/Shared/Storages/Add.php similarity index 91% rename from app/Http/Livewire/Project/Shared/Storages/Add.php rename to app/Livewire/Project/Shared/Storages/Add.php index 7278eda7a..b1f467b34 100644 --- a/app/Http/Livewire/Project/Shared/Storages/Add.php +++ b/app/Livewire/Project/Shared/Storages/Add.php @@ -1,6 +1,6 @@ validate(); $name = $this->uuid . '-' . $this->name; - $this->emit('addNewVolume', [ + $this->dispatch('addNewVolume', [ 'name' => $name, 'mount_path' => $this->mount_path, 'host_path' => $this->host_path, diff --git a/app/Http/Livewire/Project/Shared/Storages/All.php b/app/Livewire/Project/Shared/Storages/All.php similarity index 83% rename from app/Http/Livewire/Project/Shared/Storages/All.php rename to app/Livewire/Project/Shared/Storages/All.php index 457071711..598bc63d5 100644 --- a/app/Http/Livewire/Project/Shared/Storages/All.php +++ b/app/Livewire/Project/Shared/Storages/All.php @@ -1,6 +1,6 @@ validate(); $this->storage->save(); - $this->emit('success', 'Storage updated successfully'); + $this->dispatch('success', 'Storage updated successfully'); } public function delete() { $this->storage->delete(); - $this->emit('refreshStorages'); + $this->dispatch('refreshStorages'); } } diff --git a/app/Http/Livewire/Project/Shared/Webhooks.php b/app/Livewire/Project/Shared/Webhooks.php similarity index 91% rename from app/Http/Livewire/Project/Shared/Webhooks.php rename to app/Livewire/Project/Shared/Webhooks.php index d425b51df..c54a1c38f 100644 --- a/app/Http/Livewire/Project/Shared/Webhooks.php +++ b/app/Livewire/Project/Shared/Webhooks.php @@ -1,6 +1,6 @@ validate(); $this->resource->save(); - $this->emit('success','Secret Saved.'); + $this->dispatch('success','Secret Saved.'); } catch (\Exception $e) { return handleError($e, $this); } diff --git a/app/Livewire/RealtimeConnection.php b/app/Livewire/RealtimeConnection.php new file mode 100644 index 000000000..89b680277 --- /dev/null +++ b/app/Livewire/RealtimeConnection.php @@ -0,0 +1,25 @@ +user()->update(['is_notification_realtime_enabled' => false]); + $this->showNotification = false; + } + public function mount() { + $this->isNotificationEnabled = auth()->user()->is_notification_realtime_enabled; + $this->checkConnection = auth()->user()->id === 0; + } +} diff --git a/app/Http/Livewire/RunCommand.php b/app/Livewire/RunCommand.php old mode 100755 new mode 100644 similarity index 89% rename from app/Http/Livewire/RunCommand.php rename to app/Livewire/RunCommand.php index b8f4c6af8..309283403 --- a/app/Http/Livewire/RunCommand.php +++ b/app/Livewire/RunCommand.php @@ -1,6 +1,6 @@ validate(); try { $activity = remote_process([$this->command], Server::where('uuid', $this->server)->first(), ignore_errors: true); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('newMonitorActivity', $activity->id); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Security/ApiTokens.php b/app/Livewire/Security/ApiTokens.php similarity index 96% rename from app/Http/Livewire/Security/ApiTokens.php rename to app/Livewire/Security/ApiTokens.php index f00b30930..f0ffff133 100644 --- a/app/Http/Livewire/Security/ApiTokens.php +++ b/app/Livewire/Security/ApiTokens.php @@ -1,6 +1,6 @@ authorize('delete', $this->server); if ($this->server->hasDefinedResources()) { - $this->emit('error', 'Server has defined resources. Please delete them first.'); + $this->dispatch('error', 'Server has defined resources. Please delete them first.'); return; } $this->server->delete(); - return redirect()->route('server.all'); + return $this->redirectRoute('server.all', navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Server/Destination/Show.php b/app/Livewire/Server/Destination/Show.php similarity index 69% rename from app/Http/Livewire/Server/Destination/Show.php rename to app/Livewire/Server/Destination/Show.php index e021f9605..3df263f8b 100644 --- a/app/Http/Livewire/Server/Destination/Show.php +++ b/app/Livewire/Server/Destination/Show.php @@ -1,6 +1,6 @@ parameters = get_route_parameters(); try { - $this->server = Server::ownedByCurrentTeam(['name', 'proxy'])->whereUuid(request()->server_uuid)->first(); + $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first(); if (is_null($this->server)) { - return redirect()->route('server.all'); + return $this->redirectRoute('server.all', navigate: true); } } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Http/Livewire/Server/Form.php b/app/Livewire/Server/Form.php similarity index 76% rename from app/Http/Livewire/Server/Form.php rename to app/Livewire/Server/Form.php index 512a7f68a..480028ede 100644 --- a/app/Http/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -1,6 +1,6 @@ wildcard_domain = $this->server->settings->wildcard_domain; $this->cleanup_after_percentage = $this->server->settings->cleanup_after_percentage; - $this->validateServer(); + if (!$this->server->isFunctional()) { + $this->validateServer(); + } } public function serverRefresh($install = true) { @@ -56,28 +58,28 @@ class Form extends Component refresh_server_connection($this->server->privateKey); $this->validateServer(false); $this->server->settings->save(); - $this->emit('success', 'Server updated successfully.'); + $this->dispatch('success', 'Server updated successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } } public function installDocker() { - $this->emit('installDocker'); + $this->dispatch('installDocker'); $this->dockerInstallationStarted = true; $activity = InstallDocker::run($this->server); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('newMonitorActivity', $activity->id); } public function checkLocalhostConnection() { $uptime = $this->server->validateConnection(); if ($uptime) { - $this->emit('success', 'Server is reachable.'); + $this->dispatch('success', 'Server is reachable.'); $this->server->settings->is_reachable = true; $this->server->settings->is_usable = true; $this->server->settings->save(); } else { - $this->emit('error', 'Server is not reachable. Please check your connection and configuration.'); + $this->dispatch('error', 'Server is not reachable. Please check your connection and configuration.'); return; } } @@ -86,24 +88,24 @@ class Form extends Component try { $uptime = $this->server->validateConnection(); if (!$uptime) { - $install && $this->emit('error', 'Server is not reachable. Please check your connection and configuration.'); + $install && $this->dispatch('error', 'Server is not reachable. Please check your connection and configuration.'); return; } $supported_os_type = $this->server->validateOS(); if (!$supported_os_type) { - $install && $this->emit('error', 'Server OS type is not supported for automated installation. Please install Docker manually before continuing: documentation.'); + $install && $this->dispatch('error', 'Server OS type is not supported for automated installation. Please install Docker manually before continuing: documentation.'); return; } $dockerInstalled = $this->server->validateDockerEngine(); if ($dockerInstalled) { - $install && $this->emit('success', 'Docker Engine is installed.
Checking version.'); + $install && $this->dispatch('success', 'Docker Engine is installed.
Checking version.'); } else { $install && $this->installDocker(); return; } $dockerVersion = $this->server->validateDockerEngineVersion(); if ($dockerVersion) { - $install && $this->emit('success', 'Docker Engine version is 22+.'); + $install && $this->dispatch('success', 'Docker Engine version is 22+.'); } else { $install && $this->installDocker(); return; @@ -111,13 +113,13 @@ class Form extends Component if ($this->server->isSwarm()) { $swarmInstalled = $this->server->validateDockerSwarm(); if ($swarmInstalled) { - $install && $this->emit('success', 'Docker Swarm is initiated.'); + $install && $this->dispatch('success', 'Docker Swarm is initiated.'); } } } catch (\Throwable $e) { return handleError($e, $this); } finally { - $this->emit('proxyStatusUpdated'); + $this->dispatch('proxyStatusUpdated'); } } @@ -135,7 +137,7 @@ class Form extends Component return $server->id === $this->server->id; })->pluck('ip')->toArray(); if (in_array($this->server->ip, $uniqueIPs)) { - $this->emit('error', 'IP address is already in use by another team.'); + $this->dispatch('error', 'IP address is already in use by another team.'); return; } refresh_server_connection($this->server->privateKey); @@ -143,6 +145,6 @@ class Form extends Component $this->server->settings->cleanup_after_percentage = $this->cleanup_after_percentage; $this->server->settings->save(); $this->server->save(); - $this->emit('success', 'Server updated successfully.'); + $this->dispatch('success', 'Server updated successfully.'); } } diff --git a/app/Http/Livewire/Server/LogDrains.php b/app/Livewire/Server/LogDrains.php similarity index 92% rename from app/Http/Livewire/Server/LogDrains.php rename to app/Livewire/Server/LogDrains.php index 5afe540ca..bdaf152d7 100644 --- a/app/Http/Livewire/Server/LogDrains.php +++ b/app/Livewire/Server/LogDrains.php @@ -1,6 +1,6 @@ parameters = get_route_parameters(); try { - $server = Server::ownedByCurrentTeam(['name', 'description', 'ip', 'port', 'user', 'proxy'])->whereUuid(request()->server_uuid)->first(); + $server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first(); if (is_null($server)) { - return redirect()->route('server.all'); + return $this->redirectRoute('server.all', navigate: true); } $this->server = $server; } catch (\Throwable $e) { @@ -55,12 +55,12 @@ class LogDrains extends Component try { InstallLogDrain::run($this->server); if (!$this->server->isLogDrainEnabled()) { - $this->emit('serverRefresh'); - $this->emit('success', 'Log drain service stopped.'); + $this->dispatch('serverRefresh'); + $this->dispatch('success', 'Log drain service stopped.'); return; } - $this->emit('serverRefresh'); - $this->emit('success', 'Log drain service started successfully.'); + $this->dispatch('serverRefresh'); + $this->dispatch('success', 'Log drain service started successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -126,7 +126,7 @@ class LogDrains extends Component ]); } $this->server->settings->save(); - $this->emit('success', 'Settings saved successfully.'); + $this->dispatch('success', 'Settings saved successfully.'); return true; } catch (\Throwable $e) { if ($type === 'newrelic') { diff --git a/app/Http/Livewire/Server/New/ByIp.php b/app/Livewire/Server/New/ByIp.php similarity index 89% rename from app/Http/Livewire/Server/New/ByIp.php rename to app/Livewire/Server/New/ByIp.php index 858f4ffa1..3470e27f8 100644 --- a/app/Http/Livewire/Server/New/ByIp.php +++ b/app/Livewire/Server/New/ByIp.php @@ -1,6 +1,6 @@ emit('success', 'Application settings updated!'); + $this->dispatch('success', 'Application settings updated!'); } public function submit() @@ -61,7 +61,7 @@ class ByIp extends Component $this->validate(); try { if (is_null($this->private_key_id)) { - return $this->emit('error', 'You must select a private key'); + return $this->dispatch('error', 'You must select a private key'); } $server = Server::create([ 'name' => $this->name, @@ -79,7 +79,7 @@ class ByIp extends Component $server->settings->is_swarm_manager = $this->is_swarm_manager; $server->settings->save(); $server->addInitialNetwork(); - return redirect()->route('server.show', $server->uuid); + return $this->redirectRoute('server.show', $server->uuid, navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Server/PrivateKey/Show.php b/app/Livewire/Server/PrivateKey/Show.php similarity index 86% rename from app/Http/Livewire/Server/PrivateKey/Show.php rename to app/Livewire/Server/PrivateKey/Show.php index 22c52218a..97ee66729 100644 --- a/app/Http/Livewire/Server/PrivateKey/Show.php +++ b/app/Livewire/Server/PrivateKey/Show.php @@ -1,6 +1,6 @@ server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first(); if (is_null($this->server)) { - return redirect()->route('server.all'); + return $this->redirectRoute('server.all', navigate: true); } $this->privateKeys = PrivateKey::ownedByCurrentTeam()->get()->where('is_git_related', false); } catch (\Throwable $e) { diff --git a/app/Http/Livewire/Server/Proxy.php b/app/Livewire/Server/Proxy.php similarity index 86% rename from app/Http/Livewire/Server/Proxy.php rename to app/Livewire/Server/Proxy.php index 66eb307b3..79ddb203b 100644 --- a/app/Http/Livewire/Server/Proxy.php +++ b/app/Livewire/Server/Proxy.php @@ -1,6 +1,6 @@ server->proxy = null; $this->server->save(); - $this->emit('proxyStatusUpdated'); + $this->dispatch('proxyStatusUpdated'); } public function select_proxy($proxy_type) @@ -42,7 +42,7 @@ class Proxy extends Component $this->server->proxy->set('type', $proxy_type); $this->server->save(); $this->selectedProxy = $this->server->proxy->type; - $this->emit('proxyStatusUpdated'); + $this->dispatch('proxyStatusUpdated'); } public function submit() @@ -53,7 +53,7 @@ class Proxy extends Component $this->server->save(); setup_default_redirect_404(redirect_url: $this->server->proxy->redirect_url, server: $this->server); - $this->emit('success', 'Proxy configuration saved.'); + $this->dispatch('success', 'Proxy configuration saved.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -73,9 +73,9 @@ class Proxy extends Component try { $this->proxy_settings = CheckConfiguration::run($this->server); if (Str::of($this->proxy_settings)->contains('--api.dashboard=true') && Str::of($this->proxy_settings)->contains('--api.insecure=true')) { - $this->emit('traefikDashboardAvailable', true); + $this->dispatch('traefikDashboardAvailable', true); } else { - $this->emit('traefikDashboardAvailable', false); + $this->dispatch('traefikDashboardAvailable', false); } } catch (\Throwable $e) { diff --git a/app/Http/Livewire/Server/Proxy/Deploy.php b/app/Livewire/Server/Proxy/Deploy.php similarity index 86% rename from app/Http/Livewire/Server/Proxy/Deploy.php rename to app/Livewire/Server/Proxy/Deploy.php index 9612eccc7..4c748b7fa 100644 --- a/app/Http/Livewire/Server/Proxy/Deploy.php +++ b/app/Livewire/Server/Proxy/Deploy.php @@ -1,6 +1,6 @@ server, true); - $this->emit('startProxyPolling'); - $this->emit('proxyChecked'); + $this->dispatch('startProxyPolling'); + $this->dispatch('proxyChecked'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -50,7 +50,7 @@ class Deploy extends Component { try { $activity = StartProxy::run($this->server); - $this->emit('newMonitorActivity', $activity->id); + $this->dispatch('newMonitorActivity', $activity->id); } catch (\Throwable $e) { return handleError($e, $this); } @@ -65,14 +65,14 @@ class Deploy extends Component ], $this->server); $this->server->proxy->status = 'exited'; $this->server->save(); - $this->emit('proxyStatusUpdated'); + $this->dispatch('proxyStatusUpdated'); } else { instant_remote_process([ "docker rm -f coolify-proxy", ], $this->server); $this->server->proxy->status = 'exited'; $this->server->save(); - $this->emit('proxyStatusUpdated'); + $this->dispatch('proxyStatusUpdated'); } } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Http/Livewire/Server/Proxy/Logs.php b/app/Livewire/Server/Proxy/Logs.php similarity index 69% rename from app/Http/Livewire/Server/Proxy/Logs.php rename to app/Livewire/Server/Proxy/Logs.php index cb8c245a6..e1ca0ca3f 100644 --- a/app/Http/Livewire/Server/Proxy/Logs.php +++ b/app/Livewire/Server/Proxy/Logs.php @@ -1,6 +1,6 @@ parameters = get_route_parameters(); try { - $this->server = Server::ownedByCurrentTeam(['name', 'proxy'])->whereUuid(request()->server_uuid)->first(); + $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first(); if (is_null($this->server)) { - return redirect()->route('server.all'); + return $this->redirectRoute('server.all', navigate: true); } } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Http/Livewire/Server/Proxy/Modal.php b/app/Livewire/Server/Proxy/Modal.php similarity index 66% rename from app/Http/Livewire/Server/Proxy/Modal.php rename to app/Livewire/Server/Proxy/Modal.php index 2674abe3d..5679944d0 100644 --- a/app/Http/Livewire/Server/Proxy/Modal.php +++ b/app/Livewire/Server/Proxy/Modal.php @@ -1,6 +1,6 @@ emit('proxyStatusUpdated'); + $this->dispatch('proxyStatusUpdated'); } } diff --git a/app/Http/Livewire/Server/Proxy/Show.php b/app/Livewire/Server/Proxy/Show.php similarity index 74% rename from app/Http/Livewire/Server/Proxy/Show.php rename to app/Livewire/Server/Proxy/Show.php index 26ea54e49..4c515b926 100644 --- a/app/Http/Livewire/Server/Proxy/Show.php +++ b/app/Livewire/Server/Proxy/Show.php @@ -1,6 +1,6 @@ parameters = get_route_parameters(); try { - $this->server = Server::ownedByCurrentTeam(['name', 'proxy'])->whereUuid(request()->server_uuid)->first(); + $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first(); if (is_null($this->server)) { - return redirect()->route('server.all'); + return $this->redirectRoute('server.all', navigate: true); } } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Http/Livewire/Server/Proxy/Status.php b/app/Livewire/Server/Proxy/Status.php similarity index 79% rename from app/Http/Livewire/Server/Proxy/Status.php rename to app/Livewire/Server/Proxy/Status.php index 674dd623d..bb368e935 100644 --- a/app/Http/Livewire/Server/Proxy/Status.php +++ b/app/Livewire/Server/Proxy/Status.php @@ -1,6 +1,6 @@ numberOfPolls >= 10) { $this->polling = false; $this->numberOfPolls = 0; - $notification && $this->emit('error', 'Proxy is not running.'); + $notification && $this->dispatch('error', 'Proxy is not running.'); return; } $this->numberOfPolls++; } CheckProxy::run($this->server, true); - $this->emit('proxyStatusUpdated'); + $this->dispatch('proxyStatusUpdated'); if ($this->server->proxy->status === 'running') { $this->polling = false; - $notification && $this->emit('success', 'Proxy is running.'); + $notification && $this->dispatch('success', 'Proxy is running.'); } else { - $notification && $this->emit('error', 'Proxy is not running.'); + $notification && $this->dispatch('error', 'Proxy is not running.'); } } catch (\Throwable $e) { return handleError($e, $this); @@ -53,7 +53,7 @@ class Status extends Component { try { dispatch_sync(new ContainerStatusJob($this->server)); - $this->emit('proxyStatusUpdated'); + $this->dispatch('proxyStatusUpdated'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Server/Show.php b/app/Livewire/Server/Show.php similarity index 67% rename from app/Http/Livewire/Server/Show.php rename to app/Livewire/Server/Show.php index a72abdf94..2c0ec6e82 100644 --- a/app/Http/Livewire/Server/Show.php +++ b/app/Livewire/Server/Show.php @@ -1,6 +1,6 @@ parameters = get_route_parameters(); try { - $this->server = Server::ownedByCurrentTeam(['name', 'description', 'ip', 'port', 'user', 'proxy'])->whereUuid(request()->server_uuid)->first(); + $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first(); if (is_null($this->server)) { - return redirect()->route('server.all'); + return $this->redirectRoute('server.all', navigate: true); } } catch (\Throwable $e) { @@ -26,7 +26,7 @@ class Show extends Component } public function submit() { - $this->emit('serverRefresh',false); + $this->dispatch('serverRefresh',false); } public function render() { diff --git a/app/Http/Livewire/Server/ShowPrivateKey.php b/app/Livewire/Server/ShowPrivateKey.php similarity index 85% rename from app/Http/Livewire/Server/ShowPrivateKey.php rename to app/Livewire/Server/ShowPrivateKey.php index 98035fa7c..8478094ad 100644 --- a/app/Http/Livewire/Server/ShowPrivateKey.php +++ b/app/Livewire/Server/ShowPrivateKey.php @@ -1,6 +1,6 @@ server->validateConnection(); if ($uptime) { - $this->emit('success', 'Server is reachable.'); + $this->dispatch('success', 'Server is reachable.'); } else { - $this->emit('error', 'Server is not reachable. Please check your connection and private key configuration.'); + $this->dispatch('error', 'Server is not reachable. Please check your connection and private key configuration.'); return; } } catch (\Throwable $e) { diff --git a/app/Http/Livewire/Settings/Backup.php b/app/Livewire/Settings/Backup.php similarity index 93% rename from app/Http/Livewire/Settings/Backup.php rename to app/Livewire/Settings/Backup.php index 7a5e2f0ed..519fe1bd8 100644 --- a/app/Http/Livewire/Settings/Backup.php +++ b/app/Livewire/Settings/Backup.php @@ -1,6 +1,6 @@ backup )); - $this->emit('success', 'Backup queued. It will be available in a few minutes.'); + $this->dispatch('success', 'Backup queued. It will be available in a few minutes.'); } public function submit() { - $this->emit('success', 'Backup updated successfully.'); + $this->dispatch('success', 'Backup updated successfully.'); } } diff --git a/app/Http/Livewire/Settings/Configuration.php b/app/Livewire/Settings/Configuration.php similarity index 96% rename from app/Http/Livewire/Settings/Configuration.php rename to app/Livewire/Settings/Configuration.php index 668c3d5c4..62ade961b 100644 --- a/app/Http/Livewire/Settings/Configuration.php +++ b/app/Livewire/Settings/Configuration.php @@ -1,6 +1,6 @@ settings->next_channel = $this->next_channel; } $this->settings->save(); - $this->emit('success', 'Settings updated!'); + $this->dispatch('success', 'Settings updated!'); } public function submit() @@ -66,7 +66,7 @@ class Configuration extends Component $this->settings->save(); $this->server = Server::findOrFail(0); $this->setup_instance_fqdn(); - $this->emit('success', 'Instance settings updated successfully!'); + $this->dispatch('success', 'Instance settings updated successfully!'); } private function setup_instance_fqdn() diff --git a/app/Http/Livewire/Settings/Email.php b/app/Livewire/Settings/Email.php similarity index 91% rename from app/Http/Livewire/Settings/Email.php rename to app/Livewire/Settings/Email.php index 85a4dc04d..d005462a8 100644 --- a/app/Http/Livewire/Settings/Email.php +++ b/app/Livewire/Settings/Email.php @@ -1,6 +1,6 @@ 'required', ]); $this->settings->save(); - $this->emit('success', 'Settings saved successfully.'); + $this->dispatch('success', 'Settings saved successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -61,7 +61,7 @@ class Email extends Component 'settings.resend_api_key' => 'required' ]); $this->settings->save(); - $this->emit('success', 'Settings saved successfully.'); + $this->dispatch('success', 'Settings saved successfully.'); } catch (\Throwable $e) { $this->settings->resend_enabled = false; return handleError($e, $this); @@ -98,7 +98,7 @@ class Email extends Component 'settings.smtp_timeout' => 'nullable', ]); $this->settings->save(); - $this->emit('success', 'Settings saved successfully.'); + $this->dispatch('success', 'Settings saved successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -107,6 +107,6 @@ class Email extends Component public function sendTestNotification() { $this->settings->notify(new Test($this->emails)); - $this->emit('success', 'Test email sent.'); + $this->dispatch('success', 'Test email sent.'); } } diff --git a/app/Http/Livewire/Source/Github/Change.php b/app/Livewire/Source/Github/Change.php similarity index 76% rename from app/Http/Livewire/Source/Github/Change.php rename to app/Livewire/Source/Github/Change.php index c9ef89c02..cfea6fe9d 100644 --- a/app/Http/Livewire/Source/Github/Change.php +++ b/app/Livewire/Source/Github/Change.php @@ -1,6 +1,6 @@ github_app_uuid; $this->github_app = GithubApp::where('uuid', $github_app_uuid)->first(); if (!$this->github_app) { - return redirect()->route('source.all'); + return $this->redirectRoute('source.all', navigate: true); } $settings = InstanceSettings::get(); $this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret'); @@ -67,7 +67,7 @@ class Change extends Component $type = data_get($parameters, 'type'); $destination = data_get($parameters, 'destination'); session()->forget('from'); - return redirect()->route($back, [ + return $this->redirectRoute($back, [ 'environment_name' => $environment_name, 'project_uuid' => $project_uuid, 'type' => $type, @@ -88,9 +88,22 @@ class Change extends Component { try { $this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret'); - $this->validate(); + $this->validate([ + 'github_app.name' => 'required|string', + 'github_app.organization' => 'nullable|string', + 'github_app.api_url' => 'required|string', + 'github_app.html_url' => 'required|string', + 'github_app.custom_user' => 'required|string', + 'github_app.custom_port' => 'required|int', + 'github_app.app_id' => 'required|int', + 'github_app.installation_id' => 'required|int', + 'github_app.client_id' => 'required|string', + 'github_app.client_secret' => 'required|string', + 'github_app.webhook_secret' => 'required|string', + 'github_app.is_system_wide' => 'required|bool', + ]); $this->github_app->save(); - $this->emit('success', 'Github App updated successfully.'); + $this->dispatch('success', 'Github App updated successfully.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -98,14 +111,13 @@ class Change extends Component public function instantSave() { - $this->submit(); } public function delete() { try { $this->github_app->delete(); - redirect()->route('source.all'); + return $this->redirectRoute('source.all', navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Source/Github/Create.php b/app/Livewire/Source/Github/Create.php similarity index 91% rename from app/Http/Livewire/Source/Github/Create.php rename to app/Livewire/Source/Github/Create.php index 75951d946..543c7d2ac 100644 --- a/app/Http/Livewire/Source/Github/Create.php +++ b/app/Livewire/Source/Github/Create.php @@ -1,6 +1,6 @@ session('from') + ['source_id' => $github_app->id]]); } - redirect()->route('source.github.show', ['github_app_uuid' => $github_app->uuid]); + return $this->redirectRoute('source.github.show', ['github_app_uuid' => $github_app->uuid], navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Source/Gitlab/Change.php b/app/Livewire/Source/Gitlab/Change.php similarity index 79% rename from app/Http/Livewire/Source/Gitlab/Change.php rename to app/Livewire/Source/Gitlab/Change.php index de52e011f..34600bb7d 100644 --- a/app/Http/Livewire/Source/Gitlab/Change.php +++ b/app/Livewire/Source/Gitlab/Change.php @@ -1,6 +1,6 @@ user()->currentTeam()->id; return [ - "echo-private:custom.{$teamId},TestEvent" => 'testEvent', + "echo-private:team.{$teamId},TestEvent" => 'testEvent', ]; } public function testEvent() { - $this->emit('success', 'Realtime events configured!'); + $this->dispatch('success', 'Realtime events configured!'); } public function disable() { diff --git a/app/Http/Livewire/Subscription/Actions.php b/app/Livewire/Subscription/Actions.php similarity index 88% rename from app/Http/Livewire/Subscription/Actions.php rename to app/Livewire/Subscription/Actions.php index 2f97e899d..bd4dbd69a 100644 --- a/app/Http/Livewire/Subscription/Actions.php +++ b/app/Livewire/Subscription/Actions.php @@ -1,6 +1,6 @@ emit('success', 'Subscription cancelled successfully. Reloading in 5s.'); - $this->emit('reloadWindow', 5000); + $this->dispatch('success', 'Subscription cancelled successfully. Reloading in 5s.'); + $this->dispatch('reloadWindow', 5000); } } catch (\Throwable $e) { return handleError($e, $this); @@ -62,8 +62,8 @@ class Actions extends Component } throw new \Exception(data_get($json, 'errors.0.title', 'Something went wrong. Please try again later.')); } else { - $this->emit('success', 'Subscription resumed successfully. Reloading in 5s.'); - $this->emit('reloadWindow', 5000); + $this->dispatch('success', 'Subscription resumed successfully. Reloading in 5s.'); + $this->dispatch('reloadWindow', 5000); } } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Http/Livewire/Subscription/PricingPlans.php b/app/Livewire/Subscription/PricingPlans.php similarity index 96% rename from app/Http/Livewire/Subscription/PricingPlans.php rename to app/Livewire/Subscription/PricingPlans.php index 07ee7c792..a3afcaabc 100644 --- a/app/Http/Livewire/Subscription/PricingPlans.php +++ b/app/Livewire/Subscription/PricingPlans.php @@ -1,6 +1,6 @@ emit('error', 'Price ID not found! Please contact the administrator.'); + $this->dispatch('error', 'Price ID not found! Please contact the administrator.'); return; } $payload = [ diff --git a/app/Http/Livewire/Subscription/Show.php b/app/Livewire/Subscription/Show.php similarity index 88% rename from app/Http/Livewire/Subscription/Show.php rename to app/Livewire/Subscription/Show.php index ff028f68f..ee12eef6d 100644 --- a/app/Http/Livewire/Subscription/Show.php +++ b/app/Livewire/Subscription/Show.php @@ -1,6 +1,6 @@ redirect('/', navigate: true); } $this->settings = InstanceSettings::get(); $this->alreadySubscribed = currentTeam()->subscription()->exists(); diff --git a/app/Http/Livewire/SwitchTeam.php b/app/Livewire/SwitchTeam.php similarity index 95% rename from app/Http/Livewire/SwitchTeam.php rename to app/Livewire/SwitchTeam.php index 9a9b4c795..845619820 100644 --- a/app/Http/Livewire/SwitchTeam.php +++ b/app/Livewire/SwitchTeam.php @@ -1,6 +1,6 @@ user()->teams()->attach($team, ['role' => 'admin']); refreshSession(); - return redirect()->route('team.index'); + return $this->redirectRoute('team.index', navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Team/Delete.php b/app/Livewire/Team/Delete.php similarity index 87% rename from app/Http/Livewire/Team/Delete.php rename to app/Livewire/Team/Delete.php index b09395df4..14c7a8f82 100644 --- a/app/Http/Livewire/Team/Delete.php +++ b/app/Livewire/Team/Delete.php @@ -1,6 +1,6 @@ route('team.index'); + return $this->redirectRoute('team.index', navigate: true); } } diff --git a/app/Http/Livewire/Team/Form.php b/app/Livewire/Team/Form.php similarity index 95% rename from app/Http/Livewire/Team/Form.php rename to app/Livewire/Team/Form.php index 005a03432..3deaf0b92 100644 --- a/app/Http/Livewire/Team/Form.php +++ b/app/Livewire/Team/Form.php @@ -1,6 +1,6 @@ delete(); $this->refreshInvitations(); - $this->emit('success', 'Invitation revoked.'); + $this->dispatch('success', 'Invitation revoked.'); } public function refreshInvitations() diff --git a/app/Http/Livewire/Team/InviteLink.php b/app/Livewire/Team/InviteLink.php similarity index 91% rename from app/Http/Livewire/Team/InviteLink.php rename to app/Livewire/Team/InviteLink.php index 8fea3a6b8..5f9db3f84 100644 --- a/app/Http/Livewire/Team/InviteLink.php +++ b/app/Livewire/Team/InviteLink.php @@ -1,6 +1,6 @@ subject('You have been invited to ' . currentTeam()->name . ' on ' . config('app.name') . '.'); send_user_an_email($mail, $this->email); - $this->emit('success', 'Invitation sent via email successfully.'); - $this->emit('refreshInvitations'); + $this->dispatch('success', 'Invitation sent via email successfully.'); + $this->dispatch('refreshInvitations'); return; } else { - $this->emit('success', 'Invitation link generated.'); - $this->emit('refreshInvitations'); + $this->dispatch('success', 'Invitation link generated.'); + $this->dispatch('refreshInvitations'); } } catch (\Throwable $e) { $error_message = $e->getMessage(); diff --git a/app/Http/Livewire/Team/Member.php b/app/Livewire/Team/Member.php similarity index 82% rename from app/Http/Livewire/Team/Member.php rename to app/Livewire/Team/Member.php index 34b8e6bde..7d02dbf66 100644 --- a/app/Http/Livewire/Team/Member.php +++ b/app/Livewire/Team/Member.php @@ -1,6 +1,6 @@ member->teams()->updateExistingPivot(currentTeam()->id, ['role' => 'admin']); - $this->emit('reloadWindow'); + $this->dispatch('reloadWindow'); } public function makeReadonly() { $this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => 'member']); - $this->emit('reloadWindow'); + $this->dispatch('reloadWindow'); } public function remove() @@ -29,6 +29,6 @@ class Member extends Component Cache::remember('team:' . $this->member->id, 3600, function() { return $this->member->teams()->first(); }); - $this->emit('reloadWindow'); + $this->dispatch('reloadWindow'); } } diff --git a/app/Http/Livewire/Team/Storage/Create.php b/app/Livewire/Team/Storage/Create.php similarity index 94% rename from app/Http/Livewire/Team/Storage/Create.php rename to app/Livewire/Team/Storage/Create.php index 6d140d96c..14c4cda9b 100644 --- a/app/Http/Livewire/Team/Storage/Create.php +++ b/app/Livewire/Team/Storage/Create.php @@ -1,6 +1,6 @@ storage->team_id = currentTeam()->id; $this->storage->testConnection(); $this->storage->save(); - return redirect()->route('team.storages.show', $this->storage->uuid); + return $this->redirectRoute('team.storages.show', $this->storage->uuid, navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Team/Storage/Form.php b/app/Livewire/Team/Storage/Form.php similarity index 87% rename from app/Http/Livewire/Team/Storage/Form.php rename to app/Livewire/Team/Storage/Form.php index e49dc6741..4c95c1e26 100644 --- a/app/Http/Livewire/Team/Storage/Form.php +++ b/app/Livewire/Team/Storage/Form.php @@ -1,6 +1,6 @@ storage->testConnection(shouldSave: true); - return $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); + return $this->dispatch('success', 'Connection is working. Tested with "ListObjectsV2" action.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -43,7 +43,7 @@ class Form extends Component { try { $this->storage->delete(); - return redirect()->route('team.storages.all'); + return $this->redirectRoute('team.storages.all', navigate: true); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/Upgrade.php b/app/Livewire/Upgrade.php similarity index 91% rename from app/Http/Livewire/Upgrade.php rename to app/Livewire/Upgrade.php index fc930a997..0c6541d8f 100644 --- a/app/Http/Livewire/Upgrade.php +++ b/app/Livewire/Upgrade.php @@ -1,6 +1,6 @@ showProgress = true; UpdateCoolify::run(true); - $this->emit('success', "Upgrading to {$this->latestVersion} version..."); + $this->dispatch('success', "Upgrading to {$this->latestVersion} version..."); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Http/Livewire/VerifyEmail.php b/app/Livewire/VerifyEmail.php similarity index 83% rename from app/Http/Livewire/VerifyEmail.php rename to app/Livewire/VerifyEmail.php index e485102cb..b1aec4353 100644 --- a/app/Http/Livewire/VerifyEmail.php +++ b/app/Livewire/VerifyEmail.php @@ -1,6 +1,6 @@ rateLimit(1, 300); auth()->user()->sendVerificationEmail(); - $this->emit('success', 'Email verification link sent!'); + $this->dispatch('success', 'Email verification link sent!'); } catch(\Exception $e) { ray($e); diff --git a/app/Http/Livewire/Waitlist/Index.php b/app/Livewire/Waitlist/Index.php similarity index 78% rename from app/Http/Livewire/Waitlist/Index.php rename to app/Livewire/Waitlist/Index.php index c1e6ad939..5df8ba0b7 100644 --- a/app/Http/Livewire/Waitlist/Index.php +++ b/app/Livewire/Waitlist/Index.php @@ -1,6 +1,6 @@ route('register'); + return $this->redirectRoute('register', navigate: true); } $this->waitingInLine = Waitlist::whereVerified(true)->count(); $this->users = User::count(); @@ -43,10 +43,10 @@ class Index extends Component $found = Waitlist::where('email', $this->email)->first(); if ($found) { if (!$found->verified) { - $this->emit('error', 'You are already on the waitlist.
Please check your email to verify your email address.'); + $this->dispatch('error', 'You are already on the waitlist.
Please check your email to verify your email address.'); return; } - $this->emit('error', 'You are already on the waitlist.
You will be notified when your turn comes.
Thank you.'); + $this->dispatch('error', 'You are already on the waitlist.
You will be notified when your turn comes.
Thank you.'); return; } $waitlist = Waitlist::create([ @@ -54,7 +54,7 @@ class Index extends Component 'type' => 'registration', ]); - $this->emit('success', 'Check your email to verify your email address.'); + $this->dispatch('success', 'Check your email to verify your email address.'); dispatch(new SendConfirmationForWaitlistJob($this->email, $waitlist->uuid)); } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Models/Service.php b/app/Models/Service.php index 8b7202a65..eb0d96670 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -2,45 +2,17 @@ namespace App\Models; +use App\Actions\Service\DeleteService; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Collection; -use Symfony\Component\Yaml\Yaml; use Illuminate\Support\Str; class Service extends BaseModel { - use HasFactory; + use HasFactory, SoftDeletes; protected $guarded = []; - - protected static function booted() - { - static::deleting(function ($service) { - $storagesToDelete = collect([]); - foreach ($service->applications()->get() as $application) { - $storages = $application->persistentStorages()->get(); - foreach ($storages as $storage) { - $storagesToDelete->push($storage); - } - } - foreach ($service->databases()->get() as $database) { - $storages = $database->persistentStorages()->get(); - foreach ($storages as $storage) { - $storagesToDelete->push($storage); - } - } - $service->environment_variables()->delete(); - $service->applications()->delete(); - $service->databases()->delete(); - - $server = data_get($service, 'server'); - if ($server && $storagesToDelete->count() > 0) { - $storagesToDelete->each(function ($storage) use ($server) { - instant_remote_process(["docker volume rm -f $storage->name"], $server, false); - }); - } - }); - } public function type() { return 'service'; @@ -207,7 +179,6 @@ class Service extends BaseModel break; } } - ray($fields); $databases = $this->databases()->get(); foreach ($databases as $database) { diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index 2fe90415e..91e42c5be 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -24,6 +24,7 @@ function remote_process( ?string $type_uuid = null, ?Model $model = null, bool $ignore_errors = false, + $callEventOnFinish = null ): Activity { if (is_null($type)) { $type = ActivityTypes::INLINE->value; @@ -47,18 +48,12 @@ function remote_process( type: $type, type_uuid: $type_uuid, model: $model, - ignore_errors: $ignore_errors + ignore_errors: $ignore_errors, + call_event_on_finish: $callEventOnFinish, ), ])(); } -// function removePrivateKeyFromSshAgent(Server $server) -// { -// if (data_get($server, 'privateKey.private_key') === null) { -// throw new \Exception("Server {$server->name} does not have a private key"); -// } -// // processWithEnv()->run("echo '{$server->privateKey->private_key}' | ssh-add -d -"); -// } function savePrivateKeyToFs(Server $server) { if (data_get($server, 'privateKey.private_key') === null) { diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 3b4e2708d..4f0fda777 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -102,7 +102,7 @@ function handleError(?Throwable $error = null, ?Livewire\Component $livewire = n { if ($error instanceof TooManyRequestsException) { if (isset($livewire)) { - return $livewire->emit('error', "Too many requests. Please try again in {$error->secondsUntilAvailable} seconds."); + return $livewire->dispatch('error', "Too many requests. Please try again in {$error->secondsUntilAvailable} seconds."); } return "Too many requests. Please try again in {$error->secondsUntilAvailable} seconds."; } @@ -117,7 +117,7 @@ function handleError(?Throwable $error = null, ?Livewire\Component $livewire = n } if (isset($livewire)) { - return $livewire->emit('error', $message); + return $livewire->dispatch('error', $message); } throw new Exception($message); } @@ -967,6 +967,10 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal } } } else { + $foundEnv = EnvironmentVariable::where([ + 'key' => $key, + 'service_id' => $resource->id, + ])->first(); if ($value->contains(':-')) { $key = $value->before(':'); $defaultValue = $value->after(':-'); diff --git a/bootstrap/helpers/subscriptions.php b/bootstrap/helpers/subscriptions.php index 6707f8937..c994199f2 100644 --- a/bootstrap/helpers/subscriptions.php +++ b/bootstrap/helpers/subscriptions.php @@ -128,11 +128,12 @@ function allowedPathsForUnsubscribedAccounts() 'logout', 'waitlist', 'force-password-reset', - 'livewire/message/force-password-reset', - 'livewire/message/check-license', - 'livewire/message/switch-team', - 'livewire/message/subscription.pricing-plans', - 'livewire/message/help' + // 'livewire/message/force-password-reset', + // 'livewire/message/check-license', + // 'livewire/message/switch-team', + // 'livewire/message/subscription.pricing-plans', + // 'livewire/message/help', + 'livewire/update' ]; } function allowedPathsForBoardingAccounts() @@ -140,8 +141,9 @@ function allowedPathsForBoardingAccounts() return [ ...allowedPathsForUnsubscribedAccounts(), 'boarding', - 'livewire/message/boarding.index', - 'livewire/message/activity-monitor' + // 'livewire/message/boarding.index', + // 'livewire/message/activity-monitor', + 'livewire/update' ]; } function allowedPathsForInvalidAccounts() { @@ -149,8 +151,9 @@ function allowedPathsForInvalidAccounts() { 'logout', 'verify', 'force-password-reset', - 'livewire/message/force-password-reset', - 'livewire/message/verify-email', - 'livewire/message/help' + // 'livewire/message/force-password-reset', + // 'livewire/message/verify-email', + // 'livewire/message/help', + 'livewire/update' ]; } diff --git a/composer.json b/composer.json index 349133ffa..5a7f39844 100644 --- a/composer.json +++ b/composer.json @@ -22,9 +22,9 @@ "lcobucci/jwt": "^5.0.0", "league/flysystem-aws-s3-v3": "^3.0", "league/flysystem-sftp-v3": "^3.0", - "livewire/livewire": "^v2.12.3", + "livewire/livewire": "^3.0", "lorisleiva/laravel-actions": "^2.7", - "masmerise/livewire-toaster": "^1.2", + "masmerise/livewire-toaster": "^2.0", "nubs/random-name-generator": "^2.2", "phpseclib/phpseclib": "~3.0", "poliander/cron": "^3.0", @@ -39,7 +39,7 @@ "stripe/stripe-php": "^12.0", "symfony/yaml": "^6.2", "visus/cuid2": "^2.0.0", - "wire-elements/modal": "^1.0", + "wire-elements/modal": "^2.0", "yosymfony/toml": "^1.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index bcf9b80ec..54b33b87a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c1fc9357fddf5e7b23bb5d500c54fe29", + "content-hash": "44337ff4ff1d9c435d9776fec01ebe9c", "packages": [ { "name": "aws/aws-crt-php", @@ -3132,33 +3132,34 @@ }, { "name": "livewire/livewire", - "version": "v2.12.6", + "version": "v3.2.6", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "7d3a57b3193299cf1a0639a3935c696f4da2cf92" + "reference": "ecded08cdc4b36bbb4b26bcc7f7a171ea2e4368c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/7d3a57b3193299cf1a0639a3935c696f4da2cf92", - "reference": "7d3a57b3193299cf1a0639a3935c696f4da2cf92", + "url": "https://api.github.com/repos/livewire/livewire/zipball/ecded08cdc4b36bbb4b26bcc7f7a171ea2e4368c", + "reference": "ecded08cdc4b36bbb4b26bcc7f7a171ea2e4368c", "shasum": "" }, "require": { - "illuminate/database": "^7.0|^8.0|^9.0|^10.0", - "illuminate/support": "^7.0|^8.0|^9.0|^10.0", - "illuminate/validation": "^7.0|^8.0|^9.0|^10.0", + "illuminate/database": "^10.0", + "illuminate/support": "^10.0", + "illuminate/validation": "^10.0", "league/mime-type-detection": "^1.9", - "php": "^7.2.5|^8.0", - "symfony/http-kernel": "^5.0|^6.0" + "php": "^8.1", + "symfony/http-kernel": "^6.2" }, "require-dev": { "calebporzio/sushi": "^2.1", - "laravel/framework": "^7.0|^8.0|^9.0|^10.0", + "laravel/framework": "^10.0", + "laravel/prompts": "^0.1.6", "mockery/mockery": "^1.3.1", - "orchestra/testbench": "^5.0|^6.0|^7.0|^8.0", - "orchestra/testbench-dusk": "^5.2|^6.0|^7.0|^8.0", - "phpunit/phpunit": "^8.4|^9.0", + "orchestra/testbench": "^8.0", + "orchestra/testbench-dusk": "^8.0", + "phpunit/phpunit": "^9.0", "psy/psysh": "@stable" }, "type": "library", @@ -3193,7 +3194,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v2.12.6" + "source": "https://github.com/livewire/livewire/tree/v3.2.6" }, "funding": [ { @@ -3201,7 +3202,7 @@ "type": "github" } ], - "time": "2023-08-11T04:02:34+00:00" + "time": "2023-12-04T21:20:19+00:00" }, { "name": "lorisleiva/laravel-actions", @@ -3352,25 +3353,28 @@ }, { "name": "masmerise/livewire-toaster", - "version": "1.3.0", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/masmerise/livewire-toaster.git", - "reference": "da21267abd9684c590a131a40173fb3c42eab722" + "reference": "89aa127df5d17b915b0818761bdf83e8915036c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/masmerise/livewire-toaster/zipball/da21267abd9684c590a131a40173fb3c42eab722", - "reference": "da21267abd9684c590a131a40173fb3c42eab722", + "url": "https://api.github.com/repos/masmerise/livewire-toaster/zipball/89aa127df5d17b915b0818761bdf83e8915036c2", + "reference": "89aa127df5d17b915b0818761bdf83e8915036c2", "shasum": "" }, "require": { "laravel/framework": "^10.0", - "livewire/livewire": "^2.0", + "livewire/livewire": "^3.0", "php": "~8.2" }, + "conflict": { + "stevebauman/unfinalize": "*" + }, "require-dev": { - "dive-be/php-crowbar": "^1.1", + "dive-be/php-crowbar": "^1.0", "laravel/pint": "^1.0", "nunomaduro/larastan": "^2.0", "orchestra/testbench": "^8.0", @@ -3414,9 +3418,9 @@ ], "support": { "issues": "https://github.com/masmerise/livewire-toaster/issues", - "source": "https://github.com/masmerise/livewire-toaster/tree/1.3.0" + "source": "https://github.com/masmerise/livewire-toaster/tree/2.0.3" }, - "time": "2023-08-05T18:22:07+00:00" + "time": "2023-09-28T12:07:49+00:00" }, { "name": "monolog/monolog", @@ -10224,25 +10228,25 @@ }, { "name": "wire-elements/modal", - "version": "1.0.8", + "version": "2.0.8", "source": { "type": "git", "url": "https://github.com/wire-elements/modal.git", - "reference": "1019f423485afb6df0d1531d978e93d4ad0975fb" + "reference": "d6dac3a6ef6527a734504d8a84de49ec0a72282b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wire-elements/modal/zipball/1019f423485afb6df0d1531d978e93d4ad0975fb", - "reference": "1019f423485afb6df0d1531d978e93d4ad0975fb", + "url": "https://api.github.com/repos/wire-elements/modal/zipball/d6dac3a6ef6527a734504d8a84de49ec0a72282b", + "reference": "d6dac3a6ef6527a734504d8a84de49ec0a72282b", "shasum": "" }, "require": { - "livewire/livewire": "^2.0", - "php": "^7.4|^8.0", + "livewire/livewire": "^3.0", + "php": "^8.1", "spatie/laravel-package-tools": "^1.9" }, "require-dev": { - "orchestra/testbench": "^6.15", + "orchestra/testbench": "^8.5", "phpunit/phpunit": "^9.5" }, "type": "library", @@ -10276,9 +10280,9 @@ ], "support": { "issues": "https://github.com/wire-elements/modal/issues", - "source": "https://github.com/wire-elements/modal/tree/1.0.8" + "source": "https://github.com/wire-elements/modal/tree/2.0.8" }, - "time": "2023-04-07T12:35:15+00:00" + "time": "2023-11-12T14:57:13+00:00" }, { "name": "yosymfony/parser-utils", diff --git a/config/broadcasting.php b/config/broadcasting.php index c9149b6f6..5509b0073 100644 --- a/config/broadcasting.php +++ b/config/broadcasting.php @@ -36,7 +36,7 @@ return [ 'secret' => env('PUSHER_APP_SECRET', 'coolify'), 'app_id' => env('PUSHER_APP_ID', 'coolify'), 'options' => [ - 'host' => env('PUSHER_BACKEND_HOST', 'coolify-soketi'), + 'host' => env('PUSHER_BACKEND_HOST', 'coolify-realtime'), 'port' => env('PUSHER_BACKEND_PORT', 6001), 'scheme' => env('PUSHER_SCHEME', 'http'), 'encrypted' => true, diff --git a/config/livewire.php b/config/livewire.php index 59f8d5c4d..b1a3bf555 100644 --- a/config/livewire.php +++ b/config/livewire.php @@ -3,156 +3,145 @@ return [ /* - |-------------------------------------------------------------------------- + |--------------------------------------------------------------------------- | Class Namespace - |-------------------------------------------------------------------------- + |--------------------------------------------------------------------------- | - | This value sets the root namespace for Livewire component classes in - | your application. This value affects component auto-discovery and - | any Livewire file helper commands, like `artisan make:livewire`. - | - | After changing this item, run: `php artisan livewire:discover`. + | This value sets the root class namespace for Livewire component classes in + | your application. This value will change where component auto-discovery + | finds components. It's also referenced by the file creation commands. | */ - 'class_namespace' => 'App\\Http\\Livewire', + 'class_namespace' => 'App\\Livewire', /* - |-------------------------------------------------------------------------- + |--------------------------------------------------------------------------- | View Path - |-------------------------------------------------------------------------- + |--------------------------------------------------------------------------- | - | This value sets the path for Livewire component views. This affects - | file manipulation helper commands like `artisan make:livewire`. + | This value is used to specify where Livewire component Blade templates are + | stored when running file creation commands like `artisan make:livewire`. + | It is also used if you choose to omit a component's render() method. | */ 'view_path' => resource_path('views/livewire'), /* - |-------------------------------------------------------------------------- + |--------------------------------------------------------------------------- | Layout - |-------------------------------------------------------------------------- - | The default layout view that will be used when rendering a component via - | Route::get('/some-endpoint', SomeComponent::class);. In this case the - | the view returned by SomeComponent will be wrapped in "layouts.app" + |--------------------------------------------------------------------------- + | The view that will be used as the layout when rendering a single component + | as an entire page via `Route::get('/post/create', CreatePost::class);`. + | In this case, the view returned by CreatePost will render into $slot. | */ - 'layout' => 'layouts.app', + 'layout' => 'components.layout', /* - |-------------------------------------------------------------------------- - | Livewire Assets URL - |-------------------------------------------------------------------------- - | - | This value sets the path to Livewire JavaScript assets, for cases where - | your app's domain root is not the correct path. By default, Livewire - | will load its JavaScript assets from the app's "relative root". - | - | Examples: "/assets", "myurl.com/app". - | - */ - - 'asset_url' => null, - - /* - |-------------------------------------------------------------------------- - | Livewire App URL - |-------------------------------------------------------------------------- - | - | This value should be used if livewire assets are served from CDN. - | Livewire will communicate with an app through this url. - | - | Examples: "https://my-app.com", "myurl.com/app". - | - */ - - 'app_url' => null, - - /* - |-------------------------------------------------------------------------- - | Livewire Endpoint Middleware Group - |-------------------------------------------------------------------------- - | - | This value sets the middleware group that will be applied to the main - | Livewire "message" endpoint (the endpoint that gets hit everytime - | a Livewire component updates). It is set to "web" by default. - | - */ - - 'middleware_group' => 'web', - - /* - |-------------------------------------------------------------------------- - | Livewire Temporary File Uploads Endpoint Configuration - |-------------------------------------------------------------------------- + |--------------------------------------------------------------------------- + | Temporary File Uploads + |--------------------------------------------------------------------------- | | Livewire handles file uploads by storing uploads in a temporary directory - | before the file is validated and stored permanently. All file uploads - | are directed to a global endpoint for temporary storage. The config - | items below are used for customizing the way the endpoint works. + | before the file is stored permanently. All file uploads are directed to + | a global endpoint for temporary storage. You may configure this below: | */ 'temporary_file_upload' => [ - 'disk' => null, // Example: 'local', 's3' Default: 'default' - 'rules' => null, // Example: ['file', 'mimes:png,jpg'] Default: ['required', 'file', 'max:12288'] (12MB) - 'directory' => null, // Example: 'tmp' Default 'livewire-tmp' - 'middleware' => null, // Example: 'throttle:5,1' Default: 'throttle:60,1' - 'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs. + 'disk' => null, // Example: 'local', 's3' | Default: 'default' + 'rules' => null, // Example: ['file', 'mimes:png,jpg'] | Default: ['required', 'file', 'max:12288'] (12MB) + 'directory' => null, // Example: 'tmp' | Default: 'livewire-tmp' + 'middleware' => null, // Example: 'throttle:5,1' | Default: 'throttle:60,1' + 'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs... 'png', 'gif', 'bmp', 'svg', 'wav', 'mp4', 'mov', 'avi', 'wmv', 'mp3', 'm4a', 'jpg', 'jpeg', 'mpga', 'webp', 'wma', ], - 'max_upload_time' => 5, // Max duration (in minutes) before an upload gets invalidated. + 'max_upload_time' => 5, // Max duration (in minutes) before an upload is invalidated... ], /* - |-------------------------------------------------------------------------- - | Manifest File Path - |-------------------------------------------------------------------------- - | - | This value sets the path to the Livewire manifest file. - | The default should work for most cases (which is - | "/bootstrap/cache/livewire-components.php"), but for specific - | cases like when hosting on Laravel Vapor, it could be set to a different value. - | - | Example: for Laravel Vapor, it would be "/tmp/storage/bootstrap/cache/livewire-components.php". - | - */ - - 'manifest_path' => null, - - /* - |-------------------------------------------------------------------------- - | Back Button Cache - |-------------------------------------------------------------------------- - | - | This value determines whether the back button cache will be used on pages - | that contain Livewire. By disabling back button cache, it ensures that - | the back button shows the correct state of components, instead of - | potentially stale, cached data. - | - | Setting it to "false" (default) will disable back button cache. - | - */ - - 'back_button_cache' => false, - - /* - |-------------------------------------------------------------------------- + |--------------------------------------------------------------------------- | Render On Redirect - |-------------------------------------------------------------------------- + |--------------------------------------------------------------------------- | - | This value determines whether Livewire will render before it's redirected - | or not. Setting it to "false" (default) will mean the render method is - | skipped when redirecting. And "true" will mean the render method is - | run before redirecting. Browsers bfcache can store a potentially - | stale view if render is skipped on redirect. + | This value determines if Livewire will run a component's `render()` method + | after a redirect has been triggered using something like `redirect(...)` + | Setting this to true will render the view once more before redirecting | */ 'render_on_redirect' => false, + /* + |--------------------------------------------------------------------------- + | Eloquent Model Binding + |--------------------------------------------------------------------------- + | + | Previous versions of Livewire supported binding directly to eloquent model + | properties using wire:model by default. However, this behavior has been + | deemed too "magical" and has therefore been put under a feature flag. + | + */ + + 'legacy_model_binding' => true, + + /* + |--------------------------------------------------------------------------- + | Auto-inject Frontend Assets + |--------------------------------------------------------------------------- + | + | By default, Livewire automatically injects its JavaScript and CSS into the + | and of pages containing Livewire components. By disabling + | this behavior, you need to use @livewireStyles and @livewireScripts. + | + */ + + 'inject_assets' => true, + + /* + |--------------------------------------------------------------------------- + | Navigate (SPA mode) + |--------------------------------------------------------------------------- + | + | By adding `` to links in your Livewire application, Livewire + | will prevent the default link handling and instead request those pages + | via AJAX, creating an SPA-like effect. Configure this behavior here. + | + */ + + 'navigate' => [ + 'show_progress_bar' => true, + 'progress_bar_color' => '#ffff00', + ], + + /* + |--------------------------------------------------------------------------- + | HTML Morph Markers + |--------------------------------------------------------------------------- + | + | Livewire intelligently "morphs" existing HTML into the newly rendered HTML + | after each update. To make this process more reliable, Livewire injects + | "markers" into the rendered Blade surrounding @if, @class & @foreach. + | + */ + + 'inject_morph_markers' => true, + + /* + |--------------------------------------------------------------------------- + | Pagination Theme + |--------------------------------------------------------------------------- + | + | When enabling Livewire's pagination feature by using the `WithPagination` + | trait, Livewire will use Tailwind templates to render pagination views + | on the page. If you want Bootstrap CSS, you can specify: "bootstrap" + | + */ + + 'pagination_theme' => 'tailwind', ]; diff --git a/config/sentry.php b/config/sentry.php index f0f05d242..f86b5d19d 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.154', + 'release' => '4.0.0-beta.155', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index b101b03d8..aac53d846 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('services', function (Blueprint $table) { + $table->dropSoftDeletes(); + }); + } +}; diff --git a/database/migrations/2023_12_11_103611_add_realtime_connection_problem.php b/database/migrations/2023_12_11_103611_add_realtime_connection_problem.php new file mode 100644 index 000000000..285e2f457 --- /dev/null +++ b/database/migrations/2023_12_11_103611_add_realtime_connection_problem.php @@ -0,0 +1,28 @@ +boolean('is_notification_realtime_enabled')->default(true); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('is_notification_realtime_enabled'); + }); + } +}; diff --git a/database/seeders/PrivateKeySeeder.php b/database/seeders/PrivateKeySeeder.php index d0c9a4570..76ddce8e0 100644 --- a/database/seeders/PrivateKeySeeder.php +++ b/database/seeders/PrivateKeySeeder.php @@ -28,6 +28,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== ]); PrivateKey::create([ + "id" => 1, "team_id" => 0, "name" => "development-github-app", "description" => "This is the key for using the development GitHub app", @@ -61,6 +62,7 @@ a1C8EDKapCw5hAhizEFOUQKOygL8Ipn+tmEUkORYdZ8Q8cWFCv9nIw== "is_git_related" => true ]); PrivateKey::create([ + "id" => 2, "team_id" => 0, "name" => "development-gitlab-app", "description" => "This is the key for using the development Gitlab app", diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 4c5e98d55..44e51248e 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -56,7 +56,7 @@ services: ports: - "${FORWARD_SOKETI_PORT:-6001}:6001" environment: - SOKETI_DEBUG: "false" + SOKETI_DEBUG: "true" SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID:-coolify}" SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY:-coolify}" SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET:-coolify}" diff --git a/docker-compose.yml b/docker-compose.yml index 659ded8d9..6adfaf98a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,7 +26,7 @@ services: - coolify soketi: image: 'quay.io/soketi/soketi:1.6-16-alpine' - container_name: coolify-soketi + container_name: coolify-realtime restart: always networks: - coolify diff --git a/docker/prod-ssu/etc/s6-overlay/s6-rc.d/init-script/up b/docker/prod-ssu/etc/s6-overlay/s6-rc.d/init-script/up index 32492f6b7..09595f708 100644 --- a/docker/prod-ssu/etc/s6-overlay/s6-rc.d/init-script/up +++ b/docker/prod-ssu/etc/s6-overlay/s6-rc.d/init-script/up @@ -1,2 +1,2 @@ #!/command/execlineb -P -php /var/www/html/artisan app:init --cleanup +php /var/www/html/artisan app:init diff --git a/resources/js/app.js b/resources/js/app.js index aa3ae8f2a..526e9403e 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,19 +1,8 @@ -import Alpine from "alpinejs"; -import focus from '@alpinejs/focus'; import { createApp } from "vue"; import MagicBar from "./components/MagicBar.vue"; -import Toaster from "../../vendor/masmerise/livewire-toaster/resources/js"; +import '../../vendor/masmerise/livewire-toaster/resources/js'; import "../../vendor/wire-elements/modal/resources/js/modal"; -Alpine.plugin(focus); -Alpine.plugin(Toaster); - -window.Alpine = Alpine; -Alpine.start(); - const app = createApp({}); app.component("magic-bar", MagicBar); app.mount("#vue"); - - - diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index d2e00f58f..b2111d561 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -23,7 +23,7 @@
@csrf - @env('local') + @env('local') diff --git a/resources/views/auth/verify-email.blade.php b/resources/views/auth/verify-email.blade.php index dca6a4c6a..7db8da43b 100644 --- a/resources/views/auth/verify-email.blade.php +++ b/resources/views/auth/verify-email.blade.php @@ -3,7 +3,7 @@

Verification Email Sent

-
To activate your account, please open the email and follow the +
To activate your account, please open the email and follow the instructions.
diff --git a/resources/views/components/applications/links.blade.php b/resources/views/components/applications/links.blade.php index c5bdc4a48..d1bb5c774 100644 --- a/resources/views/components/applications/links.blade.php +++ b/resources/views/components/applications/links.blade.php @@ -1,6 +1,6 @@
@if (data_get($application, 'fqdn') || - collect(json_decode($this->application->docker_compose_domains))->count() > 0 || + collect(json_decode($this->application->docker_compose_domains))->count() > 0 || data_get($application, 'previews', collect([]))->count() > 0 || data_get($application, 'ports_mappings_array'))