fix(ui): Disable livewire navigate feature (causing spam of setInterval())

This commit is contained in:
Andras Bacsai
2025-04-29 09:04:24 +02:00
parent 05e62f57fd
commit d47946a0ad
42 changed files with 235 additions and 276 deletions

View File

@@ -51,7 +51,7 @@ class Dashboard extends Component
public function navigateToProject($projectUuid)
{
return $this->redirect(collect($this->projects)->firstWhere('uuid', $projectUuid)->navigateTo(), true);
return $this->redirect(collect($this->projects)->firstWhere('uuid', $projectUuid)->navigateTo(), navigate: false);
}
public function render()

View File

@@ -100,7 +100,7 @@ class Heading extends Component
'application_uuid' => $this->parameters['application_uuid'],
'deployment_uuid' => $this->deploymentUuid,
'environment_uuid' => $this->parameters['environment_uuid'],
], navigate: true);
], navigate: false);
}
protected function setDeploymentUuid()
@@ -147,7 +147,7 @@ class Heading extends Component
'application_uuid' => $this->parameters['application_uuid'],
'deployment_uuid' => $this->deploymentUuid,
'environment_uuid' => $this->parameters['environment_uuid'],
], navigate: true);
], navigate: false);
}
public function render()

View File

@@ -35,6 +35,6 @@ class Index extends Component
{
$project = collect($this->projects)->firstWhere('uuid', $projectUuid);
return $this->redirect($project->navigateTo(), true);
return $this->redirect($project->navigateTo(), navigate: false);
}
}

View File

@@ -2,7 +2,7 @@
return [
'coolify' => [
'version' => '4.0.0-beta.414',
'version' => '4.0.0-beta.415',
'helper_version' => '1.0.8',
'realtime_version' => '1.0.8',
'self_hosted' => env('SELF_HOSTED', true),

View File

@@ -1,10 +1,10 @@
{
"coolify": {
"v4": {
"version": "4.0.0-beta.414"
"version": "4.0.0-beta.415"
},
"nightly": {
"version": "4.0.0-beta.415"
"version": "4.0.0-beta.416"
},
"helper": {
"version": "1.0.8"

View File

@@ -123,7 +123,7 @@
<ul role="list" class="flex flex-col h-full space-y-1.5">
@if (isSubscribed() || !isCloud())
<li>
<a title="Dashboard" href="/" wire:navigate
<a title="Dashboard" href="/"
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"
stroke="currentColor">
@@ -134,7 +134,7 @@
</a>
</li>
<li>
<a title="Projects" wire:navigate
<a title="Projects"
class="{{ request()->is('project/*') || request()->is('projects') ? 'menu-item menu-item-active' : 'menu-item' }}"
href="/projects">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"
@@ -149,7 +149,7 @@
</a>
</li>
<li>
<a title="Servers" wire:navigate
<a title="Servers"
class="{{ request()->is('server/*') || request()->is('servers') ? 'menu-item menu-item-active' : 'menu-item' }}"
href="/servers">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"
@@ -168,7 +168,7 @@
</li>
<li>
<a title="Sources" wire:navigate
<a title="Sources"
class="{{ request()->is('source*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('source.all') }}">
<svg class="icon" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg">
@@ -179,7 +179,7 @@
</a>
</li>
<li>
<a title="Destinations" wire:navigate
<a title="Destinations"
class="{{ request()->is('destination*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('destination.index') }}">
@@ -192,7 +192,7 @@
</a>
</li>
<li>
<a title="S3 Storages" wire:navigate
<a title="S3 Storages"
class="{{ request()->is('storages*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('storage.index') }}">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
@@ -207,7 +207,7 @@
</a>
</li>
<li>
<a title="Shared variables" wire:navigate
<a title="Shared variables"
class="{{ request()->is('shared-variables*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('shared-variables.index') }}">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
@@ -222,7 +222,7 @@
</a>
</li>
<li>
<a title="Notifications" wire:navigate
<a title="Notifications"
class="{{ request()->is('notifications*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('notifications.email') }}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
@@ -234,7 +234,7 @@
</a>
</li>
<li>
<a title="Keys & Tokens" wire:navigate
<a title="Keys & Tokens"
class="{{ request()->is('security*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('security.private-key.index') }}">
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
@@ -246,7 +246,7 @@
</a>
</li>
<li>
<a title="Tags" wire:navigate
<a title="Tags"
class="{{ request()->is('tags*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('tags.show') }}">
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
@@ -275,7 +275,7 @@
</a>
</li>
<li>
<a title="Profile" wire:navigate
<a title="Profile"
class="{{ request()->is('profile*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('profile') }}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
@@ -290,7 +290,7 @@
</a>
</li>
<li>
<a title="Teams" wire:navigate
<a title="Teams"
class="{{ request()->is('team*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('team.index') }}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
@@ -309,7 +309,7 @@
</li>
@if (isCloud())
<li>
<a title="Subscription" wire:navigate
<a title="Subscription"
class="{{ request()->is('subscription*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('subscription.show') }}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
@@ -324,7 +324,7 @@
@if (isInstanceAdmin())
<li>
<a title="Settings" wire:navigate
<a title="Settings"
class="{{ request()->is('settings*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="/settings">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
@@ -343,7 +343,7 @@
@if (isCloud() || isDev())
@if (isInstanceAdmin() || session('impersonating'))
<li>
<a wire:navigate title="Admin" class="menu-item" href="/admin">
<a title="Admin" class="menu-item" href="/admin">
<svg class="text-pink-600 icon" viewBox="0 0 256 256"
xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor"
@@ -363,7 +363,7 @@
@endpersist
@endif
<li>
<a title="Onboarding" wire:navigate
<a title="Onboarding"
class="{{ request()->is('onboarding*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('onboarding') }}">
<svg class="icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">

View File

@@ -4,27 +4,22 @@
<div class="navbar-main">
<nav class="flex items-center gap-6 min-h-10">
<a class="{{ request()->routeIs('notifications.email') ? 'dark:text-white' : '' }}"
wire:navigate
href="{{ route('notifications.email') }}">
<button>Email</button>
</a>
<a class="{{ request()->routeIs('notifications.discord') ? 'dark:text-white' : '' }}"
wire:navigate
href="{{ route('notifications.discord') }}">
<button>Discord</button>
</a>
<a class="{{ request()->routeIs('notifications.telegram') ? 'dark:text-white' : '' }}"
wire:navigate
href="{{ route('notifications.telegram') }}">
<button>Telegram</button>
</a>
<a class="{{ request()->routeIs('notifications.slack') ? 'dark:text-white' : '' }}"
wire:navigate
href="{{ route('notifications.slack') }}">
<button>Slack</button>
</a>
<a class="{{ request()->routeIs('notifications.pushover') ? 'dark:text-white' : '' }}"
wire:navigate
href="{{ route('notifications.pushover') }}">
<button>Pushover</button>
</a>

View File

@@ -8,7 +8,6 @@
<li class="inline-flex items-center">
<div class="flex items-center">
<a class="text-xs truncate lg:text-sm"
wire:navigate
href="{{ route('project.show', ['project_uuid' => data_get($resource, 'environment.project.uuid')]) }}">
{{ data_get($resource, 'environment.project.name', 'Undefined Name') }}</a>
<svg aria-hidden="true" class="w-4 h-4 mx-1 font-bold dark:text-warning" fill="currentColor"
@@ -22,7 +21,6 @@
<li>
<div class="flex items-center">
<a class="text-xs truncate lg:text-sm"
wire:navigate
href="{{ route('project.resource.index', [
'environment_uuid' => data_get($resource, 'environment.uuid'),
'project_uuid' => data_get($resource, 'environment.project.uuid'),

View File

@@ -3,10 +3,10 @@
<div class="subtitle">Security related settings.</div>
<div class="navbar-main">
<nav class="flex items-center gap-6 scrollbar min-h-10">
<a wire:navigate href="{{ route('security.private-key.index') }}">
<a href="{{ route('security.private-key.index') }}">
<button>Private Keys</button>
</a>
<a wire:navigate href="{{ route('security.api-tokens') }}">
<a href="{{ route('security.api-tokens') }}">
<button>API tokens</button>
</a>
</nav>

View File

@@ -18,7 +18,7 @@
<div class="subtitle">{{ data_get($server, 'name') }}</div>
<div class="navbar-main">
<nav class="flex items-center gap-6 overflow-x-scroll sm:overflow-x-hidden scrollbar min-h-10 whitespace-nowrap">
<a wire:navigate class="{{ request()->routeIs('server.show') ? 'dark:text-white' : '' }}"
<a class="{{ request()->routeIs('server.show') ? 'dark:text-white' : '' }}"
href="{{ route('server.show', [
'server_uuid' => data_get($server, 'uuid'),
]) }}">
@@ -26,14 +26,14 @@
</a>
@if (!$server->isSwarmWorker() && !$server->settings->is_build_server)
<a wire:navigate class="{{ request()->routeIs('server.proxy') ? 'dark:text-white' : '' }}"
<a class="{{ request()->routeIs('server.proxy') ? 'dark:text-white' : '' }}"
href="{{ route('server.proxy', [
'server_uuid' => data_get($server, 'uuid'),
]) }}">
<button>Proxy</button>
</a>
@endif
<a wire:navigate class="{{ request()->routeIs('server.resources') ? 'dark:text-white' : '' }}"
<a class="{{ request()->routeIs('server.resources') ? 'dark:text-white' : '' }}"
href="{{ route('server.resources', [
'server_uuid' => data_get($server, 'uuid'),
]) }}">

View File

@@ -1,14 +1,14 @@
@if ($server->proxySet())
<div class="flex flex-col items-start gap-2 min-w-fit">
<a wire:navigate 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' }}"
href="{{ route('server.proxy', $parameters) }}">
<button>Configuration</button>
</a>
<a wire:navigate 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' }}"
href="{{ route('server.proxy.dynamic-confs', $parameters) }}">
<button>Dynamic Configurations</button>
</a>
<a wire:navigate 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' }}"
href="{{ route('server.proxy.logs', $parameters) }}">
<button>Logs</button>
</a>

View File

@@ -1,34 +1,34 @@
<div class="flex flex-col items-start gap-2 min-w-fit">
<a wire:navigate class="menu-item {{ $activeMenu === 'general' ? 'menu-item-active' : '' }}"
<a class="menu-item {{ $activeMenu === 'general' ? 'menu-item-active' : '' }}"
href="{{ route('server.show', ['server_uuid' => $server->uuid]) }}">General</a>
@if ($server->isFunctional())
<a wire:navigate class="menu-item {{ $activeMenu === 'advanced' ? 'menu-item-active' : '' }}"
<a class="menu-item {{ $activeMenu === 'advanced' ? 'menu-item-active' : '' }}"
href="{{ route('server.advanced', ['server_uuid' => $server->uuid]) }}">Advanced
</a>
@endif
<a wire:navigate class="menu-item {{ $activeMenu === 'private-key' ? 'menu-item-active' : '' }}"
<a class="menu-item {{ $activeMenu === 'private-key' ? 'menu-item-active' : '' }}"
href="{{ route('server.private-key', ['server_uuid' => $server->uuid]) }}">Private Key
</a>
@if (!$server->isLocalhost())
<a wire:navigate class="menu-item {{ $activeMenu === 'cloudflare-tunnels' ? 'menu-item-active' : '' }}"
<a class="menu-item {{ $activeMenu === 'cloudflare-tunnels' ? 'menu-item-active' : '' }}"
href="{{ route('server.cloudflare-tunnels', ['server_uuid' => $server->uuid]) }}">Cloudflare
Tunnels</a>
@endif
@if ($server->isFunctional())
<a wire:navigate class="menu-item {{ $activeMenu === 'docker-cleanup' ? 'menu-item-active' : '' }}"
<a class="menu-item {{ $activeMenu === 'docker-cleanup' ? 'menu-item-active' : '' }}"
href="{{ route('server.docker-cleanup', ['server_uuid' => $server->uuid]) }}">Docker Cleanup
</a>
<a wire:navigate class="menu-item {{ $activeMenu === 'destinations' ? 'menu-item-active' : '' }}"
<a class="menu-item {{ $activeMenu === 'destinations' ? 'menu-item-active' : '' }}"
href="{{ route('server.destinations', ['server_uuid' => $server->uuid]) }}">Destinations
</a>
<a wire:navigate class="menu-item {{ $activeMenu === 'log-drains' ? 'menu-item-active' : '' }}"
<a class="menu-item {{ $activeMenu === 'log-drains' ? 'menu-item-active' : '' }}"
href="{{ route('server.log-drains', ['server_uuid' => $server->uuid]) }}">Log
Drains</a>
<a class="menu-item {{ $activeMenu === 'metrics' ? 'menu-item-active' : '' }}"
href="{{ route('server.charts', ['server_uuid' => $server->uuid]) }}">Metrics</a>
@endif
@if (!$server->isLocalhost())
<a wire:navigate class="menu-item {{ $activeMenu === 'danger' ? 'menu-item-active' : '' }}"
<a class="menu-item {{ $activeMenu === 'danger' ? 'menu-item-active' : '' }}"
href="{{ route('server.delete', ['server_uuid' => $server->uuid]) }}">Danger</a>
@endif
</div>

View File

@@ -4,20 +4,18 @@
<div class="navbar-main">
<nav class="flex items-center gap-6 min-h-10 whitespace-nowrap">
<a class="{{ request()->routeIs('settings.index') ? 'dark:text-white' : '' }}"
wire:navigate
href="{{ route('settings.index') }}">
<button>Configuration</button>
</a>
<a class="{{ request()->routeIs('settings.backup') ? 'dark:text-white' : '' }}"
wire:navigate
href="{{ route('settings.backup') }}">
<button>Backup</button>
</a>
<a class="{{ request()->routeIs('settings.email') ? 'dark:text-white' : '' }}" wire:navigate
<a class="{{ request()->routeIs('settings.email') ? 'dark:text-white' : '' }}"
href="{{ route('settings.email') }}">
<button>Transactional Email</button>
</a>
<a class="{{ request()->routeIs('settings.oauth') ? 'dark:text-white' : '' }}" wire:navigate
<a class="{{ request()->routeIs('settings.oauth') ? 'dark:text-white' : '' }}"
href="{{ route('settings.oauth') }}">
<button>OAuth</button>
</a>

View File

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

View File

@@ -30,7 +30,7 @@
</div>
<div class="flex items-center justify-center gap-2 text-xs font-bold">
@if ($project->environments->first())
<a class="hover:underline" wire:navigate wire:click.stop
<a class="hover:underline" wire:click.stop
href="{{ route('project.resource.create', [
'project_uuid' => $project->uuid,
'environment_uuid' => $project->environments->first()->uuid,
@@ -38,7 +38,7 @@
<span class="p-2 font-bold">+ Add Resource</span>
</a>
@endif
<a class="hover:underline" wire:navigate wire:click.stop
<a class="hover:underline" wire:click.stop
href="{{ route('project.edit', ['project_uuid' => $project->uuid]) }}">
Settings
</a>
@@ -54,8 +54,7 @@
<x-modal-input buttonTitle="Add" title="New Project">
<livewire:project.add-empty />
</x-modal-input> your first project or
go to the <a class="underline dark:text-white" wire:navigate
href="{{ route('onboarding') }}">onboarding</a> page.
go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding</a> page.
</div>
</div>
@endif
@@ -66,7 +65,7 @@
@if ($servers->count() > 0)
<div class="grid grid-cols-1 gap-2 xl:grid-cols-2">
@foreach ($servers as $server)
<a wire:navigate href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
<a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
@class([
'gap-2 border cursor-pointer box group',
'border-transparent' => $server->settings->is_reachable,
@@ -103,8 +102,7 @@
<livewire:security.private-key.create from="server" />
</x-modal-input> a private key
or
go to the <a class="underline dark:text-white" wire:navigate
href="{{ route('onboarding') }}">onboarding</a>
go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding</a>
page.
</div>
</div>
@@ -116,8 +114,7 @@
<livewire:server.create />
</x-modal-input> your first server
or
go to the <a class="underline dark:text-white" wire:navigate
href="{{ route('onboarding') }}">onboarding</a>
go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding</a>
page.
</div>
</div>
@@ -142,8 +139,7 @@
<h4 class="pb-2">{{ $serverName }}</h4>
<div class="grid grid-cols-1 gap-2 lg:grid-cols-3">
@foreach ($deployments as $deployment)
<a wire:navigate href="{{ data_get($deployment, 'deployment_url') }}"
@class([
<a href="{{ data_get($deployment, 'deployment_url') }}" @class([
'gap-2 cursor-pointer box group border-l-2 border-dotted',
'dark:border-coolgray-300' => data_get($deployment, 'status') === 'queued',
'border-yellow-500' => data_get($deployment, 'status') === 'in_progress',

View File

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

View File

@@ -9,30 +9,27 @@
<div class="flex flex-col h-full gap-8 pt-6 sm:flex-row">
<div class="flex flex-col items-start gap-2 min-w-fit">
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.application.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>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"
href="{{ route('project.application.advanced', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>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())
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.application.swarm', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Swarm Configuration</a>
href="{{ route('project.application.swarm', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Swarm
Configuration</a>
@endif
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.application.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Environment Variables</a>
href="{{ route('project.application.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Environment
Variables</a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.application.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Persistent Storage</a>
href="{{ route('project.application.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Persistent
Storage</a>
@if ($application->git_based())
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.application.source', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Git Source</a>
href="{{ route('project.application.source', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Git
Source</a>
@endif
<a class="menu-item flex items-center gap-2" wire:current.exact="menu-item-active"
href="{{ route('project.application.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Servers
href="{{ route('project.application.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Servers
@if (str($application->status)->contains('degraded'))
<span title="Some servers are unavailable">
<svg class="w-4 h-4 text-error" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
@@ -51,36 +48,32 @@
@endif
</a>
<a class="menu-item" 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]) }}"
wire:navigate>Scheduled Tasks</a>
href="{{ route('project.application.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Scheduled
Tasks</a>
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.application.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Webhooks</a>
href="{{ route('project.application.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Webhooks</a>
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.application.preview-deployments', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Preview Deployments</a>
href="{{ route('project.application.preview-deployments', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Preview
Deployments</a>
@if ($application->build_pack !== 'dockercompose')
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.application.healthcheck', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Healthcheck</a>
href="{{ route('project.application.healthcheck', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Healthcheck</a>
@endif
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.application.rollback', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>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"
href="{{ route('project.application.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Resource Limits</a>
href="{{ route('project.application.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Resource
Limits</a>
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.application.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Resource Operations</a>
href="{{ route('project.application.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Resource
Operations</a>
<a class="menu-item" 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>
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.application.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>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"
href="{{ route('project.application.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Danger Zone</a>
href="{{ route('project.application.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Danger
Zone</a>
</div>
<div class="w-full">
@if ($currentRoute === 'project.application.configuration')

View File

@@ -3,18 +3,21 @@
<h1>Deployments</h1>
<livewire:project.shared.configuration-checker :resource="$application" />
<livewire:project.application.heading :application="$application" />
<div class="flex flex-col gap-2 pb-10" @if (!$skip) wire:poll.5000ms='reload_deployments' @endif>
<div class="flex flex-col gap-2 pb-10"
@if (!$skip) wire:poll.5000ms='reload_deployments' @endif>
<div class="flex items-end gap-2 pt-4">
<h2>Deployments <span class="text-xs">({{ $deployments_count }})</span></h2>
@if ($deployments_count > 0)
<x-forms.button disabled="{{ !$show_prev }}" wire:click="previous_page('{{ $default_take }}')">
<svg class="w-6 h-6" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m14 6l-6 6l6 6z" />
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="m14 6l-6 6l6 6z" />
</svg>
</x-forms.button>
<x-forms.button disabled="{{ !$show_next }}" wire:click="next_page('{{ $default_take }}')">
<svg class="w-6 h-6" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m10 18l6-6l-6-6z" />
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="m10 18l6-6l-6-6z" />
</svg>
</x-forms.button>
@endif
@@ -28,22 +31,30 @@
@forelse ($deployments as $deployment)
<div @class([
'p-2 border-l-2 bg-white dark:bg-coolgray-100',
'border-blue-500/50 border-dashed' => data_get($deployment, 'status') === 'in_progress',
'border-purple-500/50 border-dashed' => data_get($deployment, 'status') === 'queued',
'border-white border-dashed' => data_get($deployment, 'status') === 'cancelled-by-user',
'border-blue-500/50 border-dashed' =>
data_get($deployment, 'status') === 'in_progress',
'border-purple-500/50 border-dashed' =>
data_get($deployment, 'status') === 'queued',
'border-white border-dashed' =>
data_get($deployment, 'status') === 'cancelled-by-user',
'border-error' => data_get($deployment, 'status') === 'failed',
'border-success' => data_get($deployment, 'status') === 'finished',
])>
<a href="{{ $current_url . '/' . data_get($deployment, 'deployment_uuid') }}" wire:navigate class="block">
<a href="{{ $current_url . '/' . data_get($deployment, 'deployment_uuid') }}" class="block">
<div class="flex flex-col">
<div class="flex items-center gap-2 mb-2">
<span @class([
'px-3 py-1 rounded-md text-xs font-medium shadow-sm',
'bg-blue-100/80 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300' => data_get($deployment, 'status') === 'in_progress',
'bg-purple-100/80 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300' => data_get($deployment, 'status') === 'queued',
'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-200' => data_get($deployment, 'status') === 'failed',
'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-200' => data_get($deployment, 'status') === 'finished',
'bg-gray-100 text-gray-700 dark:bg-gray-600/30 dark:text-gray-300' => data_get($deployment, 'status') === 'cancelled-by-user',
'bg-blue-100/80 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300' =>
data_get($deployment, 'status') === 'in_progress',
'bg-purple-100/80 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300' =>
data_get($deployment, 'status') === 'queued',
'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-200' =>
data_get($deployment, 'status') === 'failed',
'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-200' =>
data_get($deployment, 'status') === 'finished',
'bg-gray-100 text-gray-700 dark:bg-gray-600/30 dark:text-gray-300' =>
data_get($deployment, 'status') === 'cancelled-by-user',
])>
@php
$statusText = match (data_get($deployment, 'status')) {
@@ -51,7 +62,7 @@
'in_progress' => 'In Progress',
'cancelled-by-user' => 'Cancelled',
'queued' => 'Queued',
default => ucfirst(data_get($deployment, 'status'))
default => ucfirst(data_get($deployment, 'status')),
};
@endphp
{{ $statusText }}
@@ -59,13 +70,18 @@
</div>
@if (data_get($deployment, 'status') !== 'queued')
<div class="text-gray-600 dark:text-gray-400 text-sm">
Started: {{ formatDateInServerTimezone(data_get($deployment, 'created_at'), data_get($application, 'destination.server')) }}
Started:
{{ formatDateInServerTimezone(data_get($deployment, 'created_at'), data_get($application, 'destination.server')) }}
@if ($deployment->status !== 'in_progress' && $deployment->status !== 'cancelled-by-user')
<br>Ended: {{ formatDateInServerTimezone(data_get($deployment, 'finished_at'), data_get($application, 'destination.server')) }}
<br>Duration: {{ calculateDuration(data_get($deployment, 'created_at'), data_get($deployment, 'finished_at')) }}
<br>Finished {{ \Carbon\Carbon::parse(data_get($deployment, 'finished_at'))->diffForHumans() }}
<br>Ended:
{{ formatDateInServerTimezone(data_get($deployment, 'finished_at'), data_get($application, 'destination.server')) }}
<br>Duration:
{{ calculateDuration(data_get($deployment, 'created_at'), data_get($deployment, 'finished_at')) }}
<br>Finished
{{ \Carbon\Carbon::parse(data_get($deployment, 'finished_at'))->diffForHumans() }}
@elseif($deployment->status === 'in_progress')
<br>Running for: {{ calculateDuration(data_get($deployment, 'created_at'), now()) }}
<br>Running for:
{{ calculateDuration(data_get($deployment, 'created_at'), now()) }}
@endif
</div>
@endif
@@ -75,14 +91,14 @@
<div x-data="{ expanded: false }">
<div class="flex items-center gap-2">
<span class="font-medium">Commit:</span>
<a wire:navigate.prevent
<a .prevent
href="{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}"
target="_blank"
class="underline">
target="_blank" class="underline">
{{ substr(data_get($deployment, 'commit'), 0, 7) }}
</a>
@if (!$deployment->commitMessage())
<span class="bg-gray-200/70 dark:bg-gray-600/20 px-2 py-0.5 rounded-md text-xs text-gray-800 dark:text-gray-100 border border-gray-400/30">
<span
class="bg-gray-200/70 dark:bg-gray-600/20 px-2 py-0.5 rounded-md text-xs text-gray-800 dark:text-gray-100 border border-gray-400/30">
@if (data_get($deployment, 'is_webhook'))
Webhook
@if (data_get($deployment, 'pull_request_id'))
@@ -101,7 +117,7 @@
@endif
@if ($deployment->commitMessage())
<span class="text-gray-600 dark:text-gray-400">-</span>
<a wire:navigate.prevent
<a .prevent
href="{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}"
target="_blank"
class="text-gray-600 dark:text-gray-400 truncate max-w-md underline">
@@ -110,12 +126,16 @@
@if ($deployment->commitMessage() !== Str::before($deployment->commitMessage(), "\n"))
<button @click="expanded = !expanded"
class="text-gray-600 dark:text-gray-400 flex items-center gap-1">
<svg x-bind:class="{'rotate-180': expanded}" class="w-4 h-4 transition-transform" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m6 9l6 6l6-6"/>
<svg x-bind:class="{ 'rotate-180': expanded }"
class="w-4 h-4 transition-transform" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor"
stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="m6 9l6 6l6-6" />
</svg>
</button>
@endif
<span class="bg-gray-200/70 dark:bg-gray-600/20 px-2 py-0.5 rounded-md text-xs text-gray-800 dark:text-gray-100 border border-gray-400/30">
<span
class="bg-gray-200/70 dark:bg-gray-600/20 px-2 py-0.5 rounded-md text-xs text-gray-800 dark:text-gray-100 border border-gray-400/30">
@if (data_get($deployment, 'is_webhook'))
Webhook
@if (data_get($deployment, 'pull_request_id'))
@@ -134,8 +154,7 @@
@endif
</div>
@if ($deployment->commitMessage())
<div x-show="expanded"
x-transition:enter="transition ease-out duration-200"
<div x-show="expanded" x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 transform -translate-y-2"
x-transition:enter-end="opacity-100 transform translate-y-0"
class="mt-2 ml-4 text-gray-600 dark:text-gray-400">

View File

@@ -3,15 +3,15 @@
<div class="navbar-main">
<nav class="flex flex-shrink-0 gap-6 items-center whitespace-nowrap scrollbar min-h-10">
<a class="{{ request()->routeIs('project.application.configuration') ? 'dark:text-white' : '' }}"
wire:navigate href="{{ route('project.application.configuration', $parameters) }}">
href="{{ route('project.application.configuration', $parameters) }}">
Configuration
</a>
<a class="{{ request()->routeIs('project.application.deployment.index') ? 'dark:text-white' : '' }}"
wire:navigate href="{{ route('project.application.deployment.index', $parameters) }}">
href="{{ route('project.application.deployment.index', $parameters) }}">
<button>Deployments</button>
</a>
<a class="{{ request()->routeIs('project.application.logs') ? 'dark:text-white' : '' }}"
wire:navigate href="{{ route('project.application.logs', $parameters) }}">
href="{{ route('project.application.logs', $parameters) }}">
<button>Logs</button>
</a>
@if (!$application->destination->server->isSwarm())

View File

@@ -8,37 +8,33 @@
<div class="flex flex-col h-full gap-8 pt-6 sm:flex-row">
<div class="flex flex-col items-start gap-2 min-w-fit">
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.database.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>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"
href="{{ route('project.database.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Environment Variables</a>
href="{{ route('project.database.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Environment
Variables</a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.database.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>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"
href="{{ route('project.database.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Persistent Storage</a>
href="{{ route('project.database.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Persistent
Storage</a>
<a class='menu-item' 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
Backups</a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.database.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>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"
href="{{ route('project.database.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Resource Limits</a>
href="{{ route('project.database.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Resource
Limits</a>
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.database.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Resource Operations</a>
href="{{ route('project.database.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Resource
Operations</a>
<a class='menu-item' 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>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.database.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>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"
href="{{ route('project.database.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Danger Zone</a>
href="{{ route('project.database.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Danger
Zone</a>
</div>
<div class="w-full">
@if ($currentRoute === 'project.database.configuration')

View File

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

View File

@@ -3,7 +3,6 @@
@forelse($database->scheduledBackups as $backup)
@if ($type == 'database')
<a class="box"
wire:navigate
href="{{ route('project.database.backup.execution', [...$parameters, 'backup_uuid' => $backup->uuid]) }}">
<div class="flex flex-col">
<div>Frequency: {{ $backup->frequency }}
@@ -13,7 +12,7 @@
</div>
</a>
@else
<div class="box" wire:navigate wire:click="setSelectedBackup('{{ data_get($backup, 'id') }}')">
<div class="box" wire:click="setSelectedBackup('{{ data_get($backup, 'id') }}')">
<div @class([
'border-coollabs' =>
data_get($backup, 'id') === data_get($selectedBackup, 'id'),

View File

@@ -12,7 +12,7 @@
<ol class="flex flex-wrap items-center gap-y-1">
<li class="inline-flex items-center">
<div class="flex items-center">
<a class="text-xs truncate lg:text-sm" wire:navigate
<a class="text-xs truncate lg:text-sm"
href="{{ route('project.show', ['project_uuid' => $project->uuid]) }}">
{{ $project->name }}</a>
<svg aria-hidden="true" class="w-4 h-4 mx-1 font-bold dark:text-warning" fill="currentColor"
@@ -25,7 +25,7 @@
</li>
<li>
<div class="flex items-center">
<a class="text-xs truncate lg:text-sm" wire:navigate
<a class="text-xs truncate lg:text-sm"
href="{{ route('project.resource.index', ['environment_uuid' => $environment->uuid, 'project_uuid' => $project->uuid]) }}">
{{ $environment->name }}
</a>

View File

@@ -24,10 +24,9 @@
<div x-text="project.description"></div>
</div>
</div>
<div class="flex items-center justify-center gap-2 pt-4 pb-2 mr-4 text-xs lg:py-0 lg:justify-normal">
<a class="mx-4 font-bold hover:underline"
wire:navigate
wire:click.stop
<div
class="flex items-center justify-center gap-2 pt-4 pb-2 mr-4 text-xs lg:py-0 lg:justify-normal">
<a class="mx-4 font-bold hover:underline" wire:click.stop
:href="`/project/${project.uuid}/edit`">
Settings
</a>

View File

@@ -6,15 +6,15 @@
<div class="flex items-center gap-2">
<h1>Resources</h1>
@if ($environment->isEmpty())
<a class="button" wire:navigate
<a class="button"
href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}">
Clone
</a>
@else
<a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}"
wire:navigate class="button">+
class="button">+
New</a>
<a class="button" wire:navigate
<a class="button"
href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}">
Clone
</a>
@@ -24,7 +24,7 @@
<nav class="flex pt-2 pb-6">
<ol class="flex items-center">
<li class="inline-flex items-center">
<a class="text-xs truncate lg:text-sm" wire:navigate
<a class="text-xs truncate lg:text-sm"
href="{{ route('project.show', ['project_uuid' => data_get($parameters, 'project_uuid')]) }}">
{{ $project->name }}</a>
</li>
@@ -44,7 +44,7 @@
</nav>
</div>
@if ($environment->isEmpty())
<a wire:navigate 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')]) }}"
class="items-center justify-center box">+ Add New Resource</a>
@else
<div x-data="searchComponent()">
@@ -61,7 +61,7 @@
class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
<template x-for="item in filteredApplications" :key="item.uuid">
<span>
<a class="h-24 box group" wire:navigate :href="item.hrefLink">
<a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col w-full">
<div class="flex gap-2 px-4">
<div class="pb-2 truncate box-title" x-text="item.name"></div>
@@ -90,15 +90,10 @@
<div
class="flex flex-wrap gap-1 pt-1 group-hover:dark:text-white group-hover:text-black group min-h-6">
<template x-for="tag in item.tags">
<a :href="`/tags/${tag.name}`"
wire:navigate
class="tag"
x-text="tag.name">
<a :href="`/tags/${tag.name}`" class="tag" x-text="tag.name">
</a>
</template>
<a :href="`${item.hrefLink}/tags`"
wire:navigate
class="add-tag">
<a :href="`${item.hrefLink}/tags`" class="add-tag">
Add tag
</a>
</div>
@@ -112,7 +107,7 @@
class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
<template x-for="item in filteredDatabases" :key="item.uuid">
<span>
<a class="h-24 box group" wire:navigate :href="item.hrefLink">
<a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col w-full">
<div class="flex gap-2 px-4">
<div class="pb-2 truncate box-title" x-text="item.name"></div>
@@ -141,15 +136,10 @@
<div
class="flex flex-wrap gap-1 pt-1 group-hover:dark:text-white group-hover:text-black group min-h-6">
<template x-for="tag in item.tags">
<a :href="`/tags/${tag.name}`"
wire:navigate
class="tag"
x-text="tag.name">
<a :href="`/tags/${tag.name}`" class="tag" x-text="tag.name">
</a>
</template>
<a :href="`${item.hrefLink}/tags`"
wire:navigate
class="add-tag">
<a :href="`${item.hrefLink}/tags`" class="add-tag">
Add tag
</a>
</div>
@@ -163,7 +153,7 @@
class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
<template x-for="item in filteredServices" :key="item.uuid">
<span>
<a class="h-24 box group" wire:navigate :href="item.hrefLink">
<a class="h-24 box group" :href="item.hrefLink">
<div class="flex flex-col w-full">
<div class="flex gap-2 px-4">
<div class="pb-2 truncate box-title" x-text="item.name"></div>
@@ -192,15 +182,10 @@
<div
class="flex flex-wrap gap-1 pt-1 group-hover:dark:text-white group-hover:text-black group min-h-6">
<template x-for="tag in item.tags">
<a :href="`/tags/${tag.name}`"
wire:navigate
class="tag"
x-text="tag.name">
<a :href="`/tags/${tag.name}`" class="tag" x-text="tag.name">
</a>
</template>
<a :href="`${item.hrefLink}/tags`"
wire:navigate
class="add-tag">
<a :href="`${item.hrefLink}/tags`" class="add-tag">
Add tag
</a>
</div>

View File

@@ -9,31 +9,28 @@
<a class="menu-item sm:min-w-fit" target="_blank" href="{{ $service->documentation() }}">Documentation
<x-external-link /></a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
wire:navigate>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"
href="{{ route('project.service.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
wire:navigate>Environment Variables</a>
href="{{ route('project.service.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Environment
Variables</a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.service.storages', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
wire:navigate>Persistent Storages</a>
href="{{ route('project.service.storages', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Persistent
Storages</a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.service.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
wire:navigate>Scheduled Tasks</a>
href="{{ route('project.service.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Scheduled
Tasks</a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.service.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
wire:navigate>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"
href="{{ route('project.service.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
wire:navigate>Resource Operations</a>
href="{{ route('project.service.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Resource
Operations</a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.service.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
wire:navigate>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"
href="{{ route('project.service.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
wire:navigate>Danger Zone</a>
href="{{ route('project.service.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Danger
Zone</a>
</div>
<div class="w-full">
@if ($currentRoute === 'project.service.configuration')
@@ -95,8 +92,7 @@
</div>
<div class="flex items-center px-4">
<a class="mx-4 text-xs font-bold hover:underline"
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $application->uuid]) }}"
wire:navigate>
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $application->uuid]) }}">
Settings
</a>
@if (str($application->status)->contains('running'))
@@ -144,14 +140,12 @@
<div class="flex items-center px-4">
@if ($database->isBackupSolutionAvailable())
<a class="mx-4 text-xs font-bold hover:underline"
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}#backups"
wire:navigate>
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}#backups">
Backups
</a>
@endif
<a class="mx-4 text-xs font-bold hover:underline"
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}"
wire:navigate>
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}">
Settings
</a>
@if (str($database->status)->contains('running'))
@@ -177,8 +171,8 @@
<div class="pb-4">Persistent storage to preserve data between deployments.</div>
<div class="pb-4 dark:text-warning text-coollabs">If you would like to add a volume, you must add it to
your compose file (<a class="underline"
href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
wire:navigate>General tab</a>).</div>
href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">General
tab</a>).</div>
@foreach ($applications as $application)
<livewire:project.service.storage wire:key="application-{{ $application->id }}"
:resource="$application" />

View File

@@ -3,17 +3,16 @@
<div class="flex flex-col h-full gap-8 pt-6 sm:flex-row">
<div class="flex flex-col items-start gap-2 min-w-fit">
<a class="menu-item"
class="{{ request()->routeIs('project.service.configuration') ? 'menu-item-active' : '' }}" wire:navigate
class="{{ request()->routeIs('project.service.configuration') ? 'menu-item-active' : '' }}"
href="{{ route('project.service.configuration', [...$parameters, 'stack_service_uuid' => null]) }}">
<button><- Back</button>
</a>
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'"
@click.prevent="activeTab = 'general'; window.location.hash = 'general'; if(window.location.search) window.location.search = ''"
wire:navigate href="#">General</a>
href="#">General</a>
@if ($serviceDatabase?->isBackupSolutionAvailable())
<a :class="activeTab === 'backups' && 'menu-item-active'" class="menu-item"
@click.prevent="activeTab = 'backups'; window.location.hash = 'backups'" wire:navigate
href="#backups">Backups</a>
@click.prevent="activeTab = 'backups'; window.location.hash = 'backups'" href="#backups">Backups</a>
@endif
</div>
<div class="w-full">

View File

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

View File

@@ -8,7 +8,7 @@
@elseif(!$resource->destination->server->isMetricsEnabled())
<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"
wire:navigate href="{{ route('server.show', $resource->destination->server->uuid) }}">Server settings</a> to
href="{{ route('server.show', $resource->destination->server->uuid) }}">Server settings</a> to
enable
it.</div>
@else

View File

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

View File

@@ -20,7 +20,6 @@
<div class="gap-2 border border-transparent box group">
<div class="flex flex-1 mx-6">
<a class="flex flex-col justify-center flex-1"
wire:navigate
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="description">
@@ -28,7 +27,6 @@
</a>
<div class="flex items-center justify-center gap-2 text-xs">
<a class="font-bold hover:underline"
wire:navigate
href="{{ route('project.environment.edit', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}">
Settings
</a>

View File

@@ -6,20 +6,12 @@
<x-modal-input buttonTitle="+ Add" title="New Private Key">
<livewire:security.private-key.create />
</x-modal-input>
<x-modal-confirmation
title="Confirm unused SSH Key Deletion?"
buttonTitle="Delete unused SSH Keys"
isErrorButton
submitAction="cleanupUnusedKeys"
:actions="['All unused SSH keys (marked with unused) are permanently deleted.']"
:confirmWithText="false"
:confirmWithPassword="false"
/>
<x-modal-confirmation title="Confirm unused SSH Key Deletion?" buttonTitle="Delete unused SSH Keys" isErrorButton
submitAction="cleanupUnusedKeys" :actions="['All unused SSH keys (marked with unused) are permanently deleted.']" :confirmWithText="false" :confirmWithPassword="false" />
</div>
<div class="grid gap-2 lg:grid-cols-2">
@forelse ($privateKeys as $key)
<a class="box group"
wire:navigate
href="{{ route('security.private-key.show', ['private_key_uuid' => data_get($key, 'uuid')]) }}">
<div class="flex flex-col mx-6">
<div class="box-title">
@@ -28,7 +20,8 @@
<div class="box-description">
{{ $key->description }}
@if (!$key->isInUse())
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-400 text-black">Unused</span>
<span
class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-400 text-black">Unused</span>
@endif
</div>

View File

@@ -11,7 +11,7 @@
<div class="subtitle">All your servers are here.</div>
<div class="grid gap-2 lg:grid-cols-2">
@forelse ($servers as $server)
<a wire:navigate href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
<a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
@class([
'gap-2 border cursor-pointer box group',
'border-transparent' =>

View File

@@ -11,10 +11,10 @@
<h2>{{ data_get($project, 'name') }}</h2>
<div class="pt-0 pb-3">{{ data_get($project, 'description') }}</div>
@forelse ($project->environments as $environment)
<a class="box group" wire:navigate
<a class="box group"
href="{{ route('shared-variables.environment.show', [
'project_uuid' => $project->uuid,
'environment_uuid' => $environment->uuid
'environment_uuid' => $environment->uuid,
]) }}">
<div class="flex flex-col justify-center flex-1 mx-6 ">
<div class="box-title"> {{ $environment->name }}</div>

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,7 @@
<h4 class="py-4">{{ $server_name }}</h4>
<div class="grid grid-cols-1 gap-2">
@foreach ($deployments as $deployment)
<a wire:navigate href="{{ data_get($deployment, 'deployment_url') }}" @class([
<a 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',
'dark:border-coolgray-300' => data_get($deployment, 'status') === 'queued',
'dark:border-yellow-500' =>

View File

@@ -7,7 +7,7 @@
</div>
<div class="flex flex-wrap gap-2 ">
@forelse ($tags as $oneTag)
<a wire:navigate :class="{{ $tag?->id == $oneTag->id }} && 'dark:bg-coollabs hover:bg-coollabs-100'"
<a :class="{{ $tag?->id == $oneTag->id }} && 'dark:bg-coollabs hover:bg-coollabs-100'"
class="w-64 box-without-bg dark:bg-coolgray-100 dark:text-white font-bold"
href="{{ route('tags.show', ['tagName' => $oneTag->name]) }}">{{ $oneTag->name }}</a>
@empty
@@ -34,7 +34,7 @@
<div class="grid grid-cols-1 gap-2 pt-4 lg:grid-cols-2 xl:grid-cols-3">
@if (isset($applications) && count($applications) > 0)
@foreach ($applications as $application)
<a wire:navigate href="{{ $application->link() }}" class="box group">
<a href="{{ $application->link() }}" class="box group">
<div class="flex flex-col">
<div class="box-title">
{{ $application->project()->name }}/{{ $application->environment->name }}
@@ -47,7 +47,7 @@
@endif
@if (isset($services) && count($services) > 0)
@foreach ($services as $service)
<a wire:navigate href="{{ $service->link() }}" class="flex flex-col box group">
<a href="{{ $service->link() }}" class="flex flex-col box group">
<div class="flex flex-col">
<div class="box-title">
{{ $service->project()->name }}/{{ $service->environment->name }}
@@ -70,7 +70,7 @@
<h4 class="py-4">{{ $serverName }}</h4>
<div class="grid grid-cols-1 gap-2 lg:grid-cols-3">
@foreach ($deployments as $deployment)
<a wire:navigate href="{{ data_get($deployment, 'deployment_url') }}" @class([
<a href="{{ data_get($deployment, 'deployment_url') }}" @class([
'gap-2 cursor-pointer box group border-l-2 border-dotted',
'dark:border-coolgray-300' => data_get($deployment, 'status') === 'queued',
'border-yellow-500' => data_get($deployment, 'status') === 'in_progress',

View File

@@ -12,7 +12,7 @@
<div class="grid gap-2 lg:grid-cols-2">
@forelse ($sources as $source)
@if ($source->getMorphClass() === 'App\Models\GithubApp')
<a class="flex gap-4 text-center hover:no-underline box group" wire:navigate
<a class="flex gap-4 text-center hover:no-underline box group"
href="{{ route('source.github.show', ['github_app_uuid' => data_get($source, 'uuid')]) }}">
<x-git-icon class="dark:text-white w-9 h-9" git="{{ $source->getMorphClass() }}" />
<div class="text-left group-hover:dark:text-white">
@@ -24,7 +24,7 @@
</a>
@endif
@if ($source->getMorphClass() === 'App\Models\GitlabApp')
<a class="flex gap-4 text-center hover:no-underline box group" wire:navigate
<a class="flex gap-4 text-center hover:no-underline box group"
href="{{ route('source.gitlab.show', ['gitlab_app_uuid' => data_get($source, 'uuid')]) }}">
<x-git-icon class="dark:text-white w-9 h-9" git="{{ $source->getMorphClass() }}" />
<div class="text-left group-hover:dark:text-white">

View File

@@ -1,10 +1,10 @@
{
"coolify": {
"v4": {
"version": "4.0.0-beta.414"
"version": "4.0.0-beta.415"
},
"nightly": {
"version": "4.0.0-beta.415"
"version": "4.0.0-beta.416"
},
"helper": {
"version": "1.0.8"