This commit is contained in:
Andras Bacsai 2023-05-04 15:45:53 +02:00
parent ec0e560bac
commit d5b332fc59
16 changed files with 149 additions and 43 deletions

View File

@ -19,9 +19,9 @@ class Change extends Component
{
$this->private_key = PrivateKey::where('uuid', $this->private_key_uuid)->first();
}
public function delete($private_key_uuid)
public function delete()
{
PrivateKey::where('uuid', $private_key_uuid)->delete();
PrivateKey::where('uuid', $this->private_key_uuid)->delete();
session('currentTeam')->privateKeys = PrivateKey::where('team_id', session('currentTeam')->id)->get();
redirect()->route('dashboard');
}

View File

@ -0,0 +1,48 @@
<?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');
}
}

View File

@ -1,10 +0,0 @@
<?php
namespace App\Http\Livewire\Project\Application;
use Livewire\Component;
class EnvironmentVariables extends Component
{
public array $envs = [];
}

View File

@ -4,6 +4,8 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Spatie\Activitylog\Models\Activity;
use Illuminate\Database\Eloquent\Builder;
use Spatie\SchemalessAttributes\Casts\SchemalessAttributes;
class Application extends BaseModel
{
@ -20,6 +22,7 @@ class Application extends BaseModel
});
}
protected $fillable = [
'name',
'description',
@ -35,6 +38,13 @@ 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
{

View File

@ -23,21 +23,26 @@ class Server extends BaseModel
'team_id',
'private_key_id',
];
public $casts = [
'extra_attributes' => SchemalessAttributes::class,
];
public function standaloneDockers()
{
return $this->hasMany(StandaloneDocker::class);
}
public function swarmDockers()
{
return $this->hasMany(SwarmDocker::class);
}
public $casts = [
'extra_attributes' => SchemalessAttributes::class,
];
public function scopeWithExtraAttributes(): Builder
{
return $this->extra_attributes->modelScope();
}
public function privateKey()
{
return $this->belongsTo(PrivateKey::class);

View File

@ -39,6 +39,8 @@ 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');

View File

@ -35,6 +35,16 @@ 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,
]
]
]);
}
}

View File

@ -2,11 +2,17 @@
document.addEventListener('alpine:init', () => {
Alpine.data('confirmModal', () => ({
open: false,
confirmAction: null,
message: 'Are you sure?',
toggleConfirmModal(customMessage) {
toggleConfirmModal(customMessage, confirmAction) {
this.confirmAction = confirmAction
this.message = customMessage
this.open = !this.open
},
confirmed() {
this.open = false
this.$dispatch(this.confirmAction)
}
}))
})
</script>
@ -16,7 +22,7 @@
<div class="flex flex-col items-center justify-center h-full">
<div class="pb-5 text-white" x-text="message"></div>
<div>
<x-inputs.button isWarning x-on:click="$dispatch('confirm')">Confirm</x-inputs.button>
<x-inputs.button isWarning x-on:click='confirmed()'>Confirm</x-inputs.button>
<x-inputs.button x-on:click="open = false">Cancel</x-inputs.button>
</div>
</div>

View File

@ -15,10 +15,10 @@
wire:loading.delay.class.remove="{{ $defaultClass }} {{ $attributes->whereStartsWith('class')->first() }}"
@endif
@isset($confirm)
x-on:click="toggleConfirmModal('{{ $confirm }}')"
x-on:click="toggleConfirmModal('{{ $confirm }}', '{{ explode('(', $confirmAction)[0] }}')"
@endisset
@isset($confirmAction)
@confirm.window="$wire.{{ $confirmAction }}()"
x-on:{{ explode('(', $confirmAction)[0] }}.window="$wire.{{ explode('(', $confirmAction)[0] }}"
@endisset>
{{ $slot }}
</button>

View File

@ -27,7 +27,7 @@
<textarea {{ $attributes }} type={{ $type }} id={{ $id }} wire:model.defer={{ $id }}></textarea>
@else
<input {{ $attributes }} type={{ $type }} id={{ $id }}
@if ($instantSave) wire:click='instantSave' wire:model.defer={{ $id }} @else wire:model.defer={{ $id }} @endif />
@if ($instantSave) wire:click='instantSave' wire:model.defer={{ $id }} @else wire:model.defer={{ $value ?? $id }} @endif />
@endif
@error($id)

View File

@ -73,6 +73,9 @@
console.log('Update initiated. Waiting for server to be dead...')
checkIfIamDead();
})
Livewire.on('reloadWindow', () => {
window.location.reload();
})
</script>
@endauth
</body>

View File

@ -9,8 +9,7 @@
<x-inputs.button>
Submit
</x-inputs.button>
<x-inputs.button confirm='Are you sure you would like to delete this private key?'
confirmAction="delete('{{ $destination->id }}')">
<x-inputs.button confirm='Are you sure you would like to delete this private key?' confirmAction="delete">
Delete
</x-inputs.button>
</div>

View File

@ -6,8 +6,7 @@
<x-inputs.button type="submit">
Submit
</x-inputs.button>
<x-inputs.button confirm='Are you sure you would like to delete this private key?'
confirmAction="delete('{{ $private_key_uuid }}')">
<x-inputs.button confirm='Are you sure you would like to delete this private key?' confirmAction="delete">
Delete
</x-inputs.button>
</form>

View File

@ -0,0 +1,28 @@
<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>

View File

@ -1,7 +0,0 @@
<div>
@forelse ($envs as $env)
{{ dump($env) }}
@empty
<p>There are no environment variables for this application.</p>
@endforelse
</div>

View File

@ -1,34 +1,47 @@
<x-layout>
<h1>Configuration</h1>
<x-applications.navbar :applicationId="$application->id" />
<div x-data="{ activeTab: 'general' }">
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }">
<div class="flex gap-4">
<a :class="activeTab === 'general' && 'text-purple-500'" @click.prevent="activeTab = 'general'"
href="#">General</a>
<a :class="activeTab === 'envs' && 'text-purple-500'" @click.prevent="activeTab = 'envs'"
href="#">Environment Variables</a>
<a :class="activeTab === 'source' && 'text-purple-500'" @click.prevent="activeTab = 'source'"
href="#">Source</a>
<a :class="activeTab === 'destination' && 'text-purple-500'" @click.prevent="activeTab = 'destination'"
<a :class="activeTab === 'general' && 'text-purple-500'"
@click.prevent="activeTab = 'general'; window.location.hash = 'general'" href="#">General</a>
<a :class="activeTab === 'environment-variables' && 'text-purple-500'"
@click.prevent="activeTab = 'environment-variables'; window.location.hash = 'environment-variables'"
href="#">Environment
Variables</a>
<a :class="activeTab === 'source' && 'text-purple-500'"
@click.prevent="activeTab = 'source'; window.location.hash = 'source'" href="#">Source</a>
<a :class="activeTab === 'destination' && 'text-purple-500'"
@click.prevent="activeTab = 'destination'; window.location.hash = 'destination'"
href="#">Destination
</a>
<a :class="activeTab === 'storages' && 'text-purple-500'" @click.prevent="activeTab = 'storages'"
href="#">Storage
<a :class="activeTab === 'storages' && 'text-purple-500'"
@click.prevent="activeTab = 'storages'; window.location.hash = 'storages'" href="#">Storage
</a>
</div>
<div x-cloak x-show="activeTab === 'general'">
<h3>General Configurations</h3>
<livewire:project.application.general :applicationId="$application->id" />
</div>
<div x-cloak x-show="activeTab === 'envs'">
<livewire:project.application.environment-variables />
<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" />
@empty
<p>There are no environment variables for this application.</p>
@endforelse
<livewire:project.application.environment-variable />
</div>
<div x-cloak x-show="activeTab === 'source'">
<h3>Source</h3>
<livewire:project.application.source :applicationId="$application->id" />
</div>
<div x-cloak x-show="activeTab === 'destination'">
<h3>Destination</h3>
<livewire:project.application.destination :destination="$application->destination" />
</div>
<div x-cloak x-show="activeTab === 'storages'">
<h3>Persistent Storages</h3>
<livewire:project.application.storages :storages="$application->persistentStorages" />
</div>
</div>