v4.0.0-beta.415 (#5722)

* feat(README): add InterviewPal sponsorship link and corresponding SVG icon

* chore(versions): update coolify version to 4.0.0-beta.413 and nightly version to 4.0.0-beta.414 in configuration files

* fix(terminal): enhance WebSocket client verification with authorized IPs in terminal server

* chore(versions): update realtime version to 1.0.8 in versions.json

* chore(versions): update realtime version to 1.0.8 in versions.json

* chore(docker): update soketi image version to 1.0.8 in production configuration files

* chore(versions): update coolify version to 4.0.0-beta.414 and nightly version to 4.0.0-beta.415 in configuration files

* fix(ApplicationDeploymentJob): ensure source is an object before checking GitHub app properties

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

* fix(ui): Remove required attribute from image input in service application view

* fix(ui): Change application image validation to be nullable in service application view

* fix(Server): Correct proxy path formatting for Traefik proxy type
This commit is contained in:
Andras Bacsai
2025-04-29 10:54:30 +02:00
committed by GitHub
parent 43e965010f
commit 1227448e53
45 changed files with 238 additions and 279 deletions

View File

@@ -51,7 +51,7 @@ class Dashboard extends Component
public function navigateToProject($projectUuid) 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() public function render()

View File

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

View File

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

View File

@@ -23,7 +23,7 @@ class ServiceApplicationView extends Component
'application.human_name' => 'nullable', 'application.human_name' => 'nullable',
'application.description' => 'nullable', 'application.description' => 'nullable',
'application.fqdn' => 'nullable', 'application.fqdn' => 'nullable',
'application.image' => 'required', 'application.image' => 'string|nullable',
'application.exclude_from_status' => 'required|boolean', 'application.exclude_from_status' => 'required|boolean',
'application.required_fqdn' => 'required|boolean', 'application.required_fqdn' => 'required|boolean',
'application.is_log_drain_enabled' => 'nullable|boolean', 'application.is_log_drain_enabled' => 'nullable|boolean',

View File

@@ -488,7 +488,7 @@ $schema://$host {
$proxy_path = "$base_path/proxy"; $proxy_path = "$base_path/proxy";
if ($proxyType === ProxyTypes::TRAEFIK->value) { if ($proxyType === ProxyTypes::TRAEFIK->value) {
$proxy_path = '/'; $proxy_path = $proxy_path.'/';
} elseif ($proxyType === ProxyTypes::CADDY->value) { } elseif ($proxyType === ProxyTypes::CADDY->value) {
$proxy_path = $proxy_path.'/caddy'; $proxy_path = $proxy_path.'/caddy';
} elseif ($proxyType === ProxyTypes::NGINX->value) { } elseif ($proxyType === ProxyTypes::NGINX->value) {

View File

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

View File

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

View File

@@ -123,7 +123,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="/" wire:navigate <a title="Dashboard" href="/"
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">
@@ -134,7 +134,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Projects" wire:navigate <a title="Projects"
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"
@@ -149,7 +149,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Servers" wire:navigate <a title="Servers"
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"
@@ -168,7 +168,7 @@
</li> </li>
<li> <li>
<a title="Sources" wire:navigate <a title="Sources"
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">
@@ -179,7 +179,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Destinations" wire:navigate <a title="Destinations"
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') }}">
@@ -192,7 +192,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="S3 Storages" wire:navigate <a title="S3 Storages"
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">
@@ -207,7 +207,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Shared variables" wire:navigate <a title="Shared variables"
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">
@@ -222,7 +222,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Notifications" wire:navigate <a title="Notifications"
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">
@@ -234,7 +234,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Keys & Tokens" wire:navigate <a title="Keys & Tokens"
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">
@@ -246,7 +246,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Tags" wire:navigate <a title="Tags"
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">
@@ -275,7 +275,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Profile" wire:navigate <a title="Profile"
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"
@@ -290,7 +290,7 @@
</a> </a>
</li> </li>
<li> <li>
<a title="Teams" wire:navigate <a title="Teams"
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"
@@ -309,7 +309,7 @@
</li> </li>
@if (isCloud()) @if (isCloud())
<li> <li>
<a title="Subscription" wire:navigate <a title="Subscription"
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">
@@ -324,7 +324,7 @@
@if (isInstanceAdmin()) @if (isInstanceAdmin())
<li> <li>
<a title="Settings" wire:navigate <a title="Settings"
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"
@@ -343,7 +343,7 @@
@if (isCloud() || isDev()) @if (isCloud() || isDev())
@if (isInstanceAdmin() || session('impersonating')) @if (isInstanceAdmin() || session('impersonating'))
<li> <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" <svg class="text-pink-600 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"
@@ -363,7 +363,7 @@
@endpersist @endpersist
@endif @endif
<li> <li>
<a title="Onboarding" wire:navigate <a title="Onboarding"
class="{{ request()->is('onboarding*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('onboarding*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('onboarding') }}"> href="{{ route('onboarding') }}">
<svg class="icon" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg"> <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"> <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' : '' }}"
wire:navigate
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' : '' }}"
wire:navigate
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' : '' }}"
wire:navigate
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' : '' }}"
wire:navigate
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' : '' }}"
wire:navigate
href="{{ route('notifications.pushover') }}"> href="{{ route('notifications.pushover') }}">
<button>Pushover</button> <button>Pushover</button>
</a> </a>

View File

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

View File

@@ -3,10 +3,10 @@
<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 wire:navigate href="{{ route('security.private-key.index') }}"> <a href="{{ route('security.private-key.index') }}">
<button>Private Keys</button> <button>Private Keys</button>
</a> </a>
<a wire:navigate href="{{ route('security.api-tokens') }}"> <a href="{{ route('security.api-tokens') }}">
<button>API tokens</button> <button>API tokens</button>
</a> </a>
</nav> </nav>

View File

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

View File

@@ -1,14 +1,14 @@
@if ($server->proxySet()) @if ($server->proxySet())
<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 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) }}"> href="{{ route('server.proxy', $parameters) }}">
<button>Configuration</button> <button>Configuration</button>
</a> </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) }}"> href="{{ route('server.proxy.dynamic-confs', $parameters) }}">
<button>Dynamic Configurations</button> <button>Dynamic Configurations</button>
</a> </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) }}"> href="{{ route('server.proxy.logs', $parameters) }}">
<button>Logs</button> <button>Logs</button>
</a> </a>

View File

@@ -1,34 +1,34 @@
<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 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> href="{{ route('server.show', ['server_uuid' => $server->uuid]) }}">General</a>
@if ($server->isFunctional()) @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 href="{{ route('server.advanced', ['server_uuid' => $server->uuid]) }}">Advanced
</a> </a>
@endif @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 href="{{ route('server.private-key', ['server_uuid' => $server->uuid]) }}">Private Key
</a> </a>
@if (!$server->isLocalhost()) @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 href="{{ route('server.cloudflare-tunnels', ['server_uuid' => $server->uuid]) }}">Cloudflare
Tunnels</a> Tunnels</a>
@endif @endif
@if ($server->isFunctional()) @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 href="{{ route('server.docker-cleanup', ['server_uuid' => $server->uuid]) }}">Docker Cleanup
</a> </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 href="{{ route('server.destinations', ['server_uuid' => $server->uuid]) }}">Destinations
</a> </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 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' : '' }}"
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 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> href="{{ route('server.delete', ['server_uuid' => $server->uuid]) }}">Danger</a>
@endif @endif
</div> </div>

View File

@@ -4,20 +4,18 @@
<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' : '' }}"
wire:navigate
href="{{ route('settings.index') }}"> href="{{ route('settings.index') }}">
<button>Configuration</button> <button>Configuration</button>
</a> </a>
<a class="{{ request()->routeIs('settings.backup') ? 'dark:text-white' : '' }}" <a class="{{ request()->routeIs('settings.backup') ? 'dark:text-white' : '' }}"
wire:navigate
href="{{ route('settings.backup') }}"> href="{{ route('settings.backup') }}">
<button>Backup</button> <button>Backup</button>
</a> </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') }}"> href="{{ route('settings.email') }}">
<button>Transactional Email</button> <button>Transactional Email</button>
</a> </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') }}"> href="{{ route('settings.oauth') }}">
<button>OAuth</button> <button>OAuth</button>
</a> </a>

View File

@@ -8,16 +8,15 @@
<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' : '' }}" wire:navigate <a class="{{ request()->routeIs('team.index') ? 'dark:text-white' : '' }}" href="{{ route('team.index') }}">
href="{{ route('team.index') }}">
<button>General</button> <button>General</button>
</a> </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') }}"> href="{{ route('team.member.index') }}">
<button>Members</button> <button>Members</button>
</a> </a>
@if (isInstanceAdmin()) @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') }}"> href="{{ route('team.admin-view') }}">
<button>Admin View</button> <button>Admin View</button>
</a> </a>

View File

@@ -30,7 +30,7 @@
</div> </div>
<div class="flex items-center justify-center gap-2 text-xs font-bold"> <div class="flex items-center justify-center gap-2 text-xs font-bold">
@if ($project->environments->first()) @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', [ 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,
@@ -38,7 +38,7 @@
<span class="p-2 font-bold">+ Add Resource</span> <span class="p-2 font-bold">+ Add Resource</span>
</a> </a>
@endif @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]) }}"> href="{{ route('project.edit', ['project_uuid' => $project->uuid]) }}">
Settings Settings
</a> </a>
@@ -54,8 +54,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" wire:navigate go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding</a> page.
href="{{ route('onboarding') }}">onboarding</a> page.
</div> </div>
</div> </div>
@endif @endif
@@ -66,7 +65,7 @@
@if ($servers->count() > 0) @if ($servers->count() > 0)
<div class="grid grid-cols-1 gap-2 xl:grid-cols-2"> <div class="grid grid-cols-1 gap-2 xl:grid-cols-2">
@foreach ($servers as $server) @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([ @class([
'gap-2 border cursor-pointer box group', 'gap-2 border cursor-pointer box group',
'border-transparent' => $server->settings->is_reachable, 'border-transparent' => $server->settings->is_reachable,
@@ -103,8 +102,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" wire:navigate go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding</a>
href="{{ route('onboarding') }}">onboarding</a>
page. page.
</div> </div>
</div> </div>
@@ -116,8 +114,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" wire:navigate go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding</a>
href="{{ route('onboarding') }}">onboarding</a>
page. page.
</div> </div>
</div> </div>
@@ -142,12 +139,11 @@
<h4 class="pb-2">{{ $serverName }}</h4> <h4 class="pb-2">{{ $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 wire:navigate href="{{ data_get($deployment, 'deployment_url') }}" <a href="{{ data_get($deployment, 'deployment_url') }}" @class([
@class([ 'gap-2 cursor-pointer box group border-l-2 border-dotted',
'gap-2 cursor-pointer box 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-yellow-500' => data_get($deployment, 'status') === 'in_progress',
'border-yellow-500' => data_get($deployment, 'status') === 'in_progress', ])>
])>
<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($deployment, 'application_name') }} {{ data_get($deployment, 'application_name') }}

View File

@@ -15,7 +15,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="box group" wire:navigate <a class="box group"
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>
@@ -24,7 +24,7 @@
</a> </a>
@endif @endif
@if ($destination->getMorphClass() === 'App\Models\SwarmDocker') @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')]) }}"> 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

@@ -9,30 +9,27 @@
<div class="flex flex-col h-full gap-8 pt-6 sm:flex-row"> <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"> <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' wire:current.exact="menu-item-active"
href="{{ route('project.application.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" href="{{ route('project.application.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">General</a>
wire:navigate>General</a>
<a class='menu-item' wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.application.advanced', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Advanced</a>
wire:navigate>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" wire:current.exact="menu-item-active"
href="{{ route('project.application.swarm', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" href="{{ route('project.application.swarm', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Swarm
wire:navigate>Swarm Configuration</a> Configuration</a>
@endif @endif
<a class='menu-item' wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.application.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Environment
wire:navigate>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"
href="{{ route('project.application.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" href="{{ route('project.application.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Persistent
wire:navigate>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' wire:current.exact="menu-item-active"
href="{{ route('project.application.source', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" href="{{ route('project.application.source', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Git
wire:navigate>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" wire:current.exact="menu-item-active"
href="{{ route('project.application.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" href="{{ route('project.application.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Servers
wire:navigate>Servers
@if (str($application->status)->contains('degraded')) @if (str($application->status)->contains('degraded'))
<span title="Some servers are unavailable"> <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"> <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 @endif
</a> </a>
<a class="menu-item" wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.application.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Scheduled
wire:navigate>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"
href="{{ route('project.application.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" href="{{ route('project.application.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Webhooks</a>
wire:navigate>Webhooks</a>
<a class="menu-item" wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.application.preview-deployments', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Preview
wire:navigate>Preview Deployments</a> Deployments</a>
@if ($application->build_pack !== 'dockercompose') @if ($application->build_pack !== 'dockercompose')
<a class="menu-item" wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.application.healthcheck', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Healthcheck</a>
wire:navigate>Healthcheck</a>
@endif @endif
<a class="menu-item" wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.application.rollback', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Rollback</a>
wire:navigate>Rollback</a>
<a class="menu-item" wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.application.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Resource
wire:navigate>Resource Limits</a> Limits</a>
<a class="menu-item" wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.application.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Resource
wire:navigate>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"
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" wire:current.exact="menu-item-active"
href="{{ route('project.application.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" href="{{ route('project.application.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Tags</a>
wire:navigate>Tags</a>
<a class="menu-item" wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.application.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}">Danger
wire:navigate>Danger Zone</a> Zone</a>
</div> </div>
<div class="w-full"> <div class="w-full">
@if ($currentRoute === 'project.application.configuration') @if ($currentRoute === 'project.application.configuration')

View File

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

View File

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

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 h-full gap-8 pt-6 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' wire:current.exact="menu-item-active"
href="{{ route('project.database.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}" href="{{ route('project.database.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">General</a>
wire:navigate>General</a>
<a class='menu-item' wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.database.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Environment
wire:navigate>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"
href="{{ route('project.database.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}" href="{{ route('project.database.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Servers</a>
wire:navigate>Servers</a>
<a class='menu-item' wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.database.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Persistent
wire:navigate>Persistent Storage</a> Storage</a>
<a class='menu-item' wire:current.exact="menu-item-active" <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 href="{{ route('project.database.import-backups', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Import
Backups</a> Backups</a>
<a class='menu-item' wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.database.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Webhooks</a>
wire:navigate>Webhooks</a>
<a class="menu-item" wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.database.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Resource
wire:navigate>Resource Limits</a> Limits</a>
<a class="menu-item" wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.database.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Resource
wire:navigate>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"
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' wire:current.exact="menu-item-active"
href="{{ route('project.database.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}" href="{{ route('project.database.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Tags</a>
wire:navigate>Tags</a>
<a class='menu-item' wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.database.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Danger
wire:navigate>Danger Zone</a> Zone</a>
</div> </div>
<div class="w-full"> <div class="w-full">
@if ($currentRoute === 'project.database.configuration') @if ($currentRoute === 'project.database.configuration')

View File

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

View File

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

View File

@@ -12,7 +12,7 @@
<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" wire:navigate <a class="text-xs truncate lg:text-sm"
href="{{ route('project.show', ['project_uuid' => $project->uuid]) }}"> href="{{ route('project.show', ['project_uuid' => $project->uuid]) }}">
{{ $project->name }}</a> {{ $project->name }}</a>
<svg aria-hidden="true" class="w-4 h-4 mx-1 font-bold dark:text-warning" fill="currentColor" <svg aria-hidden="true" class="w-4 h-4 mx-1 font-bold dark:text-warning" fill="currentColor"
@@ -25,7 +25,7 @@
</li> </li>
<li> <li>
<div class="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.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

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

View File

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

View File

@@ -9,31 +9,28 @@
<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"
href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}" href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">General</a>
wire:navigate>General</a>
<a class='menu-item' wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.service.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Environment
wire:navigate>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"
href="{{ route('project.service.storages', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}" href="{{ route('project.service.storages', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Persistent
wire:navigate>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"
href="{{ route('project.service.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}" href="{{ route('project.service.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Scheduled
wire:navigate>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"
href="{{ route('project.service.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}" href="{{ route('project.service.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Webhooks</a>
wire:navigate>Webhooks</a>
<a class='menu-item' wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.service.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Resource
wire:navigate>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"
href="{{ route('project.service.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}" href="{{ route('project.service.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Tags</a>
wire:navigate>Tags</a>
<a class='menu-item' wire:current.exact="menu-item-active" <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]) }}" href="{{ route('project.service.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">Danger
wire:navigate>Danger Zone</a> Zone</a>
</div> </div>
<div class="w-full"> <div class="w-full">
@if ($currentRoute === 'project.service.configuration') @if ($currentRoute === 'project.service.configuration')
@@ -95,8 +92,7 @@
</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"
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]) }}">
wire:navigate>
Settings Settings
</a> </a>
@if (str($application->status)->contains('running')) @if (str($application->status)->contains('running'))
@@ -144,14 +140,12 @@
<div class="flex items-center px-4"> <div class="flex items-center px-4">
@if ($database->isBackupSolutionAvailable()) @if ($database->isBackupSolutionAvailable())
<a class="mx-4 text-xs font-bold hover:underline" <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" 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>
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"
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]) }}">
wire:navigate>
Settings Settings
</a> </a>
@if (str($database->status)->contains('running')) @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">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 <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" your compose file (<a class="underline"
href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}" href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}">General
wire:navigate>General tab</a>).</div> tab</a>).</div>
@foreach ($applications as $application) @foreach ($applications as $application)
<livewire:project.service.storage wire:key="application-{{ $application->id }}" <livewire:project.service.storage wire:key="application-{{ $application->id }}"
:resource="$application" /> :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 h-full gap-8 pt-6 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' : '' }}" wire:navigate class="{{ request()->routeIs('project.service.configuration') ? 'menu-item-active' : '' }}"
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>
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'" <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 = ''" @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()) @if ($serviceDatabase?->isBackupSolutionAvailable())
<a :class="activeTab === 'backups' && 'menu-item-active'" class="menu-item" <a :class="activeTab === 'backups' && 'menu-item-active'" class="menu-item"
@click.prevent="activeTab = 'backups'; window.location.hash = 'backups'" wire:navigate @click.prevent="activeTab = 'backups'; window.location.hash = 'backups'" href="#backups">Backups</a>
href="#backups">Backups</a>
@endif @endif
</div> </div>
<div class="w-full"> <div class="w-full">

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 flex-shrink-0 gap-6 items-center whitespace-nowrap scrollbar min-h-10"> <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) }}"> href="{{ route('project.service.configuration', $parameters) }}">
<button>Configuration</button> <button>Configuration</button>
</a> </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) }}"> href="{{ route('project.service.logs', $parameters) }}">
<button>Logs</button> <button>Logs</button>
</a> </a>
@@ -129,7 +129,7 @@
<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"
href="{{ route('project.service.environment-variables', $parameters) }}" wire:navigate> href="{{ route('project.service.environment-variables', $parameters) }}">
Required environment variables missing.</a> Required environment variables missing.</a>
</div> </div>
</div> </div>

View File

@@ -30,7 +30,7 @@
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io,https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. "></x-forms.input> helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io,https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. "></x-forms.input>
@endif @endif
@endif @endif
<x-forms.input required <x-forms.input
helper="You can change the image you would like to deploy.<br><br><span class='dark:text-warning'>WARNING. You could corrupt your data. Only do it if you know what you are doing.</span>" helper="You can change the image you would like to deploy.<br><br><span class='dark:text-warning'>WARNING. You could corrupt your data. Only do it if you know what you are doing.</span>"
label="Image" id="application.image"></x-forms.input> label="Image" id="application.image"></x-forms.input>
</div> </div>

View File

@@ -8,7 +8,7 @@
@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" <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 enable
it.</div> it.</div>
@else @else

View File

@@ -12,7 +12,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="box" wire:navigate <a class="box"
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 }}
@@ -27,7 +27,7 @@
</span> </span>
</a> </a>
@elseif ($resource->type() == 'service') @elseif ($resource->type() == 'service')
<a class="box" wire:navigate <a class="box"
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

@@ -20,7 +20,6 @@
<div class="gap-2 border border-transparent box group"> <div class="gap-2 border border-transparent box 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"
wire:navigate
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">
@@ -28,7 +27,6 @@
</a> </a>
<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"
wire:navigate
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

@@ -1,25 +1,17 @@
<div> <div>
<x-security.navbar /> <x-security.navbar />
<div class="flex gap-2"> <div class="flex gap-2">
<h2 class="pb-4">Private Keys</h2> <h2 class="pb-4">Private Keys</h2>
<x-modal-input buttonTitle="+ Add" title="New Private Key"> <x-modal-input buttonTitle="+ Add" title="New Private Key">
<livewire:security.private-key.create /> <livewire:security.private-key.create />
</x-modal-input> </x-modal-input>
<x-modal-confirmation <x-modal-confirmation title="Confirm unused SSH Key Deletion?" buttonTitle="Delete unused SSH Keys" isErrorButton
title="Confirm unused SSH Key Deletion?" submitAction="cleanupUnusedKeys" :actions="['All unused SSH keys (marked with unused) are permanently deleted.']" :confirmWithText="false" :confirmWithPassword="false" />
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>
<div class="grid gap-2 lg:grid-cols-2"> <div class="grid gap-2 lg:grid-cols-2">
@forelse ($privateKeys as $key) @forelse ($privateKeys as $key)
<a class="box group" <a class="box group"
wire:navigate
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')]) }}">
<div class="flex flex-col mx-6"> <div class="flex flex-col mx-6">
<div class="box-title"> <div class="box-title">
@@ -27,15 +19,16 @@
</div> </div>
<div class="box-description"> <div class="box-description">
{{ $key->description }} {{ $key->description }}
@if (!$key->isInUse()) @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 @endif
</div> </div>
</div> </div>
</a> </a>
@empty @empty
<div>No private keys found.</div> <div>No private keys found.</div>
@endforelse @endforelse
</div> </div>
</div> </div>

View File

@@ -11,7 +11,7 @@
<div class="subtitle">All your servers are here.</div> <div class="subtitle">All your servers are here.</div>
<div class="grid gap-2 lg:grid-cols-2"> <div class="grid gap-2 lg:grid-cols-2">
@forelse ($servers as $server) @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([ @class([
'gap-2 border cursor-pointer box group', 'gap-2 border cursor-pointer box group',
'border-transparent' => 'border-transparent' =>

View File

@@ -11,10 +11,10 @@
<h2>{{ data_get($project, 'name') }}</h2> <h2>{{ data_get($project, 'name') }}</h2>
<div class="pt-0 pb-3">{{ data_get($project, 'description') }}</div> <div class="pt-0 pb-3">{{ data_get($project, 'description') }}</div>
@forelse ($project->environments as $environment) @forelse ($project->environments as $environment)
<a class="box group" wire:navigate <a class="box group"
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,
]) }}"> ]) }}">
<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>

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"> <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="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 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="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 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="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,6 @@
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
@forelse ($projects as $project) @forelse ($projects as $project)
<a class="box group" <a class="box group"
wire:navigate
href="{{ route('shared-variables.project.show', ['project_uuid' => data_get($project, 'uuid')]) }}"> href="{{ route('shared-variables.project.show', ['project_uuid' => data_get($project, 'uuid')]) }}">
<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>

View File

@@ -159,7 +159,7 @@
{{ data_get($resource, 'environment.name') }} {{ data_get($resource, 'environment.name') }}
</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="" wire:navigate class=""
href="{{ $resource->link() }}">{{ $resource->name }} href="{{ $resource->link() }}">{{ $resource->name }}
<x-internal-link /></a> <x-internal-link /></a>
</td> </td>

View File

@@ -11,7 +11,7 @@
<div class="subtitle">S3 storages for backups.</div> <div class="subtitle">S3 storages for backups.</div>
<div class="grid gap-2 lg:grid-cols-2"> <div class="grid gap-2 lg:grid-cols-2">
@forelse ($s3 as $storage) @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="flex flex-col mx-6">
<div class="box-title"> <div class="box-title">
{{ $storage->name }} {{ $storage->name }}

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 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', '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-yellow-500' => 'dark:border-yellow-500' =>

View File

@@ -7,7 +7,7 @@
</div> </div>
<div class="flex flex-wrap gap-2 "> <div class="flex flex-wrap gap-2 ">
@forelse ($tags as $oneTag) @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" 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> href="{{ route('tags.show', ['tagName' => $oneTag->name]) }}">{{ $oneTag->name }}</a>
@empty @empty
@@ -34,7 +34,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 wire:navigate href="{{ $application->link() }}" class="box group"> <a href="{{ $application->link() }}" class="box group">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="box-title"> <div class="box-title">
{{ $application->project()->name }}/{{ $application->environment->name }} {{ $application->project()->name }}/{{ $application->environment->name }}
@@ -47,7 +47,7 @@
@endif @endif
@if (isset($services) && count($services) > 0) @if (isset($services) && count($services) > 0)
@foreach ($services as $service) @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="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 +70,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 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', 'gap-2 cursor-pointer box 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-yellow-500' => data_get($deployment, 'status') === 'in_progress', 'border-yellow-500' => data_get($deployment, 'status') === 'in_progress',

View File

@@ -12,7 +12,7 @@
<div class="grid gap-2 lg:grid-cols-2"> <div class="grid gap-2 lg:grid-cols-2">
@forelse ($sources as $source) @forelse ($sources as $source)
@if ($source->getMorphClass() === 'App\Models\GithubApp') @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')]) }}"> 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() }}" /> <x-git-icon class="dark:text-white w-9 h-9" git="{{ $source->getMorphClass() }}" />
<div class="text-left group-hover:dark:text-white"> <div class="text-left group-hover:dark:text-white">
@@ -24,7 +24,7 @@
</a> </a>
@endif @endif
@if ($source->getMorphClass() === 'App\Models\GitlabApp') @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')]) }}"> 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() }}" /> <x-git-icon class="dark:text-white w-9 h-9" git="{{ $source->getMorphClass() }}" />
<div class="text-left group-hover:dark:text-white"> <div class="text-left group-hover:dark:text-white">

View File

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