Add toggleable wire:navigate SPA navigation with prefetching

Implement instance-wide SPA navigation toggle that enables smooth page transitions with prefetching on hover. Excludes terminal links which require full page lifecycle for WebSocket connections. Adds defensive checks to global-search component for SPA navigation compatibility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2025-12-17 12:09:13 +01:00
parent 254b0a15e3
commit e709e2c131
78 changed files with 286 additions and 216 deletions

View File

@@ -38,6 +38,9 @@ class Advanced extends Component
#[Validate('boolean')] #[Validate('boolean')]
public bool $disable_two_step_confirmation; public bool $disable_two_step_confirmation;
#[Validate('boolean')]
public bool $is_wire_navigate_enabled;
public function rules() public function rules()
{ {
return [ return [
@@ -50,6 +53,7 @@ class Advanced extends Component
'allowed_ips' => ['nullable', 'string', new ValidIpOrCidr], 'allowed_ips' => ['nullable', 'string', new ValidIpOrCidr],
'is_sponsorship_popup_enabled' => 'boolean', 'is_sponsorship_popup_enabled' => 'boolean',
'disable_two_step_confirmation' => 'boolean', 'disable_two_step_confirmation' => 'boolean',
'is_wire_navigate_enabled' => 'boolean',
]; ];
} }
@@ -68,6 +72,7 @@ class Advanced extends Component
$this->is_api_enabled = $this->settings->is_api_enabled; $this->is_api_enabled = $this->settings->is_api_enabled;
$this->disable_two_step_confirmation = $this->settings->disable_two_step_confirmation; $this->disable_two_step_confirmation = $this->settings->disable_two_step_confirmation;
$this->is_sponsorship_popup_enabled = $this->settings->is_sponsorship_popup_enabled; $this->is_sponsorship_popup_enabled = $this->settings->is_sponsorship_popup_enabled;
$this->is_wire_navigate_enabled = $this->settings->is_wire_navigate_enabled ?? true;
} }
public function submit() public function submit()
@@ -146,6 +151,7 @@ class Advanced extends Component
$this->settings->allowed_ips = $this->allowed_ips; $this->settings->allowed_ips = $this->allowed_ips;
$this->settings->is_sponsorship_popup_enabled = $this->is_sponsorship_popup_enabled; $this->settings->is_sponsorship_popup_enabled = $this->is_sponsorship_popup_enabled;
$this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation; $this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation;
$this->settings->is_wire_navigate_enabled = $this->is_wire_navigate_enabled;
$this->settings->save(); $this->settings->save();
$this->dispatch('success', 'Settings updated!'); $this->dispatch('success', 'Settings updated!');
} catch (\Exception $e) { } catch (\Exception $e) {

View File

@@ -29,6 +29,7 @@ class InstanceSettings extends Model
'auto_update_frequency' => 'string', 'auto_update_frequency' => 'string',
'update_check_frequency' => 'string', 'update_check_frequency' => 'string',
'sentinel_token' => 'encrypted', 'sentinel_token' => 'encrypted',
'is_wire_navigate_enabled' => 'boolean',
]; ];
protected static function booted(): void protected static function booted(): void

View File

@@ -2916,6 +2916,18 @@ function instanceSettings()
return InstanceSettings::get(); return InstanceSettings::get();
} }
function wireNavigate(): string
{
try {
$settings = instanceSettings();
// Return wire:navigate.hover for SPA navigation with prefetching, or empty string if disabled
return ($settings->is_wire_navigate_enabled ?? true) ? 'wire:navigate.hover' : '';
} catch (\Exception $e) {
return 'wire:navigate.hover';
}
}
function getHelperVersion(): string function getHelperVersion(): string
{ {
$settings = instanceSettings(); $settings = instanceSettings();

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('instance_settings', function (Blueprint $table) {
$table->boolean('is_wire_navigate_enabled')->default(true);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('instance_settings', function (Blueprint $table) {
$table->dropColumn('is_wire_navigate_enabled');
});
}
};

View File

@@ -1,6 +1,6 @@
<div class="flex flex-col items-center justify-center h-32"> <div class="flex flex-col items-center justify-center h-32">
<span class="text-xl font-bold dark:text-white">You have reached the limit of {{ $name }} you can create.</span> <span class="text-xl font-bold dark:text-white">You have reached the limit of {{ $name }} you can create.</span>
<span>Please <a class="dark:text-white underline "href="{{ route('subscription.show') }}">upgrade your <span>Please <a class="dark:text-white underline" {{ wireNavigate() }} href="{{ route('subscription.show') }}">upgrade your
subscription</a> to create more subscription</a> to create more
{{ $name }}.</span> {{ $name }}.</span>
</div> </div>

View File

@@ -79,7 +79,7 @@
}"> }">
<div class="flex lg:pt-6 pt-4 pb-4 pl-2"> <div class="flex lg:pt-6 pt-4 pb-4 pl-2">
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<a href="/" class="text-2xl font-bold tracking-wide dark:text-white hover:opacity-80 transition-opacity">Coolify</a> <a href="/" {{ wireNavigate() }} class="text-2xl font-bold tracking-wide dark:text-white hover:opacity-80 transition-opacity">Coolify</a>
<x-version /> <x-version />
</div> </div>
<div> <div>
@@ -105,7 +105,7 @@
<ul role="list" class="flex flex-col h-full space-y-1.5"> <ul role="list" class="flex flex-col h-full space-y-1.5">
@if (isSubscribed() || !isCloud()) @if (isSubscribed() || !isCloud())
<li> <li>
<a title="Dashboard" href="/" <a title="Dashboard" href="/" {{ wireNavigate() }}
class="{{ request()->is('/') ? 'menu-item-active menu-item' : 'menu-item' }}"> class="{{ request()->is('/') ? 'menu-item-active menu-item' : 'menu-item' }}">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" fill="none" viewBox="0 0 24 24" <svg xmlns="http://www.w3.org/2000/svg" class="icon" fill="none" viewBox="0 0 24 24"
stroke="currentColor"> stroke="currentColor">
@@ -116,7 +116,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Projects" <a title="Projects" {{ wireNavigate() }}
class="{{ request()->is('project/*') || request()->is('projects') ? 'menu-item menu-item-active' : 'menu-item' }}" class="{{ request()->is('project/*') || request()->is('projects') ? 'menu-item menu-item-active' : 'menu-item' }}"
href="/projects"> href="/projects">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"
@@ -131,7 +131,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Servers" <a title="Servers" {{ wireNavigate() }}
class="{{ request()->is('server/*') || request()->is('servers') ? 'menu-item menu-item-active' : 'menu-item' }}" class="{{ request()->is('server/*') || request()->is('servers') ? 'menu-item menu-item-active' : 'menu-item' }}"
href="/servers"> href="/servers">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"
@@ -150,7 +150,7 @@
</li> </li>
<li> <li>
<a title="Sources" <a title="Sources" {{ wireNavigate() }}
class="{{ request()->is('source*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('source*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('source.all') }}"> href="{{ route('source.all') }}">
<svg class="icon" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg"> <svg class="icon" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg">
@@ -161,7 +161,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Destinations" <a title="Destinations" {{ wireNavigate() }}
class="{{ request()->is('destination*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('destination*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('destination.index') }}"> href="{{ route('destination.index') }}">
@@ -174,7 +174,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="S3 Storages" <a title="S3 Storages" {{ wireNavigate() }}
class="{{ request()->is('storages*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('storages*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('storage.index') }}"> href="{{ route('storage.index') }}">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
@@ -189,7 +189,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Shared variables" <a title="Shared variables" {{ wireNavigate() }}
class="{{ request()->is('shared-variables*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('shared-variables*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('shared-variables.index') }}"> href="{{ route('shared-variables.index') }}">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
@@ -204,7 +204,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Notifications" <a title="Notifications" {{ wireNavigate() }}
class="{{ request()->is('notifications*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('notifications*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('notifications.email') }}"> href="{{ route('notifications.email') }}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
@@ -216,7 +216,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Keys & Tokens" <a title="Keys & Tokens" {{ wireNavigate() }}
class="{{ request()->is('security*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('security*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('security.private-key.index') }}"> href="{{ route('security.private-key.index') }}">
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
@@ -228,7 +228,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Tags" <a title="Tags" {{ wireNavigate() }}
class="{{ request()->is('tags*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('tags*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('tags.show') }}"> href="{{ route('tags.show') }}">
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
@@ -259,7 +259,7 @@
</li> </li>
@endcan @endcan
<li> <li>
<a title="Profile" <a title="Profile" {{ wireNavigate() }}
class="{{ request()->is('profile*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('profile*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('profile') }}"> href="{{ route('profile') }}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
@@ -274,7 +274,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Teams" <a title="Teams" {{ wireNavigate() }}
class="{{ request()->is('team*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('team*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('team.index') }}"> href="{{ route('team.index') }}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
@@ -293,7 +293,7 @@
</li> </li>
@if (isCloud() && auth()->user()->isAdmin()) @if (isCloud() && auth()->user()->isAdmin())
<li> <li>
<a title="Subscription" <a title="Subscription" {{ wireNavigate() }}
class="{{ request()->is('subscription*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('subscription*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('subscription.show') }}"> href="{{ route('subscription.show') }}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
@@ -308,7 +308,7 @@
@if (isInstanceAdmin()) @if (isInstanceAdmin())
<li> <li>
<a title="Settings" <a title="Settings" {{ wireNavigate() }}
class="{{ request()->is('settings*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('settings*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="/settings"> href="/settings">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
@@ -327,7 +327,7 @@
@if (isCloud() || isDev()) @if (isCloud() || isDev())
@if (isInstanceAdmin() || session('impersonating')) @if (isInstanceAdmin() || session('impersonating'))
<li> <li>
<a title="Admin" class="menu-item" href="/admin"> <a title="Admin" class="menu-item" href="/admin" {{ wireNavigate() }}>
<svg class="text-pink-500 icon" viewBox="0 0 256 256" <svg class="text-pink-500 icon" viewBox="0 0 256 256"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor" <path fill="currentColor"

View File

@@ -3,27 +3,27 @@
<div class="subtitle">Get notified about your infrastructure.</div> <div class="subtitle">Get notified about your infrastructure.</div>
<div class="navbar-main"> <div class="navbar-main">
<nav class="flex items-center gap-6 min-h-10"> <nav class="flex items-center gap-6 min-h-10">
<a class="{{ request()->routeIs('notifications.email') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('notifications.email') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('notifications.email') }}"> href="{{ route('notifications.email') }}">
<button>Email</button> <button>Email</button>
</a> </a>
<a class="{{ request()->routeIs('notifications.discord') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('notifications.discord') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('notifications.discord') }}"> href="{{ route('notifications.discord') }}">
<button>Discord</button> <button>Discord</button>
</a> </a>
<a class="{{ request()->routeIs('notifications.telegram') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('notifications.telegram') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('notifications.telegram') }}"> href="{{ route('notifications.telegram') }}">
<button>Telegram</button> <button>Telegram</button>
</a> </a>
<a class="{{ request()->routeIs('notifications.slack') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('notifications.slack') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('notifications.slack') }}"> href="{{ route('notifications.slack') }}">
<button>Slack</button> <button>Slack</button>
</a> </a>
<a class="{{ request()->routeIs('notifications.pushover') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('notifications.pushover') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('notifications.pushover') }}"> href="{{ route('notifications.pushover') }}">
<button>Pushover</button> <button>Pushover</button>
</a> </a>
<a class="{{ request()->routeIs('notifications.webhook') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('notifications.webhook') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('notifications.webhook') }}"> href="{{ route('notifications.webhook') }}">
<button>Webhook</button> <button>Webhook</button>
</a> </a>

View File

@@ -18,7 +18,7 @@
<!-- Project Level --> <!-- Project Level -->
<li class="inline-flex items-center" x-data="{ projectOpen: false, closeTimeout: null, toggle() { this.projectOpen = !this.projectOpen }, open() { clearTimeout(this.closeTimeout); this.projectOpen = true }, close() { this.closeTimeout = setTimeout(() => { this.projectOpen = false }, 100) } }"> <li class="inline-flex items-center" x-data="{ projectOpen: false, closeTimeout: null, toggle() { this.projectOpen = !this.projectOpen }, open() { clearTimeout(this.closeTimeout); this.projectOpen = true }, close() { this.closeTimeout = setTimeout(() => { this.projectOpen = false }, 100) } }">
<div class="flex items-center relative" @mouseenter="open()" @mouseleave="close()"> <div class="flex items-center relative" @mouseenter="open()" @mouseleave="close()">
<a class="text-xs truncate lg:text-sm hover:text-warning" <a class="text-xs truncate lg:text-sm hover:text-warning" {{ wireNavigate() }}
href="{{ route('project.show', ['project_uuid' => $currentProjectUuid]) }}"> href="{{ route('project.show', ['project_uuid' => $currentProjectUuid]) }}">
{{ data_get($resource, 'environment.project.name', 'Undefined Name') }} {{ data_get($resource, 'environment.project.name', 'Undefined Name') }}
</a> </a>
@@ -50,7 +50,7 @@
<li class="inline-flex items-center" x-data="{ envOpen: false, activeEnv: null, envPositions: {}, activeRes: null, resPositions: {}, activeMenuEnv: null, menuPositions: {}, closeTimeout: null, envTimeout: null, resTimeout: null, menuTimeout: null, toggle() { this.envOpen = !this.envOpen; if (!this.envOpen) { this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; } }, open() { clearTimeout(this.closeTimeout); this.envOpen = true }, close() { this.closeTimeout = setTimeout(() => { this.envOpen = false; this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openEnv(id) { clearTimeout(this.closeTimeout); clearTimeout(this.envTimeout); this.activeEnv = id }, closeEnv() { this.envTimeout = setTimeout(() => { this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openRes(id) { clearTimeout(this.envTimeout); clearTimeout(this.resTimeout); this.activeRes = id }, closeRes() { this.resTimeout = setTimeout(() => { this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openMenu(id) { clearTimeout(this.resTimeout); clearTimeout(this.menuTimeout); this.activeMenuEnv = id }, closeMenu() { this.menuTimeout = setTimeout(() => { this.activeMenuEnv = null; }, 100) } }"> <li class="inline-flex items-center" x-data="{ envOpen: false, activeEnv: null, envPositions: {}, activeRes: null, resPositions: {}, activeMenuEnv: null, menuPositions: {}, closeTimeout: null, envTimeout: null, resTimeout: null, menuTimeout: null, toggle() { this.envOpen = !this.envOpen; if (!this.envOpen) { this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; } }, open() { clearTimeout(this.closeTimeout); this.envOpen = true }, close() { this.closeTimeout = setTimeout(() => { this.envOpen = false; this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openEnv(id) { clearTimeout(this.closeTimeout); clearTimeout(this.envTimeout); this.activeEnv = id }, closeEnv() { this.envTimeout = setTimeout(() => { this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openRes(id) { clearTimeout(this.envTimeout); clearTimeout(this.resTimeout); this.activeRes = id }, closeRes() { this.resTimeout = setTimeout(() => { this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openMenu(id) { clearTimeout(this.resTimeout); clearTimeout(this.menuTimeout); this.activeMenuEnv = id }, closeMenu() { this.menuTimeout = setTimeout(() => { this.activeMenuEnv = null; }, 100) } }">
<div class="flex items-center relative" @mouseenter="open()" <div class="flex items-center relative" @mouseenter="open()"
@mouseleave="close()"> @mouseleave="close()">
<a class="text-xs truncate lg:text-sm hover:text-warning" <a class="text-xs truncate lg:text-sm hover:text-warning" {{ wireNavigate() }}
href="{{ route('project.resource.index', [ href="{{ route('project.resource.index', [
'environment_uuid' => $currentEnvironmentUuid, 'environment_uuid' => $currentEnvironmentUuid,
'project_uuid' => $currentProjectUuid, 'project_uuid' => $currentProjectUuid,
@@ -422,7 +422,7 @@
<li class="inline-flex items-center" x-data="{ resourceOpen: false, activeMenu: null, menuPosition: 0, closeTimeout: null, menuTimeout: null, toggle() { this.resourceOpen = !this.resourceOpen; if (!this.resourceOpen) { this.activeMenu = null; } }, open() { clearTimeout(this.closeTimeout); this.resourceOpen = true }, close() { this.closeTimeout = setTimeout(() => { this.resourceOpen = false; this.activeMenu = null; }, 100) }, openMenu(id) { clearTimeout(this.closeTimeout); clearTimeout(this.menuTimeout); this.activeMenu = id }, closeMenu() { this.menuTimeout = setTimeout(() => { this.activeMenu = null; }, 100) } }"> <li class="inline-flex items-center" x-data="{ resourceOpen: false, activeMenu: null, menuPosition: 0, closeTimeout: null, menuTimeout: null, toggle() { this.resourceOpen = !this.resourceOpen; if (!this.resourceOpen) { this.activeMenu = null; } }, open() { clearTimeout(this.closeTimeout); this.resourceOpen = true }, close() { this.closeTimeout = setTimeout(() => { this.resourceOpen = false; this.activeMenu = null; }, 100) }, openMenu(id) { clearTimeout(this.closeTimeout); clearTimeout(this.menuTimeout); this.activeMenu = id }, closeMenu() { this.menuTimeout = setTimeout(() => { this.activeMenu = null; }, 100) } }">
<div class="flex items-center relative" @mouseenter="open()" <div class="flex items-center relative" @mouseenter="open()"
@mouseleave="close()"> @mouseleave="close()">
<a class="text-xs truncate lg:text-sm hover:text-warning" <a class="text-xs truncate lg:text-sm hover:text-warning" {{ wireNavigate() }}
href="{{ $isApplication href="{{ $isApplication
? route('project.application.configuration', $routeParams) ? route('project.application.configuration', $routeParams)
: ($isService : ($isService

View File

@@ -3,20 +3,20 @@
<div class="subtitle">Security related settings.</div> <div class="subtitle">Security related settings.</div>
<div class="navbar-main"> <div class="navbar-main">
<nav class="flex items-center gap-6 scrollbar min-h-10"> <nav class="flex items-center gap-6 scrollbar min-h-10">
<a href="{{ route('security.private-key.index') }}"> <a href="{{ route('security.private-key.index') }}" {{ wireNavigate() }}>
<button>Private Keys</button> <button>Private Keys</button>
</a> </a>
@can('viewAny', App\Models\CloudProviderToken::class) @can('viewAny', App\Models\CloudProviderToken::class)
<a href="{{ route('security.cloud-tokens') }}"> <a href="{{ route('security.cloud-tokens') }}" {{ wireNavigate() }}>
<button>Cloud Tokens</button> <button>Cloud Tokens</button>
</a> </a>
@endcan @endcan
@can('viewAny', App\Models\CloudInitScript::class) @can('viewAny', App\Models\CloudInitScript::class)
<a href="{{ route('security.cloud-init-scripts') }}"> <a href="{{ route('security.cloud-init-scripts') }}" {{ wireNavigate() }}>
<button>Cloud-Init Scripts</button> <button>Cloud-Init Scripts</button>
</a> </a>
@endcan @endcan
<a href="{{ route('security.api-tokens') }}"> <a href="{{ route('security.api-tokens') }}" {{ wireNavigate() }}>
<button>API Tokens</button> <button>API Tokens</button>
</a> </a>
</nav> </nav>

View File

@@ -1,14 +1,14 @@
<div class="flex flex-col items-start gap-2 min-w-fit"> <div class="flex flex-col items-start gap-2 min-w-fit">
<a class="{{ request()->routeIs('server.proxy') ? 'menu-item menu-item-active' : 'menu-item' }}" <a class="{{ request()->routeIs('server.proxy') ? 'menu-item menu-item-active' : 'menu-item' }}" {{ wireNavigate() }}
href="{{ route('server.proxy', $parameters) }}"> href="{{ route('server.proxy', $parameters) }}">
<button>Configuration</button> <button>Configuration</button>
</a> </a>
@if ($server->proxySet()) @if ($server->proxySet())
<a class="{{ request()->routeIs('server.proxy.dynamic-confs') ? 'menu-item menu-item-active' : 'menu-item' }}" <a class="{{ request()->routeIs('server.proxy.dynamic-confs') ? 'menu-item menu-item-active' : 'menu-item' }}" {{ wireNavigate() }}
href="{{ route('server.proxy.dynamic-confs', $parameters) }}"> href="{{ route('server.proxy.dynamic-confs', $parameters) }}">
<button>Dynamic Configurations</button> <button>Dynamic Configurations</button>
</a> </a>
<a class="{{ request()->routeIs('server.proxy.logs') ? 'menu-item menu-item-active' : 'menu-item' }}" <a class="{{ request()->routeIs('server.proxy.logs') ? 'menu-item menu-item-active' : 'menu-item' }}" {{ wireNavigate() }}
href="{{ route('server.proxy.logs', $parameters) }}"> href="{{ route('server.proxy.logs', $parameters) }}">
<button>Logs</button> <button>Logs</button>
</a> </a>

View File

@@ -1,5 +1,5 @@
<div class="flex flex-col items-start gap-2 min-w-fit"> <div class="flex flex-col items-start gap-2 min-w-fit">
<a class="{{ request()->routeIs('server.security.patches') ? 'menu-item menu-item-active' : 'menu-item' }}" <a class="{{ request()->routeIs('server.security.patches') ? 'menu-item menu-item-active' : 'menu-item' }}" {{ wireNavigate() }}
href="{{ route('server.security.patches', $parameters) }}"> href="{{ route('server.security.patches', $parameters) }}">
Server Patching Server Patching
</a> </a>

View File

@@ -1,42 +1,42 @@
<div class="flex flex-col items-start gap-2 min-w-fit"> <div class="flex flex-col items-start gap-2 min-w-fit">
<a class="menu-item {{ $activeMenu === 'general' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'general' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.show', ['server_uuid' => $server->uuid]) }}">General</a> href="{{ route('server.show', ['server_uuid' => $server->uuid]) }}">General</a>
@if ($server->isFunctional()) @if ($server->isFunctional())
<a class="menu-item {{ $activeMenu === 'advanced' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'advanced' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.advanced', ['server_uuid' => $server->uuid]) }}">Advanced href="{{ route('server.advanced', ['server_uuid' => $server->uuid]) }}">Advanced
</a> </a>
@endif @endif
<a class="menu-item {{ $activeMenu === 'private-key' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'private-key' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.private-key', ['server_uuid' => $server->uuid]) }}">Private Key href="{{ route('server.private-key', ['server_uuid' => $server->uuid]) }}">Private Key
</a> </a>
@if ($server->hetzner_server_id) @if ($server->hetzner_server_id)
<a class="menu-item {{ $activeMenu === 'cloud-provider-token' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'cloud-provider-token' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.cloud-provider-token', ['server_uuid' => $server->uuid]) }}">Hetzner Token href="{{ route('server.cloud-provider-token', ['server_uuid' => $server->uuid]) }}">Hetzner Token
</a> </a>
@endif @endif
<a class="menu-item {{ $activeMenu === 'ca-certificate' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'ca-certificate' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.ca-certificate', ['server_uuid' => $server->uuid]) }}">CA Certificate href="{{ route('server.ca-certificate', ['server_uuid' => $server->uuid]) }}">CA Certificate
</a> </a>
@if (!$server->isLocalhost()) @if (!$server->isLocalhost())
<a class="menu-item {{ $activeMenu === 'cloudflare-tunnel' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'cloudflare-tunnel' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.cloudflare-tunnel', ['server_uuid' => $server->uuid]) }}">Cloudflare href="{{ route('server.cloudflare-tunnel', ['server_uuid' => $server->uuid]) }}">Cloudflare
Tunnel</a> Tunnel</a>
@endif @endif
@if ($server->isFunctional()) @if ($server->isFunctional())
<a class="menu-item {{ $activeMenu === 'docker-cleanup' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'docker-cleanup' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.docker-cleanup', ['server_uuid' => $server->uuid]) }}">Docker Cleanup href="{{ route('server.docker-cleanup', ['server_uuid' => $server->uuid]) }}">Docker Cleanup
</a> </a>
<a class="menu-item {{ $activeMenu === 'destinations' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'destinations' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.destinations', ['server_uuid' => $server->uuid]) }}">Destinations href="{{ route('server.destinations', ['server_uuid' => $server->uuid]) }}">Destinations
</a> </a>
<a class="menu-item {{ $activeMenu === 'log-drains' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'log-drains' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.log-drains', ['server_uuid' => $server->uuid]) }}">Log href="{{ route('server.log-drains', ['server_uuid' => $server->uuid]) }}">Log
Drains</a> Drains</a>
<a class="menu-item {{ $activeMenu === 'metrics' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'metrics' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.charts', ['server_uuid' => $server->uuid]) }}">Metrics</a> href="{{ route('server.charts', ['server_uuid' => $server->uuid]) }}">Metrics</a>
@endif @endif
@if (!$server->isLocalhost()) @if (!$server->isLocalhost())
<a class="menu-item {{ $activeMenu === 'danger' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'danger' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('server.delete', ['server_uuid' => $server->uuid]) }}">Danger</a> href="{{ route('server.delete', ['server_uuid' => $server->uuid]) }}">Danger</a>
@endif @endif
</div> </div>

View File

@@ -3,19 +3,19 @@
<div class="subtitle">Instance wide settings for Coolify.</div> <div class="subtitle">Instance wide settings for Coolify.</div>
<div class="navbar-main"> <div class="navbar-main">
<nav class="flex items-center gap-6 min-h-10 whitespace-nowrap"> <nav class="flex items-center gap-6 min-h-10 whitespace-nowrap">
<a class="{{ request()->routeIs('settings.index') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('settings.index') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('settings.index') }}"> href="{{ route('settings.index') }}">
Configuration Configuration
</a> </a>
<a class="{{ request()->routeIs('settings.backup') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('settings.backup') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('settings.backup') }}"> href="{{ route('settings.backup') }}">
Backup Backup
</a> </a>
<a class="{{ request()->routeIs('settings.email') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('settings.email') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('settings.email') }}"> href="{{ route('settings.email') }}">
Transactional Email Transactional Email
</a> </a>
<a class="{{ request()->routeIs('settings.oauth') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('settings.oauth') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('settings.oauth') }}"> href="{{ route('settings.oauth') }}">
OAuth OAuth
</a> </a>

View File

@@ -1,8 +1,8 @@
<div class="flex flex-col items-start gap-2 min-w-fit"> <div class="flex flex-col items-start gap-2 min-w-fit">
<a class="menu-item {{ $activeMenu === 'general' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'general' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('settings.index') }}">General</a> href="{{ route('settings.index') }}">General</a>
<a class="menu-item {{ $activeMenu === 'advanced' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'advanced' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('settings.advanced') }}">Advanced</a> href="{{ route('settings.advanced') }}">Advanced</a>
<a class="menu-item {{ $activeMenu === 'updates' ? 'menu-item-active' : '' }}" <a class="menu-item {{ $activeMenu === 'updates' ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('settings.updates') }}">Updates</a> href="{{ route('settings.updates') }}">Updates</a>
</div> </div>

View File

@@ -8,15 +8,16 @@
<div class="subtitle">Team wide configurations.</div> <div class="subtitle">Team wide configurations.</div>
<div class="navbar-main"> <div class="navbar-main">
<nav class="flex items-center gap-6 min-h-10"> <nav class="flex items-center gap-6 min-h-10">
<a class="{{ request()->routeIs('team.index') ? 'dark:text-white' : '' }}" href="{{ route('team.index') }}"> <a class="{{ request()->routeIs('team.index') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('team.index') }}">
General General
</a> </a>
<a class="{{ request()->routeIs('team.member.index') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('team.member.index') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('team.member.index') }}"> href="{{ route('team.member.index') }}">
Members Members
</a> </a>
@if (isInstanceAdmin()) @if (isInstanceAdmin())
<a class="{{ request()->routeIs('team.admin-view') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('team.admin-view') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('team.admin-view') }}"> href="{{ route('team.admin-view') }}">
Admin View Admin View
</a> </a>

View File

@@ -12,10 +12,10 @@
</p> </p>
@endif @endif
<div class="flex items-center mt-10 gap-x-2"> <div class="flex items-center mt-10 gap-x-2">
<a href="{{ url()->previous() }}"> <a href="{{ url()->previous() }}" {{ wireNavigate() }}>
<x-forms.button>Go back</x-forms.button> <x-forms.button>Go back</x-forms.button>
</a> </a>
<a href="{{ route('dashboard') }}"> <a href="{{ route('dashboard') }}" {{ wireNavigate() }}>
<x-forms.button>Dashboard</x-forms.button> <x-forms.button>Dashboard</x-forms.button>
</a> </a>
<a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact <a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact

View File

@@ -6,10 +6,10 @@
<p class="text-base leading-7 dark:text-neutral-400 text-black">You don't have permission to access this page. <p class="text-base leading-7 dark:text-neutral-400 text-black">You don't have permission to access this page.
</p> </p>
<div class="flex items-center mt-10 gap-x-2"> <div class="flex items-center mt-10 gap-x-2">
<a href="{{ url()->previous() }}"> <a href="{{ url()->previous() }}" {{ wireNavigate() }}>
<x-forms.button>Go back</x-forms.button> <x-forms.button>Go back</x-forms.button>
</a> </a>
<a href="{{ route('dashboard') }}"> <a href="{{ route('dashboard') }}" {{ wireNavigate() }}>
<x-forms.button>Dashboard</x-forms.button> <x-forms.button>Dashboard</x-forms.button>
</a> </a>
<a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact <a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact

View File

@@ -5,10 +5,10 @@
<p class="font-mono font-semibold text-7xl dark:text-warning">402</p> <p class="font-mono font-semibold text-7xl dark:text-warning">402</p>
<h1 class="mt-4 font-bold tracking-tight dark:text-white">Payment required.</h1> <h1 class="mt-4 font-bold tracking-tight dark:text-white">Payment required.</h1>
<div class="flex items-center mt-10 gap-x-2"> <div class="flex items-center mt-10 gap-x-2">
<a href="{{ url()->previous() }}"> <a href="{{ url()->previous() }}" {{ wireNavigate() }}>
<x-forms.button>Go back</x-forms.button> <x-forms.button>Go back</x-forms.button>
</a> </a>
<a href="{{ route('dashboard') }}"> <a href="{{ route('dashboard') }}" {{ wireNavigate() }}>
<x-forms.button>Dashboard</x-forms.button> <x-forms.button>Dashboard</x-forms.button>
</a> </a>
<a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact <a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact

View File

@@ -6,10 +6,10 @@
<p class="text-base leading-7 dark:text-neutral-400 text-black">You don't have permission to access this page. <p class="text-base leading-7 dark:text-neutral-400 text-black">You don't have permission to access this page.
</p> </p>
<div class="flex items-center mt-10 gap-x-2"> <div class="flex items-center mt-10 gap-x-2">
<a href="{{ url()->previous() }}"> <a href="{{ url()->previous() }}" {{ wireNavigate() }}>
<x-forms.button>Go back</x-forms.button> <x-forms.button>Go back</x-forms.button>
</a> </a>
<a href="{{ route('dashboard') }}"> <a href="{{ route('dashboard') }}" {{ wireNavigate() }}>
<x-forms.button>Dashboard</x-forms.button> <x-forms.button>Dashboard</x-forms.button>
</a> </a>
<a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact <a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact

View File

@@ -3,14 +3,14 @@
<div> <div>
<p class="font-mono font-semibold text-7xl dark:text-warning">404</p> <p class="font-mono font-semibold text-7xl dark:text-warning">404</p>
<h1 class="mt-4 font-bold tracking-tight dark:text-white">How did you get here?</h1> <h1 class="mt-4 font-bold tracking-tight dark:text-white">How did you get here?</h1>
<p class="text-base leading-7 dark:text-neutral-400 text-black">Sorry, we couldnt find the page youre looking <p class="text-base leading-7 dark:text-neutral-400 text-black">Sorry, we couldn't find the page you're looking
for. for.
</p> </p>
<div class="flex items-center mt-10 gap-x-2"> <div class="flex items-center mt-10 gap-x-2">
<a href="{{ url()->previous() }}"> <a href="{{ url()->previous() }}" {{ wireNavigate() }}>
<x-forms.button>Go back</x-forms.button> <x-forms.button>Go back</x-forms.button>
</a> </a>
<a href="{{ route('dashboard') }}"> <a href="{{ route('dashboard') }}" {{ wireNavigate() }}>
<x-forms.button>Dashboard</x-forms.button> <x-forms.button>Dashboard</x-forms.button>
</a> </a>
<a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact <a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact

View File

@@ -3,14 +3,14 @@
<div> <div>
<p class="font-mono font-semibold text-7xl dark:text-warning">419</p> <p class="font-mono font-semibold text-7xl dark:text-warning">419</p>
<h1 class="mt-4 font-bold tracking-tight dark:text-white">This page is definitely old, not like you!</h1> <h1 class="mt-4 font-bold tracking-tight dark:text-white">This page is definitely old, not like you!</h1>
<p class="text-base leading-7 dark:text-neutral-300 text-black">Sorry, we couldnt find the page youre looking <p class="text-base leading-7 dark:text-neutral-300 text-black">Sorry, we couldn't find the page you're looking
for. for.
</p> </p>
<div class="flex items-center mt-10 gap-x-2"> <div class="flex items-center mt-10 gap-x-2">
<a href="{{ url()->previous() }}"> <a href="{{ url()->previous() }}" {{ wireNavigate() }}>
<x-forms.button>Go back</x-forms.button> <x-forms.button>Go back</x-forms.button>
</a> </a>
<a href="{{ route('dashboard') }}"> <a href="{{ route('dashboard') }}" {{ wireNavigate() }}>
<x-forms.button>Dashboard</x-forms.button> <x-forms.button>Dashboard</x-forms.button>
</a> </a>
<a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact <a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact

View File

@@ -8,10 +8,10 @@
seconds before trying again. seconds before trying again.
</p> </p>
<div class="flex items-center mt-10 gap-x-2"> <div class="flex items-center mt-10 gap-x-2">
<a href="{{ url()->previous() }}"> <a href="{{ url()->previous() }}" {{ wireNavigate() }}>
<x-forms.button>Go back</x-forms.button> <x-forms.button>Go back</x-forms.button>
</a> </a>
<a href="{{ route('dashboard') }}"> <a href="{{ route('dashboard') }}" {{ wireNavigate() }}>
<x-forms.button>Dashboard</x-forms.button> <x-forms.button>Dashboard</x-forms.button>
</a> </a>
<a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact <a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact

View File

@@ -11,10 +11,10 @@
</div> </div>
@endif @endif
<div class="flex items-center mt-10 gap-x-2"> <div class="flex items-center mt-10 gap-x-2">
<a href="{{ url()->previous() }}"> <a href="{{ url()->previous() }}" {{ wireNavigate() }}>
<x-forms.button>Go back</x-forms.button> <x-forms.button>Go back</x-forms.button>
</a> </a>
<a href="{{ route('dashboard') }}"> <a href="{{ route('dashboard') }}" {{ wireNavigate() }}>
<x-forms.button>Dashboard</x-forms.button> <x-forms.button>Dashboard</x-forms.button>
</a> </a>
<a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact <a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact

View File

@@ -8,10 +8,10 @@
patience. patience.
</p> </p>
<div class="flex items-center mt-10 gap-x-2"> <div class="flex items-center mt-10 gap-x-2">
<a href="{{ url()->previous() }}"> <a href="{{ url()->previous() }}" {{ wireNavigate() }}>
<x-forms.button>Go back</x-forms.button> <x-forms.button>Go back</x-forms.button>
</a> </a>
<a href="{{ route('dashboard') }}"> <a href="{{ route('dashboard') }}" {{ wireNavigate() }}>
<x-forms.button>Dashboard</x-forms.button> <x-forms.button>Dashboard</x-forms.button>
</a> </a>
<a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact <a target="_blank" class="text-xs" href="{{ config('constants.urls.contact') }}">Contact

View File

@@ -36,7 +36,7 @@
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2"> <div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
@foreach ($projects as $project) @foreach ($projects as $project)
<div class="relative gap-2 cursor-pointer coolbox group"> <div class="relative gap-2 cursor-pointer coolbox group">
<a href="{{ $project->navigateTo() }}" class="absolute inset-0"></a> <a href="{{ $project->navigateTo() }}" {{ wireNavigate() }} class="absolute inset-0"></a>
<div class="flex flex-1 mx-6"> <div class="flex flex-1 mx-6">
<div class="flex flex-col justify-center flex-1"> <div class="flex flex-col justify-center flex-1">
<div class="box-title">{{ $project->name }}</div> <div class="box-title">{{ $project->name }}</div>
@@ -47,7 +47,7 @@
<div class="relative z-10 flex items-center justify-center gap-4 text-xs font-bold"> <div class="relative z-10 flex items-center justify-center gap-4 text-xs font-bold">
@if ($project->environments->first()) @if ($project->environments->first())
@can('createAnyResource') @can('createAnyResource')
<a class="hover:underline" <a class="hover:underline" {{ wireNavigate() }}
href="{{ route('project.resource.create', [ href="{{ route('project.resource.create', [
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
'environment_uuid' => $project->environments->first()->uuid, 'environment_uuid' => $project->environments->first()->uuid,
@@ -57,7 +57,7 @@
@endcan @endcan
@endif @endif
@can('update', $project) @can('update', $project)
<a class="hover:underline" <a class="hover:underline" {{ wireNavigate() }}
href="{{ route('project.edit', ['project_uuid' => $project->uuid]) }}"> href="{{ route('project.edit', ['project_uuid' => $project->uuid]) }}">
Settings Settings
</a> </a>
@@ -74,7 +74,7 @@
<x-modal-input buttonTitle="Add" title="New Project"> <x-modal-input buttonTitle="Add" title="New Project">
<livewire:project.add-empty /> <livewire:project.add-empty />
</x-modal-input> your first project or </x-modal-input> your first project or
go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding</a> page. go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}" {{ wireNavigate() }}>onboarding</a> page.
</div> </div>
</div> </div>
@endif @endif
@@ -101,7 +101,7 @@
@if ($servers->count() > 0) @if ($servers->count() > 0)
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2"> <div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
@foreach ($servers as $server) @foreach ($servers as $server)
<a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}" <a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}" {{ wireNavigate() }}
@class([ @class([
'gap-2 border cursor-pointer coolbox group', 'gap-2 border cursor-pointer coolbox group',
'border-red-500' => 'border-red-500' =>
@@ -138,7 +138,7 @@
<livewire:security.private-key.create from="server" /> <livewire:security.private-key.create from="server" />
</x-modal-input> a private key </x-modal-input> a private key
or or
go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding</a> go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}" {{ wireNavigate() }}>onboarding</a>
page. page.
</div> </div>
</div> </div>
@@ -150,7 +150,7 @@
<livewire:server.create /> <livewire:server.create />
</x-modal-input> your first server </x-modal-input> your first server
or or
go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding</a> go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}" {{ wireNavigate() }}>onboarding</a>
page. page.
</div> </div>
</div> </div>

View File

@@ -39,7 +39,7 @@
<div class="p-4 space-y-3"> <div class="p-4 space-y-3">
@foreach ($this->deployments as $deployment) @foreach ($this->deployments as $deployment)
<a href="{{ $deployment->deployment_url }}" <a href="{{ $deployment->deployment_url }}" {{ wireNavigate() }}
class="flex items-start gap-3 p-3 rounded-lg dark:bg-coolgray-200 bg-gray-50 transition-all duration-200 hover:ring-2 hover:ring-coollabs dark:hover:ring-warning cursor-pointer"> class="flex items-start gap-3 p-3 rounded-lg dark:bg-coolgray-200 bg-gray-50 transition-all duration-200 hover:ring-2 hover:ring-coollabs dark:hover:ring-warning cursor-pointer">
<!-- Status indicator --> <!-- Status indicator -->
<div class="flex-shrink-0 mt-1"> <div class="flex-shrink-0 mt-1">

View File

@@ -17,7 +17,7 @@
@forelse ($servers as $server) @forelse ($servers as $server)
@forelse ($server->destinations() as $destination) @forelse ($server->destinations() as $destination)
@if ($destination->getMorphClass() === 'App\Models\StandaloneDocker') @if ($destination->getMorphClass() === 'App\Models\StandaloneDocker')
<a class="coolbox group" <a class="coolbox group" {{ wireNavigate() }}
href="{{ route('destination.show', ['destination_uuid' => data_get($destination, 'uuid')]) }}"> href="{{ route('destination.show', ['destination_uuid' => data_get($destination, 'uuid')]) }}">
<div class="flex flex-col justify-center mx-6"> <div class="flex flex-col justify-center mx-6">
<div class="box-title">{{ $destination->name }}</div> <div class="box-title">{{ $destination->name }}</div>
@@ -26,7 +26,7 @@
</a> </a>
@endif @endif
@if ($destination->getMorphClass() === 'App\Models\SwarmDocker') @if ($destination->getMorphClass() === 'App\Models\SwarmDocker')
<a class="coolbox group" <a class="coolbox group" {{ wireNavigate() }}
href="{{ route('destination.show', ['destination_uuid' => data_get($destination, 'uuid')]) }}"> href="{{ route('destination.show', ['destination_uuid' => data_get($destination, 'uuid')]) }}">
<div class="flex flex-col mx-6"> <div class="flex flex-col mx-6">
<div class="box-title">{{ $destination->name }}</div> <div class="box-title">{{ $destination->name }}</div>

View File

@@ -70,6 +70,11 @@
}, },
openModal() { openModal() {
// Check if $wire is available (may not be after SPA navigation destroys/recreates component)
if (typeof $wire === 'undefined' || !$wire) {
console.warn('Global search: $wire not available, skipping open');
return;
}
this.modalOpen = true; this.modalOpen = true;
this.selectedIndex = -1; this.selectedIndex = -1;
this.isLoadingInitialData = true; this.isLoadingInitialData = true;
@@ -79,6 +84,10 @@
this.creatableItems = $wire.creatableItems || []; this.creatableItems = $wire.creatableItems || [];
this.isLoadingInitialData = false; this.isLoadingInitialData = false;
setTimeout(() => this.$refs.searchInput?.focus(), 50); setTimeout(() => this.$refs.searchInput?.focus(), 50);
}).catch(() => {
// Handle case where component was destroyed during navigation
this.modalOpen = false;
this.isLoadingInitialData = false;
}); });
}, },
closeModal() { closeModal() {
@@ -90,7 +99,10 @@
this.allSearchableItems = []; this.allSearchableItems = [];
// Ensure scroll is restored // Ensure scroll is restored
document.body.style.overflow = ''; document.body.style.overflow = '';
@this.closeSearchModal(); // Use $wire instead of @this for SPA navigation compatibility
if ($wire) {
$wire.closeSearchModal();
}
}, },
navigateResults(direction) { navigateResults(direction) {
const results = document.querySelectorAll('.search-result-item'); const results = document.querySelectorAll('.search-result-item');
@@ -120,7 +132,7 @@
const trimmed = value.trim().toLowerCase(); const trimmed = value.trim().toLowerCase();
if (trimmed === '') { if (trimmed === '') {
if ($wire.isSelectingResource) { if (typeof $wire !== 'undefined' && $wire && $wire.isSelectingResource) {
$wire.cancelResourceSelection(); $wire.cancelResourceSelection();
} }
return; return;
@@ -149,7 +161,7 @@
(item.quickcommand && item.quickcommand.toLowerCase().includes(trimmed)); (item.quickcommand && item.quickcommand.toLowerCase().includes(trimmed));
}); });
if (matchingItem) { if (matchingItem && typeof $wire !== 'undefined' && $wire) {
$wire.navigateToResource(matchingItem.type); $wire.navigateToResource(matchingItem.type);
} }
} }
@@ -186,7 +198,7 @@
// If search query is empty, close the modal // If search query is empty, close the modal
if (!this.searchQuery || this.searchQuery === '') { if (!this.searchQuery || this.searchQuery === '') {
// Check if we're in a selection state using Alpine-accessible Livewire state // Check if we're in a selection state using Alpine-accessible Livewire state
if ($wire.isSelectingResource) { if (typeof $wire !== 'undefined' && $wire && $wire.isSelectingResource) {
$wire.cancelResourceSelection(); $wire.cancelResourceSelection();
setTimeout(() => this.$refs.searchInput?.focus(), 100); setTimeout(() => this.$refs.searchInput?.focus(), 100);
} else { } else {
@@ -227,19 +239,23 @@
document.removeEventListener('keydown', arrowKeyHandler); document.removeEventListener('keydown', arrowKeyHandler);
}); });
// Watch for auto-open resource // Watch for auto-open resource (only if $wire is available)
this.$watch('$wire.autoOpenResource', value => { if (typeof $wire !== 'undefined' && $wire) {
if (value) { this.$watch('$wire.autoOpenResource', value => {
// Close search modal first if (value) {
this.closeModal(); // Close search modal first
// Open the specific resource modal after a short delay this.closeModal();
setTimeout(() => { // Open the specific resource modal after a short delay
this.$dispatch('open-create-modal-' + value); setTimeout(() => {
// Reset the value so it can trigger again this.$dispatch('open-create-modal-' + value);
@this.set('autoOpenResource', null); // Reset the value so it can trigger again
}, 150); if (typeof $wire !== 'undefined' && $wire) {
} $wire.set('autoOpenResource', null);
}); }
}, 150);
}
});
}
// Listen for closeSearchModal event from backend // Listen for closeSearchModal event from backend
window.addEventListener('closeSearchModal', () => { window.addEventListener('closeSearchModal', () => {

View File

@@ -137,7 +137,7 @@
<div><span class="font-bold text-red-500">WARNING:</span> Your subscription is in over-due. If your <div><span class="font-bold text-red-500">WARNING:</span> Your subscription is in over-due. If your
latest latest
payment is not paid within a week, all automations <span class="font-bold text-red-500">will payment is not paid within a week, all automations <span class="font-bold text-red-500">will
be deactivated</span>. Visit <a href="{{ route('subscription.show') }}" be deactivated</span>. Visit <a href="{{ route('subscription.show') }}" {{ wireNavigate() }}
class="underline dark:text-white">/subscription</a> to check your subscription status or pay class="underline dark:text-white">/subscription</a> to check your subscription status or pay
your your
invoice (or check your email for the invoice). invoice (or check your email for the invoice).
@@ -148,7 +148,7 @@
<x-banner :closable=false> <x-banner :closable=false>
<div><span class="font-bold text-red-500">WARNING:</span> The number of active servers exceeds the limit <div><span class="font-bold text-red-500">WARNING:</span> The number of active servers exceeds the limit
covered by your payment. If not resolved, some of your servers <span class="font-bold text-red-500">will covered by your payment. If not resolved, some of your servers <span class="font-bold text-red-500">will
be deactivated</span>. Visit <a href="{{ route('subscription.show') }}" be deactivated</span>. Visit <a href="{{ route('subscription.show') }}" {{ wireNavigate() }}
class="underline dark:text-white">/subscription</a> to update your subscription or remove some class="underline dark:text-white">/subscription</a> to update your subscription or remove some
servers. servers.
</div> </div>
@@ -172,7 +172,7 @@
highly recommended to enable at least highly recommended to enable at least
one one
notification channel to receive important alerts.<br>Visit <a notification channel to receive important alerts.<br>Visit <a
href="{{ route('notifications.email') }}" class="underline dark:text-white">/notification</a> to href="{{ route('notifications.email') }}" {{ wireNavigate() }} class="underline dark:text-white">/notification</a> to
enable notifications.</span> enable notifications.</span>
</x-slot:description> </x-slot:description>
<x-slot:button-text @click="disableNotification()"> <x-slot:button-text @click="disableNotification()">

View File

@@ -8,27 +8,27 @@
<div class="flex flex-col h-full gap-8 sm:flex-row"> <div class="flex flex-col h-full gap-8 sm:flex-row">
<div class="flex flex-col items-start gap-2 min-w-fit"> <div class="flex flex-col items-start gap-2 min-w-fit">
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">General</a> href="{{ route('project.application.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">General</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.advanced', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Advanced</a> href="{{ route('project.application.advanced', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Advanced</a>
@if ($application->destination->server->isSwarm()) @if ($application->destination->server->isSwarm())
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.swarm', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Swarm href="{{ route('project.application.swarm', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Swarm
Configuration</a> Configuration</a>
@endif @endif
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Environment href="{{ route('project.application.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Environment
Variables</a> Variables</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Persistent href="{{ route('project.application.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Persistent
Storage</a> Storage</a>
@if ($application->git_based()) @if ($application->git_based())
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.source', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Git href="{{ route('project.application.source', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Git
Source</a> Source</a>
@endif @endif
<a class="menu-item flex items-center gap-2" wire:current.exact="menu-item-active" <a class="menu-item flex items-center gap-2" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Servers href="{{ route('project.application.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Servers
@if ($application->server_status == false) @if ($application->server_status == false)
<span title="One or more servers are unreachable or misconfigured."> <span title="One or more servers are unreachable or misconfigured.">
@@ -46,33 +46,33 @@
</span> </span>
@endif @endif
</a> </a>
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Scheduled href="{{ route('project.application.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Scheduled
Tasks</a> Tasks</a>
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Webhooks</a> href="{{ route('project.application.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Webhooks</a>
@if ($application->deploymentType() !== 'deploy_key') @if ($application->deploymentType() !== 'deploy_key')
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.preview-deployments', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Preview href="{{ route('project.application.preview-deployments', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Preview
Deployments</a> Deployments</a>
@endif @endif
@if ($application->build_pack !== 'dockercompose') @if ($application->build_pack !== 'dockercompose')
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.healthcheck', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Healthcheck</a> href="{{ route('project.application.healthcheck', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Healthcheck</a>
@endif @endif
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.rollback', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Rollback</a> href="{{ route('project.application.rollback', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Rollback</a>
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Resource href="{{ route('project.application.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Resource
Limits</a> Limits</a>
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Resource href="{{ route('project.application.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Resource
Operations</a> Operations</a>
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Metrics</a> href="{{ route('project.application.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Metrics</a>
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Tags</a> href="{{ route('project.application.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Tags</a>
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.application.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Danger href="{{ route('project.application.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Danger
Zone</a> Zone</a>
</div> </div>

View File

@@ -45,7 +45,7 @@
'border-error' => data_get($deployment, 'status') === 'failed', 'border-error' => data_get($deployment, 'status') === 'failed',
'border-success' => data_get($deployment, 'status') === 'finished', 'border-success' => data_get($deployment, 'status') === 'finished',
])> ])>
<a href="{{ $current_url . '/' . data_get($deployment, 'deployment_uuid') }}" class="block"> <a href="{{ $current_url . '/' . data_get($deployment, 'deployment_uuid') }}" {{ wireNavigate() }} class="block">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="flex items-center gap-2 mb-2"> <div class="flex items-center gap-2 mb-2">
<span @class([ <span @class([

View File

@@ -236,11 +236,7 @@
@endif @endif
<div class="flex flex-col gap-2 pt-6 pb-10"> <div class="flex flex-col gap-2 pt-6 pb-10">
@if ($application->build_pack === 'dockercompose') @if ($application->build_pack === 'dockercompose')
@can('update', $application) <div class="flex flex-col gap-2" @can('update', $application) x-init="$wire.dispatch('loadCompose', true)" @endcan>
<div class="flex flex-col gap-2" x-init="$wire.dispatch('loadCompose', true)">
@else
<div class="flex flex-col gap-2">
@endcan
<div x-data="{ <div x-data="{
baseDir: '{{ $application->base_directory }}', baseDir: '{{ $application->base_directory }}',
composeLocation: '{{ $application->docker_compose_location }}', composeLocation: '{{ $application->docker_compose_location }}',

View File

@@ -2,15 +2,15 @@
<x-resources.breadcrumbs :resource="$application" :parameters="$parameters" :title="$lastDeploymentInfo" :lastDeploymentLink="$lastDeploymentLink" /> <x-resources.breadcrumbs :resource="$application" :parameters="$parameters" :title="$lastDeploymentInfo" :lastDeploymentLink="$lastDeploymentLink" />
<div class="navbar-main"> <div class="navbar-main">
<nav class="flex shrink-0 gap-6 items-center whitespace-nowrap scrollbar min-h-10"> <nav class="flex shrink-0 gap-6 items-center whitespace-nowrap scrollbar min-h-10">
<a class="{{ request()->routeIs('project.application.configuration') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('project.application.configuration') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('project.application.configuration', $parameters) }}"> href="{{ route('project.application.configuration', $parameters) }}">
Configuration Configuration
</a> </a>
<a class="{{ request()->routeIs('project.application.deployment.index') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('project.application.deployment.index') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('project.application.deployment.index', $parameters) }}"> href="{{ route('project.application.deployment.index', $parameters) }}">
Deployments Deployments
</a> </a>
<a class="{{ request()->routeIs('project.application.logs') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('project.application.logs') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('project.application.logs', $parameters) }}"> href="{{ route('project.application.logs', $parameters) }}">
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
Logs Logs

View File

@@ -94,12 +94,12 @@
</a> </a>
@if (count($parameters) > 0) @if (count($parameters) > 0)
| |
<a <a {{ wireNavigate() }}
href="{{ route('project.application.deployment.index', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}"> href="{{ route('project.application.deployment.index', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}">
Deployment Logs Deployment Logs
</a> </a>
| |
<a <a {{ wireNavigate() }}
href="{{ route('project.application.logs', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}"> href="{{ route('project.application.logs', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}">
Application Logs Application Logs
</a> </a>

View File

@@ -7,34 +7,34 @@
<livewire:project.database.heading :database="$database" /> <livewire:project.database.heading :database="$database" />
<div class="flex flex-col h-full gap-8 sm:flex-row"> <div class="flex flex-col h-full gap-8 sm:flex-row">
<div class="flex flex-col items-start gap-2 min-w-fit"> <div class="flex flex-col items-start gap-2 min-w-fit">
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">General</a> href="{{ route('project.database.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">General</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Environment href="{{ route('project.database.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Environment
Variables</a> Variables</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Servers</a> href="{{ route('project.database.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Servers</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Persistent href="{{ route('project.database.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Persistent
Storage</a> Storage</a>
@can('update', $database) @can('update', $database)
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.import-backups', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Import href="{{ route('project.database.import-backups', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Import
Backups</a> Backups</a>
@endcan @endcan
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Webhooks</a> href="{{ route('project.database.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Webhooks</a>
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Resource href="{{ route('project.database.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Resource
Limits</a> Limits</a>
<a class="menu-item" wire:current.exact="menu-item-active" <a class="menu-item" {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Resource href="{{ route('project.database.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Resource
Operations</a> Operations</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Metrics</a> href="{{ route('project.database.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Metrics</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Tags</a> href="{{ route('project.database.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Tags</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' {{ wireNavigate() }} wire:current.exact="menu-item-active"
href="{{ route('project.database.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Danger href="{{ route('project.database.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Danger
Zone</a> Zone</a>
</div> </div>

View File

@@ -11,12 +11,12 @@
<div class="navbar-main"> <div class="navbar-main">
<nav <nav
class="flex overflow-x-scroll shrink-0 gap-6 items-center whitespace-nowrap sm:overflow-x-hidden scrollbar min-h-10"> class="flex overflow-x-scroll shrink-0 gap-6 items-center whitespace-nowrap sm:overflow-x-hidden scrollbar min-h-10">
<a class="{{ request()->routeIs('project.database.configuration') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('project.database.configuration') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('project.database.configuration', $parameters) }}"> href="{{ route('project.database.configuration', $parameters) }}">
Configuration Configuration
</a> </a>
<a class="{{ request()->routeIs('project.database.logs') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('project.database.logs') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('project.database.logs', $parameters) }}"> href="{{ route('project.database.logs', $parameters) }}">
Logs Logs
</a> </a>
@@ -31,7 +31,7 @@
$database->getMorphClass() === 'App\Models\StandaloneMongodb' || $database->getMorphClass() === 'App\Models\StandaloneMongodb' ||
$database->getMorphClass() === 'App\Models\StandaloneMysql' || $database->getMorphClass() === 'App\Models\StandaloneMysql' ||
$database->getMorphClass() === 'App\Models\StandaloneMariadb') $database->getMorphClass() === 'App\Models\StandaloneMariadb')
<a class="{{ request()->routeIs('project.database.backup.index') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('project.database.backup.index') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('project.database.backup.index', $parameters) }}"> href="{{ route('project.database.backup.index', $parameters) }}">
Backups Backups
</a> </a>

View File

@@ -28,7 +28,7 @@
</div> </div>
@endif @endif
<x-forms.input <x-forms.input
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>" helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' {{ wireNavigate() }} href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>"
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k" placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k"
id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" /> id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" />
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">

View File

@@ -49,7 +49,7 @@
@endif @endif
<div class="pt-2"> <div class="pt-2">
<x-forms.input <x-forms.input
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>" helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' {{ wireNavigate() }} href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>"
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k" placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k"
id="customDockerRunOptions" label="Custom Docker Options" canGate="update" id="customDockerRunOptions" label="Custom Docker Options" canGate="update"
:canResource="$database" /> :canResource="$database" />

View File

@@ -40,7 +40,7 @@
</div> </div>
@endif @endif
<x-forms.input <x-forms.input
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>" helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' {{ wireNavigate() }} href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>"
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k" placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k"
id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" /> id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" />
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">

View File

@@ -46,7 +46,7 @@
@endif @endif
<div class="pt-2"> <div class="pt-2">
<x-forms.input <x-forms.input
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>" helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' {{ wireNavigate() }} href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>"
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k" placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k"
id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" /> id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" />
</div> </div>

View File

@@ -58,7 +58,7 @@
placeholder="If empty, use default. See in docker docs." /> placeholder="If empty, use default. See in docker docs." />
</div> </div>
<x-forms.input <x-forms.input
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>" helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' {{ wireNavigate() }} href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>"
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k" placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k"
id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" /> id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" />
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">

View File

@@ -50,7 +50,7 @@
@endif @endif
</div> </div>
<x-forms.input <x-forms.input
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>" helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' {{ wireNavigate() }} href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>"
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k" placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k"
id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" /> id="customDockerRunOptions" label="Custom Docker Options" canGate="update" :canResource="$database" />
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">

View File

@@ -32,7 +32,7 @@
$backup->latest_log && $backup->latest_log &&
data_get($backup->latest_log, 'status') === 'success', data_get($backup->latest_log, 'status') === 'success',
'border-gray-200 dark:border-coolgray-300' => !$backup->latest_log, 'border-gray-200 dark:border-coolgray-300' => !$backup->latest_log,
]) ]) {{ wireNavigate() }}
href="{{ route('project.database.backup.execution', [...$parameters, 'backup_uuid' => $backup->uuid]) }}"> href="{{ route('project.database.backup.execution', [...$parameters, 'backup_uuid' => $backup->uuid]) }}">
@if ($backup->latest_log && data_get($backup->latest_log, 'status') === 'running') @if ($backup->latest_log && data_get($backup->latest_log, 'status') === 'running')
<div class="absolute top-2 right-2"> <div class="absolute top-2 right-2">

View File

@@ -14,14 +14,14 @@
<ol class="flex flex-wrap items-center gap-y-1"> <ol class="flex flex-wrap items-center gap-y-1">
<li class="inline-flex items-center"> <li class="inline-flex items-center">
<div class="flex items-center"> <div class="flex items-center">
<a class="text-xs truncate lg:text-sm" <a class="text-xs truncate lg:text-sm" {{ wireNavigate() }}
href="{{ route('project.show', ['project_uuid' => $project->uuid]) }}"> href="{{ route('project.show', ['project_uuid' => $project->uuid]) }}">
{{ $project->name }}</a> {{ $project->name }}</a>
</div> </div>
</li> </li>
<li> <li>
<div class="flex items-center"> <div class="flex items-center">
<a class="text-xs truncate lg:text-sm" <a class="text-xs truncate lg:text-sm" {{ wireNavigate() }}
href="{{ route('project.resource.index', ['environment_uuid' => $environment->uuid, 'project_uuid' => $project->uuid]) }}"> href="{{ route('project.resource.index', ['environment_uuid' => $environment->uuid, 'project_uuid' => $project->uuid]) }}">
{{ $environment->name }} {{ $environment->name }}
</a> </a>

View File

@@ -25,7 +25,7 @@
<div class="relative z-10 flex items-center justify-center gap-4 text-xs font-bold"> <div class="relative z-10 flex items-center justify-center gap-4 text-xs font-bold">
@if ($project->environments->first()) @if ($project->environments->first())
@can('createAnyResource') @can('createAnyResource')
<a class="hover:underline" <a class="hover:underline" {{ wireNavigate() }}
href="{{ route('project.resource.create', [ href="{{ route('project.resource.create', [
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
'environment_uuid' => $project->environments->first()->uuid, 'environment_uuid' => $project->environments->first()->uuid,
@@ -35,7 +35,7 @@
@endcan @endcan
@endif @endif
@can('update', $project) @can('update', $project)
<a class="hover:underline" <a class="hover:underline" {{ wireNavigate() }}
href="{{ route('project.edit', ['project_uuid' => $project->uuid]) }}"> href="{{ route('project.edit', ['project_uuid' => $project->uuid]) }}">
Settings Settings
</a> </a>

View File

@@ -38,7 +38,7 @@
<div> <div>
No private keys found. No private keys found.
</div> </div>
<a href="{{ route('security.private-key.index') }}"> <a href="{{ route('security.private-key.index') }}" {{ wireNavigate() }}>
<x-forms.button>Create a new private key</x-forms.button> <x-forms.button>Create a new private key</x-forms.button>
</a> </a>
</div> </div>

View File

@@ -13,7 +13,7 @@
</x-forms.button> </x-forms.button>
</div> </div>
<div> <div>
For example application deployments, checkout <a class="underline dark:text-white" For example application deployments, checkout <a class="underline dark:text-white" {{ wireNavigate() }}
href="https://github.com/coollabsio/coolify-examples/" target="_blank">Coolify href="https://github.com/coollabsio/coolify-examples/" target="_blank">Coolify
Examples</a>. Examples</a>.
</div> </div>

View File

@@ -385,7 +385,7 @@
<div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap"> <div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap">
@if ($onlyBuildServerAvailable) @if ($onlyBuildServerAvailable)
<div> Only build servers are available, you need at least one server that is not set as build <div> Only build servers are available, you need at least one server that is not set as build
server. <a class="underline dark:text-white" href="/servers"> server. <a class="underline dark:text-white" href="/servers" {{ wireNavigate() }}>
Go to servers page Go to servers page
</a> </div> </a> </div>
@else @else
@@ -404,7 +404,7 @@
<div> <div>
<div>No validated & reachable servers found. <a class="underline dark:text-white" <div>No validated & reachable servers found. <a class="underline dark:text-white"
href="/servers"> href="/servers" {{ wireNavigate() }}>
Go to servers page Go to servers page
</a></div> </a></div>
</div> </div>

View File

@@ -7,19 +7,19 @@
<h1>Resources</h1> <h1>Resources</h1>
@if ($environment->isEmpty()) @if ($environment->isEmpty())
@can('createAnyResource') @can('createAnyResource')
<a class="button" <a class="button" {{ wireNavigate() }}
href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}"> href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}">
Clone Clone
</a> </a>
@endcan @endcan
@else @else
@can('createAnyResource') @can('createAnyResource')
<a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}" <a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}" {{ wireNavigate() }}
class="button">+ class="button">+
New</a> New</a>
@endcan @endcan
@can('createAnyResource') @can('createAnyResource')
<a class="button" <a class="button" {{ wireNavigate() }}
href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}"> href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}">
Clone Clone
</a> </a>
@@ -36,7 +36,7 @@
<ol class="flex items-center"> <ol class="flex items-center">
<li class="inline-flex items-center" x-data="{ projectOpen: false, toggle() { this.projectOpen = !this.projectOpen }, open() { this.projectOpen = true }, close() { this.projectOpen = false } }"> <li class="inline-flex items-center" x-data="{ projectOpen: false, toggle() { this.projectOpen = !this.projectOpen }, open() { this.projectOpen = true }, close() { this.projectOpen = false } }">
<div class="flex items-center relative" @mouseenter="open()" @mouseleave="close()"> <div class="flex items-center relative" @mouseenter="open()" @mouseleave="close()">
<a class="text-xs truncate lg:text-sm hover:text-warning" <a class="text-xs truncate lg:text-sm hover:text-warning" {{ wireNavigate() }}
href="{{ route('project.show', ['project_uuid' => data_get($parameters, 'project_uuid')]) }}"> href="{{ route('project.show', ['project_uuid' => data_get($parameters, 'project_uuid')]) }}">
{{ $project->name }}</a> {{ $project->name }}</a>
<button type="button" @click.stop="toggle()" class="px-1 text-warning"> <button type="button" @click.stop="toggle()" class="px-1 text-warning">
@@ -66,7 +66,7 @@
@endphp @endphp
<li class="inline-flex items-center" x-data="{ envOpen: false, activeEnv: null, envPositions: {}, activeRes: null, resPositions: {}, activeMenuEnv: null, menuPositions: {}, closeTimeout: null, envTimeout: null, resTimeout: null, menuTimeout: null, toggle() { this.envOpen = !this.envOpen; if (!this.envOpen) { this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; } }, open() { clearTimeout(this.closeTimeout); this.envOpen = true }, close() { this.closeTimeout = setTimeout(() => { this.envOpen = false; this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openEnv(id) { clearTimeout(this.closeTimeout); clearTimeout(this.envTimeout); this.activeEnv = id }, closeEnv() { this.envTimeout = setTimeout(() => { this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openRes(id) { clearTimeout(this.envTimeout); clearTimeout(this.resTimeout); this.activeRes = id }, closeRes() { this.resTimeout = setTimeout(() => { this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openMenu(id) { clearTimeout(this.resTimeout); clearTimeout(this.menuTimeout); this.activeMenuEnv = id }, closeMenu() { this.menuTimeout = setTimeout(() => { this.activeMenuEnv = null; }, 100) } }"> <li class="inline-flex items-center" x-data="{ envOpen: false, activeEnv: null, envPositions: {}, activeRes: null, resPositions: {}, activeMenuEnv: null, menuPositions: {}, closeTimeout: null, envTimeout: null, resTimeout: null, menuTimeout: null, toggle() { this.envOpen = !this.envOpen; if (!this.envOpen) { this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; } }, open() { clearTimeout(this.closeTimeout); this.envOpen = true }, close() { this.closeTimeout = setTimeout(() => { this.envOpen = false; this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openEnv(id) { clearTimeout(this.closeTimeout); clearTimeout(this.envTimeout); this.activeEnv = id }, closeEnv() { this.envTimeout = setTimeout(() => { this.activeEnv = null; this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openRes(id) { clearTimeout(this.envTimeout); clearTimeout(this.resTimeout); this.activeRes = id }, closeRes() { this.resTimeout = setTimeout(() => { this.activeRes = null; this.activeMenuEnv = null; }, 100) }, openMenu(id) { clearTimeout(this.resTimeout); clearTimeout(this.menuTimeout); this.activeMenuEnv = id }, closeMenu() { this.menuTimeout = setTimeout(() => { this.activeMenuEnv = null; }, 100) } }">
<div class="flex items-center relative" @mouseenter="open()" @mouseleave="close()"> <div class="flex items-center relative" @mouseenter="open()" @mouseleave="close()">
<a class="text-xs truncate lg:text-sm hover:text-warning" <a class="text-xs truncate lg:text-sm hover:text-warning" {{ wireNavigate() }}
href="{{ route('project.resource.index', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => $environment->uuid]) }}"> href="{{ route('project.resource.index', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => $environment->uuid]) }}">
{{ $environment->name }} {{ $environment->name }}
</a> </a>
@@ -106,7 +106,7 @@
</div> </div>
@endforeach @endforeach
<div class="border-t border-neutral-200 dark:border-coolgray-200 mt-1 pt-1"> <div class="border-t border-neutral-200 dark:border-coolgray-200 mt-1 pt-1">
<a href="{{ route('project.show', ['project_uuid' => data_get($parameters, 'project_uuid')]) }}" <a href="{{ route('project.show', ['project_uuid' => data_get($parameters, 'project_uuid')]) }}" {{ wireNavigate() }}
class="flex items-center gap-2 px-4 py-2 text-sm hover:bg-neutral-100 dark:hover:bg-coolgray-200"> class="flex items-center gap-2 px-4 py-2 text-sm hover:bg-neutral-100 dark:hover:bg-coolgray-200">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
@@ -311,7 +311,7 @@
</div> </div>
@if ($environment->isEmpty()) @if ($environment->isEmpty())
@can('createAnyResource') @can('createAnyResource')
<a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}" <a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}" {{ wireNavigate() }}
class="items-center justify-center coolbox">+ Add Resource</a> class="items-center justify-center coolbox">+ Add Resource</a>
@else @else
<div <div

View File

@@ -8,27 +8,27 @@
<div class="flex flex-col items-start gap-2 min-w-fit"> <div class="flex flex-col items-start gap-2 min-w-fit">
<a class="menu-item sm:min-w-fit" target="_blank" href="{{ $service->documentation() }}">Documentation <a class="menu-item sm:min-w-fit" target="_blank" href="{{ $service->documentation() }}">Documentation
<x-external-link /></a> <x-external-link /></a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active" {{ wireNavigate() }}
href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">General</a> href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">General</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active" {{ wireNavigate() }}
href="{{ route('project.service.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Environment href="{{ route('project.service.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Environment
Variables</a> Variables</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active" {{ wireNavigate() }}
href="{{ route('project.service.storages', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Persistent href="{{ route('project.service.storages', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Persistent
Storages</a> Storages</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active" {{ wireNavigate() }}
href="{{ route('project.service.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Scheduled href="{{ route('project.service.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Scheduled
Tasks</a> Tasks</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active" {{ wireNavigate() }}
href="{{ route('project.service.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Webhooks</a> href="{{ route('project.service.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Webhooks</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active" {{ wireNavigate() }}
href="{{ route('project.service.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Resource href="{{ route('project.service.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Resource
Operations</a> Operations</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active" {{ wireNavigate() }}
href="{{ route('project.service.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Tags</a> href="{{ route('project.service.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Tags</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active" {{ wireNavigate() }}
href="{{ route('project.service.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Danger href="{{ route('project.service.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Danger
Zone</a> Zone</a>
</div> </div>
@@ -104,7 +104,7 @@
<div class="pt-2 text-xs">{{ formatContainerStatus($application->status) }}</div> <div class="pt-2 text-xs">{{ formatContainerStatus($application->status) }}</div>
</div> </div>
<div class="flex items-center px-4"> <div class="flex items-center px-4">
<a class="mx-4 text-xs font-bold hover:underline" <a class="mx-4 text-xs font-bold hover:underline" {{ wireNavigate() }}
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $application->uuid]) }}"> href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $application->uuid]) }}">
Settings Settings
</a> </a>
@@ -154,12 +154,12 @@
</div> </div>
<div class="flex items-center px-4"> <div class="flex items-center px-4">
@if ($database->isBackupSolutionAvailable() || $database->is_migrated) @if ($database->isBackupSolutionAvailable() || $database->is_migrated)
<a class="mx-4 text-xs font-bold hover:underline" <a class="mx-4 text-xs font-bold hover:underline" {{ wireNavigate() }}
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}#backups"> href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}#backups">
Backups Backups
</a> </a>
@endif @endif
<a class="mx-4 text-xs font-bold hover:underline" <a class="mx-4 text-xs font-bold hover:underline" {{ wireNavigate() }}
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}"> href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}">
Settings Settings
</a> </a>

View File

@@ -10,11 +10,11 @@
<x-resources.breadcrumbs :resource="$service" :parameters="$parameters" /> <x-resources.breadcrumbs :resource="$service" :parameters="$parameters" />
<div class="navbar-main" x-data"> <div class="navbar-main" x-data">
<nav class="flex shrink-0 gap-6 items-center whitespace-nowrap scrollbar min-h-10"> <nav class="flex shrink-0 gap-6 items-center whitespace-nowrap scrollbar min-h-10">
<a class="{{ request()->routeIs('project.service.configuration') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('project.service.configuration') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('project.service.configuration', $parameters) }}"> href="{{ route('project.service.configuration', $parameters) }}">
<button>Configuration</button> <button>Configuration</button>
</a> </a>
<a class="{{ request()->routeIs('project.service.logs') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('project.service.logs') ? 'dark:text-white' : '' }}" {{ wireNavigate() }}
href="{{ route('project.service.logs', $parameters) }}"> href="{{ route('project.service.logs', $parameters) }}">
<button>Logs</button> <button>Logs</button>
</a> </a>
@@ -127,7 +127,7 @@
@else @else
<div class="flex flex-wrap order-first gap-2 items-center sm:order-last"> <div class="flex flex-wrap order-first gap-2 items-center sm:order-last">
<div class="text-error"> <div class="text-error">
Unable to deploy. <a class="underline font-bold cursor-pointer" Unable to deploy. <a class="underline font-bold cursor-pointer" {{ wireNavigate() }}
href="{{ route('project.service.environment-variables', $parameters) }}"> href="{{ route('project.service.environment-variables', $parameters) }}">
Required environment variables missing.</a> Required environment variables missing.</a>
</div> </div>

View File

@@ -3,7 +3,7 @@
<div class="flex flex-col h-full gap-8 sm:flex-row"> <div class="flex flex-col h-full gap-8 sm:flex-row">
<div class="flex flex-col items-start gap-2 min-w-fit"> <div class="flex flex-col items-start gap-2 min-w-fit">
<a class="menu-item" <a class="menu-item"
class="{{ request()->routeIs('project.service.configuration') ? 'menu-item-active' : '' }}" class="{{ request()->routeIs('project.service.configuration') ? 'menu-item-active' : '' }}" {{ wireNavigate() }}
href="{{ route('project.service.configuration', [...$parameters, 'stack_service_uuid' => null]) }}"> href="{{ route('project.service.configuration', [...$parameters, 'stack_service_uuid' => null]) }}">
<button><- Back</button> <button><- Back</button>
</a> </a>

View File

@@ -23,7 +23,7 @@
<div class="w-96"> <div class="w-96">
<x-forms.checkbox canGate="update" :canResource="$service" instantSave id="connectToDockerNetwork" <x-forms.checkbox canGate="update" :canResource="$service" instantSave id="connectToDockerNetwork"
label="Connect To Predefined Network" label="Connect To Predefined Network"
helper="By default, you do not reach the Coolify defined networks.<br>Starting a docker compose based resource will have an internal network. <br>If you connect to a Coolify defined network, you maybe need to use different internal DNS names to connect to a resource.<br><br>For more information, check <a class='underline dark:text-white' target='_blank' href='https://coolify.io/docs/knowledge-base/docker/compose#connect-to-predefined-networks'>this</a>." /> helper="By default, you do not reach the Coolify defined networks.<br>Starting a docker compose based resource will have an internal network. <br>If you connect to a Coolify defined network, you maybe need to use different internal DNS names to connect to a resource.<br><br>For more information, check <a class='underline dark:text-white' {{ wireNavigate() }} target='_blank' href='https://coolify.io/docs/knowledge-base/docker/compose#connect-to-predefined-networks'>this</a>." />
</div> </div>
@if ($fields->count() > 0) @if ($fields->count() > 0)
<div> <div>

View File

@@ -5,7 +5,7 @@
@if (!$healthCheckEnabled) @if (!$healthCheckEnabled)
<x-modal-confirmation title="Confirm Healthcheck Enable?" buttonTitle="Enable Healthcheck" <x-modal-confirmation title="Confirm Healthcheck Enable?" buttonTitle="Enable Healthcheck"
submitAction="toggleHealthcheck" :actions="['Enable healthcheck for this resource.']" submitAction="toggleHealthcheck" :actions="['Enable healthcheck for this resource.']"
warningMessage="If the health check fails, your application will become inaccessible. Please review the <a href='https://coolify.io/docs/knowledge-base/health-checks' target='_blank' class='underline text-white'>Health Checks</a> guide before proceeding!" warningMessage="If the health check fails, your application will become inaccessible. Please review the <a {{ wireNavigate() }} href='https://coolify.io/docs/knowledge-base/health-checks' target='_blank' class='underline text-white'>Health Checks</a> guide before proceeding!"
step2ButtonText="Enable Healthcheck" :confirmWithText="false" :confirmWithPassword="false" step2ButtonText="Enable Healthcheck" :confirmWithText="false" :confirmWithPassword="false"
isHighlightedButton> isHighlightedButton>
</x-modal-confirmation> </x-modal-confirmation>

View File

@@ -8,7 +8,7 @@
<div class="alert alert-warning">Metrics are not available for Docker Compose applications yet!</div> <div class="alert alert-warning">Metrics are not available for Docker Compose applications yet!</div>
@elseif(!$resource->destination->server->isMetricsEnabled()) @elseif(!$resource->destination->server->isMetricsEnabled())
<div class="alert alert-warning">Metrics are only available for servers with Sentinel & Metrics enabled!</div> <div class="alert alert-warning">Metrics are only available for servers with Sentinel & Metrics enabled!</div>
<div>Go to <a class="underline dark:text-white" href="{{ route('server.show', $resource->destination->server->uuid) }}">Server settings</a> to enable it.</div> <div>Go to <a class="underline dark:text-white" href="{{ route('server.show', $resource->destination->server->uuid) }}" {{ wireNavigate() }}>Server settings</a> to enable it.</div>
@else @else
@if (!str($resource->status)->contains('running')) @if (!str($resource->status)->contains('running'))
<div class="alert alert-warning">Metrics are only available when the application container is running!</div> <div class="alert alert-warning">Metrics are only available when the application container is running!</div>

View File

@@ -14,7 +14,7 @@
<div class="flex flex-col flex-wrap gap-2 pt-4"> <div class="flex flex-col flex-wrap gap-2 pt-4">
@forelse($resource->scheduled_tasks as $task) @forelse($resource->scheduled_tasks as $task)
@if ($resource->type() == 'application') @if ($resource->type() == 'application')
<a class="coolbox" <a class="coolbox" {{ wireNavigate() }}
href="{{ route('project.application.scheduled-tasks', [...$parameters, 'task_uuid' => $task->uuid]) }}"> href="{{ route('project.application.scheduled-tasks', [...$parameters, 'task_uuid' => $task->uuid]) }}">
<span class="flex flex-col"> <span class="flex flex-col">
<span class="text-lg font-bold">{{ $task->name }} <span class="text-lg font-bold">{{ $task->name }}
@@ -29,7 +29,7 @@
</span> </span>
</a> </a>
@elseif ($resource->type() == 'service') @elseif ($resource->type() == 'service')
<a class="coolbox" <a class="coolbox" {{ wireNavigate() }}
href="{{ route('project.service.scheduled-tasks', [...$parameters, 'task_uuid' => $task->uuid]) }}"> href="{{ route('project.service.scheduled-tasks', [...$parameters, 'task_uuid' => $task->uuid]) }}">
<span class="flex flex-col"> <span class="flex flex-col">
<span class="text-lg font-bold">{{ $task->name }} <span class="text-lg font-bold">{{ $task->name }}

View File

@@ -23,7 +23,7 @@
@forelse ($project->environments->sortBy('created_at') as $environment) @forelse ($project->environments->sortBy('created_at') as $environment)
<div class="gap-2 coolbox group"> <div class="gap-2 coolbox group">
<div class="flex flex-1 mx-6"> <div class="flex flex-1 mx-6">
<a class="flex flex-col justify-center flex-1" <a class="flex flex-col justify-center flex-1" {{ wireNavigate() }}
href="{{ route('project.resource.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}"> href="{{ route('project.resource.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}">
<div class="font-bold dark:text-white"> {{ $environment->name }}</div> <div class="font-bold dark:text-white"> {{ $environment->name }}</div>
<div class="description"> <div class="description">
@@ -31,7 +31,7 @@
</a> </a>
@can('update', $project) @can('update', $project)
<div class="flex items-center justify-center gap-2 text-xs"> <div class="flex items-center justify-center gap-2 text-xs">
<a class="font-bold hover:underline" <a class="font-bold hover:underline" {{ wireNavigate() }}
href="{{ route('project.environment.edit', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}"> href="{{ route('project.environment.edit', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}">
Settings Settings
</a> </a>

View File

@@ -7,7 +7,7 @@
<h2>API Tokens</h2> <h2>API Tokens</h2>
@if (!$isApiEnabled) @if (!$isApiEnabled)
<div>API is disabled. If you want to use the API, please enable it in the <a <div>API is disabled. If you want to use the API, please enable it in the <a
href="{{ route('settings.advanced') }}" class="underline dark:text-white">Settings</a> menu.</div> href="{{ route('settings.advanced') }}" class="underline dark:text-white" {{ wireNavigate() }}>Settings</a> menu.</div>
@else @else
<div>Tokens are created with the current team as scope.</div> <div>Tokens are created with the current team as scope.</div>
</div> </div>

View File

@@ -17,7 +17,7 @@
@can('view', $key) @can('view', $key)
{{-- Admin/Owner: Clickable link --}} {{-- Admin/Owner: Clickable link --}}
<a class="coolbox group" <a class="coolbox group"
href="{{ route('security.private-key.show', ['private_key_uuid' => data_get($key, 'uuid')]) }}"> href="{{ route('security.private-key.show', ['private_key_uuid' => data_get($key, 'uuid')]) }}" {{ wireNavigate() }}>
<div class="flex flex-col justify-center mx-6"> <div class="flex flex-col justify-center mx-6">
<div class="box-title"> <div class="box-title">
{{ data_get($key, 'name') }} {{ data_get($key, 'name') }}

View File

@@ -289,7 +289,7 @@
</div> </div>
@else @else
<div>Metrics are disabled for this server. Enable them in <a class="underline dark:text-white" <div>Metrics are disabled for this server. Enable them in <a class="underline dark:text-white"
href="{{ route('server.show', ['server_uuid' => $server->uuid]) }}">General</a> settings.</div> href="{{ route('server.show', ['server_uuid' => $server->uuid]) }}" {{ wireNavigate() }}>General</a> settings.</div>
@endif @endif
</div> </div>
</div> </div>

View File

@@ -20,12 +20,12 @@
<h4 class="pt-4 pb-2">Available Destinations</h4> <h4 class="pt-4 pb-2">Available Destinations</h4>
<div class="flex gap-2"> <div class="flex gap-2">
@foreach ($server->standaloneDockers as $docker) @foreach ($server->standaloneDockers as $docker)
<a href="{{ route('destination.show', ['destination_uuid' => data_get($docker, 'uuid')]) }}"> <a href="{{ route('destination.show', ['destination_uuid' => data_get($docker, 'uuid')]) }}" {{ wireNavigate() }}>
<x-forms.button>{{ data_get($docker, 'network') }} </x-forms.button> <x-forms.button>{{ data_get($docker, 'network') }} </x-forms.button>
</a> </a>
@endforeach @endforeach
@foreach ($server->swarmDockers as $docker) @foreach ($server->swarmDockers as $docker)
<a href="{{ route('destination.show', ['destination_uuid' => data_get($docker, 'uuid')]) }}"> <a href="{{ route('destination.show', ['destination_uuid' => data_get($docker, 'uuid')]) }}" {{ wireNavigate() }}>
<x-forms.button>{{ data_get($docker, 'network') }} </x-forms.button> <x-forms.button>{{ data_get($docker, 'network') }} </x-forms.button>
</a> </a>
@endforeach @endforeach

View File

@@ -13,7 +13,7 @@
<div class="subtitle">All your servers are here.</div> <div class="subtitle">All your servers are here.</div>
<div class="grid gap-4 lg:grid-cols-2 -mt-1"> <div class="grid gap-4 lg:grid-cols-2 -mt-1">
@forelse ($servers as $server) @forelse ($servers as $server)
<a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}" <a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}" {{ wireNavigate() }}
@class([ @class([
'gap-2 border cursor-pointer coolbox group', 'gap-2 border cursor-pointer coolbox group',
'border-red-500' => 'border-red-500' =>

View File

@@ -65,14 +65,14 @@
class="flex items-center gap-6 overflow-x-scroll sm:overflow-x-hidden scrollbar min-h-10 whitespace-nowrap pt-2"> class="flex items-center gap-6 overflow-x-scroll sm:overflow-x-hidden scrollbar min-h-10 whitespace-nowrap pt-2">
<a class="{{ request()->routeIs('server.show') ? 'dark:text-white' : '' }}" href="{{ route('server.show', [ <a class="{{ request()->routeIs('server.show') ? 'dark:text-white' : '' }}" href="{{ route('server.show', [
'server_uuid' => data_get($server, 'uuid'), 'server_uuid' => data_get($server, 'uuid'),
]) }}"> ]) }}" {{ wireNavigate() }}>
Configuration Configuration
</a> </a>
@if (!$server->isSwarmWorker() && !$server->settings->is_build_server) @if (!$server->isSwarmWorker() && !$server->settings->is_build_server)
<a class="{{ request()->routeIs('server.proxy') ? 'dark:text-white' : '' }} flex items-center gap-1" href="{{ route('server.proxy', [ <a class="{{ request()->routeIs('server.proxy') ? 'dark:text-white' : '' }} flex items-center gap-1" href="{{ route('server.proxy', [
'server_uuid' => data_get($server, 'uuid'), 'server_uuid' => data_get($server, 'uuid'),
]) }}"> ]) }}" {{ wireNavigate() }}>
Proxy Proxy
@if ($this->hasTraefikOutdated) @if ($this->hasTraefikOutdated)
<svg class="w-4 h-4 text-warning" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg"> <svg class="w-4 h-4 text-warning" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
@@ -84,7 +84,7 @@
@endif @endif
<a class="{{ request()->routeIs('server.resources') ? 'dark:text-white' : '' }}" href="{{ route('server.resources', [ <a class="{{ request()->routeIs('server.resources') ? 'dark:text-white' : '' }}" href="{{ route('server.resources', [
'server_uuid' => data_get($server, 'uuid'), 'server_uuid' => data_get($server, 'uuid'),
]) }}"> ]) }}" {{ wireNavigate() }}>
Resources Resources
</a> </a>
@can('canAccessTerminal') @can('canAccessTerminal')
@@ -97,7 +97,7 @@
@can('update', $server) @can('update', $server)
<a class="{{ request()->routeIs('server.security.patches') ? 'dark:text-white' : '' }}" href="{{ route('server.security.patches', [ <a class="{{ request()->routeIs('server.security.patches') ? 'dark:text-white' : '' }}" href="{{ route('server.security.patches', [
'server_uuid' => data_get($server, 'uuid'), 'server_uuid' => data_get($server, 'uuid'),
]) }}"> ]) }}" {{ wireNavigate() }}>
Security Security
</a> </a>
@endcan @endcan

View File

@@ -68,7 +68,7 @@
{{ data_get($resource, 'environment.name') }} {{ data_get($resource, 'environment.name') }}
</td> </td>
<td class="px-5 py-4 text-sm whitespace-nowrap hover:underline"> <td class="px-5 py-4 text-sm whitespace-nowrap hover:underline">
<a class="" <a class="" {{ wireNavigate() }}
href="{{ $resource->link() }}">{{ $resource->name }} href="{{ $resource->link() }}">{{ $resource->name }}
<x-internal-link /></a> <x-internal-link /></a>
</td> </td>

View File

@@ -19,7 +19,7 @@
<span class="text-xs text-neutral-500">(experimental)</span> <span class="text-xs text-neutral-500">(experimental)</span>
<x-helper <x-helper
helper="Only available for apt, dnf and zypper package managers atm, more coming helper="Only available for apt, dnf and zypper package managers atm, more coming
soon.<br/>Status notifications sent every week.<br/>You can disable notifications in the <a class='dark:text-white underline' href='{{ route('notifications.email') }}'>notification settings</a>." /> soon.<br/>Status notifications sent every week.<br/>You can disable notifications in the <a class='dark:text-white underline' href='{{ route('notifications.email') }}' {{ wireNavigate() }}>notification settings</a>." />
@if (isDev()) @if (isDev())
<x-forms.button type="button" wire:click="sendTestEmail"> <x-forms.button type="button" wire:click="sendTestEmail">
Send Test Email (dev only)</x-forms.button> Send Test Email (dev only)</x-forms.button>

View File

@@ -43,7 +43,7 @@
Please validate your server to enable Instance Backup. Please validate your server to enable Instance Backup.
</div> </div>
<a href="{{ route('server.show', [$server->uuid]) }}" <a href="{{ route('server.show', [$server->uuid]) }}"
class="text-black hover:text-gray-700 dark:text-white dark:hover:text-gray-200 underline"> class="text-black hover:text-gray-700 dark:text-white dark:hover:text-gray-200 underline" {{ wireNavigate() }}>
Go to Server Settings to Validate Go to Server Settings to Validate
</a> </a>
</div> </div>

View File

@@ -50,9 +50,14 @@
environments! environments!
</x-callout> </x-callout>
@endif @endif
<h4 class="pt-4">UI Settings</h4>
<div class="md:w-96">
<x-forms.checkbox instantSave id="is_wire_navigate_enabled" label="SPA Navigation"
helper="Enable single-page application (SPA) style navigation with prefetching on hover. When enabled, page transitions are smoother without full page reloads and pages are prefetched when hovering over links. Disable if you experience navigation issues." />
</div>
<h4 class="pt-4">Confirmation Settings</h4> <h4 class="pt-4">Confirmation Settings</h4>
<div class="md:w-96"> <div class="md:w-96">
<x-forms.checkbox instantSave id=" is_sponsorship_popup_enabled" label="Show Sponsorship Popup" <x-forms.checkbox instantSave id="is_sponsorship_popup_enabled" label="Show Sponsorship Popup"
helper="Show monthly sponsorship reminders to support Coolify development. Disable to hide these messages permanently." /> helper="Show monthly sponsorship reminders to support Coolify development. Disable to hide these messages permanently." />
</div> </div>
</div> </div>

View File

@@ -15,7 +15,7 @@
href="{{ route('shared-variables.environment.show', [ href="{{ route('shared-variables.environment.show', [
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
'environment_uuid' => $environment->uuid, 'environment_uuid' => $environment->uuid,
]) }}"> ]) }}" {{ wireNavigate() }}>
<div class="flex flex-col justify-center flex-1 mx-6 "> <div class="flex flex-col justify-center flex-1 mx-6 ">
<div class="box-title"> {{ $environment->name }}</div> <div class="box-title"> {{ $environment->name }}</div>
<div class="box-description"> <div class="box-description">

View File

@@ -8,19 +8,19 @@
<div class="subtitle">Set Team / Project / Environment wide variables.</div> <div class="subtitle">Set Team / Project / Environment wide variables.</div>
<div class="flex flex-col gap-2 -mt-1"> <div class="flex flex-col gap-2 -mt-1">
<a class="coolbox group" href="{{ route('shared-variables.team.index') }}"> <a class="coolbox group" href="{{ route('shared-variables.team.index') }}" {{ wireNavigate() }}>
<div class="flex flex-col justify-center mx-6"> <div class="flex flex-col justify-center mx-6">
<div class="box-title">Team wide</div> <div class="box-title">Team wide</div>
<div class="box-description">Usable for all resources in a team.</div> <div class="box-description">Usable for all resources in a team.</div>
</div> </div>
</a> </a>
<a class="coolbox group" href="{{ route('shared-variables.project.index') }}"> <a class="coolbox group" href="{{ route('shared-variables.project.index') }}" {{ wireNavigate() }}>
<div class="flex flex-col justify-center mx-6"> <div class="flex flex-col justify-center mx-6">
<div class="box-title">Project wide</div> <div class="box-title">Project wide</div>
<div class="box-description">Usable for all resources in a project.</div> <div class="box-description">Usable for all resources in a project.</div>
</div> </div>
</a> </a>
<a class="coolbox group" href="{{ route('shared-variables.environment.index') }}"> <a class="coolbox group" href="{{ route('shared-variables.environment.index') }}" {{ wireNavigate() }}>
<div class="flex flex-col justify-center mx-6"> <div class="flex flex-col justify-center mx-6">
<div class="box-title">Environment wide</div> <div class="box-title">Environment wide</div>
<div class="box-description">Usable for all resources in an environment.</div> <div class="box-description">Usable for all resources in an environment.</div>

View File

@@ -9,7 +9,7 @@
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
@forelse ($projects as $project) @forelse ($projects as $project)
<a class="coolbox group" <a class="coolbox group"
href="{{ route('shared-variables.project.show', ['project_uuid' => data_get($project, 'uuid')]) }}"> href="{{ route('shared-variables.project.show', ['project_uuid' => data_get($project, 'uuid')]) }}" {{ wireNavigate() }}>
<div class="flex flex-col justify-center mx-6 "> <div class="flex flex-col justify-center mx-6 ">
<div class="box-title">{{ $project->name }}</div> <div class="box-title">{{ $project->name }}</div>
<div class="box-description "> <div class="box-description ">

View File

@@ -184,6 +184,7 @@
</td> </td>
<td class="px-5 py-4 text-sm whitespace-nowrap"><a <td class="px-5 py-4 text-sm whitespace-nowrap"><a
class="" class=""
{{ wireNavigate() }}
href="{{ $resource->link() }}">{{ $resource->name }} href="{{ $resource->link() }}">{{ $resource->name }}
<x-internal-link /></a> <x-internal-link /></a>
</td> </td>

View File

@@ -13,7 +13,7 @@
<div class="subtitle">S3 storages for backups.</div> <div class="subtitle">S3 storages for backups.</div>
<div class="grid gap-4 lg:grid-cols-2 -mt-1"> <div class="grid gap-4 lg:grid-cols-2 -mt-1">
@forelse ($s3 as $storage) @forelse ($s3 as $storage)
<a href="/storages/{{ $storage->uuid }}" @class(['gap-2 border cursor-pointer coolbox group'])> <a {{ wireNavigate() }} href="/storages/{{ $storage->uuid }}" @class(['gap-2 border cursor-pointer coolbox group'])>
<div class="flex flex-col justify-center mx-6"> <div class="flex flex-col justify-center mx-6">
<div class="box-title"> <div class="box-title">
{{ $storage->name }} {{ $storage->name }}

View File

@@ -152,7 +152,7 @@
</svg> </svg>
Do you require official support for your self-hosted instance?<a class="underline" Do you require official support for your self-hosted instance?<a class="underline"
href="https://coolify.io/docs/contact">Contact Us</a> href="https://coolify.io/docs/contact" target="_blank">Contact Us</a>
</li> </li>
</ul> </ul>
</div> </div>

View File

@@ -3,7 +3,7 @@
<h4 class="py-4">{{ $server_name }}</h4> <h4 class="py-4">{{ $server_name }}</h4>
<div class="grid grid-cols-1 gap-2"> <div class="grid grid-cols-1 gap-2">
@foreach ($deployments as $deployment) @foreach ($deployments as $deployment)
<a href="{{ data_get($deployment, 'deployment_url') }}" @class([ <a {{ wireNavigate() }} href="{{ data_get($deployment, 'deployment_url') }}" @class([
'box-without-bg-without-border dark:bg-coolgray-100 bg-white gap-2 cursor-pointer group border-l-2', 'box-without-bg-without-border dark:bg-coolgray-100 bg-white gap-2 cursor-pointer group border-l-2',
'dark:border-coolgray-300' => data_get($deployment, 'status') === 'queued', 'dark:border-coolgray-300' => data_get($deployment, 'status') === 'queued',
'dark:border-warning-500' => 'dark:border-warning-500' =>

View File

@@ -9,6 +9,7 @@
@forelse ($tags as $oneTag) @forelse ($tags as $oneTag)
<a :class="{{ $tag?->id == $oneTag->id }} && 'dark:bg-coollabs'" <a :class="{{ $tag?->id == $oneTag->id }} && 'dark:bg-coollabs'"
class="min-w-32 coolbox dark:text-white font-bold flex justify-center items-center" class="min-w-32 coolbox dark:text-white font-bold flex justify-center items-center"
{{ wireNavigate() }}
href="{{ route('tags.show', ['tagName' => $oneTag->name]) }}">{{ data_get_str($oneTag, 'name')->limit(30) }}</a> href="{{ route('tags.show', ['tagName' => $oneTag->name]) }}">{{ data_get_str($oneTag, 'name')->limit(30) }}</a>
@empty @empty
<div>No tags yet defined yet. Go to a resource and add a tag there.</div> <div>No tags yet defined yet. Go to a resource and add a tag there.</div>
@@ -34,7 +35,7 @@
<div class="grid grid-cols-1 gap-2 pt-4 lg:grid-cols-2 xl:grid-cols-3"> <div class="grid grid-cols-1 gap-2 pt-4 lg:grid-cols-2 xl:grid-cols-3">
@if (isset($applications) && count($applications) > 0) @if (isset($applications) && count($applications) > 0)
@foreach ($applications as $application) @foreach ($applications as $application)
<a href="{{ $application->link() }}" class="coolbox group"> <a {{ wireNavigate() }} href="{{ $application->link() }}" class="coolbox group">
<div class="flex flex-col justify-center"> <div class="flex flex-col justify-center">
<div class="box-title"> <div class="box-title">
{{ $application->project()->name }}/{{ $application->environment->name }} {{ $application->project()->name }}/{{ $application->environment->name }}
@@ -47,7 +48,7 @@
@endif @endif
@if (isset($services) && count($services) > 0) @if (isset($services) && count($services) > 0)
@foreach ($services as $service) @foreach ($services as $service)
<a href="{{ $service->link() }}" class="flex flex-col coolbox group"> <a {{ wireNavigate() }} href="{{ $service->link() }}" class="flex flex-col coolbox group">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="box-title"> <div class="box-title">
{{ $service->project()->name }}/{{ $service->environment->name }} {{ $service->project()->name }}/{{ $service->environment->name }}
@@ -70,7 +71,7 @@
<h4 class="py-4">{{ $serverName }}</h4> <h4 class="py-4">{{ $serverName }}</h4>
<div class="grid grid-cols-1 gap-2 lg:grid-cols-3"> <div class="grid grid-cols-1 gap-2 lg:grid-cols-3">
@foreach ($deployments as $deployment) @foreach ($deployments as $deployment)
<a href="{{ data_get($deployment, 'deployment_url') }}" @class([ <a {{ wireNavigate() }} href="{{ data_get($deployment, 'deployment_url') }}" @class([
'gap-2 cursor-pointer coolbox group border-l-2 border-dotted', 'gap-2 cursor-pointer coolbox group border-l-2 border-dotted',
'dark:border-coolgray-300' => data_get($deployment, 'status') === 'queued', 'dark:border-coolgray-300' => data_get($deployment, 'status') === 'queued',
'border-warning-500' => data_get($deployment, 'status') === 'in_progress', 'border-warning-500' => data_get($deployment, 'status') === 'in_progress',

View File

@@ -32,6 +32,7 @@
<div>You can't delete your last / personal team.</div> <div>You can't delete your last / personal team.</div>
@elseif(currentTeam()->subscription) @elseif(currentTeam()->subscription)
<div>Please cancel your subscription <a class="underline dark:text-white" <div>Please cancel your subscription <a class="underline dark:text-white"
{{ wireNavigate() }}
href="{{ route('subscription.show') }}">here</a> before deleting this team.</div> href="{{ route('subscription.show') }}">here</a> before deleting this team.</div>
@else @else
@if (currentTeam()->isEmpty()) @if (currentTeam()->isEmpty())

View File

@@ -41,6 +41,7 @@
<h2>Invite New Member</h2> <h2>Invite New Member</h2>
@if (isInstanceAdmin()) @if (isInstanceAdmin())
<div class="pb-4 text-xs dark:text-warning">You need to configure (as root team) <a <div class="pb-4 text-xs dark:text-warning">You need to configure (as root team) <a
{{ wireNavigate() }}
href="/settings/email" class="underline dark:text-warning">Transactional href="/settings/email" class="underline dark:text-warning">Transactional
Emails</a> Emails</a>
before before

View File

@@ -15,6 +15,7 @@
@forelse ($sources as $source) @forelse ($sources as $source)
@if ($source->getMorphClass() === 'App\Models\GithubApp') @if ($source->getMorphClass() === 'App\Models\GithubApp')
<a class="flex gap-2 text-center hover:no-underline coolbox group" <a class="flex gap-2 text-center hover:no-underline coolbox group"
{{ wireNavigate() }}
href="{{ route('source.github.show', ['github_app_uuid' => data_get($source, 'uuid')]) }}"> href="{{ route('source.github.show', ['github_app_uuid' => data_get($source, 'uuid')]) }}">
{{-- <x-git-icon class="dark:text-white w-8 h-8 mt-1" git="{{ $source->getMorphClass() }}" /> --}} {{-- <x-git-icon class="dark:text-white w-8 h-8 mt-1" git="{{ $source->getMorphClass() }}" /> --}}
<div class="text-left dark:group-hover:text-white flex flex-col justify-center mx-6"> <div class="text-left dark:group-hover:text-white flex flex-col justify-center mx-6">