Merge pull request #1790 from coollabsio/next

v4.0.0-beta.228
This commit is contained in:
Andras Bacsai 2024-03-01 09:32:19 +01:00 committed by GitHub
commit 3d87a88d3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 1401 additions and 46 deletions

View File

@ -33,7 +33,9 @@ Special thanks to our biggest sponsors, [CCCareers](https://cccareers.org/) and
<a href="https://cccareers.org/" target="_blank"><img src="./other/logos/ccc-logo.webp" alt="cccareers logo" width="200"/></a> <a href="https://cccareers.org/" target="_blank"><img src="./other/logos/ccc-logo.webp" alt="cccareers logo" width="200"/></a>
<a href="https://appwrite.io" target="_blank"><img src="./other/logos/appwrite.svg" alt="appwrite logo" width="200"/></a> <a href="https://appwrite.io" target="_blank"><img src="./other/logos/appwrite.svg" alt="appwrite logo" width="200"/></a>
## Github Sponsors ($15+) ## Github Sponsors ($40+)
<a href="https://cryptojobslist.com/?utm_source=coolify.io"><img src="https://github.com/cryptojobslist.png" width="60px" alt="CryptoJobsList" /></a>
<a href="https://typebot.io/?utm_source=coolify.io"><img src="https://pbs.twimg.com/profile_images/1509194008366657543/9I-C7uWT_400x400.jpg" width="60px" alt="typebot"/></a>
<a href="https://bc.direct"><img width="60px" alt="BC Direct" src="https://github.com/coollabsio/coolify/assets/5845193/a4063c41-95ed-4a32-8814-cd1475572e37"/></a> <a href="https://bc.direct"><img width="60px" alt="BC Direct" src="https://github.com/coollabsio/coolify/assets/5845193/a4063c41-95ed-4a32-8814-cd1475572e37"/></a>
<a href="https://github.com/automazeio"><img src="https://github.com/automazeio.png" width="60px" alt="Corentin Clichy" /></a> <a href="https://github.com/automazeio"><img src="https://github.com/automazeio.png" width="60px" alt="Corentin Clichy" /></a>
<a href="https://github.com/corentinclichy"><img src="https://github.com/corentinclichy.png" width="60px" alt="Corentin Clichy" /></a> <a href="https://github.com/corentinclichy"><img src="https://github.com/corentinclichy.png" width="60px" alt="Corentin Clichy" /></a>

View File

@ -16,7 +16,7 @@ class StartService
$commands[] = "cd " . $service->workdir(); $commands[] = "cd " . $service->workdir();
$commands[] = "echo 'Saved configuration files to {$service->workdir()}.'"; $commands[] = "echo 'Saved configuration files to {$service->workdir()}.'";
$commands[] = "echo 'Creating Docker network.'"; $commands[] = "echo 'Creating Docker network.'";
$commands[] = "docker network inspect $service->uuid >/dev/null 2>&1 || docker network create --attachable $service->uuid >/dev/null 2>&1 || true"; $commands[] = "docker network inspect $service->uuid >/dev/null 2>&1 || docker network create --attachable $service->uuid";
$commands[] = "echo Starting service."; $commands[] = "echo Starting service.";
$commands[] = "echo 'Pulling images.'"; $commands[] = "echo 'Pulling images.'";
$commands[] = "docker compose pull"; $commands[] = "docker compose pull";

View File

@ -10,7 +10,8 @@ use Livewire\Component;
class Create extends Component class Create extends Component
{ {
public $type; public $type;
public function mount() { public function mount()
{
$services = getServiceTemplates(); $services = getServiceTemplates();
$type = str(request()->query('type')); $type = str(request()->query('type'));
$destination_uuid = request()->query('destination'); $destination_uuid = request()->query('destination');
@ -70,7 +71,7 @@ class Create extends Component
$generatedValue = $value; $generatedValue = $value;
if ($value->contains('SERVICE_')) { if ($value->contains('SERVICE_')) {
$command = $value->after('SERVICE_')->beforeLast('_'); $command = $value->after('SERVICE_')->beforeLast('_');
$generatedValue = generateEnvValue($command->value()); $generatedValue = generateEnvValue($command->value(), $service);
} }
EnvironmentVariable::create([ EnvironmentVariable::create([
'key' => $key, 'key' => $key,

View File

@ -55,7 +55,7 @@ class Resources extends Component
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} }
$this->loadUnmanagedContainers(); // $this->loadUnmanagedContainers();
} }
public function render() public function render()
{ {

View File

@ -263,6 +263,7 @@ class Server extends BaseModel
} }
public function loadUnmanagedContainers() public function loadUnmanagedContainers()
{ {
if ($this->isFunctional()) {
$containers = instant_remote_process(["docker ps -a --format '{{json .}}' "], $this); $containers = instant_remote_process(["docker ps -a --format '{{json .}}' "], $this);
$containers = format_docker_command_output_to_json($containers); $containers = format_docker_command_output_to_json($containers);
$containers = $containers->map(function ($container) { $containers = $containers->map(function ($container) {
@ -275,6 +276,7 @@ class Server extends BaseModel
$containers = $containers->filter(); $containers = $containers->filter();
return collect($containers); return collect($containers);
} }
}
public function hasDefinedResources() public function hasDefinedResources()
{ {
$applications = $this->applications()->count() > 0; $applications = $this->applications()->count() > 0;

View File

@ -102,6 +102,30 @@ class Service extends BaseModel
foreach ($applications as $application) { foreach ($applications as $application) {
$image = str($application->image)->before(':')->value(); $image = str($application->image)->before(':')->value();
switch ($image) { switch ($image) {
case str($image)?->contains('kong'):
$data = collect([]);
$dashboard_user = $this->environment_variables()->where('key', 'SERVICE_USER_ADMIN')->first();
$dashboard_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_ADMIN')->first();
if ($dashboard_user) {
$data = $data->merge([
'Dashboard User' => [
'key' => data_get($dashboard_user, 'key'),
'value' => data_get($dashboard_user, 'value'),
'rules' => 'required',
],
]);
}
if ($dashboard_password) {
$data = $data->merge([
'Dashboard Password' => [
'key' => data_get($dashboard_password, 'key'),
'value' => data_get($dashboard_password, 'value'),
'rules' => 'required',
'isPassword' => true,
],
]);
}
$fields->put('Supabase', $data->toArray());
case str($image)?->contains('minio'): case str($image)?->contains('minio'):
$data = collect([]); $data = collect([]);
$console_url = $this->environment_variables()->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first(); $console_url = $this->environment_variables()->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first();

View File

@ -33,6 +33,11 @@ use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Illuminate\Support\Stringable; use Illuminate\Support\Stringable;
use Lcobucci\JWT\Encoding\ChainedFormatter;
use Lcobucci\JWT\Encoding\JoseEncoder;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Token\Builder;
use Poliander\Cron\CronExpression; use Poliander\Cron\CronExpression;
use Visus\Cuid2\Cuid2; use Visus\Cuid2\Cuid2;
use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA;
@ -625,7 +630,6 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} }
} }
$definedNetwork = collect([$resource->uuid]); $definedNetwork = collect([$resource->uuid]);
$services = collect($services)->map(function ($service, $serviceName) use ($topLevelVolumes, $topLevelNetworks, $definedNetwork, $isNew, $generatedServiceFQDNS, $resource) { $services = collect($services)->map(function ($service, $serviceName) use ($topLevelVolumes, $topLevelNetworks, $definedNetwork, $isNew, $generatedServiceFQDNS, $resource) {
$serviceVolumes = collect(data_get($service, 'volumes', [])); $serviceVolumes = collect(data_get($service, 'volumes', []));
$servicePorts = collect(data_get($service, 'ports', [])); $servicePorts = collect(data_get($service, 'ports', []));
@ -927,6 +931,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$savedService->fqdn = $fqdn; $savedService->fqdn = $fqdn;
$savedService->save(); $savedService->save();
} }
EnvironmentVariable::create([
'key' => $key,
'value' => $fqdn,
'is_build_time' => false,
'service_id' => $resource->id,
'is_preview' => false,
]);
} }
// data_forget($service, "environment.$variableName"); // data_forget($service, "environment.$variableName");
// $yaml = data_forget($yaml, "services.$serviceName.environment.$variableName"); // $yaml = data_forget($yaml, "services.$serviceName.environment.$variableName");
@ -978,7 +989,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} }
} }
} else { } else {
$generatedValue = generateEnvValue($command); $generatedValue = generateEnvValue($command, $resource);
if (!$foundEnv) { if (!$foundEnv) {
EnvironmentVariable::create([ EnvironmentVariable::create([
'key' => $key, 'key' => $key,
@ -1394,7 +1405,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
]); ]);
} }
} else { } else {
$generatedValue = generateEnvValue($command); $generatedValue = generateEnvValue($command, $service);
if (!$foundEnv) { if (!$foundEnv) {
EnvironmentVariable::create([ EnvironmentVariable::create([
'key' => $key, 'key' => $key,
@ -1570,7 +1581,7 @@ function parseEnvVariable(Str|string $value)
'port' => $port, 'port' => $port,
]; ];
} }
function generateEnvValue(string $command) function generateEnvValue(string $command, Service $service)
{ {
switch ($command) { switch ($command) {
case 'PASSWORD': case 'PASSWORD':
@ -1591,6 +1602,46 @@ function generateEnvValue(string $command)
case 'USER': case 'USER':
$generatedValue = Str::random(16); $generatedValue = Str::random(16);
break; break;
case 'SUPABASEANON':
$signingKey = $service->environment_variables()->where('key', 'SERVICE_PASSWORD_JWT')->first();
if (is_null($signingKey)) {
return;
} else {
$signingKey = $signingKey->value;
}
$key = InMemory::plainText($signingKey);
$algorithm = new Sha256();
$tokenBuilder = (new Builder(new JoseEncoder(), ChainedFormatter::default()));
$now = new DateTimeImmutable();
$now = $now->setTime($now->format('H'), $now->format('i'));
$token = $tokenBuilder
->issuedBy('supabase')
->issuedAt($now)
->expiresAt($now->modify('+100 year'))
->withClaim('role', 'anon')
->getToken($algorithm, $key);
$generatedValue = $token->toString();
break;
case 'SUPABASESERVICE':
$signingKey = $service->environment_variables()->where('key', 'SERVICE_PASSWORD_JWT')->first();
if (is_null($signingKey)) {
return;
} else {
$signingKey = $signingKey->value;
}
$key = InMemory::plainText($signingKey);
$algorithm = new Sha256();
$tokenBuilder = (new Builder(new JoseEncoder(), ChainedFormatter::default()));
$now = new DateTimeImmutable();
$now = $now->setTime($now->format('H'), $now->format('i'));
$token = $tokenBuilder
->issuedBy('supabase')
->issuedAt($now)
->expiresAt($now->modify('+100 year'))
->withClaim('role', 'service_role')
->getToken($algorithm, $key);
$generatedValue = $token->toString();
break;
default: default:
$generatedValue = Str::random(16); $generatedValue = Str::random(16);
break; break;

View File

@ -7,7 +7,7 @@ return [
// The release version of your application // The release version of your application
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
'release' => '4.0.0-beta.227', 'release' => '4.0.0-beta.228',
// When left empty or `null` the Laravel environment will be used // When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'), 'environment' => config('app.env'),

View File

@ -1,3 +1,3 @@
<?php <?php
return '4.0.0-beta.227'; return '4.0.0-beta.228';

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="white" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14m-6 6l6-6m-6-6l6 6"/>
</svg>

After

Width:  |  Height:  |  Size: 203 B

15
public/svgs/supabase.svg Normal file
View File

@ -0,0 +1,15 @@
<svg width="109" height="113" viewBox="0 0 109 113" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M63.7076 110.284C60.8481 113.885 55.0502 111.912 54.9813 107.314L53.9738 40.0627L99.1935 40.0627C107.384 40.0627 111.952 49.5228 106.859 55.9374L63.7076 110.284Z" fill="url(#paint0_linear)"/>
<path d="M63.7076 110.284C60.8481 113.885 55.0502 111.912 54.9813 107.314L53.9738 40.0627L99.1935 40.0627C107.384 40.0627 111.952 49.5228 106.859 55.9374L63.7076 110.284Z" fill="url(#paint1_linear)" fill-opacity="0.2"/>
<path d="M45.317 2.07103C48.1765 -1.53037 53.9745 0.442937 54.0434 5.041L54.4849 72.2922H9.83113C1.64038 72.2922 -2.92775 62.8321 2.1655 56.4175L45.317 2.07103Z" fill="#3ECF8E"/>
<defs>
<linearGradient id="paint0_linear" x1="53.9738" y1="54.974" x2="94.1635" y2="71.8295" gradientUnits="userSpaceOnUse">
<stop stop-color="#249361"/>
<stop offset="1" stop-color="#3ECF8E"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="36.1558" y1="30.578" x2="54.4844" y2="65.0806" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<img class="inline-flex w-4 h-4" src="{{ asset('svgs/internal-link.svg') }}">

View File

@ -1,5 +1,5 @@
<x-emails.layout> <x-emails.layout>
Your trial ends soon. Please update payment details [here]({{ $stripeCustomerPortal }}), Your trial ends soon. Please update payment details [here]({{ $stripeCustomerPortal }}),
Your servers & deployed resources will be untouched, but you won't be able to deploy new resources and lost all automations and integrations. Your servers & deployed resources will be untouched, but you won't be able to deploy new resources and lose all automations and integrations.
</x-emails.layout> </x-emails.layout>

View File

@ -16,7 +16,6 @@
<button class="text-white btn-link">{{ data_get($docker, 'network') }} </button> <button class="text-white btn-link">{{ data_get($docker, 'network') }} </button>
</a> </a>
@empty @empty
<div class="">N/A</div>
@endforelse @endforelse
@forelse ($server->swarmDockers as $docker) @forelse ($server->swarmDockers as $docker)
<a <a
@ -24,7 +23,6 @@
<button class="text-white btn-link">{{ data_get($docker, 'network') }} </button> <button class="text-white btn-link">{{ data_get($docker, 'network') }} </button>
</a> </a>
@empty @empty
<div class="">N/A</div>
@endforelse @endforelse
</div> </div>
<div class="pt-2"> <div class="pt-2">

View File

@ -50,7 +50,7 @@
<template x-for="item in filteredApplications" :key="item.id"> <template x-for="item in filteredApplications" :key="item.id">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col mx-6"> <div class="flex flex-col w-full px-4 mx-2">
<div class="flex gap-2"> <div class="flex gap-2">
<div class="pb-2 font-bold text-white" x-text="item.name"></div> <div class="pb-2 font-bold text-white" x-text="item.name"></div>
<template x-if="item.status.startsWith('running')"> <template x-if="item.status.startsWith('running')">
@ -66,8 +66,8 @@
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div> <div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
</template> </template>
</div> </div>
<div class="description" x-text="item.description"></div> <div class="max-w-full truncate description" x-text="item.description"></div>
<div class="description break-all" x-text="item.fqdn"></div> <div class="max-w-full truncate description" x-text="item.fqdn"></div>
</div> </div>
</a> </a>
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6"> <div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
@ -83,7 +83,7 @@
<template x-for="item in filteredPostgresqls" :key="item.id"> <template x-for="item in filteredPostgresqls" :key="item.id">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col mx-6"> <div class="flex flex-col px-4 mx-2">
<div class="flex gap-2"> <div class="flex gap-2">
<div class="pb-2 font-bold text-white" x-text="item.name"></div> <div class="pb-2 font-bold text-white" x-text="item.name"></div>
<template x-if="item.status.startsWith('running')"> <template x-if="item.status.startsWith('running')">
@ -99,7 +99,7 @@
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div> <div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
</template> </template>
</div> </div>
<div class="description" x-text="item.description"></div> <div class="max-w-full truncate description" x-text="item.description"></div>
</div> </div>
</a> </a>
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6"> <div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
@ -115,7 +115,7 @@
<template x-for="item in filteredRedis" :key="item.id"> <template x-for="item in filteredRedis" :key="item.id">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col mx-6"> <div class="flex flex-col px-4 mx-2">
<div class="flex gap-2"> <div class="flex gap-2">
<div class="pb-2 font-bold text-white" x-text="item.name"></div> <div class="pb-2 font-bold text-white" x-text="item.name"></div>
<template x-if="item.status.startsWith('running')"> <template x-if="item.status.startsWith('running')">
@ -131,7 +131,7 @@
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div> <div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
</template> </template>
</div> </div>
<div class="description" x-text="item.description"></div> <div class="max-w-full truncate description" x-text="item.description"></div>
</div> </div>
</a> </a>
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6"> <div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
@ -147,7 +147,7 @@
<template x-for="item in filteredMongodbs" :key="item.id"> <template x-for="item in filteredMongodbs" :key="item.id">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col mx-6"> <div class="flex flex-col px-4 mx-2">
<div class="flex gap-2"> <div class="flex gap-2">
<div class="pb-2 font-bold text-white" x-text="item.name"></div> <div class="pb-2 font-bold text-white" x-text="item.name"></div>
<template x-if="item.status.startsWith('running')"> <template x-if="item.status.startsWith('running')">
@ -163,7 +163,7 @@
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div> <div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
</template> </template>
</div> </div>
<div class="description" x-text="item.description"></div> <div class="max-w-full truncate description" x-text="item.description"></div>
</div> </div>
</a> </a>
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6"> <div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
@ -179,7 +179,7 @@
<template x-for="item in filteredMysqls" :key="item.id"> <template x-for="item in filteredMysqls" :key="item.id">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col mx-6"> <div class="flex flex-col px-4 mx-2">
<div class="flex gap-2"> <div class="flex gap-2">
<div class="pb-2 font-bold text-white" x-text="item.name"></div> <div class="pb-2 font-bold text-white" x-text="item.name"></div>
<template x-if="item.status.startsWith('running')"> <template x-if="item.status.startsWith('running')">
@ -195,7 +195,7 @@
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div> <div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
</template> </template>
</div> </div>
<div class="description" x-text="item.description"></div> <div class="max-w-full truncate description" x-text="item.description"></div>
</div> </div>
</a> </a>
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6"> <div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
@ -211,7 +211,7 @@
<template x-for="item in filteredMariadbs" :key="item.id"> <template x-for="item in filteredMariadbs" :key="item.id">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col mx-6"> <div class="flex flex-col px-4 mx-2">
<div class="flex gap-2"> <div class="flex gap-2">
<div class="pb-2 font-bold text-white" x-text="item.name"></div> <div class="pb-2 font-bold text-white" x-text="item.name"></div>
<template x-if="item.status.startsWith('running')"> <template x-if="item.status.startsWith('running')">
@ -227,7 +227,7 @@
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div> <div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
</template> </template>
</div> </div>
<div class="description" x-text="item.description"></div> <div class="max-w-full truncate description" x-text="item.description"></div>
</div> </div>
</a> </a>
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6"> <div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
@ -243,7 +243,7 @@
<template x-for="item in filteredServices" :key="item.id"> <template x-for="item in filteredServices" :key="item.id">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col mx-6"> <div class="flex flex-col px-4 mx-2">
<div class="flex gap-2"> <div class="flex gap-2">
<div class="pb-2 font-bold text-white" x-text="item.name"></div> <div class="pb-2 font-bold text-white" x-text="item.name"></div>
<template x-if="item.status.startsWith('running')"> <template x-if="item.status.startsWith('running')">
@ -259,7 +259,7 @@
<div title="degraded" class="mt-1 bg-warning badge badge-xs"></div> <div title="degraded" class="mt-1 bg-warning badge badge-xs"></div>
</template> </template>
</div> </div>
<div class="description" x-text="item.description"></div> <div class="max-w-full truncate description" x-text="item.description"></div>
</div> </div>
</a> </a>
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6"> <div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">

View File

@ -1,7 +1,7 @@
<div> <div>
<div x-init="$wire.getLogs" id="screen" x-data="{ fullscreen: false, alwaysScroll: false, intervalId: null }"> <div x-init="$wire.getLogs" id="screen" x-data="{ fullscreen: false, alwaysScroll: false, intervalId: null }">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<h3>{{ $container }}</h3> <h3>{{ str($container)->beforeLast('-')->headline() }}</h3>
@if ($pull_request) @if ($pull_request)
<div>({{ $pull_request }})</div> <div>({{ $pull_request }})</div>
@endif @endif

View File

@ -4,7 +4,7 @@
<h2>General</h2> <h2>General</h2>
@if ($server->id === 0) @if ($server->id === 0)
<x-new-modal buttonTitle="Save" title="Change Localhost" action="submit"> <x-new-modal buttonTitle="Save" title="Change Localhost" action="submit">
You could lost a lot of functionalities if you change the server details of the server where Coolify You could lose a lot of functionalities if you change the server details of the server where Coolify
is is
running on.<br>Please think again. running on.<br>Please think again.
</x-new-modal> </x-new-modal>

View File

@ -45,7 +45,7 @@
{{ data_get($resource, 'environment.name') }} {{ data_get($resource, 'environment.name') }}
</td> </td>
<td class="px-5 py-4 text-sm whitespace-nowrap"><a class="" <td class="px-5 py-4 text-sm whitespace-nowrap"><a class=""
href="{{ $resource->link() }}">{{ $resource->name }} </a> href="{{ $resource->link() }}">{{ $resource->name }} <x-internal-link/></a>
</td> </td>
<td class="px-5 py-4 text-sm whitespace-nowrap"> <td class="px-5 py-4 text-sm whitespace-nowrap">
{{ str($resource->type())->headline() }}</td> {{ str($resource->type())->headline() }}</td>
@ -68,7 +68,7 @@
</div> </div>
</div> </div>
<div x-cloak x-show="activeTab === 'unmanaged'" class="h-full"> <div x-cloak x-show="activeTab === 'unmanaged'" class="h-full">
<div class="flex flex-col"> <div class="flex flex-col" x-init="$wire.loadUnmanagedContainers()">
<div class="flex gap-2"> <div class="flex gap-2">
<h2>Resources</h2> <h2>Resources</h2>
<x-forms.button wire:click="refreshStatus">Refresh</x-forms.button> <x-forms.button wire:click="refreshStatus">Refresh</x-forms.button>

View File

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
## Do not modify this file. You will lost the ability to autoupdate! ## Do not modify this file. You will lose the ability to autoupdate!
VERSION="1.0.4" VERSION="1.0.4"
CDN="https://cdn.coollabs.io/coolify" CDN="https://cdn.coollabs.io/coolify"

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
"version": "3.12.36" "version": "3.12.36"
}, },
"v4": { "v4": {
"version": "4.0.0-beta.227" "version": "4.0.0-beta.228"
} }
} }
} }