commit
74c126c731
@ -198,7 +198,7 @@ Files:
|
||||
}
|
||||
$restart_command = [
|
||||
"echo 'Stopping old Fluent Bit'",
|
||||
"cd $config_path && docker rm -f coolify-log-drain || true",
|
||||
"cd $config_path && docker compose down --remove-orphans || true",
|
||||
"echo 'Starting Fluent Bit'",
|
||||
"cd $config_path && docker compose up -d --remove-orphans",
|
||||
];
|
||||
|
@ -618,6 +618,9 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
||||
}
|
||||
} else {
|
||||
$this->dockerImageTag = str($this->commit)->substr(0, 128);
|
||||
if ($this->application->docker_registry_image_tag) {
|
||||
$this->dockerImageTag = $this->application->docker_registry_image_tag;
|
||||
}
|
||||
if ($this->application->docker_registry_image_name) {
|
||||
$this->build_image_name = Str::lower("{$this->application->docker_registry_image_name}:{$this->dockerImageTag}-build");
|
||||
$this->production_image_name = Str::lower("{$this->application->docker_registry_image_name}:{$this->dockerImageTag}");
|
||||
|
@ -11,6 +11,9 @@ class Index extends Component
|
||||
public $users = [];
|
||||
public function mount()
|
||||
{
|
||||
if (!isCloud()) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
if (auth()->user()->id !== 0 && session('adminToken') === null) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Livewire\Boarding;
|
||||
|
||||
use App\Actions\Server\InstallDocker;
|
||||
use App\Enums\ProxyTypes;
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
@ -121,15 +122,16 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||
}
|
||||
$this->selectedExistingPrivateKey = $this->createdServer->privateKey->id;
|
||||
$this->serverPublicKey = $this->createdServer->privateKey->publicKey();
|
||||
$this->validateServer();
|
||||
$this->installServer();
|
||||
}
|
||||
public function getProxyType()
|
||||
{
|
||||
$proxyTypeSet = $this->createdServer->proxy->type;
|
||||
if (!$proxyTypeSet) {
|
||||
$this->currentState = 'select-proxy';
|
||||
return;
|
||||
}
|
||||
$this->selectProxy(ProxyTypes::TRAEFIK_V2->value);
|
||||
// $proxyTypeSet = $this->createdServer->proxy->type;
|
||||
// if (!$proxyTypeSet) {
|
||||
// $this->currentState = 'select-proxy';
|
||||
// return;
|
||||
// }
|
||||
$this->getProjects();
|
||||
}
|
||||
public function selectExistingPrivateKey()
|
||||
@ -193,7 +195,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||
$this->createdServer->settings->is_cloudflare_tunnel = $this->isCloudflareTunnel;
|
||||
$this->createdServer->settings->save();
|
||||
$this->createdServer->addInitialNetwork();
|
||||
$this->validateServer();
|
||||
$this->currentState = 'validate-server';
|
||||
}
|
||||
public function installServer()
|
||||
{
|
||||
@ -219,7 +221,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||
$dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $this->createdServer, true);
|
||||
$dockerVersion = checkMinimumDockerEngineVersion($dockerVersion);
|
||||
if (is_null($dockerVersion)) {
|
||||
$this->currentState = 'install-docker';
|
||||
$this->currentState = 'validate-server';
|
||||
throw new \Exception('Docker not found or old version is installed.');
|
||||
}
|
||||
$this->createdServer->settings()->update([
|
||||
@ -227,27 +229,10 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||
]);
|
||||
$this->getProxyType();
|
||||
} catch (\Throwable $e) {
|
||||
// $this->dockerInstallationStarted = false;
|
||||
return handleError(error: $e, livewire: $this);
|
||||
}
|
||||
}
|
||||
public function installDocker()
|
||||
{
|
||||
try {
|
||||
$this->dockerInstallationStarted = true;
|
||||
$activity = InstallDocker::run($this->createdServer);
|
||||
$this->dispatch('installDocker');
|
||||
$this->dispatch('activityMonitor', $activity->id);
|
||||
} catch (\Throwable $e) {
|
||||
$this->dockerInstallationStarted = false;
|
||||
return handleError(error: $e, livewire: $this);
|
||||
}
|
||||
}
|
||||
public function dockerInstalledOrSkipped()
|
||||
{
|
||||
$this->validateServer();
|
||||
}
|
||||
public function selectProxy(string|null $proxyType = null)
|
||||
public function selectProxy(?string $proxyType = null)
|
||||
{
|
||||
if (!$proxyType) {
|
||||
return $this->getProjects();
|
||||
|
@ -22,6 +22,7 @@ class Dashboard extends Component
|
||||
}
|
||||
public function cleanup_queue()
|
||||
{
|
||||
$this->dispatch('success', 'Cleanup started.');
|
||||
Artisan::queue('app:init', [
|
||||
'--cleanup-deployments' => 'true'
|
||||
]);
|
||||
|
@ -56,15 +56,15 @@ class Heading extends Component
|
||||
return;
|
||||
}
|
||||
if ($this->application->destination->server->isSwarm() && str($this->application->docker_registry_image_name)->isEmpty()) {
|
||||
$this->dispatch('error', 'Failed to deploy', 'To deploy to a Swarm cluster you must set a Docker image name first.');
|
||||
$this->dispatch('error', 'Failed to deploy.', 'To deploy to a Swarm cluster you must set a Docker image name first.');
|
||||
return;
|
||||
}
|
||||
if (data_get($this->application, 'settings.is_build_server_enabled') && str($this->application->docker_registry_image_name)->isEmpty()) {
|
||||
$this->dispatch('error', 'Failed to deploy', 'To use a build server, you must first set a Docker image.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/build-server">documentation</a>');
|
||||
$this->dispatch('error', 'Failed to deploy.', 'To use a build server, you must first set a Docker image.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/build-server">documentation</a>');
|
||||
return;
|
||||
}
|
||||
if ($this->application->additional_servers->count() > 0 && str($this->application->docker_registry_image_name)->isEmpty()) {
|
||||
$this->dispatch('error', 'Failed to deploy', 'To deploy to more than one server, you must first set a Docker image.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/build-server">documentation</a>');
|
||||
$this->dispatch('error', 'Failed to deploy.', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/multiple-servers">documentation</a>');
|
||||
return;
|
||||
}
|
||||
$this->setDeploymentUuid();
|
||||
@ -103,7 +103,7 @@ class Heading extends Component
|
||||
public function restart()
|
||||
{
|
||||
if ($this->application->additional_servers->count() > 0 && str($this->application->docker_registry_image_name)->isEmpty()) {
|
||||
$this->dispatch('error', 'Failed to deploy', 'To deploy to more than one server, you must first set a Docker image.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/build-server">documentation</a>');
|
||||
$this->dispatch('error', 'Failed to deploy', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/multiple-servers">documentation</a>');
|
||||
return;
|
||||
}
|
||||
$this->setDeploymentUuid();
|
||||
|
@ -27,12 +27,12 @@ class Index extends Component
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->query = request()->query();
|
||||
$this->service = Service::whereUuid($this->parameters['service_uuid'])->firstOrFail();
|
||||
$service = $this->service->applications()->whereName($this->parameters['service_name'])->first();
|
||||
$service = $this->service->applications()->whereUuid($this->parameters['stack_service_uuid'])->first();
|
||||
if ($service) {
|
||||
$this->serviceApplication = $service;
|
||||
$this->serviceApplication->getFilesFromServer();
|
||||
} else {
|
||||
$this->serviceDatabase = $this->service->databases()->whereName($this->parameters['service_name'])->first();
|
||||
$this->serviceDatabase = $this->service->databases()->whereUuid($this->parameters['stack_service_uuid'])->first();
|
||||
$this->serviceDatabase->getFilesFromServer();
|
||||
}
|
||||
$this->s3s = currentTeam()->s3s;
|
||||
|
@ -37,10 +37,13 @@ class Destination extends Component
|
||||
$this->networks = $this->networks->reject(function ($network) use ($all_networks) {
|
||||
return $all_networks->pluck('id')->contains($network->id);
|
||||
});
|
||||
|
||||
}
|
||||
public function redeploy(int $network_id, int $server_id)
|
||||
{
|
||||
if ($this->resource->additional_servers->count() > 0 && str($this->resource->docker_registry_image_name)->isEmpty()) {
|
||||
$this->dispatch('error', 'Failed to deploy.', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/server/multiple-servers">documentation</a>');
|
||||
return;
|
||||
}
|
||||
$deployment_uuid = new Cuid2(7);
|
||||
$server = Server::find($server_id);
|
||||
$destination = StandaloneDocker::find($network_id);
|
||||
|
@ -12,7 +12,7 @@ class Status extends Component
|
||||
public Server $server;
|
||||
public bool $polling = false;
|
||||
public int $numberOfPolls = 0;
|
||||
protected $listeners = ['proxyStatusUpdated', 'startProxyPolling'];
|
||||
protected $listeners = ['proxyStatusUpdated' => '$refresh', 'startProxyPolling'];
|
||||
|
||||
public function startProxyPolling()
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Livewire\Server;
|
||||
|
||||
use App\Actions\Proxy\StartProxy;
|
||||
use App\Models\Server;
|
||||
use Livewire\Component;
|
||||
|
||||
@ -14,18 +15,23 @@ class ValidateAndInstall extends Component
|
||||
public $uptime = null;
|
||||
public $supported_os_type = null;
|
||||
public $docker_installed = null;
|
||||
public $docker_compose_installed = null;
|
||||
public $docker_version = null;
|
||||
public $proxy_started = false;
|
||||
public $error = null;
|
||||
|
||||
protected $listeners = ['validateServer' => 'init', 'validateDockerEngine', 'validateServerNow' => 'validateServer'];
|
||||
|
||||
public function init(bool $install = true)
|
||||
{
|
||||
|
||||
$this->install = $install;
|
||||
$this->uptime = null;
|
||||
$this->supported_os_type = null;
|
||||
$this->docker_installed = null;
|
||||
$this->docker_version = null;
|
||||
$this->docker_compose_installed = null;
|
||||
$this->proxy_started = null;
|
||||
$this->error = null;
|
||||
$this->number_of_tries = 0;
|
||||
$this->dispatch('validateServerNow');
|
||||
@ -43,6 +49,11 @@ class ValidateAndInstall extends Component
|
||||
if ($swarmInstalled) {
|
||||
$this->dispatch('success', 'Docker Swarm is initiated.');
|
||||
}
|
||||
} else {
|
||||
$proxy = StartProxy::run($this->server);
|
||||
if ($proxy) {
|
||||
$this->proxy_started = true;
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
@ -67,9 +78,9 @@ class ValidateAndInstall extends Component
|
||||
public function validateDockerEngine()
|
||||
{
|
||||
$this->docker_installed = $this->server->validateDockerEngine();
|
||||
if (!$this->docker_installed) {
|
||||
$this->docker_compose_installed = $this->server->validateDockerCompose();
|
||||
if (!$this->docker_installed || !$this->docker_compose_installed) {
|
||||
if ($this->install) {
|
||||
ray($this->number_of_tries, $this->max_tries);
|
||||
if ($this->number_of_tries == $this->max_tries) {
|
||||
$this->error = 'Docker Engine could not be installed. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
||||
return;
|
||||
|
@ -200,9 +200,6 @@ class Application extends BaseModel
|
||||
set: fn ($value) => $value === "" ? null : $value,
|
||||
);
|
||||
}
|
||||
|
||||
// Normal Deployments
|
||||
|
||||
public function portsMappingsArray(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -214,7 +211,7 @@ class Application extends BaseModel
|
||||
}
|
||||
public function realStatus()
|
||||
{
|
||||
return $this->getRawOriginal('status');
|
||||
return $this->getRawOriginal('status');
|
||||
}
|
||||
public function status(): Attribute
|
||||
{
|
||||
|
@ -443,6 +443,21 @@ class Server extends BaseModel
|
||||
$this->validateCoolifyNetwork(isSwarm: false, isBuildServer: $this->settings->is_build_server);
|
||||
return true;
|
||||
}
|
||||
public function validateDockerCompose($throwError = false)
|
||||
{
|
||||
$dockerCompose = instant_remote_process(["docker compose version"], $this, false);
|
||||
if (is_null($dockerCompose)) {
|
||||
$this->settings->is_usable = false;
|
||||
$this->settings->save();
|
||||
if ($throwError) {
|
||||
throw new \Exception('Server is not usable. Docker Compose is not installed.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$this->settings->is_usable = true;
|
||||
$this->settings->save();
|
||||
return true;
|
||||
}
|
||||
public function validateDockerSwarm()
|
||||
{
|
||||
$swarmStatus = instant_remote_process(["docker info|grep -i swarm"], $this, false);
|
||||
|
@ -13,6 +13,11 @@ const VALID_CRON_STRINGS = [
|
||||
const RESTART_MODE = 'unless-stopped';
|
||||
|
||||
const DATABASE_DOCKER_IMAGES = [
|
||||
'bitnami/mariadb',
|
||||
'bitnami/mongodb',
|
||||
'bitnami/mysql',
|
||||
'bitnami/postgresql',
|
||||
'bitnami/redis',
|
||||
'mysql',
|
||||
'mariadb',
|
||||
'postgres',
|
||||
|
@ -349,18 +349,8 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
foreach ($matches as $match) {
|
||||
$option = $match[1];
|
||||
$value = isset($match[2]) && $match[2] !== '' ? $match[2] : true;
|
||||
if ($list_options->contains($option)) {
|
||||
$value = explode(',', $value);
|
||||
}
|
||||
if (array_key_exists($option, $options)) {
|
||||
if (is_array($options[$option])) {
|
||||
$options[$option][] = $value;
|
||||
} else {
|
||||
$options[$option] = [$options[$option], $value];
|
||||
}
|
||||
} else {
|
||||
$options[$option] = $value;
|
||||
}
|
||||
$options[$option][] = $value;
|
||||
$options[$option] = array_unique($options[$option]);
|
||||
}
|
||||
$options = collect($options);
|
||||
// Easily get mappings from https://github.com/composerize/composerize/blob/master/packages/composerize/src/mappings.js
|
||||
@ -370,7 +360,7 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
}
|
||||
if ($option === '--ulimit') {
|
||||
$ulimits = collect([]);
|
||||
collect($value)->map(function ($ulimit) use ($ulimits){
|
||||
collect($value)->map(function ($ulimit) use ($ulimits) {
|
||||
$ulimit = explode('=', $ulimit);
|
||||
$type = $ulimit[0];
|
||||
$limits = explode(':', $ulimit[1]);
|
||||
@ -381,7 +371,6 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
'soft' => $soft_limit,
|
||||
'hard' => $hard_limit
|
||||
]);
|
||||
|
||||
} else {
|
||||
$soft_limit = $ulimit[1];
|
||||
$ulimits->put($type, [
|
||||
|
@ -7,7 +7,7 @@ return [
|
||||
|
||||
// The release version of your application
|
||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||
'release' => '4.0.0-beta.212',
|
||||
'release' => '4.0.0-beta.213',
|
||||
// When left empty or `null` the Laravel environment will be used
|
||||
'environment' => config('app.env'),
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
return '4.0.0-beta.212';
|
||||
return '4.0.0-beta.213';
|
||||
|
@ -28,8 +28,8 @@
|
||||
<a class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs hover:text-white"
|
||||
target="_blank" href="{{ getFqdnWithoutPort($domain) }}">
|
||||
<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">
|
||||
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" />
|
||||
@ -84,7 +84,7 @@
|
||||
@endif
|
||||
@if (data_get($application, 'ports_mappings_array'))
|
||||
@foreach ($application->ports_mappings_array as $port)
|
||||
@if (isDev())
|
||||
@if ($application->destination->server->id === 0)
|
||||
<li>
|
||||
<a class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs hover:text-white"
|
||||
target="_blank" href="http://localhost:{{ explode(':', $port)[0] }}">
|
||||
@ -114,9 +114,29 @@
|
||||
<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 {{ $port }}
|
||||
{{ $application->destination->server->ip }}:{{ explode(':', $port)[0] }}
|
||||
</a>
|
||||
</li>
|
||||
@if (count($application->additional_servers) > 0)
|
||||
@foreach ($application->additional_servers as $server)
|
||||
<li>
|
||||
<a class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs hover:text-white"
|
||||
target="_blank"
|
||||
href="http://{{ $server->ip }}:{{ 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>
|
||||
{{ $server->ip }}:{{ explode(':', $port)[0] }}
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
|
@ -40,109 +40,139 @@
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<details x-data="{ open: false }" class="dropdown dropdown-right" x-bind:open="open">
|
||||
<summary class="bg-transparent border-none btn hover:bg-transparent no-animation"
|
||||
x-on:click.prevent="open = !open" x-on:click.away="open = false"> <svg class="icon"
|
||||
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M224 128a8 8 0 0 1-8 8h-80v80a8 8 0 0 1-16 0v-80H40a8 8 0 0 1 0-16h80V40a8 8 0 0 1 16 0v80h80a8 8 0 0 1 8 8" />
|
||||
</svg></summary>
|
||||
<ul tabindex="0" class="w-64 p-2 border border-coolgray-200 dropdown-content menu bg-coolgray-100 ">
|
||||
<li title="Tags" class="border-transparent hover:bg-coolgray-200 ">
|
||||
<a class=" hover:bg-transparent hover:no-underline" href="{{ route('tags.index') }}">
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2">
|
||||
<path
|
||||
d="M3 8v4.172a2 2 0 0 0 .586 1.414l5.71 5.71a2.41 2.41 0 0 0 3.408 0l3.592-3.592a2.41 2.41 0 0 0 0-3.408l-5.71-5.71A2 2 0 0 0 9.172 6H5a2 2 0 0 0-2 2" />
|
||||
<path d="m18 19l1.592-1.592a4.82 4.82 0 0 0 0-6.816L15 6m-8 4h-.01" />
|
||||
</g>
|
||||
</svg>
|
||||
Tags
|
||||
</a>
|
||||
</li>
|
||||
<li title="Command Center" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('command-center') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('command-center') ? ' icon' : 'icon' }}" 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="M5 7l5 5l-5 5" />
|
||||
<path d="M12 19l7 0" />
|
||||
</svg>
|
||||
Command Center
|
||||
</a>
|
||||
</li>
|
||||
<li title="Source" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('source.all') }}">
|
||||
<svg class="icon" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="m6.793 1.207l.353.354l-.353-.354ZM1.207 6.793l-.353-.354l.353.354Zm0 1.414l.354-.353l-.354.353Zm5.586 5.586l-.354.353l.354-.353Zm1.414 0l-.353-.354l.353.354Zm5.586-5.586l.353.354l-.353-.354Zm0-1.414l-.354.353l.354-.353ZM8.207 1.207l.354-.353l-.354.353ZM6.44.854L.854 6.439l.707.707l5.585-5.585L6.44.854ZM.854 8.56l5.585 5.585l.707-.707l-5.585-5.585l-.707.707Zm7.707 5.585l5.585-5.585l-.707-.707l-5.585 5.585l.707.707Zm5.585-7.707L8.561.854l-.707.707l5.585 5.585l.707-.707Zm0 2.122a1.5 1.5 0 0 0 0-2.122l-.707.707a.5.5 0 0 1 0 .708l.707.707ZM6.44 14.146a1.5 1.5 0 0 0 2.122 0l-.707-.707a.5.5 0 0 1-.708 0l-.707.707ZM.854 6.44a1.5 1.5 0 0 0 0 2.122l.707-.707a.5.5 0 0 1 0-.708L.854 6.44Zm6.292-4.878a.5.5 0 0 1 .708 0L8.56.854a1.5 1.5 0 0 0-2.122 0l.707.707Zm-2 1.293l1 1l.708-.708l-1-1l-.708.708ZM7.5 5a.5.5 0 0 1-.5-.5H6A1.5 1.5 0 0 0 7.5 6V5Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 9 4.5H8ZM7.5 4a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 7.5 3v1Zm0-1A1.5 1.5 0 0 0 6 4.5h1a.5.5 0 0 1 .5-.5V3Zm.646 2.854l1.5 1.5l.707-.708l-1.5-1.5l-.707.708ZM10.5 8a.5.5 0 0 1-.5-.5H9A1.5 1.5 0 0 0 10.5 9V8Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 12 7.5h-1Zm-.5-.5a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 10.5 6v1Zm0-1A1.5 1.5 0 0 0 9 7.5h1a.5.5 0 0 1 .5-.5V6ZM7 5.5v4h1v-4H7Zm.5 5.5a.5.5 0 0 1-.5-.5H6A1.5 1.5 0 0 0 7.5 12v-1Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 9 10.5H8Zm-.5-.5a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 7.5 9v1Zm0-1A1.5 1.5 0 0 0 6 10.5h1a.5.5 0 0 1 .5-.5V9Z" />
|
||||
</svg>
|
||||
Sources
|
||||
</a>
|
||||
</li>
|
||||
<li title="Security" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('security.private-key.index') }}">
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="m16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1-4.069 0l-.301-.301l-6.558 6.558a2 2 0 0 1-1.239.578L5.172 21H4a1 1 0 0 1-.993-.883L3 20v-1.172a2 2 0 0 1 .467-1.284l.119-.13L4 17h2v-2h2v-2l2.144-2.144l-.301-.301a2.877 2.877 0 0 1 0-4.069l2.643-2.643a2.877 2.877 0 0 1 4.069 0zM15 9h.01" />
|
||||
</svg>
|
||||
Security
|
||||
</a>
|
||||
</li>
|
||||
<li title="Profile" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('profile') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" 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-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
|
||||
<path d="M12 10m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
|
||||
<path d="M6.168 18.849a4 4 0 0 1 3.832 -2.849h4a4 4 0 0 1 3.834 2.855" />
|
||||
</svg>
|
||||
Profile
|
||||
</a>
|
||||
</li>
|
||||
<li title="Teams" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('team.index') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" 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="M10 13a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M8 21v-1a2 2 0 0 1 2 -2h4a2 2 0 0 1 2 2v1" />
|
||||
<path d="M15 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M17 10h2a2 2 0 0 1 2 2v1" />
|
||||
<path d="M5 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M3 13v-1a2 2 0 0 1 2 -2h2" />
|
||||
</svg>
|
||||
Teams
|
||||
</a>
|
||||
</li>
|
||||
@if (isInstanceAdmin())
|
||||
<li title="Settings" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="/settings">
|
||||
<div class="inline-block text-left " x-data="{ open: false }">
|
||||
<div>
|
||||
<button x-on:click.prevent="open = !open" x-on:click.away="open = false" type="button"
|
||||
class="py-4 mx-4" id="menu-button" aria-expanded="true" aria-haspopup="true">
|
||||
<svg class="icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M224 128a8 8 0 0 1-8 8h-80v80a8 8 0 0 1-16 0v-80H40a8 8 0 0 1 0-16h80V40a8 8 0 0 1 16 0v80h80a8 8 0 0 1 8 8" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div x-show="open" x-cloak
|
||||
class="absolute left-0 z-10 w-56 mx-4 mt-2 origin-top-right rounded shadow-lg bg-coolgray-100 ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
|
||||
<div class="py-1" role="none">
|
||||
<li title="Tags" class="border-transparent hover:bg-coolgray-200 ">
|
||||
<a class=" hover:bg-transparent hover:no-underline" href="{{ route('tags.index') }}">
|
||||
<svg class="{{ request()->is('tags*') ? 'text-warning icon' : 'icon' }}"viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2">
|
||||
<path
|
||||
d="M3 8v4.172a2 2 0 0 0 .586 1.414l5.71 5.71a2.41 2.41 0 0 0 3.408 0l3.592-3.592a2.41 2.41 0 0 0 0-3.408l-5.71-5.71A2 2 0 0 0 9.172 6H5a2 2 0 0 0-2 2" />
|
||||
<path d="m18 19l1.592-1.592a4.82 4.82 0 0 0 0-6.816L15 6m-8 4h-.01" />
|
||||
</g>
|
||||
</svg>
|
||||
Tags
|
||||
</a>
|
||||
</li>
|
||||
<li title="Command Center" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('command-center') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('settings*') ? 'text-warning icon' : 'icon' }}"
|
||||
class="{{ request()->is('command-center*') ? 'text-warning icon' : 'icon' }}"
|
||||
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="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z" />
|
||||
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
|
||||
<path d="M5 7l5 5l-5 5" />
|
||||
<path d="M12 19l7 0" />
|
||||
</svg>
|
||||
Settings
|
||||
Command Center
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<li title="Source" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('source.all') }}">
|
||||
<svg class="{{ request()->is('source*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="m6.793 1.207l.353.354l-.353-.354ZM1.207 6.793l-.353-.354l.353.354Zm0 1.414l.354-.353l-.354.353Zm5.586 5.586l-.354.353l.354-.353Zm1.414 0l-.353-.354l.353.354Zm5.586-5.586l.353.354l-.353-.354Zm0-1.414l-.354.353l.354-.353ZM8.207 1.207l.354-.353l-.354.353ZM6.44.854L.854 6.439l.707.707l5.585-5.585L6.44.854ZM.854 8.56l5.585 5.585l.707-.707l-5.585-5.585l-.707.707Zm7.707 5.585l5.585-5.585l-.707-.707l-5.585 5.585l.707.707Zm5.585-7.707L8.561.854l-.707.707l5.585 5.585l.707-.707Zm0 2.122a1.5 1.5 0 0 0 0-2.122l-.707.707a.5.5 0 0 1 0 .708l.707.707ZM6.44 14.146a1.5 1.5 0 0 0 2.122 0l-.707-.707a.5.5 0 0 1-.708 0l-.707.707ZM.854 6.44a1.5 1.5 0 0 0 0 2.122l.707-.707a.5.5 0 0 1 0-.708L.854 6.44Zm6.292-4.878a.5.5 0 0 1 .708 0L8.56.854a1.5 1.5 0 0 0-2.122 0l.707.707Zm-2 1.293l1 1l.708-.708l-1-1l-.708.708ZM7.5 5a.5.5 0 0 1-.5-.5H6A1.5 1.5 0 0 0 7.5 6V5Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 9 4.5H8ZM7.5 4a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 7.5 3v1Zm0-1A1.5 1.5 0 0 0 6 4.5h1a.5.5 0 0 1 .5-.5V3Zm.646 2.854l1.5 1.5l.707-.708l-1.5-1.5l-.707.708ZM10.5 8a.5.5 0 0 1-.5-.5H9A1.5 1.5 0 0 0 10.5 9V8Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 12 7.5h-1Zm-.5-.5a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 10.5 6v1Zm0-1A1.5 1.5 0 0 0 9 7.5h1a.5.5 0 0 1 .5-.5V6ZM7 5.5v4h1v-4H7Zm.5 5.5a.5.5 0 0 1-.5-.5H6A1.5 1.5 0 0 0 7.5 12v-1Zm.5-.5a.5.5 0 0 1-.5.5v1A1.5 1.5 0 0 0 9 10.5H8Zm-.5-.5a.5.5 0 0 1 .5.5h1A1.5 1.5 0 0 0 7.5 9v1Zm0-1A1.5 1.5 0 0 0 6 10.5h1a.5.5 0 0 1 .5-.5V9Z" />
|
||||
</svg>
|
||||
Sources
|
||||
</a>
|
||||
</li>
|
||||
<li title="Security" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline"
|
||||
href="{{ route('security.private-key.index') }}">
|
||||
<svg class="{{ request()->is('security*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round"
|
||||
stroke-linejoin="round" stroke-width="2"
|
||||
d="m16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1-4.069 0l-.301-.301l-6.558 6.558a2 2 0 0 1-1.239.578L5.172 21H4a1 1 0 0 1-.993-.883L3 20v-1.172a2 2 0 0 1 .467-1.284l.119-.13L4 17h2v-2h2v-2l2.144-2.144l-.301-.301a2.877 2.877 0 0 1 0-4.069l2.643-2.643a2.877 2.877 0 0 1 4.069 0zM15 9h.01" />
|
||||
</svg>
|
||||
Security
|
||||
</a>
|
||||
</li>
|
||||
<li title="Profile" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('profile') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('profile*') ? 'text-warning icon' : 'icon' }}"
|
||||
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-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
|
||||
<path d="M12 10m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
|
||||
<path d="M6.168 18.849a4 4 0 0 1 3.832 -2.849h4a4 4 0 0 1 3.834 2.855" />
|
||||
</svg>
|
||||
Profile
|
||||
</a>
|
||||
</li>
|
||||
<li title="Teams" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('team.index') }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
|
||||
class="{{ request()->is('team*') ? 'text-warning icon' : 'icon' }}"
|
||||
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 13a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M8 21v-1a2 2 0 0 1 2 -2h4a2 2 0 0 1 2 2v1" />
|
||||
<path d="M15 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M17 10h2a2 2 0 0 1 2 2v1" />
|
||||
<path d="M5 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M3 13v-1a2 2 0 0 1 2 -2h2" />
|
||||
</svg>
|
||||
Teams @if (isCloud())
|
||||
/ Subscription
|
||||
@endif
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@if (isInstanceAdmin())
|
||||
<li title="Settings" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="/settings">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
class="{{ request()->is('settings*') ? 'text-warning icon' : 'icon' }}"
|
||||
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="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z" />
|
||||
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
|
||||
</svg>
|
||||
Settings
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<li title="Boarding" class="hover:bg-coolgray-200">
|
||||
<a class="hover:bg-transparent hover:no-underline" href="{{ route('boarding') }}">
|
||||
<svg class="{{ request()->is('boarding*') ? 'text-warning icon' : 'icon' }}"
|
||||
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M224 128a8 8 0 0 1-8 8h-88a8 8 0 0 1 0-16h88a8 8 0 0 1 8 8m-96-56h88a8 8 0 0 0 0-16h-88a8 8 0 0 0 0 16m88 112h-88a8 8 0 0 0 0 16h88a8 8 0 0 0 0-16M82.34 42.34L56 68.69L45.66 58.34a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32 0l32-32a8 8 0 0 0-11.32-11.32m0 64L56 132.69l-10.34-10.35a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32 0l32-32a8 8 0 0 0-11.32-11.32m0 64L56 196.69l-10.34-10.35a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32 0l32-32a8 8 0 0 0-11.32-11.32" />
|
||||
</svg>
|
||||
Boarding
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<details class="dropdown dropdown-right" x-bind:open="open">
|
||||
<summary class="bg-transparent border-none btn hover:bg-transparent no-animation"> </summary>
|
||||
<ul tabindex="0" class="w-64 p-2 border border-coolgray-200 dropdown-content menu bg-coolgray-100 ">
|
||||
|
||||
</ul>
|
||||
</details>
|
||||
@if (isCloud())
|
||||
@if (isCloud() && isInstanceAdmin())
|
||||
<li title="Admin">
|
||||
<a class="hover:bg-transparent" href="/admin">
|
||||
<svg class="text-pink-600 icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
@ -180,11 +210,12 @@
|
||||
</div>
|
||||
</li>
|
||||
<form action="/logout" method="POST" class="hover:bg-transparent">
|
||||
<li title="Logout" class="mb-6 hover:transparent">
|
||||
<li title="Logout" class="mb-6 hover:transparent">
|
||||
@csrf
|
||||
<button type="submit" class="rounded-none hover:text-white hover:bg-transparent">
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2a9.985 9.985 0 0 1 8 4h-2.71a8 8 0 1 0 .001 12h2.71A9.985 9.985 0 0 1 12 22m7-6v-3h-8v-2h8V8l5 4z"/>
|
||||
<path fill="currentColor"
|
||||
d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2a9.985 9.985 0 0 1 8 4h-2.71a8 8 0 1 0 .001 12h2.71A9.985 9.985 0 0 1 12 22m7-6v-3h-8v-2h8V8l5 4z" />
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
|
@ -1,4 +1,4 @@
|
||||
@props(['closeWithX' => 'false', 'fullScreen' => 'false'])
|
||||
@props(['closeWithX' => false, 'fullScreen' => false])
|
||||
<div x-data="{
|
||||
slideOverOpen: false
|
||||
}" class="relative w-auto h-auto">
|
||||
@ -19,7 +19,7 @@
|
||||
x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full"
|
||||
@class([
|
||||
'max-w-md w-screen' => !$fullScreen,
|
||||
'max-w-7xl w-screen' => $fullScreen,
|
||||
'max-w-4xl w-screen' => $fullScreen,
|
||||
])>
|
||||
<div
|
||||
class="flex flex-col h-full py-6 overflow-hidden border-l shadow-lg bg-base-100 border-neutral-800">
|
||||
|
@ -7,7 +7,7 @@
|
||||
<div class="pl-2 pr-1 text-xs font-bold tracking-widerr text-warning">
|
||||
{{ str($status)->before(':')->headline() }}
|
||||
</div>
|
||||
@if (!str($status)->startsWith('Proxy'))
|
||||
@if (!str($status)->startsWith('Proxy') && !str($status)->contains('('))
|
||||
<div class="text-xs text-warning">({{ str($status)->after(':') }})</div>
|
||||
@endif
|
||||
</div>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<div class="pl-2 pr-1 text-xs font-bold tracking-wider text-success">
|
||||
{{ str($status)->before(':')->headline() }}
|
||||
</div>
|
||||
@if (!str($status)->startsWith('Proxy'))
|
||||
@if (!str($status)->startsWith('Proxy') && !str($status)->contains('('))
|
||||
<div class="text-xs text-success">({{ str($status)->after(':') }})</div>
|
||||
@endif
|
||||
</div>
|
||||
|
@ -121,18 +121,24 @@
|
||||
There are already servers available for your Team. Do you want to use one of them?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewServer">No (create one for me)
|
||||
</x-forms.button>
|
||||
<div>
|
||||
<form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing servers" class="w-96" id='selectedExistingServer'>
|
||||
@foreach ($servers as $server)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $server->id }}">
|
||||
{{ $server->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Server</x-forms.button>
|
||||
</form>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewServer">No (create one
|
||||
for
|
||||
me)
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div>
|
||||
<form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing servers" class="w-96" id='selectedExistingServer'>
|
||||
@foreach ($servers as $server)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $server->id }}">
|
||||
{{ $server->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Server</x-forms.button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@if (!$serverReachable)
|
||||
This server is not reachable with the following public key.
|
||||
@ -216,7 +222,7 @@
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<br><span class='text-warning'>Coolify does not install/setup Cloudflare (cloudflared) on your server.</span>"
|
||||
id="isCloudflareTunnel" label="Cloudflare Tunnel" />
|
||||
</div>
|
||||
<x-forms.button type="submit">Check Connection</x-forms.button>
|
||||
<x-forms.button type="submit">Continue</x-forms.button>
|
||||
</form>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
@ -227,14 +233,15 @@
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'install-docker')
|
||||
<x-boarding-step title="Install Docker">
|
||||
@if ($currentState === 'validate-server')
|
||||
<x-boarding-step title="Validate & Configure Server">
|
||||
<x-slot:question>
|
||||
Could not find Docker Engine on your server. Do you want me to install it for you?
|
||||
I need to validate your server (connection, Docker Engine, etc) and configure if something is
|
||||
missing for me. Are you okay with this?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Configuring Server</x-slot:title>
|
||||
<x-slot:title>Validating & Configuring</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$this->createdServer" />
|
||||
</x-slot:content>
|
||||
@ -254,7 +261,7 @@
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
{{-- <div>
|
||||
@if ($currentState === 'select-proxy')
|
||||
<x-boarding-step title="Select a Proxy">
|
||||
<x-slot:question>
|
||||
@ -281,7 +288,7 @@
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
</div> --}}
|
||||
<div>
|
||||
@if ($currentState === 'create-project')
|
||||
<x-boarding-step title="Project">
|
||||
|
@ -1,5 +1,9 @@
|
||||
<div>
|
||||
<livewire:project.application.preview.form :application="$application" />
|
||||
@if (count($application->additional_servers) > 0)
|
||||
<div class="pb-4">Previews will be deployed on <span
|
||||
class="text-warning">{{ $application->destination->server->name }}</span>.</div>
|
||||
@endif
|
||||
<div>
|
||||
@if ($application->is_github_based())
|
||||
<div class="flex items-center gap-2">
|
||||
@ -51,7 +55,7 @@
|
||||
</div>
|
||||
@if ($application->previews->count() > 0)
|
||||
<div class="pb-4">Previews</div>
|
||||
<div class="flex gap-6 ">
|
||||
<div class="flex flex-wrap gap-6">
|
||||
@foreach ($application->previews as $preview)
|
||||
<div class="flex flex-col p-4 bg-coolgray-200">
|
||||
<div class="flex gap-2">PR #{{ data_get($preview, 'pull_request_id') }} |
|
||||
|
@ -213,9 +213,9 @@
|
||||
@endif --}}
|
||||
<div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap">
|
||||
@forelse($servers as $server)
|
||||
<div class="box group" wire:click="setServer({{ $server }})">
|
||||
<div class="w-64 box group" wire:click="setServer({{ $server }})">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="group-hover:text-white">
|
||||
<div class="font-bold group-hover:text-white">
|
||||
{{ $server->name }}
|
||||
</div>
|
||||
<div class="text-xs group-hover:text-white">
|
||||
@ -263,13 +263,13 @@
|
||||
Standalone Docker <span class="text-xs">({{ $standaloneDocker->name }})</span>
|
||||
</div>
|
||||
<div class="text-xs group-hover:text-white">
|
||||
network: {{ $standaloneDocker->network }}</div>
|
||||
Network: {{ $standaloneDocker->network }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
<a href="{{ route('destination.new', ['server_id' => $server_id]) }}"
|
||||
class="items-center justify-center pb-10 text-center box-without-bg group bg-coollabs hover:bg-coollabs-100">
|
||||
class="items-center justify-center text-center box-without-bg group bg-coollabs hover:bg-coollabs-100">
|
||||
<div class="flex flex-col mx-6 ">
|
||||
<div class="font-bold text-white">
|
||||
+ Add New
|
||||
|
@ -48,25 +48,27 @@
|
||||
<x-forms.input placeholder="Search for name, fqdn..." class="w-full" x-model="search" />
|
||||
<div class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||
<template x-for="item in filteredApplications" :key="item.id">
|
||||
<span class="relative">
|
||||
<span>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<div class="flex gap-2">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div title="running" class="mt-1 bg-success badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div title="exited" class="mt-1 bg-error badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div title="restarting" class="mt-1 bg-warningbadge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('degraded')">
|
||||
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="description" x-text="item.description"></div>
|
||||
<div class="description" x-text="item.fqdn"></div>
|
||||
</div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')" >
|
||||
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('degraded')">
|
||||
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
</a>
|
||||
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
|
||||
<template x-for="tag in item.tags">
|
||||
@ -79,21 +81,26 @@
|
||||
</span>
|
||||
</template>
|
||||
<template x-for="item in filteredPostgresqls" :key="item.id">
|
||||
<span class="relative">
|
||||
<span>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold text-white" x-text="item.name"></div>
|
||||
<div class="flex gap-2">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div title="running" class="mt-1 bg-success badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div title="exited" class="mt-1 bg-error badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div title="restarting" class="mt-1 bg-warningbadge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('degraded')">
|
||||
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="description" x-text="item.description"></div>
|
||||
</div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
</a>
|
||||
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
|
||||
<template x-for="tag in item.tags">
|
||||
@ -106,22 +113,26 @@
|
||||
</span>
|
||||
</template>
|
||||
<template x-for="item in filteredRedis" :key="item.id">
|
||||
<span class="relative">
|
||||
<span>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold text-white" x-text="item.name"></div>
|
||||
<div class="flex gap-2">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div title="running" class="mt-1 bg-success badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div title="exited" class="mt-1 bg-error badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div title="restarting" class="mt-1 bg-warningbadge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('degraded')">
|
||||
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="description" x-text="item.description"></div>
|
||||
</div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
|
||||
</a>
|
||||
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
|
||||
<template x-for="tag in item.tags">
|
||||
@ -134,21 +145,26 @@
|
||||
</span>
|
||||
</template>
|
||||
<template x-for="item in filteredMongodbs" :key="item.id">
|
||||
<span class="relative">
|
||||
<span>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold text-white" x-text="item.name"></div>
|
||||
<div class="flex gap-2">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div title="running" class="mt-1 bg-success badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div title="exited" class="mt-1 bg-error badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div title="restarting" class="mt-1 bg-warningbadge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('degraded')">
|
||||
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="description" x-text="item.description"></div>
|
||||
</div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
</a>
|
||||
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
|
||||
<template x-for="tag in item.tags">
|
||||
@ -161,21 +177,26 @@
|
||||
</span>
|
||||
</template>
|
||||
<template x-for="item in filteredMysqls" :key="item.id">
|
||||
<span class="relative">
|
||||
<span>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold text-white" x-text="item.name"></div>
|
||||
<div class="flex gap-2">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div title="running" class="mt-1 bg-success badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div title="exited" class="mt-1 bg-error badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div title="restarting" class="mt-1 bg-warningbadge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('degraded')">
|
||||
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="description" x-text="item.description"></div>
|
||||
</div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
</a>
|
||||
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
|
||||
<template x-for="tag in item.tags">
|
||||
@ -188,21 +209,26 @@
|
||||
</span>
|
||||
</template>
|
||||
<template x-for="item in filteredMariadbs" :key="item.id">
|
||||
<span class="relative">
|
||||
<span>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold text-white" x-text="item.name"></div>
|
||||
<div class="flex gap-2">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div title="running" class="mt-1 bg-success badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div title="exited" class="mt-1 bg-error badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div title="restarting" class="mt-1 bg-warningbadge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('degraded')">
|
||||
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="description" x-text="item.description"></div>
|
||||
</div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
</a>
|
||||
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
|
||||
<template x-for="tag in item.tags">
|
||||
@ -215,21 +241,26 @@
|
||||
</span>
|
||||
</template>
|
||||
<template x-for="item in filteredServices" :key="item.id">
|
||||
<span class="relative">
|
||||
<span>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold text-white" x-text="item.name"></div>
|
||||
<div class="flex gap-2">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div title="running" class="mt-1 bg-success badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div title="exited" class="mt-1 bg-error badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('restarting')">
|
||||
<div title="restarting" class="mt-1 bg-warningbadge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('degraded')">
|
||||
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="description" x-text="item.description"></div>
|
||||
</div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('exited')">
|
||||
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
<template x-if="item.status.startsWith('degraded')">
|
||||
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
|
||||
</template>
|
||||
</a>
|
||||
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
|
||||
<template x-for="tag in item.tags">
|
||||
|
@ -76,7 +76,7 @@
|
||||
</div>
|
||||
<div class="flex items-center px-4">
|
||||
<a class="flex flex-col flex-1 group-hover:text-white hover:no-underline"
|
||||
href="{{ route('project.service.index', [...$parameters, 'service_name' => $application->name]) }}">
|
||||
href="{{ route('project.service.index', [...$parameters, 'stack_service_uuid' => $application->uuid]) }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon hover:text-warning"
|
||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
@ -122,7 +122,7 @@
|
||||
</div>
|
||||
<div class="flex items-center px-4">
|
||||
<a class="flex flex-col flex-1 group-hover:text-white hover:no-underline"
|
||||
href="{{ route('project.service.index', [...$parameters, 'service_name' => $database->name]) }}">
|
||||
href="{{ route('project.service.index', [...$parameters, 'stack_service_uuid' => $database->uuid]) }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon hover:text-warning"
|
||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
|
@ -3,7 +3,7 @@
|
||||
<div class="flex h-full pt-6">
|
||||
<div class="flex flex-col gap-4 min-w-fit">
|
||||
<a class="{{ request()->routeIs('project.service.configuration') ? 'text-white' : '' }}"
|
||||
href="{{ route('project.service.configuration', [...$parameters, 'service_name' => null]) }}">
|
||||
href="{{ route('project.service.configuration', [...$parameters, 'stack_service_uuid' => null]) }}">
|
||||
<button><- Back</button>
|
||||
</a>
|
||||
<a :class="activeTab === 'general' && 'text-white'"
|
||||
|
@ -55,21 +55,25 @@
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
{{-- @if ($resource->getMorphClass() === 'App\Models\Application')
|
||||
@if ($resource->getMorphClass() === 'App\Models\Application')
|
||||
@if (count($networks) > 0)
|
||||
<h4>Choose another server</h4>
|
||||
<div class="pb-4 description">(experimental) </div>
|
||||
<div class="grid grid-cols-1 gap-4 ">
|
||||
<div class="grid grid-cols-1 gap-4">
|
||||
@foreach ($networks as $network)
|
||||
<div wire:click="addServer('{{ $network->id }}','{{ data_get($network, 'server.id') }}')"
|
||||
class="box w-96">
|
||||
{{ data_get($network, 'server.name') }}
|
||||
{{ $network->name }}
|
||||
class="relative flex flex-col text-white cursor-default box w-96">
|
||||
<div>
|
||||
Server: {{ data_get($network, 'server.name') }}
|
||||
</div>
|
||||
<div>
|
||||
Network: {{ data_get($network, 'name') }}
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="text-neutral-500">No additional servers available to attach.</div>
|
||||
@endif
|
||||
@endif --}}
|
||||
@endif
|
||||
</div>
|
||||
|
@ -19,7 +19,7 @@
|
||||
@endif
|
||||
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id !== 0)
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Configuring Server</x-slot:title>
|
||||
<x-slot:title>Validating & Configuring</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$server" />
|
||||
</x-slot:content>
|
||||
|
@ -12,12 +12,21 @@
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input type="password" required id="server.settings.logdrain_newrelic_license_key"
|
||||
label="License Key" />
|
||||
<x-forms.input required id="server.settings.logdrain_newrelic_base_uri"
|
||||
placeholder="https://log-api.eu.newrelic.com/log/v1"
|
||||
helper="For EU use: https://log-api.eu.newrelic.com/log/v1<br>For US use: https://log-api.newrelic.com/log/v1"
|
||||
label="Endpoint" />
|
||||
@if ($server->isLogDrainEnabled())
|
||||
<x-forms.input disabled type="password" required
|
||||
id="server.settings.logdrain_newrelic_license_key" label="License Key" />
|
||||
<x-forms.input disabled required id="server.settings.logdrain_newrelic_base_uri"
|
||||
placeholder="https://log-api.eu.newrelic.com/log/v1"
|
||||
helper="For EU use: https://log-api.eu.newrelic.com/log/v1<br>For US use: https://log-api.newrelic.com/log/v1"
|
||||
label="Endpoint" />
|
||||
@else
|
||||
<x-forms.input type="password" required id="server.settings.logdrain_newrelic_license_key"
|
||||
label="License Key" />
|
||||
<x-forms.input required id="server.settings.logdrain_newrelic_base_uri"
|
||||
placeholder="https://log-api.eu.newrelic.com/log/v1"
|
||||
helper="For EU use: https://log-api.eu.newrelic.com/log/v1<br>For US use: https://log-api.newrelic.com/log/v1"
|
||||
label="Endpoint" />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4 pt-6">
|
||||
@ -35,9 +44,17 @@
|
||||
<form wire:submit='submit("axiom")' class="flex flex-col">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input type="password" required id="server.settings.logdrain_axiom_api_key"
|
||||
label="API Key" />
|
||||
<x-forms.input required id="server.settings.logdrain_axiom_dataset_name" label="Dataset Name" />
|
||||
@if ($server->isLogDrainEnabled())
|
||||
<x-forms.input disabled type="password" required id="server.settings.logdrain_axiom_api_key"
|
||||
label="API Key" />
|
||||
<x-forms.input disabled required id="server.settings.logdrain_axiom_dataset_name"
|
||||
label="Dataset Name" />
|
||||
@else
|
||||
<x-forms.input type="password" required id="server.settings.logdrain_axiom_api_key"
|
||||
label="API Key" />
|
||||
<x-forms.input required id="server.settings.logdrain_axiom_dataset_name"
|
||||
label="Dataset Name" />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4 pt-6">
|
||||
@ -71,10 +88,18 @@
|
||||
</div>
|
||||
<form wire:submit='submit("custom")' class="flex flex-col">
|
||||
<div class="flex flex-col gap-4">
|
||||
<x-forms.textarea rows="6" required id="server.settings.logdrain_custom_config"
|
||||
label="Custom FluentBit Configuration" />
|
||||
<x-forms.textarea id="server.settings.logdrain_custom_config_parser"
|
||||
label="Custom Parser Configuration" />
|
||||
@if ($server->isLogDrainEnabled())
|
||||
<x-forms.textarea disabled rows="6" required id="server.settings.logdrain_custom_config"
|
||||
label="Custom FluentBit Configuration" />
|
||||
<x-forms.textarea disabled id="server.settings.logdrain_custom_config_parser"
|
||||
label="Custom Parser Configuration" />
|
||||
@else
|
||||
<x-forms.textarea rows="6" required id="server.settings.logdrain_custom_config"
|
||||
label="Custom FluentBit Configuration" />
|
||||
<x-forms.textarea id="server.settings.logdrain_custom_config_parser"
|
||||
label="Custom Parser Configuration" />
|
||||
@endif
|
||||
|
||||
</div>
|
||||
<div class="flex justify-end gap-4 pt-6">
|
||||
<x-forms.button type="submit">
|
||||
|
@ -51,7 +51,7 @@
|
||||
</x-forms.button>
|
||||
</div>
|
||||
@else
|
||||
<button onclick="checkProxy()"
|
||||
<button x-on:click="$wire.dispatch('checkProxy')"
|
||||
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"
|
||||
@ -64,9 +64,6 @@
|
||||
@endif
|
||||
@endif
|
||||
<script>
|
||||
function checkProxy() {
|
||||
window.Livewire.dispatch('checkProxy')
|
||||
}
|
||||
Livewire.on('proxyChecked', () => {
|
||||
startProxy.showModal();
|
||||
window.Livewire.dispatch('startProxy');
|
||||
|
@ -68,6 +68,51 @@
|
||||
<div class="w-64"><x-loading text="Docker is installed:" /></div>
|
||||
@endif
|
||||
@endif
|
||||
@if ($docker_compose_installed)
|
||||
<div class="flex w-64 gap-2">Docker Compose is installed: <svg class="w-5 h-5 text-success"
|
||||
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="currentColor">
|
||||
<path
|
||||
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
||||
opacity=".2" />
|
||||
<path
|
||||
d="m243.28 68.24l-24-23.56a16 16 0 0 0-22.58 0L104 136l-.11-.11l-36.64-35.27a16 16 0 0 0-22.57.06l-24 24a16 16 0 0 0 0 22.61l71.62 72a16 16 0 0 0 22.63 0l128.4-128.38a16 16 0 0 0-.05-22.67M103.62 208L32 136l24-24l.11.11l36.64 35.27a16 16 0 0 0 22.52 0L208.06 56L232 79.6Z" />
|
||||
</g>
|
||||
</svg></div>
|
||||
@if ($proxy_started)
|
||||
<div class="flex w-64 gap-2">Proxy Started: <svg class="w-5 h-5 text-success" viewBox="0 0 256 256"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="currentColor">
|
||||
<path
|
||||
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
||||
opacity=".2" />
|
||||
<path
|
||||
d="m243.28 68.24l-24-23.56a16 16 0 0 0-22.58 0L104 136l-.11-.11l-36.64-35.27a16 16 0 0 0-22.57.06l-24 24a16 16 0 0 0 0 22.61l71.62 72a16 16 0 0 0 22.63 0l128.4-128.38a16 16 0 0 0-.05-22.67M103.62 208L32 136l24-24l.11.11l36.64 35.27a16 16 0 0 0 22.52 0L208.06 56L232 79.6Z" />
|
||||
</g>
|
||||
</svg></div>
|
||||
@else
|
||||
@if ($error)
|
||||
<div class="flex w-64 gap-2">Proxy Started: <svg class="w-5 h-5 text-error" viewBox="0 0 256 256"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
||||
</svg></div>
|
||||
@else
|
||||
<div class="w-64"><x-loading text="Proxy Started:" /></div>
|
||||
@endif
|
||||
@endif
|
||||
@else
|
||||
@if ($error)
|
||||
<div class="flex w-64 gap-2">Docker Compose is installed: <svg class="w-5 h-5 text-error"
|
||||
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
||||
</svg></div>
|
||||
@else
|
||||
<div class="w-64"><x-loading text="Docker Compose is installed:" /></div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@endif
|
||||
@isset($docker_version)
|
||||
<div class="flex w-64 gap-2">Minimum Docker version installed: <svg class="w-5 h-5 text-success"
|
||||
@ -81,6 +126,7 @@
|
||||
</g>
|
||||
</svg></div>
|
||||
@endisset
|
||||
|
||||
<livewire:new-activity-monitor header="Logs" />
|
||||
@isset($error)
|
||||
<pre class="font-bold whitespace-pre-line text-error">{!! $error !!}</pre>
|
||||
|
@ -79,9 +79,7 @@ use App\Livewire\Waitlist\Index as WaitlistIndex;
|
||||
if (isDev()) {
|
||||
Route::get('/dev/compose', Compose::class)->name('dev.compose');
|
||||
}
|
||||
if (isCloud()) {
|
||||
Route::get('/admin', AdminIndex::class)->name('admin.index');
|
||||
}
|
||||
Route::get('/admin', AdminIndex::class)->name('admin.index');
|
||||
|
||||
Route::post('/forgot-password', [Controller::class, 'forgot_password'])->name('password.forgot');
|
||||
Route::get('/api/v1/test/realtime', [Controller::class, 'realtime_test'])->middleware('auth');
|
||||
@ -165,7 +163,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
||||
});
|
||||
Route::prefix('project/{project_uuid}/{environment_name}/service/{service_uuid}')->group(function () {
|
||||
Route::get('/', ServiceConfiguration::class)->name('project.service.configuration');
|
||||
Route::get('/{service_name}', ServiceIndex::class)->name('project.service.index');
|
||||
Route::get('/{stack_service_uuid}', ServiceIndex::class)->name('project.service.index');
|
||||
Route::get('/command', ExecuteContainerCommand::class)->name('project.service.command');
|
||||
Route::get('/tasks/{task_uuid}', ScheduledTaskShow::class)->name('project.service.scheduled-tasks');
|
||||
});
|
||||
|
@ -861,7 +861,11 @@ Route::post('/payments/stripe/events', function () {
|
||||
$subscription = Subscription::where('stripe_customer_id', $customerId)->first();
|
||||
if (!$subscription) {
|
||||
Sleep::for(5)->seconds();
|
||||
$subscription = Subscription::where('stripe_customer_id', $customerId)->firstOrFail();
|
||||
$subscription = Subscription::where('stripe_customer_id', $customerId)->first();
|
||||
}
|
||||
if (!$subscription) {
|
||||
send_internal_notification('No subscription found for: ' . $customerId);
|
||||
return response("No subscription found", 400);
|
||||
}
|
||||
$trialEndedAlready = data_get($subscription, 'stripe_trial_already_ended');
|
||||
$cancelAtPeriodEnd = data_get($data, 'cancel_at_period_end');
|
||||
|
9
tests/Feature/DockerRunTest.php
Normal file
9
tests/Feature/DockerRunTest.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
it('ConvertDockerTunCommand', function () {
|
||||
$input = '--cap-add=NET_ADMIN --cap-add=NET_RAW --cap-add SYS_ADMIN';
|
||||
$output = convert_docker_run_to_compose($input);
|
||||
expect($output)->toBe([
|
||||
'cap_add' => ['NET_ADMIN', 'NET_RAW', 'SYS_ADMIN'],
|
||||
])->ray();
|
||||
});
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
it('returns a successful response', function () {
|
||||
$response = $this->get('/api/health');
|
||||
|
||||
$response->assertStatus(200);
|
||||
});
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
test('parse', function () {
|
||||
|
||||
expect($result)->toBe(3);
|
||||
});
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
uses(
|
||||
Tests\TestCase::class,
|
||||
// Tests\TestCase::class,
|
||||
// Illuminate\Foundation\Testing\RefreshDatabase::class,
|
||||
)->in('Feature');
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
test('that true is true', function () {
|
||||
expect(true)->toBeTrue();
|
||||
});
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
test('globals')
|
||||
->expect(['dd', 'dump'])
|
||||
->not->toBeUsed();
|
@ -4,7 +4,7 @@
|
||||
"version": "3.12.36"
|
||||
},
|
||||
"v4": {
|
||||
"version": "4.0.0-beta.212"
|
||||
"version": "4.0.0-beta.213"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user