feat: init postgresql database
This commit is contained in:
parent
0a040a0531
commit
a020bc872d
25
app/Actions/Database/StartPostgresql.php
Normal file
25
app/Actions/Database/StartPostgresql.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Database;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\Team;
|
||||
use App\Models\Postgresql;
|
||||
|
||||
class StartPostgresql
|
||||
{
|
||||
public function __invoke(Server $server, Postgresql $database)
|
||||
{
|
||||
$activity = remote_process([
|
||||
"echo 'Creating required Docker networks...'",
|
||||
"echo 'Creating required Docker networks...'",
|
||||
"echo 'Creating required Docker networks...'",
|
||||
"sleep 4",
|
||||
"echo 'Creating required Docker networks...'",
|
||||
"echo 'Creating required Docker networks...'",
|
||||
|
||||
], $server);
|
||||
return $activity;
|
||||
}
|
||||
}
|
@ -84,4 +84,4 @@ public function deployment()
|
||||
'deployment_uuid' => $deploymentUuid,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
@ -43,7 +43,9 @@ public function dashboard()
|
||||
$s3s = S3Storage::ownedByCurrentTeam()->get();
|
||||
$resources = 0;
|
||||
foreach ($projects as $project) {
|
||||
ray($project->postgresqls);
|
||||
$resources += $project->applications->count();
|
||||
$resources += $project->postgresqls->count();
|
||||
}
|
||||
|
||||
return view('dashboard', [
|
||||
|
30
app/Http/Controllers/DatabaseController.php
Normal file
30
app/Http/Controllers/DatabaseController.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\ApplicationDeploymentQueue;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Http\Request;
|
||||
use Spatie\Activitylog\Models\Activity;
|
||||
|
||||
class DatabaseController extends Controller
|
||||
{
|
||||
use AuthorizesRequests, ValidatesRequests;
|
||||
public function configuration()
|
||||
{
|
||||
$project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
|
||||
if (!$project) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
$environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
|
||||
if (!$environment) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
$database = $environment->databases->where('uuid', request()->route('database_uuid'))->first();
|
||||
if (!$database) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
return view('project.database.configuration', ['database' => $database]);
|
||||
}
|
||||
}
|
@ -51,4 +51,4 @@ protected function setStatus($status)
|
||||
]);
|
||||
$this->activity->save();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
namespace App\Http\Livewire\Dev;
|
||||
|
||||
use App\Models\S3Storage;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
@ -14,7 +14,6 @@ class S3Test extends Component
|
||||
public $file;
|
||||
public function mount() {
|
||||
$this->s3 = S3Storage::first();
|
||||
ray($this->s3);
|
||||
}
|
||||
public function save() {
|
||||
try {
|
@ -33,6 +33,7 @@ class General extends Component
|
||||
|
||||
protected $rules = [
|
||||
'application.name' => 'required',
|
||||
'application.description' => 'nullable',
|
||||
'application.fqdn' => 'nullable',
|
||||
'application.git_repository' => 'required',
|
||||
'application.git_branch' => 'required',
|
||||
@ -49,6 +50,7 @@ class General extends Component
|
||||
];
|
||||
protected $validationAttributes = [
|
||||
'application.name' => 'name',
|
||||
'application.description' => 'description',
|
||||
'application.fqdn' => 'FQDN',
|
||||
'application.git_repository' => 'Git repository',
|
||||
'application.git_branch' => 'Git branch',
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Application;
|
||||
namespace App\Http\Livewire\Project\Application;
|
||||
|
||||
use App\Jobs\ApplicationContainerStatusJob;
|
||||
use App\Models\Application;
|
23
app/Http/Livewire/Project/Database/Heading.php
Normal file
23
app/Http/Livewire/Project/Database/Heading.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Database;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Actions\Database\StartPostgresql;
|
||||
|
||||
class Heading extends Component
|
||||
{
|
||||
public $database;
|
||||
public array $parameters;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = getRouteParameters();
|
||||
}
|
||||
public function start() {
|
||||
if ($this->database->type() === 'postgresql') {
|
||||
$activity = resolve(StartPostgresql::class)($this->database->destination->server, $this->database);
|
||||
$this->emit('newMonitorActivity', $activity->id);
|
||||
}
|
||||
}
|
||||
}
|
39
app/Http/Livewire/Project/Database/Postgresql/General.php
Normal file
39
app/Http/Livewire/Project/Database/Postgresql/General.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Database\Postgresql;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class General extends Component
|
||||
{
|
||||
public $database;
|
||||
protected $rules = [
|
||||
'database.name' => 'required',
|
||||
'database.description' => 'nullable',
|
||||
'database.postgres_user' => 'required',
|
||||
'database.postgres_password' => 'required',
|
||||
'database.postgres_db' => 'required',
|
||||
'database.postgres_initdb_args' => 'nullable',
|
||||
'database.postgres_host_auth_method' => 'nullable',
|
||||
'database.init_scripts' => 'nullable',
|
||||
];
|
||||
protected $validationAttributes = [
|
||||
'database.name' => 'Name',
|
||||
'database.description' => 'Description',
|
||||
'database.postgres_user' => 'Postgres User',
|
||||
'database.postgres_password' => 'Postgres Password',
|
||||
'database.postgres_db' => 'Postgres DB',
|
||||
'database.postgres_initdb_args' => 'Postgres Initdb Args',
|
||||
'database.postgres_host_auth_method' => 'Postgres Host Auth Method',
|
||||
'database.init_scripts' => 'Init Scripts',
|
||||
];
|
||||
public function submit() {
|
||||
try {
|
||||
$this->validate();
|
||||
$this->database->save();
|
||||
$this->emit('success', 'Database updated successfully.');
|
||||
} catch (\Exception $e) {
|
||||
return general_error_handler(err: $e, that: $this);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,6 +17,12 @@ protected function name(): Attribute
|
||||
set: fn (string $value) => strtolower($value),
|
||||
);
|
||||
}
|
||||
public function can_delete_environment() {
|
||||
return $this->applications()->count() == 0 && $this->postgresqls()->count() == 0;
|
||||
}
|
||||
public function databases() {
|
||||
return $this->postgresqls();
|
||||
}
|
||||
public function project()
|
||||
{
|
||||
return $this->belongsTo(Project::class);
|
||||
@ -25,12 +31,12 @@ public function applications()
|
||||
{
|
||||
return $this->hasMany(Application::class);
|
||||
}
|
||||
public function databases()
|
||||
public function postgresqls()
|
||||
{
|
||||
return $this->hasMany(Database::class);
|
||||
return $this->hasMany(Postgresql::class);
|
||||
}
|
||||
public function services()
|
||||
{
|
||||
return $this->hasMany(Service::class);
|
||||
}
|
||||
}
|
||||
}
|
25
app/Models/Postgresql.php
Normal file
25
app/Models/Postgresql.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Postgresql extends BaseModel
|
||||
{
|
||||
use HasFactory;
|
||||
protected $guarded = [];
|
||||
protected $casts = [
|
||||
'postgres_password' => 'encrypted',
|
||||
];
|
||||
public function type() {
|
||||
return 'postgresql';
|
||||
}
|
||||
public function environment()
|
||||
{
|
||||
return $this->belongsTo(Environment::class);
|
||||
}
|
||||
public function destination()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
}
|
@ -46,4 +46,8 @@ public function applications()
|
||||
{
|
||||
return $this->hasManyThrough(Application::class, Environment::class);
|
||||
}
|
||||
}
|
||||
public function postgresqls()
|
||||
{
|
||||
return $this->hasManyThrough(Postgresql::class, Environment::class);
|
||||
}
|
||||
}
|
@ -8,6 +8,10 @@ class S3Storage extends BaseModel
|
||||
{
|
||||
use HasFactory;
|
||||
protected $guarded = [];
|
||||
protected $casts = [
|
||||
'key' => 'encrypted',
|
||||
'secret' => 'encrypted',
|
||||
];
|
||||
|
||||
static public function ownedByCurrentTeam(array $select = ['*'])
|
||||
{
|
||||
|
@ -13,9 +13,9 @@ public function applications()
|
||||
{
|
||||
return $this->morphMany(Application::class, 'destination');
|
||||
}
|
||||
public function databases()
|
||||
public function postgresqls()
|
||||
{
|
||||
return $this->morphMany(Database::class, 'destination');
|
||||
return $this->morphMany(Postgresql::class, 'destination');
|
||||
}
|
||||
public function server()
|
||||
{
|
||||
@ -25,4 +25,4 @@ public function attachedTo()
|
||||
{
|
||||
return $this->applications->count() > 0 || $this->databases->count() > 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ class Modal extends Component
|
||||
*/
|
||||
public function __construct(
|
||||
public string $modalId,
|
||||
public string $modalTitle,
|
||||
public string|null $modalTitle = null,
|
||||
public string|null $modalBody = null,
|
||||
public string|null $modalSubmit = null,
|
||||
public bool $yesOrNo = false,
|
||||
@ -30,4 +30,4 @@ public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.modal');
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ public function up(): void
|
||||
Schema::create('s3_storages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->string('name')->nullable();
|
||||
$table->string('name');
|
||||
$table->longText('description')->nullable();
|
||||
$table->string('region')->default('us-east-1');
|
||||
$table->longText('key');
|
||||
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('postgresqls', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->string('name');
|
||||
$table->string('description')->nullable();
|
||||
|
||||
$table->string('postgres_user')->default('postgres');
|
||||
$table->string('postgres_password');
|
||||
$table->string('postgres_db')->default('postgres');
|
||||
$table->string('postgres_initdb_args')->nullable();
|
||||
$table->string('postgres_host_auth_method')->nullable();
|
||||
$table->json('init_scripts')->nullable();
|
||||
|
||||
$table->timestamp('started_at')->nullable();
|
||||
$table->morphs('destination');
|
||||
|
||||
$table->foreignId('environment_id');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('postgresqls');
|
||||
}
|
||||
};
|
@ -11,15 +11,8 @@
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('databases', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->string('name');
|
||||
|
||||
$table->morphs('destination');
|
||||
|
||||
$table->foreignId('environment_id');
|
||||
$table->timestamps();
|
||||
Schema::table('applications', function (Blueprint $table) {
|
||||
$table->string('description')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
@ -28,6 +21,8 @@ public function up(): void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('databases');
|
||||
Schema::table('applications', function (Blueprint $table) {
|
||||
$table->dropColumn('description');
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
@ -19,13 +19,11 @@ class ApplicationSeeder extends Seeder
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$environment_1 = Environment::find(1);
|
||||
$standalone_docker_1 = StandaloneDocker::find(1);
|
||||
|
||||
$github_public_source = GithubApp::where('name', 'Public GitHub')->first();
|
||||
|
||||
Application::create([
|
||||
'name' => 'coollabsio/coolify-examples:nodejs-fastify',
|
||||
'description' => 'NodeJS Fastify Example',
|
||||
'fqdn' => 'http://foo.com',
|
||||
'repository_project_id' => 603035348,
|
||||
'git_repository' => 'coollabsio/coolify-examples',
|
||||
@ -33,11 +31,11 @@ public function run(): void
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '3000',
|
||||
'ports_mappings' => '3000:3000',
|
||||
'environment_id' => $environment_1->id,
|
||||
'destination_id' => $standalone_docker_1->id,
|
||||
'environment_id' => 1,
|
||||
'destination_id' => 1,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
'source_id' => $github_public_source->id,
|
||||
'source_type' => GithubApp::class
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ public function run(): void
|
||||
EnvironmentVariableSeeder::class,
|
||||
LocalPersistentVolumeSeeder::class,
|
||||
S3StorageSeeder::class,
|
||||
PostgresqlSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
26
database/seeders/PostgresqlSeeder.php
Normal file
26
database/seeders/PostgresqlSeeder.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\Postgresql;
|
||||
use App\Models\StandaloneDocker;
|
||||
|
||||
class PostgresqlSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Postgresql::create([
|
||||
'name' => 'Local PostgreSQL',
|
||||
'description' => 'Local PostgreSQL for testing',
|
||||
'postgres_password' => 'postgres',
|
||||
'environment_id' => 1,
|
||||
'destination_id' => 1,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
]);
|
||||
}
|
||||
}
|
41
resources/views/components/databases/navbar.blade.php
Normal file
41
resources/views/components/databases/navbar.blade.php
Normal file
@ -0,0 +1,41 @@
|
||||
<div class="navbar-main">
|
||||
<a class="{{ request()->routeIs('project.database.configuration') ? 'text-white' : '' }}"
|
||||
href="{{ route('project.database.configuration', $parameters) }}">
|
||||
<button>Configuration</button>
|
||||
</a>
|
||||
{{-- <x-applications.links :application="$application" /> --}}
|
||||
<div class="flex-1"></div>
|
||||
{{-- <x-applications.advanced :application="$application" /> --}}
|
||||
|
||||
@if ($database->status === 'running')
|
||||
<button wire:click='start' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-warning" viewBox="0 0 24 24" stroke-width="2"
|
||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path
|
||||
d="M10.09 4.01l.496 -.495a2 2 0 0 1 2.828 0l7.071 7.07a2 2 0 0 1 0 2.83l-7.07 7.07a2 2 0 0 1 -2.83 0l-7.07 -7.07a2 2 0 0 1 0 -2.83l3.535 -3.535h-3.988">
|
||||
</path>
|
||||
<path d="M7.05 11.038v-3.988"></path>
|
||||
</svg>
|
||||
Restart
|
||||
</button>
|
||||
<button wire:click='stop' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-error" viewBox="0 0 24 24" stroke-width="2"
|
||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M6 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z"></path>
|
||||
<path d="M14 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z"></path>
|
||||
</svg>
|
||||
Stop
|
||||
</button>
|
||||
@else
|
||||
<button wire:click='start' onclick="logs.showModal()"
|
||||
class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-warning" viewBox="0 0 24 24" stroke-width="1.5"
|
||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M7 4v16l13 -8z" />
|
||||
</svg>Start
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
@ -10,7 +10,9 @@
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex flex-col w-full gap-2">
|
||||
<h3 class="text-lg font-bold">{{ $modalTitle }}</h3>
|
||||
@isset($modalTitle)
|
||||
<h3 class="text-lg font-bold">{{ $modalTitle }}</h3>
|
||||
@endisset
|
||||
@isset($modalBody)
|
||||
{{ $modalBody }}
|
||||
@endisset
|
||||
@ -31,8 +33,11 @@
|
||||
</div>
|
||||
</form>
|
||||
@else
|
||||
<form method="dialog" class="flex flex-col gap-2 rounded modal-box" wire:submit.prevent='submit'>
|
||||
<h3 class="text-lg font-bold">{{ $modalTitle }}</h3>
|
||||
<form method="dialog" class="flex flex-col w-11/12 max-w-5xl gap-2 rounded modal-box"
|
||||
wire:submit.prevent='submit'>
|
||||
@isset($modalTitle)
|
||||
<h3 class="text-lg font-bold">{{ $modalTitle }}</h3>
|
||||
@endisset
|
||||
@isset($modalBody)
|
||||
{{ $modalBody }}
|
||||
@endisset
|
||||
|
@ -3,7 +3,7 @@
|
||||
<li class="inline-flex items-center">
|
||||
<a class="text-xs truncate lg:text-sm"
|
||||
href="{{ route('project.show', ['project_uuid' => $this->parameters['project_uuid']]) }}">
|
||||
{{ $application->environment->project->name }}</a>
|
||||
{{ $resource->environment->project->name }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="flex items-center">
|
||||
@ -25,7 +25,7 @@
|
||||
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<span class="text-xs truncate lg:text-sm">{{ data_get($application, 'name') }}</span>
|
||||
<span class="text-xs truncate lg:text-sm">{{ data_get($resource, 'name') }}</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
@ -38,9 +38,9 @@
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
@if ($application->status === 'running')
|
||||
@if ($resource->status === 'running')
|
||||
<x-status.running />
|
||||
@elseif($application->status === 'restarting')
|
||||
@elseif($resource->status === 'restarting')
|
||||
<x-status.restarting />
|
||||
@else
|
||||
<x-status.stopped />
|
@ -23,6 +23,6 @@
|
||||
</div>
|
||||
</div>
|
||||
@if (isDev())
|
||||
<livewire:s3-test />
|
||||
<livewire:dev.s3-test />
|
||||
@endif
|
||||
</x-layout>
|
||||
|
@ -10,21 +10,22 @@
|
||||
<div class="flex flex-col gap-2 py-4">
|
||||
<div class="flex flex-col items-end gap-2 xl:flex-row">
|
||||
<x-forms.input id="application.name" label="Name" required />
|
||||
<x-forms.input placeholder="https://coolify.io" id="application.fqdn" label="Domains"
|
||||
helper="You can specify one domain with path or more with comma.<br><span class='text-helper'>Example</span>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3" />
|
||||
@if ($wildcard_domain)
|
||||
<div class="flex flex-row gap-2">
|
||||
@if ($global_wildcard_domain)
|
||||
<x-forms.button wire:click="generateGlobalRandomDomain">Set Global Wildcard
|
||||
</x-forms.button>
|
||||
@endif
|
||||
@if ($server_wildcard_domain)
|
||||
<x-forms.button wire:click="generateServerRandomDomain">Set Server Wildcard
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
<x-forms.input id="application.description" label="Description" />
|
||||
</div>
|
||||
<x-forms.input placeholder="https://coolify.io" id="application.fqdn" label="Domains"
|
||||
helper="You can specify one domain with path or more with comma.<br><span class='text-helper'>Example</span>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3" />
|
||||
@if ($wildcard_domain)
|
||||
<div class="flex flex-row gap-2">
|
||||
@if ($global_wildcard_domain)
|
||||
<x-forms.button wire:click="generateGlobalRandomDomain">Set Global Wildcard
|
||||
</x-forms.button>
|
||||
@endif
|
||||
@if ($server_wildcard_domain)
|
||||
<x-forms.button wire:click="generateServerRandomDomain">Set Server Wildcard
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
<x-forms.select id="application.build_pack" label="Build Pack" required>
|
||||
<option value="nixpacks">Nixpacks</option>
|
||||
<option disabled value="docker">Docker</option>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<nav x-init="$wire.check_status" wire:poll.10000ms="check_status">
|
||||
<x-applications.breadcrumbs :application="$application" :parameters="$parameters" />
|
||||
<x-resources.breadcrumbs :resource="$application" :parameters="$parameters" />
|
||||
<x-applications.navbar :application="$application" :parameters="$parameters" />
|
||||
</nav>
|
@ -0,0 +1,4 @@
|
||||
<nav>
|
||||
<x-resources.breadcrumbs :resource="$database" :parameters="$parameters" />
|
||||
<x-databases.navbar :database="$database" :parameters="$parameters" />
|
||||
</nav>
|
@ -0,0 +1,18 @@
|
||||
<div>
|
||||
<form wire:submit.prevent="submit">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>General</h2>
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<x-forms.input label="Name" id="database.name" />
|
||||
<x-forms.input label="Description" id="database.description" />
|
||||
<x-forms.input label="Username" id="database.postgres_username" placeholder="If empty, use postgres." />
|
||||
<x-forms.input label="Password" id="database.postgres_password" type="password" />
|
||||
<x-forms.input label="Database" id="database.postgres_db" placeholder="If empty, use $USERNAME." />
|
||||
<x-forms.input label="Init Args" id="database.postgres_initdb_args" placeholder="If empty, use default." />
|
||||
<x-forms.input label="Host Auth Method" id="database.postgres_host_auth_method"
|
||||
placeholder="If empty, use default." />
|
||||
</form>
|
||||
</div>
|
@ -1,6 +1,6 @@
|
||||
<x-layout>
|
||||
<h1>Configuration</h1>
|
||||
<livewire:application.heading :application="$application" />
|
||||
<livewire:project.application.heading :application="$application" />
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex h-full pt-6">
|
||||
<div class="flex flex-col gap-4 min-w-fit">
|
||||
<a :class="activeTab === 'general' && 'text-white'"
|
||||
|
@ -1,5 +1,5 @@
|
||||
<x-layout>
|
||||
<h1 class="py-0">Deployment</h1>
|
||||
<livewire:application.heading :application="$application" />
|
||||
<livewire:project.application.heading :application="$application" />
|
||||
<livewire:project.application.deployment-logs :application_deployment_queue="$application_deployment_queue" />
|
||||
</x-layout>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<x-layout>
|
||||
<h1>Deployments</h1>
|
||||
<livewire:application.heading :application="$application" />
|
||||
<livewire:project.application.heading :application="$application" />
|
||||
<livewire:project.application.deployments :application="$application" :deployments="$deployments" :deployments_count="$deployments_count" />
|
||||
</x-layout>
|
||||
|
@ -1,5 +0,0 @@
|
||||
<x-layout>
|
||||
<h1>Database</h1>
|
||||
|
||||
|
||||
</x-layout>
|
65
resources/views/project/database/configuration.blade.php
Normal file
65
resources/views/project/database/configuration.blade.php
Normal file
@ -0,0 +1,65 @@
|
||||
<x-layout>
|
||||
<h1>Configuration</h1>
|
||||
<livewire:project.database.heading :database="$database" />
|
||||
<x-modal modalId="logs">
|
||||
<x-slot:modalBody>
|
||||
<livewire:activity-monitor :header="true" />
|
||||
</x-slot:modalBody>
|
||||
<x-slot:modalSubmit>
|
||||
<x-forms.button onclick="logs.close()" type="submit">
|
||||
Close
|
||||
</x-forms.button>
|
||||
</x-slot:modalSubmit>
|
||||
</x-modal>
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex h-full pt-6">
|
||||
<div class="flex flex-col gap-4 min-w-fit">
|
||||
<a :class="activeTab === 'general' && 'text-white'"
|
||||
@click.prevent="activeTab = 'general'; window.location.hash = 'general'" href="#">General</a>
|
||||
<a :class="activeTab === 'environment-variables' && 'text-white'"
|
||||
@click.prevent="activeTab = 'environment-variables'; window.location.hash = 'environment-variables'"
|
||||
href="#">Environment
|
||||
Variables</a>
|
||||
<a :class="activeTab === 'source' && 'text-white'"
|
||||
@click.prevent="activeTab = 'source'; window.location.hash = 'source'" href="#">Source</a>
|
||||
<a :class="activeTab === 'destination' && 'text-white'"
|
||||
@click.prevent="activeTab = 'destination'; window.location.hash = 'destination'"
|
||||
href="#">Destination
|
||||
</a>
|
||||
<a :class="activeTab === 'storages' && 'text-white'"
|
||||
@click.prevent="activeTab = 'storages'; window.location.hash = 'storages'" href="#">Storages
|
||||
</a>
|
||||
<a :class="activeTab === 'resource-limits' && 'text-white'"
|
||||
@click.prevent="activeTab = 'resource-limits'; window.location.hash = 'resource-limits'"
|
||||
href="#">Resource Limits
|
||||
</a>
|
||||
<a :class="activeTab === 'danger' && 'text-white'"
|
||||
@click.prevent="activeTab = 'danger'; window.location.hash = 'danger'" href="#">Danger Zone
|
||||
</a>
|
||||
</div>
|
||||
<div class="w-full pl-8">
|
||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||
@if ($database->getMorphClass() === 'App\Models\Postgresql')
|
||||
<livewire:project.database.postgresql.general :database="$database" />
|
||||
@endif
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'environment-variables'">
|
||||
{{-- <livewire:project.application.environment-variable.all :application="$application" /> --}}
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'source'">
|
||||
{{-- <livewire:project.application.source :application="$application" /> --}}
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'destination'">
|
||||
{{-- <livewire:project.application.destination :destination="$application->destination" /> --}}
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'storages'">
|
||||
{{-- <livewire:project.application.storages.all :application="$application" /> --}}
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'resource-limits'">
|
||||
{{-- <livewire:project.application.resource-limits :application="$application" /> --}}
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'danger'">
|
||||
{{-- <livewire:project.application.danger :application="$application" /> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-layout>
|
@ -5,7 +5,7 @@
|
||||
<a href="{{ route('project.resources.new', ['project_uuid' => request()->route('project_uuid'), 'environment_name' => request()->route('environment_name')]) }} "
|
||||
class="font-normal text-white normal-case border-none rounded hover:no-underline btn btn-primary btn-sm no-animation">+
|
||||
Add</a>
|
||||
@if ($environment->applications->count() === 0)
|
||||
@if ($environment->can_delete_environment())
|
||||
<livewire:project.delete-environment :environment_id="$environment->id" />
|
||||
@endif
|
||||
</div>
|
||||
@ -31,14 +31,26 @@ class="font-normal text-white normal-case border-none rounded hover:no-underline
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
@if ($environment->applications->count() === 0)
|
||||
@if ($environment->can_delete_environment())
|
||||
<p>No resources found.</p>
|
||||
@endif
|
||||
<div class="grid gap-2 lg:grid-cols-2">
|
||||
@foreach ($environment->applications->sortBy('name') as $application)
|
||||
<a class="box"
|
||||
href="{{ route('project.application.configuration', [$project->uuid, $environment->name, $application->uuid]) }}">
|
||||
{{ $application->name }}
|
||||
<div class="flex flex-col">
|
||||
<div>{{ $application->name }}</div>
|
||||
<div class="text-xs text-gray-400">{{ $application->description }}</div>
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
@foreach ($environment->databases->sortBy('name') as $databases)
|
||||
<a class="box"
|
||||
href="{{ route('project.database.configuration', [$project->uuid, $environment->name, $databases->uuid]) }}">
|
||||
<div class="flex flex-col">
|
||||
<div>{{ $databases->name }}</div>
|
||||
<div class="text-xs text-gray-400">{{ $databases->description }}</div>
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\ApplicationController;
|
||||
use App\Http\Controllers\DatabaseController;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\MagicController;
|
||||
use App\Http\Controllers\ProjectController;
|
||||
@ -52,6 +53,7 @@
|
||||
Route::get('/project/{project_uuid}/{environment_name}/new', [ProjectController::class, 'new'])->name('project.resources.new');
|
||||
Route::get('/project/{project_uuid}/{environment_name}', [ProjectController::class, 'resources'])->name('project.resources');
|
||||
Route::get('/project/{project_uuid}/{environment_name}/application/{application_uuid}', [ApplicationController::class, 'configuration'])->name('project.application.configuration');
|
||||
Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}', [DatabaseController::class, 'configuration'])->name('project.database.configuration');
|
||||
Route::get('/project/{project_uuid}/{environment_name}/application/{application_uuid}/deployment', [ApplicationController::class, 'deployments'])->name('project.application.deployments');
|
||||
Route::get(
|
||||
'/project/{project_uuid}/{environment_name}/application/{application_uuid}/deployment/{deployment_uuid}',
|
||||
|
Loading…
Reference in New Issue
Block a user