fix modal, add env variables, etc
This commit is contained in:
parent
d5b332fc59
commit
c4a4801414
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application;
|
||||
|
||||
use App\Models\Application;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Livewire\Component;
|
||||
|
||||
class EnvironmentVariable extends Component
|
||||
{
|
||||
public $parameters;
|
||||
public $env;
|
||||
public string|null $keyName = null;
|
||||
public string|null $value = null;
|
||||
public bool $isBuildOnly = false;
|
||||
public bool $isNewEnv = false;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = Route::current()->parameters();
|
||||
if (data_get($this->env, 'value') !== null) {
|
||||
$this->value = $this->env['value'];
|
||||
$this->isBuildOnly = $this->env['isBuildOnly'];
|
||||
} else {
|
||||
$this->isNewEnv = true;
|
||||
}
|
||||
}
|
||||
public function updateEnv()
|
||||
{
|
||||
$application = Application::where('uuid', $this->parameters['application_uuid'])->first();
|
||||
$application->environment_variables->set("{$this->keyName}.value", $this->value);
|
||||
$application->environment_variables->set("{$this->keyName}.isBuildOnly", $this->isBuildOnly);
|
||||
$application->save();
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
$this->updateEnv();
|
||||
$this->emit('reloadWindow');
|
||||
}
|
||||
public function delete()
|
||||
{
|
||||
$application = Application::where('uuid', $this->parameters['application_uuid'])->first();
|
||||
$application->environment_variables->forget($this->keyName);
|
||||
$application->save();
|
||||
$this->emit('reloadWindow');
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application\EnvironmentVariable;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\EnvironmentVariable;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Livewire\Component;
|
||||
|
||||
class Add extends Component
|
||||
{
|
||||
public $parameters;
|
||||
public string $key;
|
||||
public string $value;
|
||||
public bool $is_build_time = false;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = Route::current()->parameters();
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$application_id = Application::where('uuid', $this->parameters['application_uuid'])->firstOrFail()->id;
|
||||
EnvironmentVariable::create([
|
||||
'key' => $this->key,
|
||||
'value' => $this->value,
|
||||
'is_build_time' => $this->is_build_time,
|
||||
'application_id' => $application_id,
|
||||
]);
|
||||
$this->emit('reloadWindow');
|
||||
} catch (mixed $e) {
|
||||
dd('asdf');
|
||||
if ($e instanceof QueryException) {
|
||||
dd($e->errorInfo);
|
||||
$this->emit('error', $e->errorInfo[2]);
|
||||
} else {
|
||||
$this->emit('error', $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application\EnvironmentVariable;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Livewire\Component;
|
||||
|
||||
class Show extends Component
|
||||
{
|
||||
public $parameters;
|
||||
public ModelsEnvironmentVariable $env;
|
||||
|
||||
protected $rules = [
|
||||
'env.key' => 'required|string',
|
||||
'env.value' => 'required|string',
|
||||
'env.is_build_time' => 'required|boolean',
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = Route::current()->parameters();
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
$this->validate();
|
||||
$this->env->save();
|
||||
}
|
||||
public function delete()
|
||||
{
|
||||
$this->env->delete();
|
||||
$this->emit('reloadWindow');
|
||||
}
|
||||
}
|
@ -4,8 +4,7 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Spatie\Activitylog\Models\Activity;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Spatie\SchemalessAttributes\Casts\SchemalessAttributes;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Application extends BaseModel
|
||||
{
|
||||
@ -38,14 +37,6 @@ class Application extends BaseModel
|
||||
'ports_exposes',
|
||||
'publish_directory',
|
||||
];
|
||||
public $casts = [
|
||||
'environment_variables' => SchemalessAttributes::class,
|
||||
];
|
||||
public function scopeWithEnvironmentVariables(): Builder
|
||||
{
|
||||
return $this->environment_variables->modelScope();
|
||||
}
|
||||
|
||||
public function publishDirectory(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -83,6 +74,10 @@ class Application extends BaseModel
|
||||
: explode(',', $this->ports_exposes)
|
||||
);
|
||||
}
|
||||
public function environment_variables(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class);
|
||||
}
|
||||
public function environment()
|
||||
{
|
||||
return $this->belongsTo(Environment::class);
|
||||
|
46
app/Models/EnvironmentVariable.php
Normal file
46
app/Models/EnvironmentVariable.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class EnvironmentVariable extends Model
|
||||
{
|
||||
|
||||
protected $fillable = ['key', 'value', 'is_build_time', 'application_id'];
|
||||
protected $casts = [
|
||||
'value' => 'encrypted',
|
||||
'is_build_time' => 'boolean',
|
||||
];
|
||||
private function get_environment_variables(string $environment_variable): string|null
|
||||
{
|
||||
$team_id = session('currentTeam')->id;
|
||||
if (str_contains(trim($environment_variable), '{{') && str_contains(trim($environment_variable), '}}')) {
|
||||
$environment_variable = preg_replace('/\s+/', '', $environment_variable);
|
||||
$environment_variable = str_replace('{{', '', $environment_variable);
|
||||
$environment_variable = str_replace('}}', '', $environment_variable);
|
||||
if (str_starts_with($environment_variable, 'global.')) {
|
||||
$environment_variable = str_replace('global.', '', $environment_variable);
|
||||
// $environment_variable = GlobalEnvironmentVariable::where('name', $environment_variable)->where('team_id', $team_id)->first()?->value;
|
||||
return $environment_variable;
|
||||
}
|
||||
}
|
||||
return decrypt($environment_variable);
|
||||
}
|
||||
private function set_environment_variables(string $environment_variable): string|null
|
||||
{
|
||||
if (!str_contains(trim($environment_variable), '{{') && !str_contains(trim($environment_variable), '}}')) {
|
||||
return encrypt($environment_variable);
|
||||
}
|
||||
return $environment_variable;
|
||||
}
|
||||
protected function value(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn (string $value) => $this->get_environment_variables($value),
|
||||
set: fn (string $value) => $this->set_environment_variables($value),
|
||||
);
|
||||
}
|
||||
}
|
@ -39,8 +39,6 @@ return new class extends Migration
|
||||
$table->string('base_directory')->default('/');
|
||||
$table->string('publish_directory')->nullable();
|
||||
|
||||
$table->schemalessAttributes('environment_variables');
|
||||
|
||||
$table->string('health_check_path')->default('/');
|
||||
$table->string('health_check_port')->nullable();
|
||||
$table->string('health_check_host')->default('localhost');
|
||||
|
@ -0,0 +1,39 @@
|
||||
<?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('environment_variables', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->string('key');
|
||||
$table->string('value')->nullable();
|
||||
$table->boolean('is_build_time')->default(false);
|
||||
|
||||
$table->foreignId('application_id')->nullable();
|
||||
$table->foreignId('service_id')->nullable();
|
||||
$table->foreignId('database_id')->nullable();
|
||||
|
||||
$table->unique(['key', 'application_id', 'is_build_time']);
|
||||
$table->unique(['key', 'service_id', 'is_build_time']);
|
||||
$table->unique(['key', 'database_id', 'is_build_time']);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('environment_variables');
|
||||
}
|
||||
};
|
@ -35,16 +35,6 @@ class ApplicationSeeder extends Seeder
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
'source_id' => $github_public_source->id,
|
||||
'source_type' => GithubApp::class,
|
||||
'environment_variables' => [
|
||||
'NODE_ENV' => [
|
||||
'value' => 'production',
|
||||
'isBuildOnly' => true,
|
||||
],
|
||||
'PORT' => [
|
||||
'value' => 3000,
|
||||
'isBuildOnly' => false,
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Environment;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
@ -27,6 +28,7 @@ class DatabaseSeeder extends Seeder
|
||||
ApplicationSettingsSeeder::class,
|
||||
DBSeeder::class,
|
||||
ServiceSeeder::class,
|
||||
EnvironmentVariableSeeder::class,
|
||||
LocalPersistentVolumeSeeder::class,
|
||||
]);
|
||||
}
|
||||
|
22
database/seeders/EnvironmentVariableSeeder.php
Normal file
22
database/seeders/EnvironmentVariableSeeder.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\EnvironmentVariable;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class EnvironmentVariableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
EnvironmentVariable::create([
|
||||
'key' => 'NODE_ENV',
|
||||
'value' => 'production',
|
||||
'is_build_time' => true,
|
||||
'application_id' => 1,
|
||||
]);
|
||||
}
|
||||
}
|
@ -26,7 +26,8 @@
|
||||
@if ($type === 'textarea')
|
||||
<textarea {{ $attributes }} type={{ $type }} id={{ $id }} wire:model.defer={{ $id }}></textarea>
|
||||
@else
|
||||
<input {{ $attributes }} type={{ $type }} id={{ $id }}
|
||||
<input wire:dirty.class="text-black bg-amber-300" {{ $attributes }} type={{ $type }}
|
||||
id={{ $id }}
|
||||
@if ($instantSave) wire:click='instantSave' wire:model.defer={{ $id }} @else wire:model.defer={{ $value ?? $id }} @endif />
|
||||
@endif
|
||||
|
||||
|
@ -76,6 +76,9 @@
|
||||
Livewire.on('reloadWindow', () => {
|
||||
window.location.reload();
|
||||
})
|
||||
Livewire.on('error', (message) => {
|
||||
alert(message);
|
||||
})
|
||||
</script>
|
||||
@endauth
|
||||
</body>
|
||||
|
19
resources/views/components/naked-modal.blade.php
Normal file
19
resources/views/components/naked-modal.blade.php
Normal file
@ -0,0 +1,19 @@
|
||||
@props([
|
||||
'show' => null,
|
||||
'message' => 'Are you sure you want to delete this?',
|
||||
'action' => 'delete',
|
||||
])
|
||||
<div x-cloak x-show="{{ $show }}" x-transition.opacity class="fixed inset-0 bg-slate-900/75"></div>
|
||||
<div x-cloak x-show="{{ $show }}" x-transition class="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div @click.away="{{ $show }} = false" class="w-screen h-20 max-w-xl mx-auto bg-black rounded-lg">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="pb-5 text-white">{{ $message }}</div>
|
||||
<div>
|
||||
<x-inputs.button isWarning wire:click='{{ $action }}'>
|
||||
Yes
|
||||
</x-inputs.button>
|
||||
<x-inputs.button x-on:click="{{ $show }} = false">No</x-inputs.button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
5
resources/views/errors/401.blade.php
Normal file
5
resources/views/errors/401.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Unauthorized'))
|
||||
@section('code', '401')
|
||||
@section('message', __('Unauthorized'))
|
5
resources/views/errors/402.blade.php
Normal file
5
resources/views/errors/402.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Payment Required'))
|
||||
@section('code', '402')
|
||||
@section('message', __('Payment Required'))
|
5
resources/views/errors/403.blade.php
Normal file
5
resources/views/errors/403.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Forbidden'))
|
||||
@section('code', '403')
|
||||
@section('message', __($exception->getMessage() ?: 'Forbidden'))
|
5
resources/views/errors/404.blade.php
Normal file
5
resources/views/errors/404.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Not Found'))
|
||||
@section('code', '404')
|
||||
@section('message', __('Not Found'))
|
5
resources/views/errors/419.blade.php
Normal file
5
resources/views/errors/419.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Page Expired'))
|
||||
@section('code', '419')
|
||||
@section('message', __('Page Expired'))
|
5
resources/views/errors/429.blade.php
Normal file
5
resources/views/errors/429.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Too Many Requests'))
|
||||
@section('code', '429')
|
||||
@section('message', __('Too Many Requests'))
|
5
resources/views/errors/500.blade.php
Normal file
5
resources/views/errors/500.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Server Error'))
|
||||
@section('code', '500')
|
||||
@section('message', __('Server Error'))
|
5
resources/views/errors/503.blade.php
Normal file
5
resources/views/errors/503.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Service Unavailable'))
|
||||
@section('code', '503')
|
||||
@section('message', __('Service Unavailable'))
|
53
resources/views/errors/layout.blade.php
Normal file
53
resources/views/errors/layout.blade.php
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>@yield('title')</title>
|
||||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
html, body {
|
||||
background-color: #fff;
|
||||
color: #636b6f;
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-weight: 100;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.position-ref {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36px;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex-center position-ref full-height">
|
||||
<div class="content">
|
||||
<div class="title">
|
||||
@yield('message')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
34
resources/views/errors/minimal.blade.php
Normal file
34
resources/views/errors/minimal.blade.php
Normal file
File diff suppressed because one or more lines are too long
@ -1,28 +0,0 @@
|
||||
<div>
|
||||
@if ($isNewEnv === true)
|
||||
<form wire:submit.prevent='submit' class="flex gap-2 p-4">
|
||||
@else
|
||||
<form wire:submit.prevent='updateEnv' class="flex gap-2 p-4">
|
||||
@endif
|
||||
<input type="text" wire:model.defer="keyName" />
|
||||
<input type="text" wire:model.defer="value" />
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="checkbox" wire:model.defer="isBuildOnly" />
|
||||
<label>Used during build?</label>
|
||||
</div>
|
||||
</div>
|
||||
<x-inputs.button type="submit">
|
||||
@if ($isNewEnv)
|
||||
Add
|
||||
@else
|
||||
Update
|
||||
@endif
|
||||
</x-inputs.button>
|
||||
@if ($isNewEnv === false)
|
||||
<x-inputs.button isWarning wire:click.prevent='delete'>
|
||||
Delete
|
||||
</x-inputs.button>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
@ -0,0 +1,13 @@
|
||||
<form wire:submit.prevent='submit' class="flex gap-2 p-4">
|
||||
<input type="text" wire:model.defer="key" wire:dirty.class="text-black bg-amber-300" />
|
||||
<input type="text" wire:model.defer="value" wire:dirty.class="text-black bg-amber-300" />
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="checkbox" wire:model.defer="is_build_time" />
|
||||
<label>Used during build?</label>
|
||||
</div>
|
||||
</div>
|
||||
<x-inputs.button type="submit">
|
||||
Add
|
||||
</x-inputs.button>
|
||||
</form>
|
@ -0,0 +1,19 @@
|
||||
<div x-data="{ deleteEnvironment: false }">
|
||||
<form wire:submit.prevent='submit' class="flex gap-2 p-4">
|
||||
<input type="text" wire:model.defer="env.key" wire:dirty.class="text-black bg-amber-300" />
|
||||
<input type="text" wire:model.defer="env.value" wire:dirty.class="text-black bg-amber-300" />
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="checkbox" wire:model.defer="env.is_build_time" />
|
||||
<label>Used during build?</label>
|
||||
</div>
|
||||
</div>
|
||||
<x-inputs.button type="submit">
|
||||
Update
|
||||
</x-inputs.button>
|
||||
<x-inputs.button x-on:click="deleteEnvironment = true" isWarning>
|
||||
Delete
|
||||
</x-inputs.button>
|
||||
</form>
|
||||
<x-naked-modal show="deleteEnvironment" message="Are you sure you want to delete {{ $env->key }}?" />
|
||||
</div>
|
@ -25,12 +25,13 @@
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'environment-variables'" class="flex flex-col gap-2">
|
||||
<h3>Environment Variables</h3>
|
||||
@forelse ($application->environment_variables->all() as $keyName => $env)
|
||||
<livewire:project.application.environment-variable :keyName="$keyName" :env="$env" />
|
||||
@forelse ($application->environment_variables as $env)
|
||||
<livewire:project.application.environment-variable.show :env="$env" />
|
||||
@empty
|
||||
<p>There are no environment variables for this application.</p>
|
||||
@endforelse
|
||||
<livewire:project.application.environment-variable />
|
||||
<h4>Add new environment variable</h4>
|
||||
<livewire:project.application.environment-variable.add />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'source'">
|
||||
<h3>Source</h3>
|
||||
|
Loading…
x
Reference in New Issue
Block a user