updates
This commit is contained in:
parent
0f28acac00
commit
e5aad4d170
@ -21,7 +21,7 @@ class Deploy extends Component
|
||||
protected $source;
|
||||
|
||||
protected $listeners = [
|
||||
'applicationStatusChanged' => 'applicationStatusChanged',
|
||||
'applicationStatusChanged',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
@ -40,8 +40,12 @@ protected function set_deployment_uuid()
|
||||
$this->deployment_uuid = new Cuid2(7);
|
||||
$this->parameters['deployment_uuid'] = $this->deployment_uuid;
|
||||
}
|
||||
public function deploy(bool $force = false)
|
||||
public function deploy(bool $force = false, bool|null $debug = null)
|
||||
{
|
||||
if ($debug && !$this->application->settings->is_debug_enabled) {
|
||||
$this->application->settings->is_debug_enabled = true;
|
||||
$this->application->settings->save();
|
||||
}
|
||||
$this->set_deployment_uuid();
|
||||
|
||||
queue_application_deployment(
|
||||
@ -62,5 +66,6 @@ public function stop()
|
||||
instant_remote_process(["docker rm -f {$this->application->uuid}"], $this->application->destination->server);
|
||||
$this->application->status = get_container_status(server: $this->application->destination->server, container_id: $this->application->uuid);
|
||||
$this->application->save();
|
||||
$this->emit('applicationStatusChanged');
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,12 @@
|
||||
|
||||
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 bool $is_preview = false;
|
||||
public string $key;
|
||||
public string $value;
|
||||
public bool $is_build_time = false;
|
||||
@ -32,6 +29,7 @@ public function submit()
|
||||
'key' => $this->key,
|
||||
'value' => $this->value,
|
||||
'is_build_time' => $this->is_build_time,
|
||||
'is_preview' => $this->is_preview,
|
||||
]);
|
||||
}
|
||||
public function clear()
|
||||
|
@ -21,6 +21,7 @@ public function submit($data)
|
||||
'key' => $data['key'],
|
||||
'value' => $data['value'],
|
||||
'is_build_time' => $data['is_build_time'],
|
||||
'is_preview' => $data['is_preview'],
|
||||
'application_id' => $this->application->id,
|
||||
]);
|
||||
$this->application->refresh();
|
||||
|
@ -11,7 +11,7 @@ class Status extends Component
|
||||
|
||||
public function applicationStatusChanged()
|
||||
{
|
||||
$this->emit('applicationStatusChanged');
|
||||
$this->application->refresh();
|
||||
$this->emit('applicationStatusChanged');
|
||||
}
|
||||
}
|
||||
|
@ -14,16 +14,22 @@
|
||||
class PublicGitRepository extends Component
|
||||
{
|
||||
public string $repository_url;
|
||||
private object $repository_url_parsed;
|
||||
|
||||
public int $port = 3000;
|
||||
public string $type;
|
||||
public $parameters;
|
||||
public $query;
|
||||
|
||||
public $github_apps;
|
||||
public $gitlab_apps;
|
||||
|
||||
public $branches = [];
|
||||
public string $selected_branch = 'main';
|
||||
public bool $is_static = false;
|
||||
public null|string $publish_directory = null;
|
||||
public string|null $publish_directory = null;
|
||||
|
||||
private GithubApp|GitlabApp $git_source;
|
||||
private string $git_host;
|
||||
private string $git_repository;
|
||||
private string $git_branch;
|
||||
|
||||
protected $rules = [
|
||||
'repository_url' => 'required|url',
|
||||
@ -34,7 +40,7 @@ class PublicGitRepository extends Component
|
||||
public function mount()
|
||||
{
|
||||
if (config('app.env') === 'local') {
|
||||
$this->repository_url = 'https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify';
|
||||
$this->repository_url = 'https://github.com/coollabsio/coolify-examples';
|
||||
$this->port = 3000;
|
||||
}
|
||||
$this->parameters = get_parameters();
|
||||
@ -52,18 +58,43 @@ public function instantSave()
|
||||
}
|
||||
$this->emit('saved', 'Application settings updated!');
|
||||
}
|
||||
public function load_branches()
|
||||
{
|
||||
$this->get_git_source();
|
||||
|
||||
try {
|
||||
['data' => $data] = get_from_git_api($this->git_source, "/repos/{$this->git_repository}/branches");
|
||||
$this->branches = collect($data)->pluck('name')->toArray();
|
||||
} catch (\Throwable $th) {
|
||||
return general_error_handler($th, $this);
|
||||
}
|
||||
}
|
||||
private function get_git_source()
|
||||
{
|
||||
$this->repository_url_parsed = Url::fromString($this->repository_url);
|
||||
$this->git_host = $this->repository_url_parsed->getHost();
|
||||
$this->git_repository = $this->repository_url_parsed->getSegment(1) . '/' . $this->repository_url_parsed->getSegment(2);
|
||||
$this->git_branch = $this->repository_url_parsed->getSegment(4) ?? 'main';
|
||||
|
||||
if ($this->git_host == 'github.com') {
|
||||
$this->git_source = GithubApp::where('name', 'Public GitHub')->first();
|
||||
} elseif ($this->git_host == 'gitlab.com') {
|
||||
$this->git_source = GitlabApp::where('name', 'Public GitLab')->first();
|
||||
} elseif ($this->git_host == 'bitbucket.org') {
|
||||
// Not supported yet
|
||||
}
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->validate();
|
||||
|
||||
$url = Url::fromString($this->repository_url);
|
||||
$git_host = $url->getHost();
|
||||
$git_repository = $url->getSegment(1) . '/' . $url->getSegment(2);
|
||||
$git_branch = $url->getSegment(4) ?? 'main';
|
||||
|
||||
$destination_uuid = $this->query['destination'];
|
||||
$project_uuid = $this->parameters['project_uuid'];
|
||||
$environment_name = $this->parameters['environment_name'];
|
||||
|
||||
$this->get_git_source();
|
||||
$this->git_branch = $this->selected_branch ?? $this->git_branch;
|
||||
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
$destination = SwarmDocker::where('uuid', $destination_uuid)->first();
|
||||
@ -73,29 +104,24 @@ public function submit()
|
||||
}
|
||||
$destination_class = $destination->getMorphClass();
|
||||
|
||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
||||
$project = Project::where('uuid', $project_uuid)->first();
|
||||
$environment = $project->load(['environments'])->environments->where('name', $environment_name)->first();
|
||||
|
||||
|
||||
$application_init = [
|
||||
'name' => generate_application_name($git_repository, $git_branch),
|
||||
'git_repository' => $git_repository,
|
||||
'git_branch' => $git_branch,
|
||||
'name' => generate_application_name($this->git_repository, $this->git_branch),
|
||||
'git_repository' => $this->git_repository,
|
||||
'git_branch' => $this->git_branch,
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => $this->port,
|
||||
'publish_directory' => $this->publish_directory,
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination_class,
|
||||
'source_id' => $this->git_source->id,
|
||||
'source_type' => $this->git_source->getMorphClass()
|
||||
];
|
||||
if ($git_host == 'github.com') {
|
||||
$application_init['source_id'] = GithubApp::where('name', 'Public GitHub')->first()->id;
|
||||
$application_init['source_type'] = GithubApp::class;
|
||||
} elseif ($git_host == 'gitlab.com') {
|
||||
$application_init['source_id'] = GitlabApp::where('name', 'Public GitLab')->first()->id;
|
||||
$application_init['source_type'] = GitlabApp::class;
|
||||
} elseif ($git_host == 'bitbucket.org') {
|
||||
}
|
||||
|
||||
$application = Application::create($application_init);
|
||||
$application->settings->is_static = $this->is_static;
|
||||
$application->settings->save();
|
||||
@ -106,7 +132,7 @@ public function submit()
|
||||
'application_uuid' => $application->uuid,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return general_error_handler($e);
|
||||
return general_error_handler($e, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public function __construct(
|
||||
|
||||
$this->application = Application::find($this->application_id);
|
||||
|
||||
if ($this->pull_request_id) {
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$this->preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->application->id, $this->pull_request_id);
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ public function handle(): void
|
||||
}
|
||||
|
||||
$this->workdir = "/artifacts/{$this->deployment_uuid}";
|
||||
if ($this->pull_request_id) {
|
||||
if ($this->pull_request_id !== 0) {
|
||||
ray('Deploying pull/' . $this->pull_request_id . '/head for application: ' . $this->application->name);
|
||||
$this->deploy_pull_request();
|
||||
} else {
|
||||
@ -177,7 +177,7 @@ private function build_image()
|
||||
"echo -n 'Building image... '",
|
||||
]);
|
||||
|
||||
if ($this->application->settings->is_static) {
|
||||
if ($this->application->settings->is_static && isset($this->application->build_command)) {
|
||||
$this->execute_now([
|
||||
$this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t { $this->build_image_name {$this->workdir}"),
|
||||
], isDebuggable: true);
|
||||
@ -292,9 +292,17 @@ private function execute_in_builder(string $command)
|
||||
private function generate_environment_variables($ports)
|
||||
{
|
||||
$environment_variables = collect();
|
||||
|
||||
foreach ($this->application->runtime_environment_variables as $env) {
|
||||
$environment_variables->push("$env->key=$env->value");
|
||||
ray('Generate Environment Variables');
|
||||
if ($this->pull_request_id === 0) {
|
||||
ray($this->application->runtime_environment_variables);
|
||||
foreach ($this->application->runtime_environment_variables as $env) {
|
||||
$environment_variables->push("$env->key=$env->value");
|
||||
}
|
||||
} else {
|
||||
ray($this->application->runtime_environment_variables_preview);
|
||||
foreach ($this->application->runtime_environment_variables_preview as $env) {
|
||||
$environment_variables->push("$env->key=$env->value");
|
||||
}
|
||||
}
|
||||
// Add PORT if not exists, use the first port as default
|
||||
if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('PORT'))->isEmpty()) {
|
||||
@ -305,17 +313,31 @@ private function generate_environment_variables($ports)
|
||||
private function generate_env_variables()
|
||||
{
|
||||
$this->env_args = collect([]);
|
||||
foreach ($this->application->nixpacks_environment_variables as $env) {
|
||||
$this->env_args->push("--env {$env->key}={$env->value}");
|
||||
if ($this->pull_request_id === 0) {
|
||||
foreach ($this->application->nixpacks_environment_variables as $env) {
|
||||
$this->env_args->push("--env {$env->key}={$env->value}");
|
||||
}
|
||||
} else {
|
||||
foreach ($this->application->nixpacks_environment_variables_preview as $env) {
|
||||
$this->env_args->push("--env {$env->key}={$env->value}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->env_args = $this->env_args->implode(' ');
|
||||
}
|
||||
private function generate_build_env_variables()
|
||||
{
|
||||
$this->build_args = collect(["--build-arg SOURCE_COMMIT={$this->git_commit}"]);
|
||||
foreach ($this->application->build_environment_variables as $env) {
|
||||
$this->build_args->push("--build-arg {$env->key}={$env->value}");
|
||||
if ($this->pull_request_id === 0) {
|
||||
foreach ($this->application->build_environment_variables as $env) {
|
||||
$this->build_args->push("--build-arg {$env->key}={$env->value}");
|
||||
}
|
||||
} else {
|
||||
foreach ($this->application->build_environment_variables_preview as $env) {
|
||||
$this->build_args->push("--build-arg {$env->key}={$env->value}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->build_args = $this->build_args->implode(' ');
|
||||
}
|
||||
private function add_build_env_variables_to_dockerfile()
|
||||
@ -336,15 +358,11 @@ private function add_build_env_variables_to_dockerfile()
|
||||
private function generate_docker_compose()
|
||||
{
|
||||
$ports = $this->application->settings->is_static ? [80] : $this->application->ports_exposes_array;
|
||||
if ($this->pull_request_id) {
|
||||
$persistent_storages = [];
|
||||
$volume_names = [];
|
||||
$environment_variables = [];
|
||||
} else {
|
||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||
$environment_variables = $this->generate_environment_variables($ports);
|
||||
}
|
||||
|
||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||
$environment_variables = $this->generate_environment_variables($ports);
|
||||
|
||||
$docker_compose = [
|
||||
'version' => '3.8',
|
||||
'services' => [
|
||||
@ -385,7 +403,7 @@ private function generate_docker_compose()
|
||||
]
|
||||
]
|
||||
];
|
||||
if (count($this->application->ports_mappings_array) > 0 && !$this->pull_request_id) {
|
||||
if (count($this->application->ports_mappings_array) > 0 && $this->pull_request_id === 0) {
|
||||
$docker_compose['services'][$this->container_name]['ports'] = $this->application->ports_mappings_array;
|
||||
}
|
||||
if (count($persistent_storages) > 0) {
|
||||
@ -400,8 +418,12 @@ private function generate_local_persistent_volumes()
|
||||
{
|
||||
foreach ($this->application->persistentStorages as $persistentStorage) {
|
||||
$volume_name = $persistentStorage->host_path ?? $persistentStorage->name;
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$volume_name = $volume_name . '-pr-' . $this->pull_request_id;
|
||||
}
|
||||
$local_persistent_volumes[] = $volume_name . ':' . $persistentStorage->mount_path;
|
||||
}
|
||||
ray('local_persistent_volumes', $local_persistent_volumes);
|
||||
return $local_persistent_volumes ?? [];
|
||||
}
|
||||
|
||||
@ -411,8 +433,14 @@ private function generate_local_persistent_volumes_only_volume_names()
|
||||
if ($persistentStorage->host_path) {
|
||||
continue;
|
||||
}
|
||||
$local_persistent_volumes_names[$persistentStorage->name] = [
|
||||
'name' => $persistentStorage->name,
|
||||
$name = $persistentStorage->name;
|
||||
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$name = $name . '-pr-' . $this->pull_request_id;
|
||||
}
|
||||
|
||||
$local_persistent_volumes_names[$name] = [
|
||||
'name' => $name,
|
||||
'external' => false,
|
||||
];
|
||||
}
|
||||
@ -443,11 +471,11 @@ private function set_labels_for_applications()
|
||||
$labels[] = 'coolify.applicationId=' . $this->application->id;
|
||||
$labels[] = 'coolify.type=application';
|
||||
$labels[] = 'coolify.name=' . $this->application->name;
|
||||
if ($this->pull_request_id) {
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$labels[] = 'coolify.pullRequestId=' . $this->pull_request_id;
|
||||
}
|
||||
if ($this->application->fqdn) {
|
||||
if ($this->pull_request_id) {
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$preview_fqdn = data_get($this->preview, 'fqdn');
|
||||
$template = $this->application->preview_url_template;
|
||||
$url = Url::fromString($this->application->fqdn);
|
||||
@ -566,7 +594,7 @@ private function set_git_import_settings($git_clone_command)
|
||||
private function importing_git_repository()
|
||||
{
|
||||
$git_clone_command = "git clone -q -b {$this->application->git_branch}";
|
||||
if ($this->pull_request_id) {
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$pr_branch_name = "pr-{$this->pull_request_id}-coolify";
|
||||
}
|
||||
|
||||
@ -583,7 +611,7 @@ private function importing_git_repository()
|
||||
|
||||
$commands = [$this->execute_in_builder($git_clone_command)];
|
||||
|
||||
if ($this->pull_request_id) {
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$commands[] = $this->execute_in_builder("cd {$this->workdir} && git fetch origin pull/{$this->pull_request_id}/head:$pr_branch_name >/dev/null 2>&1 && git checkout $pr_branch_name >/dev/null 2>&1");
|
||||
}
|
||||
return $commands;
|
||||
@ -592,7 +620,7 @@ private function importing_git_repository()
|
||||
$commands = [
|
||||
$this->execute_in_builder("git clone -q -b {$this->application->git_branch} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$this->application->git_repository}.git {$this->workdir}")
|
||||
];
|
||||
if ($this->pull_request_id) {
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$commands[] = $this->execute_in_builder("cd {$this->workdir} && git fetch origin pull/{$this->pull_request_id}/head:$pr_branch_name && git checkout $pr_branch_name");
|
||||
}
|
||||
return $commands;
|
||||
|
@ -99,21 +99,39 @@ public function portsExposesArray(): Attribute
|
||||
: explode(',', $this->ports_exposes)
|
||||
);
|
||||
}
|
||||
// Normal Deployments
|
||||
public function environment_variables(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class);
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false);
|
||||
}
|
||||
public function runtime_environment_variables(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('key', 'not like', 'NIXPACKS_%');
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('key', 'not like', 'NIXPACKS_%');
|
||||
}
|
||||
public function build_environment_variables(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_build_time', true)->where('key', 'not like', 'NIXPACKS_%');
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('is_build_time', true)->where('key', 'not like', 'NIXPACKS_%');
|
||||
}
|
||||
public function nixpacks_environment_variables(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('key', 'like', 'NIXPACKS_%');
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('key', 'like', 'NIXPACKS_%');
|
||||
}
|
||||
// Preview Deployments
|
||||
public function environment_variables_preview(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true);
|
||||
}
|
||||
public function runtime_environment_variables_preview(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('key', 'not like', 'NIXPACKS_%');
|
||||
}
|
||||
public function build_environment_variables_preview(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('is_build_time', true)->where('key', 'not like', 'NIXPACKS_%');
|
||||
}
|
||||
public function nixpacks_environment_variables_preview(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('key', 'like', 'NIXPACKS_%');
|
||||
}
|
||||
public function private_key()
|
||||
{
|
||||
|
@ -2,13 +2,28 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class EnvironmentVariable extends Model
|
||||
{
|
||||
protected $fillable = ['key', 'value', 'is_build_time', 'application_id'];
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function ($environment_variable) {
|
||||
if (!$environment_variable->is_preview) {
|
||||
ModelsEnvironmentVariable::create([
|
||||
'key' => $environment_variable->key,
|
||||
'value' => $environment_variable->value,
|
||||
'is_build_time' => $environment_variable->is_build_time,
|
||||
'application_id' => $environment_variable->application_id,
|
||||
'is_preview' => true,
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
protected $fillable = ['key', 'value', 'is_build_time', 'application_id', 'is_preview'];
|
||||
protected $casts = [
|
||||
"key" => 'string',
|
||||
'value' => 'encrypted',
|
||||
|
@ -17,14 +17,15 @@ public function up(): void
|
||||
$table->string('key');
|
||||
$table->string('value')->nullable();
|
||||
$table->boolean('is_build_time')->default(false);
|
||||
$table->boolean('is_preview')->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->unique(['key', 'application_id', 'is_build_time', 'is_preview']);
|
||||
$table->unique(['key', 'service_id', 'is_build_time', 'is_preview']);
|
||||
$table->unique(['key', 'database_id', 'is_build_time', 'is_preview']);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
8
package-lock.json
generated
8
package-lock.json
generated
@ -7,7 +7,7 @@
|
||||
"dependencies": {
|
||||
"@tailwindcss/typography": "0.5.9",
|
||||
"alpinejs": "3.12.2",
|
||||
"daisyui": "3.0.0",
|
||||
"daisyui": "3.0.3",
|
||||
"tailwindcss-scrollbar": "0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -941,9 +941,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/daisyui": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-3.0.0.tgz",
|
||||
"integrity": "sha512-EuNK9JQd5yrPLDynAPQkG/29vjZXFWhBK4HXvM83d9oJU0EmF35UNLLs0cslBFfLK4b+bOuhgoYPJ4BjytOxNQ==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-3.0.3.tgz",
|
||||
"integrity": "sha512-RSbXsEBj2LonvjOKEI0I64F5xFJrFrthPgxRNeAZKmACQ3NoIoP45lO6UXLW3bm8PVOUGpKf1Br2SWwc1NqnHQ==",
|
||||
"dependencies": {
|
||||
"colord": "^2.9",
|
||||
"css-selector-tokenizer": "^0.8",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"dependencies": {
|
||||
"@tailwindcss/typography": "0.5.9",
|
||||
"alpinejs": "3.12.2",
|
||||
"daisyui": "3.0.0",
|
||||
"daisyui": "3.0.3",
|
||||
"tailwindcss-scrollbar": "0.1.0"
|
||||
}
|
||||
}
|
@ -14,14 +14,14 @@ body {
|
||||
@apply scrollbar min-h-screen bg-coolgray-100 text-neutral-400 antialiased ;
|
||||
}
|
||||
main {
|
||||
@apply px-32 xl:px-14 mx-auto max-w-screen-xl;
|
||||
@apply px-32 xl:px-14 mx-auto max-w-screen-xl pt-10;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
@apply toggle toggle-warning toggle-xs rounded;
|
||||
}
|
||||
input {
|
||||
@apply input input-sm placeholder:text-neutral-700 text-white rounded-none;
|
||||
@apply input input-sm h-7 outline-none placeholder:text-neutral-700 text-white rounded-none;
|
||||
}
|
||||
input[type="text"],[type="number"],[type="email"],[type="password"] {
|
||||
@apply read-only:opacity-40;
|
||||
@ -34,7 +34,7 @@ textarea {
|
||||
@apply textarea placeholder:text-neutral-700 text-white rounded-none;
|
||||
}
|
||||
select {
|
||||
@apply select select-sm disabled:opacity-40 font-normal placeholder:text-neutral-700 text-white rounded-none;
|
||||
@apply select select-sm disabled:bg-coolgray-200 border-none disabled:opacity-50 font-normal placeholder:text-neutral-700 text-white rounded-none;
|
||||
}
|
||||
.breadcrumbs > ul > li::before {
|
||||
@apply text-warning opacity-100;
|
||||
@ -47,7 +47,7 @@ button[type="button"] {
|
||||
@apply hover:bg-coolgray-400 btn h-7 btn-xs border-none bg-coolgray-200 no-animation normal-case text-white rounded;
|
||||
}
|
||||
button[type="submit"] {
|
||||
@apply btn btn-xs no-animation h-7 normal-case text-white btn-primary rounded;
|
||||
@apply hover:bg-coolgray-400 btn h-7 btn-xs border-none bg-coolgray-200 no-animation normal-case text-white rounded;
|
||||
}
|
||||
button[isWarning] {
|
||||
@apply bg-error;
|
||||
|
@ -15,23 +15,32 @@
|
||||
]) }}">
|
||||
<button>Deployments</button>
|
||||
</a>
|
||||
<livewire:project.application.status :application="$application" />
|
||||
<div class="flex-1"></div>
|
||||
<div class="dropdown dropdown-bottom">
|
||||
<label tabindex="0">
|
||||
<x-forms.button>
|
||||
Open
|
||||
<x-chevron-down />
|
||||
</x-forms.button>
|
||||
<div class="dropdown dropdown-bottom dropdown-hover">
|
||||
<label tabindex="0" class="flex items-center gap-2 text-sm cursor-pointer hover:text-white"> Links
|
||||
<x-chevron-down />
|
||||
</label>
|
||||
<ul tabindex="0"
|
||||
class="mt-1 text-xs text-white normal-case rounded min-w-max dropdown-content menu bg-coolgray-200">
|
||||
class="text-xs text-white normal-case rounded min-w-max dropdown-content menu bg-coolgray-200">
|
||||
<li>
|
||||
<a target="_blank" class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs"
|
||||
href="{{ $application->gitBranchLocation }}">
|
||||
<x-git-icon git="{{ $application->source->getMorphClass() }}" />
|
||||
Git Repository
|
||||
</a>
|
||||
</li>
|
||||
@if (data_get($application, 'fqdn'))
|
||||
<li>
|
||||
<a class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs" target="_blank"
|
||||
href="{{ $application->fqdn }}">
|
||||
{{ $application->fqdn }}
|
||||
<x-external-link />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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="M9 15l6 -6" />
|
||||
<path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" />
|
||||
<path
|
||||
d="M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463" />
|
||||
</svg>{{ $application->fqdn }}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@ -40,9 +49,16 @@ class="mt-1 text-xs text-white normal-case rounded min-w-max dropdown-content me
|
||||
@if (config('app.env') === 'local')
|
||||
<li>
|
||||
<a class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs"
|
||||
target="_blank" href="http://localhost:{{ explode(':', $port)[0] }}">Port
|
||||
{{ explode(':', $port)[0] }}
|
||||
<x-external-link />
|
||||
target="_blank" href="http://localhost:{{ explode(':', $port)[0] }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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="M9 15l6 -6" />
|
||||
<path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" />
|
||||
<path
|
||||
d="M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463" />
|
||||
</svg>{{ $port }}
|
||||
</a>
|
||||
</li>
|
||||
@else
|
||||
@ -50,7 +66,6 @@ class="mt-1 text-xs text-white normal-case rounded min-w-max dropdown-content me
|
||||
<a class="text-xs hover:no-underline hover:bg-coollabs" target="_blank"
|
||||
href="http://{{ $application->destination->server->ip }}:{{ explode(':', $port)[0] }}">Port
|
||||
{{ $port }}
|
||||
<x-external-link />
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
|
@ -5,15 +5,17 @@
|
||||
])
|
||||
|
||||
<span {{ $attributes->merge(['class' => 'flex flex-col']) }}>
|
||||
<label for={{ $id }}>
|
||||
@if ($label)
|
||||
{{ $label }}
|
||||
@else
|
||||
{{ $id }}
|
||||
@endif
|
||||
@if ($required)
|
||||
<span class="text-warning">*</span>
|
||||
@endif
|
||||
<label class="label" for={{ $id }}>
|
||||
<span class="label-text">
|
||||
@if ($label)
|
||||
{{ $label }}
|
||||
@else
|
||||
{{ $id }}
|
||||
@endif
|
||||
@if ($required)
|
||||
<span class="text-warning">*</span>
|
||||
@endif
|
||||
</span>
|
||||
</label>
|
||||
<select {{ $attributes }} wire:model.defer={{ $id }}>
|
||||
{{ $slot }}
|
||||
|
18
resources/views/components/git-icon.blade.php
Normal file
18
resources/views/components/git-icon.blade.php
Normal file
@ -0,0 +1,18 @@
|
||||
@props([
|
||||
'git' => null,
|
||||
])
|
||||
|
||||
@if ($git === 'App\Models\GithubApp')
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" />
|
||||
</svg>
|
||||
@elseif($git === 'App\Models\GitlabApp')
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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="M21 14l-9 7l-9 -7l3 -11l3 7h6l3 -7z" />
|
||||
</svg>
|
||||
@endif
|
@ -1 +1 @@
|
||||
<span class="loading loading-bars"></span>
|
||||
<span {{ $attributes->class(['bg-warning loading', 'loading-spinner' => !$attributes->has('class')]) }}></span>
|
||||
|
@ -1,13 +1,16 @@
|
||||
<div>
|
||||
@if ($this->activity)
|
||||
@if ($header)
|
||||
<h2>Logs</h2>
|
||||
<div class="flex gap-2">
|
||||
<h2>Logs</h2>
|
||||
@if ($isPollingActive)
|
||||
<x-loading />
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
<div
|
||||
class="scrollbar flex flex-col-reverse w-full overflow-y-auto border border-solid rounded border-coolgray-300 max-h-[32rem] p-4 text-xs text-white">
|
||||
@if ($isPollingActive)
|
||||
<span class="loading loading-bars"></span>
|
||||
@endif
|
||||
|
||||
<pre class="font-mono whitespace-pre-wrap" @if ($isPollingActive) wire:poll.2000ms="polling" @endif>{{ \App\Actions\CoolifyTask\RunRemoteProcess::decodeOutput($this->activity) }}</pre>
|
||||
{{-- @else
|
||||
<pre class="whitespace-pre-wrap">Output will be here...</pre> --}}
|
||||
|
@ -1,7 +1,6 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Notifications</h2>
|
||||
<x-forms.button isHighlighted class="text-white normal-case btn btn-xs no-animation btn-primary"
|
||||
wire:click="sendTestNotification">
|
||||
<x-forms.button class="text-white normal-case btn btn-xs no-animation btn-primary" wire:click="sendTestNotification">
|
||||
Send Test Notifications
|
||||
</x-forms.button>
|
||||
</div>
|
||||
|
@ -1,40 +1,114 @@
|
||||
<div class="flex items-center gap-2">
|
||||
@if ($application->status === 'running')
|
||||
<div class="dropdown dropdown-bottom">
|
||||
<x-forms.button isHighlighted tabindex="0" class="">
|
||||
Actions
|
||||
<x-chevron-down />
|
||||
</x-forms.button>
|
||||
<div class="dropdown dropdown-bottom dropdown-hover">
|
||||
<label tabindex="0" class="flex items-center gap-2 cursor-pointer hover:text-white"> Actions
|
||||
<x-chevron-down />
|
||||
</label>
|
||||
@if ($application->status === 'running')
|
||||
<ul tabindex="0"
|
||||
class="mt-1 text-xs text-white normal-case rounded min-w-max dropdown-content menu bg-coolgray-200">
|
||||
class="text-xs text-white normal-case rounded min-w-max dropdown-content menu bg-coolgray-200">
|
||||
<li>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy'>Restart</div>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy'><svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6" 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="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4" />
|
||||
<path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4" />
|
||||
<path d="M12 9l0 3" />
|
||||
<path d="M12 15l.01 0" />
|
||||
</svg>Restart</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy(true)'>Force deploy without cache</div>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy(true, true)'><svg
|
||||
xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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="M9 9v-1a3 3 0 0 1 6 0v1" />
|
||||
<path d="M8 9h8a6 6 0 0 1 1 3v3a5 5 0 0 1 -10 0v-3a6 6 0 0 1 1 -3" />
|
||||
<path d="M3 13l4 0" />
|
||||
<path d="M17 13l4 0" />
|
||||
<path d="M12 20l0 -6" />
|
||||
<path d="M4 19l3.35 -2" />
|
||||
<path d="M20 19l-3.35 -2" />
|
||||
<path d="M4 7l3.75 2.4" />
|
||||
<path d="M20 7l-3.75 2.4" />
|
||||
</svg>Force deploy (with
|
||||
debug)
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="rounded-none hover:bg-red-500" wire:click='stop'>Stop</div>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy(true)'><svg
|
||||
xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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="M12.983 8.978c3.955 -.182 7.017 -1.446 7.017 -2.978c0 -1.657 -3.582 -3 -8 -3c-1.661 0 -3.204 .19 -4.483 .515m-2.783 1.228c-.471 .382 -.734 .808 -.734 1.257c0 1.22 1.944 2.271 4.734 2.74" />
|
||||
<path
|
||||
d="M4 6v6c0 1.657 3.582 3 8 3c.986 0 1.93 -.067 2.802 -.19m3.187 -.82c1.251 -.53 2.011 -1.228 2.011 -1.99v-6" />
|
||||
<path d="M4 12v6c0 1.657 3.582 3 8 3c3.217 0 5.991 -.712 7.261 -1.74m.739 -3.26v-4" />
|
||||
<path d="M3 3l18 18" />
|
||||
</svg>Force deploy (without
|
||||
cache)
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="rounded-none hover:bg-red-500" wire:click='stop'><svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6" 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="M8 13v-7.5a1.5 1.5 0 0 1 3 0v6.5" />
|
||||
<path d="M11 5.5v-2a1.5 1.5 0 1 1 3 0v8.5" />
|
||||
<path d="M14 5.5a1.5 1.5 0 0 1 3 0v6.5" />
|
||||
<path
|
||||
d="M17 7.5a1.5 1.5 0 0 1 3 0v8.5a6 6 0 0 1 -6 6h-2h.208a6 6 0 0 1 -5.012 -2.7a69.74 69.74 0 0 1 -.196 -.3c-.312 -.479 -1.407 -2.388 -3.286 -5.728a1.5 1.5 0 0 1 .536 -2.022a1.867 1.867 0 0 1 2.28 .28l1.47 1.47" />
|
||||
</svg>Stop</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@else
|
||||
<div class="dropdown dropdown-bottom">
|
||||
<label tabindex="0">
|
||||
<x-forms.button isHighlighted>
|
||||
Actions
|
||||
<x-chevron-down />
|
||||
</x-forms.button>
|
||||
</label>
|
||||
@else
|
||||
<ul tabindex="0"
|
||||
class="mt-1 text-xs text-white normal-case rounded min-w-max dropdown-content menu bg-coolgray-200">
|
||||
class="text-xs text-white normal-case rounded min-w-max dropdown-content menu bg-coolgray-200">
|
||||
<li>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy'>Deploy</div>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy'><svg
|
||||
xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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>Deploy</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy(true)'>Deploy without cache</div>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy(true, true)'><svg
|
||||
xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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="M9 9v-1a3 3 0 0 1 6 0v1" />
|
||||
<path d="M8 9h8a6 6 0 0 1 1 3v3a5 5 0 0 1 -10 0v-3a6 6 0 0 1 1 -3" />
|
||||
<path d="M3 13l4 0" />
|
||||
<path d="M17 13l4 0" />
|
||||
<path d="M12 20l0 -6" />
|
||||
<path d="M4 19l3.35 -2" />
|
||||
<path d="M20 19l-3.35 -2" />
|
||||
<path d="M4 7l3.75 2.4" />
|
||||
<path d="M20 7l-3.75 2.4" />
|
||||
</svg>Force deploy (with
|
||||
debug)
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="rounded-none hover:bg-coollabs" wire:click='deploy(true)'><svg
|
||||
xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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="M12.983 8.978c3.955 -.182 7.017 -1.446 7.017 -2.978c0 -1.657 -3.582 -3 -8 -3c-1.661 0 -3.204 .19 -4.483 .515m-2.783 1.228c-.471 .382 -.734 .808 -.734 1.257c0 1.22 1.944 2.271 4.734 2.74" />
|
||||
<path
|
||||
d="M4 6v6c0 1.657 3.582 3 8 3c.986 0 1.93 -.067 2.802 -.19m3.187 -.82c1.251 -.53 2.011 -1.228 2.011 -1.99v-6" />
|
||||
<path d="M4 12v6c0 1.657 3.582 3 8 3c3.217 0 5.991 -.712 7.261 -1.74m.739 -3.26v-4" />
|
||||
<path d="M3 3l18 18" />
|
||||
</svg>Force deploy (without
|
||||
cache)
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,14 +2,15 @@
|
||||
<h2>Logs</h2>
|
||||
<livewire:project.application.deployment-navbar :activity="$activity" :application="$application" :deployment_uuid="$deployment_uuid" />
|
||||
@if (data_get($activity, 'properties.status') === 'in_progress')
|
||||
<div class="pt-2 text-sm">Deployment is
|
||||
<span class="text-warning">{{ Str::headline(data_get($activity, 'properties.status')) }}</span>. Logs will
|
||||
be updated
|
||||
automatically.
|
||||
<div class="flex items-center gap-1 pt-2 text-sm">Deployment is
|
||||
<div class="text-warning"> {{ Str::headline(data_get($activity, 'properties.status')) }}.</div>
|
||||
<x-loading class="loading-ring" />
|
||||
</div>
|
||||
<div>Logs will be updated automatically.</div>
|
||||
@else
|
||||
<div class="pt-2 text-sm">Deployment is <span
|
||||
class="text-warning">{{ Str::headline(data_get($activity, 'properties.status')) }}</span>.</div>
|
||||
class="text-warning">{{ Str::headline(data_get($activity, 'properties.status')) }}</span>.
|
||||
</div>
|
||||
@endif
|
||||
<div
|
||||
class="scrollbar flex flex-col-reverse w-full overflow-y-auto border border-solid rounded border-coolgray-300 max-h-[32rem] p-4 mt-4 text-xs text-white">
|
||||
|
@ -2,14 +2,11 @@
|
||||
@if ($skip == 0) wire:poll.5000ms='reload_deployments' @endif>
|
||||
<h2 class="pt-4">Deployments <span class="text-xs">({{ $deployments_count }})</span></h2>
|
||||
@if (count($deployments) === 0)
|
||||
<x-forms.button isHighlighted wire:click="load_deployments({{ $default_take }})">Load Deployments
|
||||
<x-forms.button wire:click="load_deployments({{ $default_take }})">Load Deployments
|
||||
</x-forms.button>
|
||||
@endif
|
||||
<div wire:loading wire:target='load_deployments'>
|
||||
<x-loading />
|
||||
</div>
|
||||
@if ($show_next)
|
||||
<x-forms.button isHighlighted wire:click="load_deployments({{ $default_take }})">Show More
|
||||
<x-forms.button wire:click="load_deployments({{ $default_take }})">Show More
|
||||
</x-forms.button>
|
||||
@endif
|
||||
@foreach ($deployments as $deployment)
|
||||
|
@ -1,8 +1,8 @@
|
||||
<div>
|
||||
<h2>Destination</h2>
|
||||
<div class="text-sm">The destination server / network where your application will be deployed to.</div>
|
||||
<div class="py-4">
|
||||
<div class="py-4 text-sm">
|
||||
<p>Server: {{ data_get($destination, 'server.name') }}</p>
|
||||
<p>Destination: {{ $destination->network }}</p>
|
||||
<p>Destination Network: {{ $destination->network }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,12 +1,10 @@
|
||||
<form wire:submit.prevent='submit' class="flex flex-col max-w-fit">
|
||||
<div class="flex gap-2">
|
||||
<div class="flex items-end justify-center gap-2">
|
||||
<x-forms.input placeholder="NODE_ENV" noDirty id="key" label="Name" required />
|
||||
<x-forms.input placeholder="production" noDirty id="value" label="Value" required />
|
||||
<x-forms.checkbox noDirty class="flex-col items-center" id="is_build_time" label="Build Variable?" />
|
||||
</div>
|
||||
<div class="pt-2">
|
||||
<x-forms.checkbox noDirty class="flex-col text-center w-96" id="is_build_time" label="Build Variable?" />
|
||||
<x-forms.button type="submit">
|
||||
Add
|
||||
Add New Variable
|
||||
</x-forms.button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,17 +1,24 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
<div>
|
||||
<h2>Environment Variables</h2>
|
||||
<div class="text-sm">Environment (secrets) configuration. You can set variables for your Preview Deployments as
|
||||
well
|
||||
here.</div>
|
||||
<div class="text-sm">Environment (secrets) variables for normal deployments.</div>
|
||||
</div>
|
||||
@forelse ($application->environment_variables as $env)
|
||||
@foreach ($application->environment_variables as $env)
|
||||
<livewire:project.application.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" />
|
||||
@empty
|
||||
<p>There are no environment variables added for this application.</p>
|
||||
@endforelse
|
||||
<div class="pt-10">
|
||||
@endforeach
|
||||
<div class="pt-2 pb-8">
|
||||
<livewire:project.application.environment-variable.add />
|
||||
</div>
|
||||
<div>
|
||||
<h3>Preview Deployments</h3>
|
||||
<div class="text-sm">Environment (secrets) variables for Preview Deployments.</div>
|
||||
</div>
|
||||
@foreach ($application->environment_variables_preview as $env)
|
||||
<livewire:project.application.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" />
|
||||
@endforeach
|
||||
<div class="pt-2 pb-8">
|
||||
<livewire:project.application.environment-variable.add is_preview="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,17 +1,17 @@
|
||||
<div x-data="{ deleteEnvironment: false }">
|
||||
<form wire:submit.prevent='submit' class="flex flex-col max-w-fit">
|
||||
<div class="flex gap-2">
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input label="Name" id="env.key" />
|
||||
<x-forms.input label="Value" id="env.value" />
|
||||
<x-forms.checkbox disabled class="flex-col items-center" id="env.is_build_time" label="Build Variable?" />
|
||||
</div>
|
||||
<div class="pt-2">
|
||||
<x-forms.button type="submit">
|
||||
Update
|
||||
</x-forms.button>
|
||||
<x-forms.button x-on:click.prevent="deleteEnvironment = true">
|
||||
Delete
|
||||
</x-forms.button>
|
||||
<x-forms.checkbox disabled class="flex-col text-center w-96" id="env.is_build_time" label="Build Variable?" />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.button type="submit">
|
||||
Update
|
||||
</x-forms.button>
|
||||
<x-forms.button x-on:click.prevent="deleteEnvironment = true">
|
||||
Delete
|
||||
</x-forms.button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<x-naked-modal show="deleteEnvironment" message="Are you sure you want to delete {{ $env->key }}?" />
|
||||
|
@ -18,11 +18,11 @@
|
||||
<div class="pb-6">
|
||||
<div class="text-sm">Set Random Domain</div>
|
||||
@if ($global_wildcard_domain)
|
||||
<x-forms.button isHighlighted wire:click="generateGlobalRandomDomain">Global Wildcard
|
||||
<x-forms.button wire:click="generateGlobalRandomDomain">Global Wildcard
|
||||
</x-forms.button>
|
||||
@endif
|
||||
@if ($project_wildcard_domain)
|
||||
<x-forms.button isHighlighted wire:click="generateProjectRandomDomain">Project Wildcard
|
||||
<x-forms.button wire:click="generateProjectRandomDomain">Project Wildcard
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
|
@ -1,40 +1,69 @@
|
||||
<div>
|
||||
<livewire:project.application.preview.form :application="$application" />
|
||||
<h3>Pull Requests on Git</h3>
|
||||
<div>
|
||||
<x-forms.button wire:click="load_prs">Load Pull Requests (open)
|
||||
</x-forms.button>
|
||||
<div class="flex items-center gap-2">
|
||||
<h3>Pull Requests on Git</h3>
|
||||
<x-forms.button wire:click="load_prs">Load Pull Requests (open)
|
||||
</x-forms.button>
|
||||
</div>
|
||||
@isset($rate_limit_remaining)
|
||||
<div class="pt-1 text-sm">Requests remaning till rate limited by Git: {{ $rate_limit_remaining }}</div>
|
||||
@endisset
|
||||
@if (count($pull_requests) > 0)
|
||||
<div wire:loading.remove wire:target='load_prs' class="flex gap-4 py-8">
|
||||
@foreach ($pull_requests as $pull_request)
|
||||
<div class="flex flex-col gap-4 p-4 text-sm bg-coolgray-200 hover:bg-coolgray-300">
|
||||
<div class="text-base font-bold text-white">PR #{{ data_get($pull_request, 'number') }} |
|
||||
{{ data_get($pull_request, 'title') }}</div>
|
||||
<div class="flex items-center justify-start gap-2">
|
||||
<x-forms.button isHighlighted
|
||||
wire:click="deploy('{{ data_get($pull_request, 'number') }}', '{{ data_get($pull_request, 'html_url') }}')">
|
||||
Deploy
|
||||
</x-forms.button>
|
||||
<a target="_blank" class="text-xs" href="{{ data_get($pull_request, 'html_url') }}">Open PR
|
||||
on
|
||||
Git
|
||||
<x-external-link />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
<div wire:loading.remove wire:target='load_prs' class="flex gap-4 py-4">
|
||||
<div class="overflow-x-auto table-md">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr class="text-warning border-coolgray-200">
|
||||
<th>PR Number</th>
|
||||
<th>PR Title</th>
|
||||
<th>Git</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($pull_requests as $pull_request)
|
||||
<tr class="border-coolgray-200">
|
||||
<th>{{ data_get($pull_request, 'number') }}</th>
|
||||
<td>{{ data_get($pull_request, 'title') }}</td>
|
||||
<td>
|
||||
<a target="_blank" class="text-xs"
|
||||
href="{{ data_get($pull_request, 'html_url') }}">Open PR on
|
||||
Git
|
||||
<x-external-link />
|
||||
</a>
|
||||
</td>
|
||||
<td class="flex items-center justify-center gap-2">
|
||||
<x-forms.button
|
||||
wire:click="deploy('{{ data_get($pull_request, 'number') }}', '{{ data_get($pull_request, 'html_url') }}')">
|
||||
Deploy
|
||||
</x-forms.button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@if ($application->previews->count() > 0)
|
||||
<h3>Preview Deployments</h3>
|
||||
<h4 class="pt-4">Preview Deployments</h4>
|
||||
<div class="flex gap-6 text-sm">
|
||||
@foreach ($application->previews as $preview)
|
||||
<div class="flex flex-col p-4 bg-coolgray-200 " x-init="$wire.loadStatus('{{ data_get($preview, 'pull_request_id') }}')">
|
||||
<div>PR #{{ data_get($preview, 'pull_request_id') }} | {{ data_get($preview, 'status') }}
|
||||
<div class="flex gap-2">PR #{{ data_get($preview, 'pull_request_id') }} |
|
||||
@if (data_get($preview, 'status') === 'running')
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="badge badge-success badge-xs"></div>
|
||||
<div class="text-xs font-medium tracking-wide">Running</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="badge badge-error badge-xs"></div>
|
||||
<div class="text-xs font-medium tracking-wide">Stopped</div>
|
||||
</div>
|
||||
@endif
|
||||
@if (data_get($preview, 'status') !== 'exited')
|
||||
| <a target="_blank" href="{{ data_get($preview, 'fqdn') }}">Open Preview
|
||||
<x-external-link />
|
||||
@ -46,7 +75,7 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 pt-6">
|
||||
<x-forms.button isHighlighted wire:click="deploy({{ data_get($preview, 'pull_request_id') }})">
|
||||
<x-forms.button wire:click="deploy({{ data_get($preview, 'pull_request_id') }})">
|
||||
@if (data_get($preview, 'status') === 'exited')
|
||||
Deploy
|
||||
@else
|
||||
@ -58,7 +87,6 @@
|
||||
Preview
|
||||
</x-forms.button>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
@ -1,12 +1,9 @@
|
||||
<div x-init="$wire.loadImages">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Rollback</h2>
|
||||
<x-forms.button isHighlighted wire:click='loadImages'>Reload Available Images</x-forms.button>
|
||||
<x-forms.button wire:click='loadImages'>Reload Available Images</x-forms.button>
|
||||
</div>
|
||||
<div class="pb-4 text-sm">You can easily rollback to a previously built image quickly.</div>
|
||||
<div wire:loading wire:target='loadImages'>
|
||||
<x-loading />
|
||||
</div>
|
||||
<div wire:loading.remove wire:target='loadImages'>
|
||||
<div class="flex flex-wrap">
|
||||
@forelse ($images as $image)
|
||||
@ -28,8 +25,7 @@
|
||||
Rollback
|
||||
</x-forms.button>
|
||||
@else
|
||||
<x-forms.button isHighlighted
|
||||
wire:click="rollbackImage('{{ data_get($image, 'tag') }}')">
|
||||
<x-forms.button wire:click="rollbackImage('{{ data_get($image, 'tag') }}')">
|
||||
Rollback
|
||||
</x-forms.button>
|
||||
@endif
|
||||
|
@ -1,25 +1,32 @@
|
||||
<div>
|
||||
<form wire:submit.prevent='submit' class="flex flex-col">
|
||||
<form wire:submit.prevent='submit' class="flex flex-col w-96">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Source</h2>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
<a target="_blank" class="hover:no-underline" href="{{ $application->gitBranchLocation }}">
|
||||
<x-forms.button>
|
||||
<x-git-icon git="{{ $application->source->getMorphClass() }}" />Open Repository on Git
|
||||
<x-external-link />
|
||||
</x-forms.button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-sm">Code source of your application.</div>
|
||||
<div class="py-4 ">
|
||||
<a target="_blank" class="hover:no-underline" href="{{ $application->gitCommits }}">
|
||||
<x-forms.button>Open Commits on Git
|
||||
<x-external-link />
|
||||
</x-forms.button>
|
||||
</a>
|
||||
<a target="_blank" class="hover:no-underline" href="{{ $application->gitBranchLocation }}">
|
||||
<x-forms.button>Open Repository on Git
|
||||
<x-forms.input placeholder="coollabsio/coolify-example" id="application.git_repository" label="Repository" />
|
||||
<x-forms.input placeholder="main" id="application.git_branch" label="Branch" />
|
||||
<div class="flex items-end gap-2 w-96">
|
||||
<x-forms.input placeholder="HEAD" id="application.git_commit_sha" placeholder="HEAD" label="Commit SHA" />
|
||||
<a target="_blank" class="flex hover:no-underline" href="{{ $application->gitCommits }}">
|
||||
<x-forms.button><svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" 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="M12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
|
||||
<path d="M12 3l0 6" />
|
||||
<path d="M12 15l0 6" />
|
||||
</svg>Open Commits on Git
|
||||
<x-external-link />
|
||||
</x-forms.button>
|
||||
</a>
|
||||
</div>
|
||||
<x-forms.input placeholder="coollabsio/coolify-example" id="application.git_repository" label="Repository" />
|
||||
<x-forms.input placeholder="main" id="application.git_branch" label=" Branch" />
|
||||
<x-forms.input placeholder="HEAD" id="application.git_commit_sha" placeholder="HEAD" label="Commit SHA" />
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
@ -1,13 +1,15 @@
|
||||
<div wire:poll.5000ms='applicationStatusChanged'>
|
||||
@if ($application->status === 'running')
|
||||
<span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
|
||||
<x-loading wire:loading.delay.longer />
|
||||
<div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
|
||||
<div class="text-xs font-medium tracking-wide text-white badge border-success">Running</div>
|
||||
<div class="badge badge-success badge-xs"></div>
|
||||
<div class="text-xs font-medium tracking-wide">Running</div>
|
||||
</div>
|
||||
@else
|
||||
<span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
|
||||
<x-loading wire:loading.delay.longer />
|
||||
<div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
|
||||
<div class="text-xs font-medium tracking-wide text-white badge border-error">Stopped</div>
|
||||
<div class="badge badge-error badge-xs"></div>
|
||||
<div class="text-xs font-medium tracking-wide">Stopped</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
@ -1,10 +1,10 @@
|
||||
<form wire:submit.prevent='submit' class="flex flex-col px-2 pt-10 max-w-fit">
|
||||
<form wire:submit.prevent='submit' class="flex flex-col w-full px-2">
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="pv-name" noDirty id="name" label="Name" required />
|
||||
<x-forms.input placeholder="/root" noDirty id="host_path" label="Source Path" />
|
||||
<x-forms.input placeholder="/tmp/root" noDirty id="mount_path" label="Destination Path" required />
|
||||
<x-forms.button type="submit">
|
||||
Add
|
||||
Add New Volume
|
||||
</x-forms.button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,6 +1,11 @@
|
||||
<div>
|
||||
<h2>Storages</h2>
|
||||
<div class="text-sm">Persistent storage to preserve data between deployments.</div>
|
||||
<div>
|
||||
<h2>Storages</h2>
|
||||
<div class="text-sm">Persistent storage to preserve data between deployments.</div>
|
||||
<div class="text-sm">Preview Deployments has a <span class='text-helper'>-pr-#PRNumber</span> in their
|
||||
volume
|
||||
name, example: <span class='text-helper'>-pr-1</span>.</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 py-4">
|
||||
@forelse ($application->persistentStorages as $storage)
|
||||
<livewire:project.application.storages.show wire:key="storage-{{ $storage->id }}" :storage="$storage" />
|
||||
|
@ -1,10 +1,28 @@
|
||||
<div>
|
||||
<h1>Enter a public repository URL</h1>
|
||||
<form class="flex flex-col gap-2" wire:submit.prevent='submit'>
|
||||
<x-forms.checkbox instantSave id="is_static" label="Is it a static site?" />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input id="repository_url" label="Repository URL"
|
||||
helper="<span class='text-helper'>Example</span>https://github.com/coollabsio/coolify-examples => main branch will be selected<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify => nodejs-fastify branch will be selected" />
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input wire:keypress.enter='load_branches' id="repository_url" label="Repository URL"
|
||||
helper="<span class='text-helper'>Example</span>https://github.com/coollabsio/coolify-examples => main branch will be selected<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify => nodejs-fastify branch will be selected" />
|
||||
<x-forms.button wire:click.prevent="load_branches">
|
||||
Check repository
|
||||
</x-forms.button>
|
||||
</div>
|
||||
@if (count($branches) > 0)
|
||||
<x-forms.select id="selected_branch" label="Branch">
|
||||
<option value="default" disabled selected>Select a branch</option>
|
||||
@foreach ($branches as $branch)
|
||||
<option value="{{ $branch }}">{{ $branch }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
@else
|
||||
<x-forms.select id="branch" label="Branch" disabled>
|
||||
<option value="default" selected>Set a repository first</option>
|
||||
</x-forms.select>
|
||||
@endif
|
||||
</div>
|
||||
@if ($is_static)
|
||||
<x-forms.input id="publish_directory" label="Publish Directory"
|
||||
helper="If there is a build process involved (like Svelte, React, Next, etc..), please specify the output directory for the build assets." />
|
||||
@ -12,9 +30,18 @@
|
||||
<x-forms.input type="number" id="port" label="Port" :readonly="$is_static"
|
||||
helper="The port your application listens on." />
|
||||
@endif
|
||||
|
||||
</div>
|
||||
<x-forms.button type="submit">
|
||||
Submit
|
||||
</x-forms.button>
|
||||
<x-forms.checkbox instantSave id="is_static" label="Is it a static site?" />
|
||||
@if (count($branches) > 0)
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@else
|
||||
<x-forms.button disabled type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@endif
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
@ -38,7 +38,7 @@
|
||||
</div>
|
||||
</div>
|
||||
@if (!$server->settings->is_validated)
|
||||
<x-forms.button class="mt-4" isHighlighted wire:click.prevent='validateServer'>
|
||||
<x-forms.button class="mt-4" wire:click.prevent='validateServer'>
|
||||
Validate Server
|
||||
</x-forms.button>
|
||||
@endif
|
||||
|
@ -2,7 +2,7 @@
|
||||
@if ($server->settings->is_validated)
|
||||
@if ($server->extra_attributes->proxy_status === 'running')
|
||||
<div class="dropdown dropdown-bottom">
|
||||
<x-forms.button isHighlighted tabindex="0">
|
||||
<x-forms.button tabindex="0">
|
||||
Actions
|
||||
<x-chevron-down />
|
||||
</x-forms.button>
|
||||
@ -33,9 +33,9 @@ class="mt-1 text-xs text-white normal-case rounded min-w-max dropdown-content me
|
||||
</ul>
|
||||
</div>
|
||||
@else
|
||||
<x-forms.button isHighlighted wire:click='deploy'> <svg xmlns="http://www.w3.org/2000/svg" class="icon"
|
||||
width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||
fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<x-forms.button wire:click='deploy'> <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="44"
|
||||
height="44" 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</x-forms.button>
|
||||
|
@ -2,12 +2,12 @@
|
||||
@if ($server->settings->is_validated)
|
||||
<div wire:poll.5000ms="proxyStatus">
|
||||
@if ($server->extra_attributes->proxy_status === 'running')
|
||||
<span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
|
||||
<x-loading wire:loading.delay.longer />
|
||||
<div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
|
||||
<div class="text-xs font-medium tracking-wide text-white badge border-success">Running</div>
|
||||
</div>
|
||||
@else
|
||||
<span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
|
||||
<x-loading wire:loading.delay.longer />
|
||||
<div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
|
||||
<div class="text-xs font-medium tracking-wide text-white badge border-error">Stopped</div>
|
||||
</div>
|
||||
|
@ -33,7 +33,7 @@
|
||||
<div class="pb-4">
|
||||
<div class="text-sm">You need to register a GitHub App before using this source!</div>
|
||||
<form>
|
||||
<x-forms.button isHighlighted x-on:click.prevent="createGithubApp">Register a GitHub
|
||||
<x-forms.button x-on:click.prevent="createGithubApp">Register a GitHub
|
||||
Application
|
||||
</x-forms.button>
|
||||
</form>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<x-forms.select wire:model="selectedTeamId" class="w-64 select-xs">
|
||||
<div class="w-64 -mt-9">
|
||||
<x-forms.select wire:model="selectedTeamId" class="pr-0 select-xs ">
|
||||
<option value="default" disabled selected>Switch team</option>
|
||||
@foreach (auth()->user()->teams as $team)
|
||||
<option value="{{ $team->id }}">{{ $team->name }}</option>
|
||||
|
@ -9,6 +9,9 @@
|
||||
href="{{ route('project.resources', ['environment_name' => request()->route('environment_name'), 'project_uuid' => request()->route('project_uuid')]) }}">{{ request()->route('environment_name') }}</a>
|
||||
</li>
|
||||
<li>{{ data_get($application, 'name') }}</li>
|
||||
<li>
|
||||
<livewire:project.application.status :application="$application" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<x-applications.navbar :application="$application" />
|
||||
|
@ -9,6 +9,9 @@
|
||||
href="{{ route('project.resources', ['environment_name' => request()->route('environment_name'), 'project_uuid' => request()->route('project_uuid')]) }}">{{ request()->route('environment_name') }}</a>
|
||||
</li>
|
||||
<li>{{ data_get($application, 'name') }}</li>
|
||||
<li>
|
||||
<livewire:project.application.status :application="$application" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<x-applications.navbar :application="$application" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
<x-layout>
|
||||
<h1>Deployments</h1>
|
||||
<div class="pb-10 text-sm breadcrumbs">
|
||||
<ul>`
|
||||
<ul>
|
||||
<li><a
|
||||
href="{{ route('project.show', ['project_uuid' => request()->route('project_uuid')]) }}">{{ $application->environment->project->name }}</a>
|
||||
</li>
|
||||
@ -9,6 +9,9 @@
|
||||
href="{{ route('project.resources', ['environment_name' => request()->route('environment_name'), 'project_uuid' => request()->route('project_uuid')]) }}">{{ request()->route('environment_name') }}</a>
|
||||
</li>
|
||||
<li>{{ data_get($application, 'name') }}</li>
|
||||
<li>
|
||||
<livewire:project.application.status :application="$application" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<x-applications.navbar :application="$application" />
|
||||
|
@ -22,7 +22,7 @@
|
||||
<h2>Invite a new member</h2>
|
||||
<form class="flex items-center gap-2">
|
||||
<x-forms.input type="email" name="email" placeholder="Email" />
|
||||
<x-forms.button isHighlighted>Invite</x-forms.button>
|
||||
<x-forms.button>Invite</x-forms.button>
|
||||
</form>
|
||||
</div>
|
||||
</x-layout>
|
||||
|
Loading…
Reference in New Issue
Block a user