mirror of
https://github.com/cupcakearmy/coolify.git
synced 2024-10-22 08:04:19 +02:00
refactor: Remove unused server timezone seeder and related code
This commit is contained in:
parent
b8ff0540e2
commit
68169f75d1
@ -35,6 +35,7 @@ protected function schedule(Schedule $schedule): void
|
||||
// Instance Jobs
|
||||
$schedule->command('horizon:snapshot')->everyMinute();
|
||||
$schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer();
|
||||
$schedule->job(new PullCoolifyImageJob)->cron($settings->update_check_frequency)->timezone($settings->instance_timezone)->onOneServer();
|
||||
// Server Jobs
|
||||
$this->check_scheduled_backups($schedule);
|
||||
$this->check_resources($schedule);
|
||||
@ -134,6 +135,7 @@ private function check_scheduled_backups($schedule)
|
||||
if (is_null(data_get($scheduled_backup, 'database'))) {
|
||||
ray('database not found');
|
||||
$scheduled_backup->delete();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -165,6 +167,7 @@ private function check_scheduled_tasks($schedule)
|
||||
if (! $application && ! $service) {
|
||||
ray('application/service attached to scheduled task does not exist');
|
||||
$scheduled_task->delete();
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($application) {
|
||||
@ -192,8 +195,8 @@ private function check_scheduled_tasks($schedule)
|
||||
|
||||
protected function commands(): void
|
||||
{
|
||||
$this->load(__DIR__ . '/Commands');
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,7 @@
|
||||
use App\Actions\Server\StartSentinel;
|
||||
use App\Actions\Server\StopSentinel;
|
||||
use App\Jobs\PullSentinelImageJob;
|
||||
use App\Models\Server;;
|
||||
|
||||
use App\Models\Server;
|
||||
use Livewire\Component;
|
||||
|
||||
class Form extends Component
|
||||
@ -23,6 +22,8 @@ class Form extends Component
|
||||
|
||||
public bool $revalidate = false;
|
||||
|
||||
public $timezones;
|
||||
|
||||
protected $listeners = ['serverInstalled', 'revalidate' => '$refresh'];
|
||||
|
||||
protected $rules = [
|
||||
@ -71,8 +72,6 @@ class Form extends Component
|
||||
'server.settings.server_timezone' => 'Server Timezone',
|
||||
];
|
||||
|
||||
public $timezones;
|
||||
|
||||
public function mount(Server $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
@ -174,7 +173,7 @@ public function checkLocalhostConnection()
|
||||
$this->server->settings->save();
|
||||
$this->dispatch('proxyStatusUpdated');
|
||||
} else {
|
||||
$this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help. <br><br>Error: ' . $error);
|
||||
$this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help. <br><br>Error: '.$error);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -214,22 +213,12 @@ public function submit()
|
||||
} else {
|
||||
$this->server->settings->docker_cleanup_threshold = $this->server->settings->docker_cleanup_threshold;
|
||||
}
|
||||
$currentTimezone = $this->server->settings->getOriginal('server_timezone');
|
||||
$newTimezone = $this->server->settings->server_timezone;
|
||||
if ($currentTimezone !== $newTimezone || $currentTimezone === '') {
|
||||
try {
|
||||
$timezoneUpdated = $this->updateServerTimezone($newTimezone);
|
||||
if ($timezoneUpdated) {
|
||||
$this->server->settings->server_timezone = $newTimezone;
|
||||
$this->server->settings->save();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->dispatch('error', 'Failed to update server timezone: ' . $e->getMessage());
|
||||
return;
|
||||
$currentTimezone = $this->server->settings->getOriginal('server_timezone');
|
||||
$newTimezone = $this->server->settings->server_timezone;
|
||||
if ($currentTimezone !== $newTimezone || $currentTimezone === '') {
|
||||
$this->server->settings->server_timezone = $newTimezone;
|
||||
$this->server->settings->save();
|
||||
}
|
||||
}
|
||||
|
||||
$this->server->settings->save();
|
||||
$this->server->save();
|
||||
@ -239,89 +228,10 @@ public function submit()
|
||||
}
|
||||
}
|
||||
|
||||
public function updatedServerTimezone($value)
|
||||
public function updatedServerSettingsServerTimezone($value)
|
||||
{
|
||||
if (!is_string($value) || !in_array($value, timezone_identifiers_list())) {
|
||||
$this->addError('server.settings.server_timezone', 'Invalid timezone.');
|
||||
return;
|
||||
}
|
||||
$this->server->settings->server_timezone = $value;
|
||||
$this->updateServerTimezone($value);
|
||||
}
|
||||
|
||||
private function updateServerTimezone($desired_timezone)
|
||||
{
|
||||
try {
|
||||
$commands = [
|
||||
"if command -v timedatectl > /dev/null 2>&1 && pidof systemd > /dev/null; then",
|
||||
" timedatectl set-timezone " . escapeshellarg($desired_timezone),
|
||||
"elif [ -f /etc/timezone ]; then",
|
||||
" echo " . escapeshellarg($desired_timezone) . " > /etc/timezone",
|
||||
" rm -f /etc/localtime",
|
||||
" ln -sf /usr/share/zoneinfo/" . escapeshellarg($desired_timezone) . " /etc/localtime",
|
||||
"elif [ -f /etc/localtime ]; then",
|
||||
" rm -f /etc/localtime",
|
||||
" ln -sf /usr/share/zoneinfo/" . escapeshellarg($desired_timezone) . " /etc/localtime",
|
||||
"else",
|
||||
" echo 'Unable to set timezone'",
|
||||
" exit 1",
|
||||
"fi",
|
||||
"if command -v dpkg-reconfigure > /dev/null 2>&1; then",
|
||||
" dpkg-reconfigure -f noninteractive tzdata",
|
||||
"elif command -v tzdata-update > /dev/null 2>&1; then",
|
||||
" tzdata-update",
|
||||
"elif [ -f /etc/sysconfig/clock ]; then",
|
||||
" sed -i 's/^ZONE=.*/ZONE=\"" . $desired_timezone . "\"/' /etc/sysconfig/clock",
|
||||
" source /etc/sysconfig/clock",
|
||||
"fi",
|
||||
"if command -v systemctl > /dev/null 2>&1 && pidof systemd > /dev/null; then",
|
||||
" systemctl try-restart systemd-timesyncd.service || true",
|
||||
"elif command -v service > /dev/null 2>&1; then",
|
||||
" service ntpd restart || service ntp restart || true",
|
||||
"fi",
|
||||
"echo \"Timezone updated to: $desired_timezone\"",
|
||||
"date"
|
||||
];
|
||||
|
||||
instant_remote_process($commands, $this->server);
|
||||
|
||||
$verificationCommands = [
|
||||
"readlink /etc/localtime | sed 's#/usr/share/zoneinfo/##'",
|
||||
"date +'%Z %:z'"
|
||||
];
|
||||
$verificationResult = instant_remote_process($verificationCommands, $this->server, false);
|
||||
$verificationLines = explode("\n", trim($verificationResult));
|
||||
|
||||
if (count($verificationLines) !== 2) {
|
||||
$this->dispatch('error', 'Failed to verify timezone update. Unexpected server response.');
|
||||
return false;
|
||||
}
|
||||
|
||||
$actualTimezone = trim($verificationLines[0]);
|
||||
[$abbreviation, $offset] = explode(' ', trim($verificationLines[1]));
|
||||
|
||||
$desiredTz = new \DateTimeZone($desired_timezone);
|
||||
$desiredAbbr = (new \DateTime('now', $desiredTz))->format('T');
|
||||
$desiredOffset = $this->formatOffset($desiredTz->getOffset(new \DateTime('now', $desiredTz)));
|
||||
|
||||
if ($actualTimezone === $desired_timezone && $abbreviation === $desiredAbbr && $offset === $desiredOffset) {
|
||||
$this->server->settings->server_timezone = $desired_timezone;
|
||||
$this->server->settings->save();
|
||||
return true;
|
||||
} else {
|
||||
$this->dispatch('error', 'Failed to update server timezone. The server reported a different timezone than requested.');
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->dispatch('error', 'Failed to update server timezone: ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function formatOffset($offsetSeconds)
|
||||
{
|
||||
$hours = abs($offsetSeconds) / 3600;
|
||||
$minutes = (abs($offsetSeconds) % 3600) / 60;
|
||||
return sprintf('%s%02d:%02d', $offsetSeconds >= 0 ? '+' : '-', $hours, $minutes);
|
||||
$this->server->settings->save();
|
||||
$this->dispatch('success', 'Server timezone updated.');
|
||||
}
|
||||
}
|
||||
|
@ -170,8 +170,15 @@ public function checkManually()
|
||||
}
|
||||
}
|
||||
|
||||
public function updatedSettingsInstanceTimezone($value)
|
||||
{
|
||||
$this->settings->instance_timezone = $value;
|
||||
$this->settings->save();
|
||||
$this->dispatch('success', 'Instance timezone updated.');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.settings.index');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,30 @@ public function fqdn(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function updateCheckFrequency(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
set: function ($value) {
|
||||
return translate_cron_expression($value);
|
||||
},
|
||||
get: function ($value) {
|
||||
return translate_cron_expression($value);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function autoUpdateFrequency(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
set: function ($value) {
|
||||
return translate_cron_expression($value);
|
||||
},
|
||||
get: function ($value) {
|
||||
return translate_cron_expression($value);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public static function get()
|
||||
{
|
||||
return InstanceSettings::findOrFail(0);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use OpenApi\Attributes as OA;
|
||||
|
||||
@ -58,4 +59,18 @@ public function server()
|
||||
{
|
||||
return $this->belongsTo(Server::class);
|
||||
}
|
||||
}
|
||||
|
||||
public function dockerCleanupFrequency(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
set: function ($value) {
|
||||
ray($value);
|
||||
|
||||
return translate_cron_expression($value);
|
||||
},
|
||||
get: function ($value) {
|
||||
return translate_cron_expression($value);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -353,6 +353,14 @@ function isCloud(): bool
|
||||
return ! config('coolify.self_hosted');
|
||||
}
|
||||
|
||||
function translate_cron_expression($expression_to_validate): string
|
||||
{
|
||||
if (isset(VALID_CRON_STRINGS[$expression_to_validate])) {
|
||||
return VALID_CRON_STRINGS[$expression_to_validate];
|
||||
}
|
||||
|
||||
return $expression_to_validate;
|
||||
}
|
||||
function validate_cron_expression($expression_to_validate): bool
|
||||
{
|
||||
$isValid = false;
|
||||
|
@ -33,7 +33,6 @@ public function run(): void
|
||||
ScheduledDatabaseBackupSeeder::class,
|
||||
ScheduledDatabaseBackupExecutionSeeder::class,
|
||||
OauthSettingSeeder::class,
|
||||
ServerTimezoneSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +182,5 @@ public function run(): void
|
||||
$oauth_settings_seeder = new OauthSettingSeeder;
|
||||
$oauth_settings_seeder->run();
|
||||
|
||||
$server_timezone_seeder = new ServerTimezoneSeeder;
|
||||
$server_timezone_seeder->run();
|
||||
}
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
|
||||
class ServerTimezoneSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$defaultTimezone = config('app.timezone');
|
||||
|
||||
Server::whereHas('settings', function ($query) {
|
||||
$query->whereNull('server_timezone')->orWhere('server_timezone', '');
|
||||
})->each(function ($server) use ($defaultTimezone) {
|
||||
DB::transaction(function () use ($server, $defaultTimezone) {
|
||||
$this->updateServerTimezone($server, $defaultTimezone);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private function updateServerTimezone($server, $desired_timezone)
|
||||
{
|
||||
$commands = [
|
||||
"if command -v timedatectl > /dev/null 2>&1 && pidof systemd > /dev/null; then",
|
||||
" timedatectl set-timezone " . escapeshellarg($desired_timezone),
|
||||
"elif [ -f /etc/timezone ]; then",
|
||||
" echo " . escapeshellarg($desired_timezone) . " > /etc/timezone",
|
||||
" rm -f /etc/localtime",
|
||||
" ln -sf /usr/share/zoneinfo/" . escapeshellarg($desired_timezone) . " /etc/localtime",
|
||||
"elif [ -f /etc/localtime ]; then",
|
||||
" rm -f /etc/localtime",
|
||||
" ln -sf /usr/share/zoneinfo/" . escapeshellarg($desired_timezone) . " /etc/localtime",
|
||||
"fi",
|
||||
"if command -v dpkg-reconfigure > /dev/null 2>&1; then",
|
||||
" dpkg-reconfigure -f noninteractive tzdata",
|
||||
"elif command -v tzdata-update > /dev/null 2>&1; then",
|
||||
" tzdata-update",
|
||||
"elif [ -f /etc/sysconfig/clock ]; then",
|
||||
" sed -i 's/^ZONE=.*/ZONE=\"" . $desired_timezone . "\"/' /etc/sysconfig/clock",
|
||||
" source /etc/sysconfig/clock",
|
||||
"fi",
|
||||
"if command -v systemctl > /dev/null 2>&1 && pidof systemd > /dev/null; then",
|
||||
" systemctl try-restart systemd-timesyncd.service || true",
|
||||
"elif command -v service > /dev/null 2>&1; then",
|
||||
" service ntpd restart || service ntp restart || true",
|
||||
"fi"
|
||||
];
|
||||
|
||||
instant_remote_process($commands, $server);
|
||||
|
||||
$server->settings->server_timezone = $desired_timezone;
|
||||
$server->settings->save();
|
||||
}
|
||||
}
|
@ -1,66 +1,66 @@
|
||||
<div wire:init='refreshBackupExecutions'>
|
||||
@isset($backup)
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="py-4">Executions</h3>
|
||||
<x-forms.button wire:click='cleanupFailed'>Cleanup Failed Backups</x-forms.button>
|
||||
</div>
|
||||
<div class="flex flex-col-reverse gap-4">
|
||||
@forelse($executions as $execution)
|
||||
<div wire:key="{{ data_get($execution, 'id') }}"
|
||||
@class([
|
||||
'flex flex-col border-l-4 transition-colors cursor-pointer p-4 rounded',
|
||||
'bg-white hover:bg-gray-100 dark:bg-coolgray-100 dark:hover:bg-coolgray-200',
|
||||
'text-black dark:text-white',
|
||||
'border-green-500' => data_get($execution, 'status') === 'success',
|
||||
'border-red-500' => data_get($execution, 'status') === 'failed',
|
||||
'border-yellow-500' => data_get($execution, 'status') === 'running',
|
||||
])>
|
||||
@if (data_get($execution, 'status') === 'running')
|
||||
<div class="absolute top-2 right-2">
|
||||
<x-loading />
|
||||
</div>
|
||||
@endif
|
||||
<div class="text-gray-700 dark:text-gray-300 font-semibold mb-1">Status: {{ data_get($execution, 'status') }}</div>
|
||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
Started At: {{ $this->formatDateInServerTimezone(data_get($execution, 'created_at')) }}
|
||||
</div>
|
||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
Database: {{ data_get($execution, 'database_name', 'N/A') }}
|
||||
</div>
|
||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
Size: {{ data_get($execution, 'size') }} B /
|
||||
{{ round((int) data_get($execution, 'size') / 1024, 2) }} kB /
|
||||
{{ round((int) data_get($execution, 'size') / 1024 / 1024, 3) }} MB
|
||||
</div>
|
||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
Location: {{ data_get($execution, 'filename', 'N/A') }}
|
||||
</div>
|
||||
@if (data_get($execution, 'message'))
|
||||
<div class="mt-2 p-2 bg-gray-100 dark:bg-coolgray-200 rounded">
|
||||
<pre class="whitespace-pre-wrap text-sm">{{ data_get($execution, 'message') }}</pre>
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex gap-2 mt-4">
|
||||
@if (data_get($execution, 'status') === 'success')
|
||||
<x-forms.button class="dark:hover:bg-coolgray-400"
|
||||
x-on:click="download_file('{{ data_get($execution, 'id') }}')">Download</x-forms.button>
|
||||
@endif
|
||||
<x-modal-confirmation isErrorButton action="deleteBackup({{ data_get($execution, 'id') }})">
|
||||
<x-slot:button-title>
|
||||
Delete
|
||||
</x-slot:button-title>
|
||||
This will delete this backup. It is not reversible.<br>Please think again.
|
||||
</x-modal-confirmation>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="py-4">Executions</h3>
|
||||
<x-forms.button wire:click='cleanupFailed'>Cleanup Failed Backups</x-forms.button>
|
||||
</div>
|
||||
@empty
|
||||
<div class="p-4 bg-gray-100 dark:bg-coolgray-200 rounded">No executions found.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
<script>
|
||||
function download_file(executionId) {
|
||||
window.open('/download/backup/' + executionId, '_blank');
|
||||
}
|
||||
</script>
|
||||
<div class="flex flex-col-reverse gap-4">
|
||||
@forelse($executions as $execution)
|
||||
<div wire:key="{{ data_get($execution, 'id') }}" @class([
|
||||
'flex flex-col border-l-2 transition-colors p-4 ',
|
||||
'bg-white dark:bg-coolgray-100 ',
|
||||
'text-black dark:text-white',
|
||||
'border-green-500' => data_get($execution, 'status') === 'success',
|
||||
'border-red-500' => data_get($execution, 'status') === 'failed',
|
||||
'border-yellow-500' => data_get($execution, 'status') === 'running',
|
||||
])>
|
||||
@if (data_get($execution, 'status') === 'running')
|
||||
<div class="absolute top-2 right-2">
|
||||
<x-loading />
|
||||
</div>
|
||||
@endif
|
||||
<div class="text-gray-700 dark:text-gray-300 font-semibold mb-1">Status:
|
||||
{{ data_get($execution, 'status') }}</div>
|
||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
Started At: {{ $this->formatDateInServerTimezone(data_get($execution, 'created_at')) }}
|
||||
</div>
|
||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
Database: {{ data_get($execution, 'database_name', 'N/A') }}
|
||||
</div>
|
||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
Size: {{ data_get($execution, 'size') }} B /
|
||||
{{ round((int) data_get($execution, 'size') / 1024, 2) }} kB /
|
||||
{{ round((int) data_get($execution, 'size') / 1024 / 1024, 3) }} MB
|
||||
</div>
|
||||
<div class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
Location: {{ data_get($execution, 'filename', 'N/A') }}
|
||||
</div>
|
||||
@if (data_get($execution, 'message'))
|
||||
<div class="mt-2 p-2 bg-gray-100 dark:bg-coolgray-200 rounded">
|
||||
<pre class="whitespace-pre-wrap text-sm">{{ data_get($execution, 'message') }}</pre>
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex gap-2 mt-4">
|
||||
@if (data_get($execution, 'status') === 'success')
|
||||
<x-forms.button class="dark:hover:bg-coolgray-400"
|
||||
x-on:click="download_file('{{ data_get($execution, 'id') }}')">Download</x-forms.button>
|
||||
@endif
|
||||
<x-modal-confirmation isErrorButton action="deleteBackup({{ data_get($execution, 'id') }})">
|
||||
<x-slot:button-title>
|
||||
Delete
|
||||
</x-slot:button-title>
|
||||
This will delete this backup. It is not reversible.<br>Please think again.
|
||||
</x-modal-confirmation>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="p-4 bg-gray-100 dark:bg-coolgray-200 rounded">No executions found.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
<script>
|
||||
function download_file(executionId) {
|
||||
window.open('/download/backup/' + executionId, '_blank');
|
||||
}
|
||||
</script>
|
||||
@endisset
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,104 +3,69 @@
|
||||
<div class="flex gap-2">
|
||||
<h2>General</h2>
|
||||
@if ($server->id === 0)
|
||||
<x-modal-confirmation buttonTitle="Save" title="Change Localhost" action="submit">
|
||||
You could lose a lot of functionalities if you change the server details of the server where Coolify
|
||||
is
|
||||
running on.<br>Please think again.
|
||||
</x-modal-confirmation>
|
||||
<x-modal-confirmation buttonTitle="Save" title="Change Localhost" action="submit">
|
||||
You could lose a lot of functionalities if you change the server details of the server where Coolify
|
||||
is
|
||||
running on.<br>Please think again.
|
||||
</x-modal-confirmation>
|
||||
@else
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
@if ($server->isFunctional())
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Validate & configure</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$server" ask />
|
||||
</x-slot:content>
|
||||
<x-forms.button @click="slideOverOpen=true" wire:click.prevent='validateServer' isHighlighted>
|
||||
Revalidate server
|
||||
</x-forms.button>
|
||||
</x-slide-over>
|
||||
@endif
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
@if ($server->isFunctional())
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Validate & configure</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$server" ask />
|
||||
</x-slot:content>
|
||||
<x-forms.button @click="slideOverOpen=true" wire:click.prevent='validateServer' isHighlighted>
|
||||
Revalidate server
|
||||
</x-forms.button>
|
||||
</x-slide-over>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
@if ($server->isFunctional())
|
||||
Server is reachable and validated.
|
||||
Server is reachable and validated.
|
||||
@else
|
||||
You can't use this server until it is validated.
|
||||
You can't use this server until it is validated.
|
||||
@endif
|
||||
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id !== 0)
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Validate & configure</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$server" />
|
||||
</x-slot:content>
|
||||
<x-forms.button @click="slideOverOpen=true"
|
||||
class="w-full mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
||||
wire:click.prevent='validateServer' isHighlighted>
|
||||
Validate Server & Install Docker Engine
|
||||
</x-forms.button>
|
||||
</x-slide-over>
|
||||
@if ($server->validation_logs)
|
||||
<h4>Previous Validation Logs</h4>
|
||||
<div class="pb-8">
|
||||
{!! $server->validation_logs !!}
|
||||
</div>
|
||||
@endif
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Validate & configure</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$server" />
|
||||
</x-slot:content>
|
||||
<x-forms.button @click="slideOverOpen=true"
|
||||
class="w-full mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
||||
wire:click.prevent='validateServer' isHighlighted>
|
||||
Validate Server & Install Docker Engine
|
||||
</x-forms.button>
|
||||
</x-slide-over>
|
||||
@if ($server->validation_logs)
|
||||
<h4>Previous Validation Logs</h4>
|
||||
<div class="pb-8">
|
||||
{!! $server->validation_logs !!}
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id === 0)
|
||||
<x-forms.button class="mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
||||
wire:click.prevent='checkLocalhostConnection' isHighlighted>
|
||||
Validate Server
|
||||
</x-forms.button>
|
||||
<x-forms.button class="mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
||||
wire:click.prevent='checkLocalhostConnection' isHighlighted>
|
||||
Validate Server
|
||||
</x-forms.button>
|
||||
@endif
|
||||
@if ($server->isForceDisabled() && isCloud())
|
||||
<div class="pt-4 font-bold text-red-500">The system has disabled the server because you have exceeded the
|
||||
number of servers for which you have paid.</div>
|
||||
<div class="pt-4 font-bold text-red-500">The system has disabled the server because you have exceeded the
|
||||
number of servers for which you have paid.</div>
|
||||
@endif
|
||||
<div class="flex flex-col gap-2 pt-4">
|
||||
<div class="flex flex-col w-full gap-2 lg:flex-row">
|
||||
<x-forms.input id="server.name" label="Name" required />
|
||||
<x-forms.input id="server.description" label="Description" />
|
||||
@if (!$server->settings->is_swarm_worker && !$server->settings->is_build_server)
|
||||
<x-forms.input placeholder="https://example.com" id="wildcard_domain" label="Wildcard Domain"
|
||||
helper='A wildcard domain allows you to receive a randomly generated domain for your new applications. <br><br>For instance, if you set "https://example.com" as your wildcard domain, your applications will receive domains like "https://randomId.example.com".' />
|
||||
<x-forms.input placeholder="https://example.com" id="wildcard_domain" label="Wildcard Domain"
|
||||
helper='A wildcard domain allows you to receive a randomly generated domain for your new applications. <br><br>For instance, if you set "https://example.com" as your wildcard domain, your applications will receive domains like "https://randomId.example.com".' />
|
||||
@endif
|
||||
<div class="w-full" x-data="{
|
||||
open: false,
|
||||
search: '{{ $server->settings->server_timezone ?: '' }}',
|
||||
timezones: @js($timezones),
|
||||
placeholder: '{{ $server->settings->server_timezone ? 'Search timezone...' : 'Select Server Timezone' }}',
|
||||
init() {
|
||||
this.$watch('search', value => {
|
||||
if (value === '') {
|
||||
this.open = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
}">
|
||||
<div class="flex items-center">
|
||||
<label for="server.settings.server_timezone" class="dark:text-white">Server Timezone</label>
|
||||
<x-helper class="ml-2" helper="Current server's timezone (This setting changes your server's timezone in /etc/timezone, /etc/localtime, etc.). This is used for backups, cron jobs, etc." />
|
||||
</div>
|
||||
<div class="relative">
|
||||
<input
|
||||
x-model="search"
|
||||
@focus="open = true"
|
||||
@click.away="open = false"
|
||||
@input="open = true"
|
||||
class="w-full input"
|
||||
:placeholder="placeholder"
|
||||
wire:model.debounce.300ms="server.settings.server_timezone">
|
||||
<div x-show="open" class="absolute z-50 w-full mt-1 bg-white dark:bg-coolgray-100 border border-gray-300 dark:border-white rounded-md shadow-lg max-h-60 overflow-auto">
|
||||
<template x-for="timezone in timezones.filter(tz => tz.toLowerCase().includes(search.toLowerCase()))" :key="timezone">
|
||||
<div
|
||||
@click="search = timezone; open = false; $wire.set('server.settings.server_timezone', timezone)"
|
||||
class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-800 dark:text-gray-200"
|
||||
x-text="timezone"></div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="flex flex-col w-full gap-2 lg:flex-row">
|
||||
<x-forms.input type="password" id="server.ip" label="IP Address/Domain"
|
||||
@ -110,66 +75,108 @@ class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 text-gr
|
||||
<x-forms.input type="number" id="server.port" label="Port" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full" x-data="{
|
||||
open: false,
|
||||
search: '{{ $server->settings->server_timezone ?: '' }}',
|
||||
timezones: @js($timezones),
|
||||
placeholder: '{{ $server->settings->server_timezone ? 'Search timezone...' : 'Select Server Timezone' }}',
|
||||
init() {
|
||||
this.$watch('search', value => {
|
||||
if (value === '') {
|
||||
this.open = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
}">
|
||||
<div class="flex items-center mb-1">
|
||||
<label for="server.settings.server_timezone">Server
|
||||
Timezone</label>
|
||||
<x-helper class="ml-2" helper="Server's timezone. This is used for backups, cron jobs, etc." />
|
||||
</div>
|
||||
<div class="relative">
|
||||
<div class="inline-flex items-center relative w-64">
|
||||
<input wire:dirty.class.remove='dark:focus:ring-coolgray-300 dark:ring-coolgray-300'
|
||||
wire:dirty.class="dark:focus:ring-warning dark:ring-warning" x-model="search"
|
||||
@focus="open = true" @click.away="open = false" @input="open = true" class="w-full input "
|
||||
:placeholder="placeholder" wire:model.debounce.300ms="server.settings.server_timezone">
|
||||
<svg class="absolute right-0 w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" @click="open = true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M8.25 15L12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9" />
|
||||
</svg>
|
||||
</div>
|
||||
<div x-show="open"
|
||||
class="absolute z-50 w-64 mt-1 bg-white dark:bg-coolgray-100 border dark:border-coolgray-200 rounded-md shadow-lg max-h-60 overflow-auto scrollbar overflow-x-hidden">
|
||||
<template
|
||||
x-for="timezone in timezones.filter(tz => tz.toLowerCase().includes(search.toLowerCase()))"
|
||||
:key="timezone">
|
||||
<div @click="search = timezone; open = false; $wire.set('server.settings.server_timezone', timezone)"
|
||||
class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-coolgray-300 text-gray-800 dark:text-gray-200"
|
||||
x-text="timezone"></div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-64">
|
||||
@if ($server->isFunctional())
|
||||
@if (!$server->isLocalhost())
|
||||
<x-forms.checkbox instantSave id="server.settings.is_build_server"
|
||||
label="Use it as a build server?" />
|
||||
<div class="flex items-center gap-1 pt-6">
|
||||
<h3 class="">Cloudflare Tunnels
|
||||
</h3>
|
||||
<x-helper class="inline-flex"
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all SSH requests to your server through Cloudflare.<br><span class='dark:text-warning'>Coolify does not install or set up Cloudflare (cloudflared) on your server.</span>" />
|
||||
</div>
|
||||
@if ($server->settings->is_cloudflare_tunnel)
|
||||
<x-forms.checkbox instantSave id="server.settings.is_cloudflare_tunnel" label="Enabled" />
|
||||
@else
|
||||
<x-modal-input buttonTitle="Configure" title="Cloudflare Tunnels">
|
||||
<livewire:server.configure-cloudflare-tunnels :server_id="$server->id" />
|
||||
</x-modal-input>
|
||||
@endif
|
||||
@if (!$server->isBuildServer())
|
||||
<h3 class="pt-6">Swarm <span class="text-xs text-neutral-500">(experimental)</span></h3>
|
||||
<div class="pb-4">Read the docs <a class='underline dark:text-white'
|
||||
href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>.
|
||||
</div>
|
||||
@if ($server->settings->is_swarm_worker)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox"
|
||||
id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@endif
|
||||
@if (!$server->isLocalhost())
|
||||
<x-forms.checkbox instantSave id="server.settings.is_build_server"
|
||||
label="Use it as a build server?" />
|
||||
<div class="flex items-center gap-1 pt-6">
|
||||
<h3 class="">Cloudflare Tunnels
|
||||
</h3>
|
||||
<x-helper class="inline-flex"
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all SSH requests to your server through Cloudflare.<br><span class='dark:text-warning'>Coolify does not install or set up Cloudflare (cloudflared) on your server.</span>" />
|
||||
</div>
|
||||
@if ($server->settings->is_cloudflare_tunnel)
|
||||
<x-forms.checkbox instantSave id="server.settings.is_cloudflare_tunnel" label="Enabled" />
|
||||
@else
|
||||
<x-modal-input buttonTitle="Configure" title="Cloudflare Tunnels">
|
||||
<livewire:server.configure-cloudflare-tunnels :server_id="$server->id" />
|
||||
</x-modal-input>
|
||||
@endif
|
||||
@if (!$server->isBuildServer())
|
||||
<h3 class="pt-6">Swarm <span class="text-xs text-neutral-500">(experimental)</span></h3>
|
||||
<div class="pb-4">Read the docs <a class='underline dark:text-white'
|
||||
href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>.
|
||||
</div>
|
||||
@if ($server->settings->is_swarm_worker)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox"
|
||||
id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_manager"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Manager?" />
|
||||
@endif
|
||||
|
||||
@if ($server->settings->is_swarm_manager)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox"
|
||||
id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@if ($server->settings->is_swarm_manager)
|
||||
<x-forms.checkbox disabled instantSave type="checkbox"
|
||||
id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@endif
|
||||
@endif
|
||||
@endif
|
||||
@else
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_worker"
|
||||
helper="For more information, please read the documentation <a class='dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/swarm' target='_blank'>here</a>."
|
||||
label="Is it a Swarm Worker?" />
|
||||
@endif
|
||||
@endif
|
||||
@endif
|
||||
@else
|
||||
<div class="flex items-center gap-1 pt-6">
|
||||
<h3 class="">Cloudflare Tunnels
|
||||
</h3>
|
||||
<x-helper class="inline-flex"
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all SSH requests to your server through Cloudflare.<br><span class='dark:text-warning'>Coolify does not install or set up Cloudflare (cloudflared) on your server.</span>" />
|
||||
</div>
|
||||
@if ($server->settings->is_cloudflare_tunnel)
|
||||
<x-forms.checkbox instantSave id="server.settings.is_cloudflare_tunnel" label="Enabled" />
|
||||
@else
|
||||
<x-modal-input buttonTitle="Configure" title="Cloudflare Tunnels">
|
||||
<livewire:server.configure-cloudflare-tunnels :server_id="$server->id" />
|
||||
</x-modal-input>
|
||||
@endif
|
||||
<div class="flex items-center gap-1 pt-6">
|
||||
<h3 class="">Cloudflare Tunnels
|
||||
</h3>
|
||||
<x-helper class="inline-flex"
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all SSH requests to your server through Cloudflare.<br><span class='dark:text-warning'>Coolify does not install or set up Cloudflare (cloudflared) on your server.</span>" />
|
||||
</div>
|
||||
@if ($server->settings->is_cloudflare_tunnel)
|
||||
<x-forms.checkbox instantSave id="server.settings.is_cloudflare_tunnel" label="Enabled" />
|
||||
@else
|
||||
<x-modal-input buttonTitle="Configure" title="Cloudflare Tunnels">
|
||||
<livewire:server.configure-cloudflare-tunnels :server_id="$server->id" />
|
||||
</x-modal-input>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
</div>
|
||||
@ -194,23 +201,20 @@ class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 text-gr
|
||||
helper="The Docker cleanup tasks will run when the disk usage exceeds this threshold." />
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
@else
|
||||
<x-forms.input id="cleanup_after_percentage" label="Disk cleanup threshold (%)" required
|
||||
helper="The disk cleanup task will run when the disk usage exceeds this threshold." />
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox
|
||||
helper="This will cleanup build caches / unused images / etc every 10 minutes."
|
||||
<x-forms.checkbox helper="This will cleanup build caches / unused images / etc every 10 minutes."
|
||||
instantSave id="server.settings.is_force_cleanup_enabled"
|
||||
label="Force Cleanup Docker Engine" />
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2 sm:flex-nowrap">
|
||||
<x-forms.input id="server.settings.concurrent_builds" label="Number of concurrent builds" required
|
||||
helper="You can specify the number of simultaneous build processes/deployments that should run concurrently." />
|
||||
<x-forms.input id="server.settings.dynamic_timeout" label="Deployment timeout (seconds)" required
|
||||
helper="You can define the maximum duration for a deployment to run before timing it out." />
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex flex-wrap gap-2 sm:flex-nowrap">
|
||||
<x-forms.input id="server.settings.concurrent_builds" label="Number of concurrent builds" required
|
||||
helper="You can specify the number of simultaneous build processes/deployments that should run concurrently." />
|
||||
<x-forms.input id="server.settings.dynamic_timeout" label="Deployment timeout (seconds)" required
|
||||
helper="You can define the maximum duration for a deployment to run before timing it out." />
|
||||
</div>
|
||||
<div class="flex items-center gap-2 pt-4 pb-2">
|
||||
<h3>Sentinel</h3>
|
||||
@ -233,6 +237,5 @@ class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 text-gr
|
||||
helper="How many days should the metrics data should be reserved." />
|
||||
</div>
|
||||
</div> --}}
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
||||
|
@ -13,41 +13,60 @@
|
||||
<div>General configuration for your Coolify instance.</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<h4 class="pt-6">Instance Settings</h4>
|
||||
<div class="flex flex-wrap items-end gap-2">
|
||||
<h4 class="pt-6">Instance Settings</h4>
|
||||
<x-forms.input id="settings.fqdn" label="Instance's Domain" helper="Enter the full domain name (FQDN) of the instance, including 'https://' if you want to secure the dashboard with HTTPS. Setting this will make the dashboard accessible via this domain, secured by HTTPS, instead of just the IP address." placeholder="https://coolify.yourdomain.com" />
|
||||
<x-forms.input id="settings.instance_name" label="Instance's Name" placeholder="Coolify" />
|
||||
<div class="w-full" x-data="{
|
||||
open: false,
|
||||
search: '{{ $settings->instance_timezone }}',
|
||||
timezones: @js($timezones),
|
||||
placeholder: 'Select Instance Timezone'
|
||||
}">
|
||||
<label for="settings.instance_timezone" class="dark:text-white flex items-center">
|
||||
Instance Timezone
|
||||
<x-helper class="ml-2" helper="Timezone for the Coolify instance (this does NOT change your server's timezone in /etc/timezone, /etc/localtime, etc.). This is used for the update check and automatic update frequency." />
|
||||
</label>
|
||||
<div class="relative">
|
||||
<input
|
||||
x-model="search"
|
||||
@focus="open = true"
|
||||
@click.away="open = false"
|
||||
@input="open = true"
|
||||
class="w-full input"
|
||||
:placeholder="placeholder"
|
||||
wire:model.debounce.300ms="settings.instance_timezone"
|
||||
>
|
||||
<div x-show="open" class="absolute z-50 w-full mt-1 bg-white dark:bg-coolgray-100 border border-gray-300 dark:border-white rounded-md shadow-lg max-h-60 overflow-auto">
|
||||
<template x-for="timezone in timezones.filter(tz => tz.toLowerCase().includes(search.toLowerCase()))" :key="timezone">
|
||||
<div
|
||||
@click="search = timezone; open = false; $wire.set('settings.instance_timezone', timezone)"
|
||||
class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-800 dark:text-gray-200"
|
||||
x-text="timezone"
|
||||
></div>
|
||||
</template>
|
||||
<div class="flex gap-2 md:flex-row flex-col w-full">
|
||||
<x-forms.input id="settings.fqdn" label="Instance's Domain"
|
||||
helper="Enter the full domain name (FQDN) of the instance, including 'https://' if you want to secure the dashboard with HTTPS. Setting this will make the dashboard accessible via this domain, secured by HTTPS, instead of just the IP address."
|
||||
placeholder="https://coolify.yourdomain.com" />
|
||||
<x-forms.input id="settings.instance_name" label="Instance's Name" placeholder="Coolify" />
|
||||
<div class="w-full" x-data="{
|
||||
open: false,
|
||||
search: '{{ $settings->instance_timezone ?: '' }}',
|
||||
timezones: @js($timezones),
|
||||
placeholder: '{{ $settings->instance_timezone ? 'Search timezone...' : 'Select Server Timezone' }}',
|
||||
init() {
|
||||
this.$watch('search', value => {
|
||||
if (value === '') {
|
||||
this.open = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
}">
|
||||
<div class="flex items-center mb-1">
|
||||
<label for="settings.instance_timezone">Instance
|
||||
Timezone</label>
|
||||
<x-helper class="ml-2"
|
||||
helper="Timezone for the Coolify instance. This is used for the update check and automatic update frequency." />
|
||||
</div>
|
||||
<div class="relative">
|
||||
<div class="inline-flex items-center relative w-full">
|
||||
<input wire:dirty.class.remove='dark:focus:ring-coolgray-300 dark:ring-coolgray-300'
|
||||
wire:dirty.class="dark:focus:ring-warning dark:ring-warning" x-model="search"
|
||||
@focus="open = true" @click.away="open = false" @input="open = true"
|
||||
class="w-full input " :placeholder="placeholder"
|
||||
wire:model.debounce.300ms="settings.instance_timezone">
|
||||
<svg class="absolute right-0 w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||
@click="open = true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M8.25 15L12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9" />
|
||||
</svg>
|
||||
</div>
|
||||
<div x-show="open"
|
||||
class="absolute z-50 w-full mt-1 bg-white dark:bg-coolgray-100 border dark:border-coolgray-200 rounded-md shadow-lg max-h-60 overflow-auto scrollbar overflow-x-hidden">
|
||||
<template
|
||||
x-for="timezone in timezones.filter(tz => tz.toLowerCase().includes(search.toLowerCase()))"
|
||||
:key="timezone">
|
||||
<div @click="search = timezone; open = false; $wire.set('settings.instance_timezone', timezone)"
|
||||
class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-coolgray-300 text-gray-800 dark:text-gray-200"
|
||||
x-text="timezone"></div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="w-full pt-6">DNS Validation</h4>
|
||||
<div class="md:w-96">
|
||||
<x-forms.checkbox instantSave id="is_dns_validation_enabled" label="Enabled" />
|
||||
@ -102,4 +121,4 @@ class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 text-gr
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user