Merge branch 'next' into fix-postgres-init-scripts
This commit is contained in:
@@ -6,11 +6,11 @@
|
||||
|
||||
html,
|
||||
body {
|
||||
@apply h-full bg-neutral-50 text-neutral-800 dark:bg-base dark:text-neutral-400 w-full;
|
||||
@apply min-h-full bg-neutral-50 dark:bg-base dark:text-neutral-400 w-full;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply text-sm antialiased scrollbar;
|
||||
@apply text-sm antialiased scrollbar min-h-screen;
|
||||
}
|
||||
|
||||
.apexcharts-tooltip {
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
@endisset>
|
||||
|
||||
{{ $slot }}
|
||||
@if ($attributes->whereStartsWith('wire:click')->first())
|
||||
<x-loading-on-button wire:target="{{ $attributes->whereStartsWith('wire:click')->first() }}"
|
||||
wire:loading.delay />
|
||||
@elseif($attributes->whereStartsWith('wire:target')->first())
|
||||
<x-loading-on-button wire:target="{{ $attributes->whereStartsWith('wire:target')->first() }}"
|
||||
wire:loading.delay />
|
||||
@if ($showLoadingIndicator)
|
||||
@if ($attributes->whereStartsWith('wire:click')->first())
|
||||
<x-loading-on-button wire:target="{{ $attributes->whereStartsWith('wire:click')->first() }}"
|
||||
wire:loading.delay />
|
||||
@elseif($attributes->whereStartsWith('wire:target')->first())
|
||||
<x-loading-on-button wire:target="{{ $attributes->whereStartsWith('wire:target')->first() }}"
|
||||
wire:loading.delay />
|
||||
@endif
|
||||
@endif
|
||||
</button>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
@if (isset($text))
|
||||
<div>{{ $text }}</div>
|
||||
@endif
|
||||
<svg class="w-4 h-4 mx-1 ml-3 text-coollabs dark:text-warning animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
<svg class="w-4 h-4 mx-1 ml-3 text-coollabs dark:text-warning animate-spin" xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
|
||||
|
||||
@@ -340,17 +340,19 @@
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if (isCloud() && isInstanceAdmin())
|
||||
<li>
|
||||
<a title="Admin" class="menu-item" href="/admin">
|
||||
<svg class="text-pink-600 icon" viewBox="0 0 256 256"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M177.62 159.6a52 52 0 0 1-34 34a12.2 12.2 0 0 1-3.6.55a12 12 0 0 1-3.6-23.45a28 28 0 0 0 18.32-18.32a12 12 0 0 1 22.9 7.2ZM220 144a92 92 0 0 1-184 0c0-28.81 11.27-58.18 33.48-87.28a12 12 0 0 1 17.9-1.33l19.69 19.11L127 19.89a12 12 0 0 1 18.94-5.12C168.2 33.25 220 82.85 220 144m-24 0c0-41.71-30.61-78.39-52.52-99.29l-20.21 55.4a12 12 0 0 1-19.63 4.5L80.71 82.36C67 103.38 60 124.06 60 144a68 68 0 0 0 136 0" />
|
||||
</svg>
|
||||
Admin
|
||||
</a>
|
||||
</li>
|
||||
@if (isCloud() || isDev())
|
||||
@if (isInstanceAdmin() || session('impersonating'))
|
||||
<li>
|
||||
<a title="Admin" class="menu-item" href="/admin">
|
||||
<svg class="text-pink-600 icon" viewBox="0 0 256 256"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M177.62 159.6a52 52 0 0 1-34 34a12.2 12.2 0 0 1-3.6.55a12 12 0 0 1-3.6-23.45a28 28 0 0 0 18.32-18.32a12 12 0 0 1 22.9 7.2ZM220 144a92 92 0 0 1-184 0c0-28.81 11.27-58.18 33.48-87.28a12 12 0 0 1 17.9-1.33l19.69 19.11L127 19.89a12 12 0 0 1 18.94-5.12C168.2 33.25 220 82.85 220 144m-24 0c0-41.71-30.61-78.39-52.52-99.29l-20.21 55.4a12 12 0 0 1-19.63 4.5L80.71 82.36C67 103.38 60 124.06 60 144a68 68 0 0 0 136 0" />
|
||||
</svg>
|
||||
Admin
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@endif
|
||||
<div class="flex-1"></div>
|
||||
@if (isInstanceAdmin() && !isCloud())
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
<li>
|
||||
<div class="flex items-center">
|
||||
<a class="text-xs truncate lg:text-sm"
|
||||
href="{{ route('project.resource.index', ['environment_name' => data_get($resource, 'environment.name'), 'project_uuid' => data_get($resource, 'environment.project.uuid')]) }}">{{ data_get($resource, 'environment.name') }}</a>
|
||||
href="{{ route('project.resource.index', [
|
||||
'environment_uuid' => data_get($resource, 'environment.uuid'),
|
||||
'project_uuid' => data_get($resource, 'environment.project.uuid'),
|
||||
]) }}">{{ data_get($resource, 'environment.name') }}</a>
|
||||
<svg aria-hidden="true" class="w-4 h-4 mx-1 font-bold dark:text-warning" fill="currentColor"
|
||||
viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
|
||||
@@ -49,5 +49,6 @@
|
||||
<div class="order-first sm:order-last">
|
||||
<livewire:server.proxy.deploy :server="$server" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,30 +5,42 @@
|
||||
'noLoading' => false,
|
||||
])
|
||||
<div class="flex items-center">
|
||||
@if (!$noLoading)
|
||||
<x-loading wire:loading.delay.longer />
|
||||
@endif
|
||||
<span wire:loading.remove.delay.longer class="flex items-center">
|
||||
<div class="badge badge-success "></div>
|
||||
<div class="pl-2 pr-1 text-xs font-bold tracking-wider text-success" @if($title) title="{{$title}}" @endif>
|
||||
@if ($lastDeploymentLink)
|
||||
<a href="{{ $lastDeploymentLink }}" target="_blank" class="underline cursor-pointer">
|
||||
{{ str($status)->before(':')->headline() }}
|
||||
</a>
|
||||
@else
|
||||
{{ str($status)->before(':')->headline() }}
|
||||
@endif
|
||||
</div>
|
||||
@if (!str($status)->startsWith('Proxy') && !str($status)->contains('('))
|
||||
@if (str($status)->contains('unhealthy'))
|
||||
<x-helper helper="Unhealthy state. <span class='dark:text-warning text-coollabs'>This doesn't mean that the resource is malfunctioning.</span><br><br>- If the resource is accessible, it indicates that no health check is configured - it is not mandatory.<br>- If the resource is not accessible (returning 404 or 503), it may indicate that a health check is needed and has not passed. <span class='dark:text-warning text-coollabs'>Your action is required.</span><br><br>More details in the <a href='https://coolify.io/docs/knowledge-base/traefik/healthcheck/' class='underline dark:text-warning text-coollabs' target='_blank'>documentation</a>." >
|
||||
<div class="flex items-center">
|
||||
<span wire:loading.delay.longer>
|
||||
<div class="badge badge-warning"></div>
|
||||
</span>
|
||||
<span wire:loading.remove.delay.longer>
|
||||
<div class="badge badge-success"></div>
|
||||
</span>
|
||||
<div class="pl-2 pr-1 text-xs font-bold tracking-wider text-success"
|
||||
@if ($title) title="{{ $title }}" @endif>
|
||||
@if ($lastDeploymentLink)
|
||||
<a href="{{ $lastDeploymentLink }}" target="_blank" class="underline cursor-pointer">
|
||||
{{ str($status)->before(':')->headline() }}
|
||||
</a>
|
||||
@else
|
||||
{{ str($status)->before(':')->headline() }}
|
||||
@endif
|
||||
</div>
|
||||
@php
|
||||
$showUnhealthyHelper =
|
||||
!str($status)->startsWith('Proxy') &&
|
||||
!str($status)->contains('(') &&
|
||||
str($status)->contains('unhealthy');
|
||||
@endphp
|
||||
@if ($showUnhealthyHelper)
|
||||
<x-helper
|
||||
helper="Unhealthy state. <span class='dark:text-warning text-coollabs'>This doesn't mean that the resource is malfunctioning.</span><br><br>- If the resource is accessible, it indicates that no health check is configured - it is not mandatory.<br>- If the resource is not accessible (returning 404 or 503), it may indicate that a health check is needed and has not passed. <span class='dark:text-warning text-coollabs'>Your action is required.</span><br><br>More details in the <a href='https://coolify.io/docs/knowledge-base/traefik/healthcheck/' class='underline dark:text-warning text-coollabs' target='_blank'>documentation</a>.">
|
||||
<x-slot:icon>
|
||||
<svg class="hidden w-4 h-4 dark:text-warning lg:block" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16"></path>
|
||||
<svg class="hidden w-4 h-4 dark:text-warning lg:block" viewBox="0 0 256 256"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16">
|
||||
</path>
|
||||
</svg>
|
||||
</x-slot:icon>
|
||||
</x-helper>
|
||||
@endif
|
||||
@endif
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
<div>
|
||||
<h1>Admin Dashboard</h1>
|
||||
<h3 class="pt-4">Who am I now?</h3>
|
||||
<div class="pb-4">{{ auth()->user()->name }}</div>
|
||||
<div class="flex gap-2 pt-4">
|
||||
<h3>Who am I now?</h3>
|
||||
@if (session('impersonating'))
|
||||
<x-forms.button wire:click="back">Go back to root</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
<div class="pb-4">{{ auth()->user()->name }} ({{ auth()->user()->email }})</div>
|
||||
<form wire:submit="submitSearch" class="flex flex-col gap-2 lg:flex-row">
|
||||
<x-forms.input wire:model="search" placeholder="Search for a user" />
|
||||
<x-forms.button type="submit">Search</x-forms.button>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<div class="grid grid-cols-1 gap-2 xl:grid-cols-2">
|
||||
@foreach ($projects as $project)
|
||||
<div class="gap-2 border border-transparent cursor-pointer box group"
|
||||
onclick="gotoProject('{{ $project->uuid }}','{{ $project->default_environment }}')">
|
||||
wire:click="navigateToProject('{{ $project->uuid }}')">
|
||||
<div class="flex flex-1 mx-6">
|
||||
<div class="flex flex-col justify-center flex-1">
|
||||
<div class="box-title">{{ $project->name }}</div>
|
||||
@@ -34,10 +34,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-center gap-2 text-xs font-bold">
|
||||
<a class="hover:underline"
|
||||
href="{{ route('project.resource.create', ['project_uuid' => $project->uuid, 'environment_name' => data_get($project, 'default_environment', 'production')]) }}">
|
||||
<span class="p-2 font-bold">+ Add Resource</span>
|
||||
</a>
|
||||
@if ($project->environments->first())
|
||||
<a class="hover:underline"
|
||||
href="{{ route('project.resource.create', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_uuid' => $project->environments->first()->uuid,
|
||||
]) }}">
|
||||
<span class="p-2 font-bold">+ Add Resource</span>
|
||||
</a>
|
||||
@endif
|
||||
<a class="hover:underline"
|
||||
href="{{ route('project.edit', ['project_uuid' => $project->uuid]) }}">
|
||||
Settings
|
||||
@@ -167,15 +172,4 @@
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
|
||||
|
||||
<script>
|
||||
function gotoProject(uuid, environment) {
|
||||
if (environment) {
|
||||
window.location.href = '/project/' + uuid + '/' + environment;
|
||||
} else {
|
||||
window.location.href = '/project/' + uuid;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
|
||||
@@ -5,34 +5,36 @@
|
||||
<h1>Configuration</h1>
|
||||
<livewire:project.shared.configuration-checker :resource="$application" />
|
||||
<livewire:project.application.heading :application="$application" />
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" 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">
|
||||
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'general'; window.location.hash = 'general'" href="#">General</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>General</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.advanced', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Advanced</a>
|
||||
@if ($application->destination->server->isSwarm())
|
||||
<a class="menu-item" :class="activeTab === 'swarm' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'swarm'; window.location.hash = 'swarm'" href="#">Swarm
|
||||
<a class="menu-item"
|
||||
wire:current.exact="menu-item-active
|
||||
href="{{ route('project.application.swarm', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Swarm
|
||||
Configuration</a>
|
||||
@endif
|
||||
<a class="menu-item" :class="activeTab === 'advanced' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'advanced'; window.location.hash = 'advanced'" href="#">Advanced</a>
|
||||
@if ($application->build_pack !== 'static')
|
||||
<a class="menu-item" :class="activeTab === 'environment-variables' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'environment-variables'; window.location.hash = 'environment-variables'"
|
||||
href="#">Environment
|
||||
Variables</a>
|
||||
@endif
|
||||
@if ($application->build_pack !== 'static')
|
||||
<a class="menu-item" :class="activeTab === 'storages' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'storages'; window.location.hash = 'storages'" href="#">Storages
|
||||
</a>
|
||||
@endif
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Environment Variables</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Persistent Storage</a>
|
||||
@if ($application->git_based())
|
||||
<a class="menu-item" :class="activeTab === 'source' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'source'; window.location.hash = 'source'" href="#">Source</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.source', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Git Source</a>
|
||||
@endif
|
||||
<a class="menu-item" :class="activeTab === 'servers' && 'menu-item-active'" class="flex items-center gap-2"
|
||||
@click.prevent="activeTab = 'servers'; window.location.hash = 'servers'" href="#">Servers
|
||||
<a class="menu-item flex items-center gap-2" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Servers
|
||||
@if (str($application->status)->contains('degraded'))
|
||||
<span title="Some servers are unavailable">
|
||||
<svg class="w-4 h-4 text-error" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -50,102 +52,74 @@
|
||||
</span>
|
||||
@endif
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'scheduled-tasks' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'scheduled-tasks'; window.location.hash = 'scheduled-tasks'"
|
||||
href="#">Scheduled Tasks
|
||||
</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Scheduled Tasks</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Webhooks</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.preview-deployments', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Preview Deployments</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.healthcheck', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Healthcheck</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.rollback', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Rollback</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Resource Limits</a>
|
||||
|
||||
<a class="menu-item" :class="activeTab === 'webhooks' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'webhooks'; window.location.hash = 'webhooks'" href="#">Webhooks
|
||||
</a>
|
||||
@if ($application->git_based())
|
||||
<a class="menu-item" :class="activeTab === 'previews' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'previews'; window.location.hash = 'previews'" href="#">Preview
|
||||
Deployments
|
||||
</a>
|
||||
@endif
|
||||
@if ($application->build_pack !== 'static' && $application->build_pack !== 'dockercompose')
|
||||
<a class="menu-item" :class="activeTab === 'health' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'health'; window.location.hash = 'health'" href="#">Healthchecks
|
||||
</a>
|
||||
@endif
|
||||
<a class="menu-item" :class="activeTab === 'rollback' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'rollback'; window.location.hash = 'rollback'" href="#">Rollback
|
||||
</a>
|
||||
@if ($application->build_pack !== 'dockercompose')
|
||||
<a class="menu-item" :class="activeTab === 'resource-limits' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'resource-limits'; window.location.hash = 'resource-limits'"
|
||||
href="#">Resource Limits
|
||||
</a>
|
||||
@endif
|
||||
<a class="menu-item" :class="activeTab === 'resource-operations' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'resource-operations'; window.location.hash = 'resource-operations'"
|
||||
href="#">Resource Operations
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'metrics' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'metrics'; window.location.hash = 'metrics'" href="#">Metrics
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'tags' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'tags'; window.location.hash = 'tags'" href="#">Tags
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'danger' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'danger'; window.location.hash = 'danger'" href="#">Danger Zone
|
||||
</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Resource Operations</a>
|
||||
<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]) }}"
|
||||
wire:navigate>Metrics</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Tags</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.application.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
|
||||
wire:navigate>Danger Zone</a>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||
@if (request()->route()->getName() === 'project.application.configuration')
|
||||
<livewire:project.application.general :application="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'swarm'" class="h-full">
|
||||
@elseif (request()->route()->getName() === 'project.application.swarm' && $application->destination->server->isSwarm())
|
||||
<livewire:project.application.swarm :application="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'advanced'" class="h-full">
|
||||
@elseif (request()->route()->getName() === 'project.application.advanced')
|
||||
<livewire:project.application.advanced :application="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'environment-variables'">
|
||||
@elseif (request()->route()->getName() === 'project.application.environment-variables')
|
||||
<livewire:project.shared.environment-variable.all :resource="$application" />
|
||||
</div>
|
||||
@if ($application->git_based())
|
||||
<div x-cloak x-show="activeTab === 'source'">
|
||||
<livewire:project.application.source :application="$application" />
|
||||
</div>
|
||||
@endif
|
||||
<div x-cloak x-show="activeTab === 'servers'">
|
||||
<livewire:project.shared.destination :resource="$application" :servers="$servers" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'storages'">
|
||||
<livewire:project.service.storage :resource="$application" lazy />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'webhooks'">
|
||||
<livewire:project.shared.webhooks :resource="$application" lazy />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'previews'">
|
||||
<livewire:project.application.previews :application="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'health'">
|
||||
<livewire:project.shared.health-checks :resource="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'rollback'">
|
||||
<livewire:project.application.rollback :application="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'resource-limits'">
|
||||
<livewire:project.shared.resource-limits :resource="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'scheduled-tasks'">
|
||||
@elseif (request()->route()->getName() === 'project.application.persistent-storage')
|
||||
<livewire:project.service.storage :resource="$application" />
|
||||
@elseif (request()->route()->getName() === 'project.application.source' && $application->git_based())
|
||||
<livewire:project.application.source :application="$application" />
|
||||
@elseif (request()->route()->getName() === 'project.application.servers')
|
||||
<livewire:project.shared.destination :resource="$application" />
|
||||
@elseif (request()->route()->getName() === 'project.application.scheduled-tasks.show')
|
||||
<livewire:project.shared.scheduled-task.all :resource="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'resource-operations'">
|
||||
@elseif (request()->route()->getName() === 'project.application.webhooks')
|
||||
<livewire:project.shared.webhooks :resource="$application" />
|
||||
@elseif (request()->route()->getName() === 'project.application.preview-deployments')
|
||||
<livewire:project.application.previews :application="$application" />
|
||||
@elseif (request()->route()->getName() === 'project.application.healthcheck')
|
||||
<livewire:project.shared.health-checks :resource="$application" />
|
||||
@elseif (request()->route()->getName() === 'project.application.rollback')
|
||||
<livewire:project.application.rollback :application="$application" />
|
||||
@elseif (request()->route()->getName() === 'project.application.resource-limits')
|
||||
<livewire:project.shared.resource-limits :resource="$application" />
|
||||
@elseif (request()->route()->getName() === 'project.application.resource-operations')
|
||||
<livewire:project.shared.resource-operations :resource="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'metrics'">
|
||||
@elseif (request()->route()->getName() === 'project.application.metrics')
|
||||
<livewire:project.shared.metrics :resource="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'tags'">
|
||||
<livewire:project.shared.tags :resource="$application" lazy />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'danger'">
|
||||
@elseif (request()->route()->getName() === 'project.application.tags')
|
||||
<livewire:project.shared.tags :resource="$application" />
|
||||
@elseif (request()->route()->getName() === 'project.application.danger')
|
||||
<livewire:project.shared.danger :resource="$application" />
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,17 +2,21 @@
|
||||
<x-resources.breadcrumbs :resource="$application" :parameters="$parameters" :title="$lastDeploymentInfo" :lastDeploymentLink="$lastDeploymentLink" />
|
||||
<div class="navbar-main">
|
||||
<nav class="flex flex-shrink-0 gap-6 items-center whitespace-nowrap scrollbar min-h-10">
|
||||
<a href="{{ route('project.application.configuration', $parameters) }}">
|
||||
<a class="{{ request()->routeIs('project.application.configuration') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('project.application.configuration', $parameters) }}">
|
||||
Configuration
|
||||
</a>
|
||||
<a href="{{ route('project.application.deployment.index', $parameters) }}">
|
||||
<a class="{{ request()->routeIs('project.application.deployment.index') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('project.application.deployment.index', $parameters) }}">
|
||||
<button>Deployments</button>
|
||||
</a>
|
||||
<a href="{{ route('project.application.logs', $parameters) }}">
|
||||
<a class="{{ request()->routeIs('project.application.logs') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('project.application.logs', $parameters) }}">
|
||||
<button>Logs</button>
|
||||
</a>
|
||||
@if (!$application->destination->server->isSwarm())
|
||||
<a href="{{ route('project.application.command', $parameters) }}">
|
||||
<a class="{{ request()->routeIs('project.application.command') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('project.application.command', $parameters) }}">
|
||||
<button>Terminal</button>
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@@ -5,57 +5,44 @@
|
||||
<h1>Configuration</h1>
|
||||
<livewire:project.shared.configuration-checker :resource="$database" />
|
||||
<livewire:project.database.heading :database="$database" />
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" 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">
|
||||
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'general';
|
||||
window.location.hash = 'general'"
|
||||
href="#">General</a>
|
||||
<a class="menu-item" :class="activeTab === 'environment-variables' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'environment-variables'; window.location.hash = 'environment-variables'"
|
||||
href="#">Environment
|
||||
Variables</a>
|
||||
<a class="menu-item" :class="activeTab === 'servers' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'servers';
|
||||
window.location.hash = 'servers'"
|
||||
href="#">Servers
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'storages' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'storages';
|
||||
window.location.hash = 'storages'"
|
||||
href="#">Storages
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'import' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'import';
|
||||
window.location.hash = 'import'" href="#">Import
|
||||
Backup
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'webhooks' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'webhooks'; window.location.hash = 'webhooks'" href="#">Webhooks
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'resource-limits' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'resource-limits';
|
||||
window.location.hash = 'resource-limits'"
|
||||
href="#">Resource Limits
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'resource-operations' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'resource-operations'; window.location.hash = 'resource-operations'"
|
||||
href="#">Resource Operations
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'metrics' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'metrics'; window.location.hash = 'metrics'" href="#">Metrics
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'tags' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'tags'; window.location.hash = 'tags'" href="#">Tags
|
||||
</a>
|
||||
<a class="menu-item" :class="activeTab === 'danger' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'danger';
|
||||
window.location.hash = 'danger'"
|
||||
href="#">Danger Zone
|
||||
</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.database.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
|
||||
wire:navigate>General</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.database.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
|
||||
wire:navigate>Environment Variables</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.database.servers', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
|
||||
wire:navigate>Servers</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.database.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
|
||||
wire:navigate>Persistent Storage</a>
|
||||
<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]) }}"
|
||||
wire:navigate>Import Backups</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.database.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
|
||||
wire:navigate>Webhooks</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.database.resource-limits', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
|
||||
wire:navigate>Resource Limits</a>
|
||||
<a class="menu-item" wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.database.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
|
||||
wire:navigate>Resource Operations</a>
|
||||
<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]) }}"
|
||||
wire:navigate>Metrics</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.database.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
|
||||
wire:navigate>Tags</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.database.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
|
||||
wire:navigate>Danger Zone</a>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||
@if (request()->route()->getName() === 'project.database.configuration')
|
||||
@if ($database->type() === 'standalone-postgresql')
|
||||
<livewire:project.database.postgresql.general :database="$database" />
|
||||
@elseif ($database->type() === 'standalone-redis')
|
||||
@@ -73,37 +60,27 @@
|
||||
@elseif ($database->type() === 'standalone-clickhouse')
|
||||
<livewire:project.database.clickhouse.general :database="$database" />
|
||||
@endif
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'environment-variables'">
|
||||
@elseif (request()->route()->getName() === 'project.database.environment-variables')
|
||||
<livewire:project.shared.environment-variable.all :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'servers'">
|
||||
@elseif (request()->route()->getName() === 'project.database.servers')
|
||||
<livewire:project.shared.destination :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'storages'">
|
||||
@elseif (request()->route()->getName() === 'project.database.persistent-storage')
|
||||
<livewire:project.service.storage :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'webhooks'">
|
||||
<livewire:project.shared.webhooks :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'resource-limits'">
|
||||
<livewire:project.shared.resource-limits :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'import'">
|
||||
@elseif (request()->route()->getName() === 'project.database.import-backups')
|
||||
<livewire:project.database.import :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'resource-operations'">
|
||||
@elseif (request()->route()->getName() === 'project.database.webhooks')
|
||||
<livewire:project.shared.webhooks :resource="$database" />
|
||||
@elseif (request()->route()->getName() === 'project.database.resource-limits')
|
||||
<livewire:project.shared.resource-limits :resource="$database" />
|
||||
@elseif (request()->route()->getName() === 'project.database.resource-operations')
|
||||
<livewire:project.shared.resource-operations :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'metrics'">
|
||||
@elseif (request()->route()->getName() === 'project.database.metrics')
|
||||
<livewire:project.shared.metrics :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'tags'">
|
||||
<livewire:project.shared.tags :resource="$database" lazy />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'danger'">
|
||||
@elseif (request()->route()->getName() === 'project.database.tags')
|
||||
<livewire:project.shared.tags :resource="$database" />
|
||||
@elseif (request()->route()->getName() === 'project.database.danger')
|
||||
<livewire:project.shared.danger :resource="$database" />
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<x-slide-over @startdatabase.window="slideOverOpen = true" closeWithX fullScreen>
|
||||
<x-slot:title>Database Startup</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:activity-monitor header="Logs" showWaiting />
|
||||
<livewire:activity-monitor header="Logs" showWaiting fullHeight />
|
||||
</x-slot:content>
|
||||
</x-slide-over>
|
||||
<div class="navbar-main">
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<li>
|
||||
<div class="flex items-center">
|
||||
<a class="text-xs truncate lg:text-sm"
|
||||
href="{{ route('project.resource.index', ['environment_name' => $environment->name, 'project_uuid' => $project->uuid]) }}">
|
||||
href="{{ route('project.resource.index', ['environment_uuid' => $environment->uuid, 'project_uuid' => $project->uuid]) }}">
|
||||
{{ $environment->name }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -12,21 +12,21 @@
|
||||
<div x-data="searchComponent()">
|
||||
<x-forms.input placeholder="Search for name, description..." x-model="search" id="null" />
|
||||
<div class="grid grid-cols-2 gap-4 pt-4">
|
||||
<template x-if="allFilteredItems.length === 0">
|
||||
<template x-if="filteredProjects.length === 0">
|
||||
<div>No project found with the search term "<span x-text="search"></span>".</div>
|
||||
</template>
|
||||
|
||||
<template x-for="item in allFilteredItems" :key="item.uuid">
|
||||
<div class="box group" @click="gotoProject(item)">
|
||||
<template x-for="project in filteredProjects" :key="project.uuid">
|
||||
<div class="box group cursor-pointer" @click="$wire.navigateToProject(project.uuid)">
|
||||
<div class="flex flex-col justify-center flex-1 mx-6">
|
||||
<div class="box-title" x-text="item.name"></div>
|
||||
<div class="box-description ">
|
||||
<div x-text="item.description"></div>
|
||||
<div class="box-title" x-text="project.name"></div>
|
||||
<div class="box-description">
|
||||
<div x-text="project.description"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-center gap-2 pt-4 pb-2 mr-4 text-xs lg:py-0 lg:justify-normal">
|
||||
<a class="mx-4 font-bold hover:underline"
|
||||
:href="item.settingsRoute">
|
||||
:href="project.settingsRoute">
|
||||
Settings
|
||||
</a>
|
||||
</div>
|
||||
@@ -36,38 +36,21 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function sortFn(a, b) {
|
||||
return a.name.localeCompare(b.name)
|
||||
}
|
||||
|
||||
function searchComponent() {
|
||||
return {
|
||||
search: '',
|
||||
projects: @js($projects),
|
||||
filterAndSort(items) {
|
||||
get filteredProjects() {
|
||||
const projects = @js($projects);
|
||||
if (this.search === '') {
|
||||
return Object.values(items).sort(sortFn);
|
||||
return projects;
|
||||
}
|
||||
const searchLower = this.search.toLowerCase();
|
||||
return Object.values(items).filter(item => {
|
||||
return (item.name?.toLowerCase().includes(searchLower) ||
|
||||
item.description?.toLowerCase().includes(searchLower))
|
||||
}).sort(sortFn);
|
||||
},
|
||||
get allFilteredItems() {
|
||||
return [
|
||||
this.projects,
|
||||
].flatMap((items) => this.filterAndSort(items));
|
||||
return projects.filter(project => {
|
||||
return (project.name?.toLowerCase().includes(searchLower) ||
|
||||
project.description?.toLowerCase().includes(searchLower))
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function gotoProject(item) {
|
||||
if (item.default_environment) {
|
||||
window.location.href = '/project/' + item.uuid + '/' + item.default_environment;
|
||||
} else {
|
||||
window.location.href = '/project/' + item.uuid;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
|
||||
@@ -273,77 +273,74 @@
|
||||
<h2>Select a Postgresql type</h2>
|
||||
<div>If you need extra extensions, you can select Supabase PostgreSQL (or others), otherwise select PostgreSQL
|
||||
16 (default).</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="gap-2 border border-transparent cursor-pointer box-without-bg dark:bg-coolgray-100 bg-white dark:hover:text-neutral-400 dark:hover:bg-coollabs group flex "
|
||||
wire:click="setPostgresqlType('postgres:16-alpine')">
|
||||
<div class="flex flex-col">
|
||||
<div class="box-title">PostgreSQL 16 (default)</div>
|
||||
<div class="box-description">
|
||||
PostgreSQL is a powerful, open-source object-relational database system (no extensions).
|
||||
</div>
|
||||
<div class="flex flex-col gap-6 pt-8">
|
||||
<div class="gap-2 border border-transparent cursor-pointer box-without-bg dark:bg-coolgray-100 bg-white dark:hover:text-neutral-400 dark:hover:bg-coollabs group flex "
|
||||
wire:click="setPostgresqlType('postgres:16-alpine')">
|
||||
<div class="flex flex-col">
|
||||
<div class="box-title">PostgreSQL 16 (default)</div>
|
||||
<div class="box-description">
|
||||
PostgreSQL is a powerful, open-source object-relational database system (no extensions).
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
|
||||
<div class="flex items-center px-2" title="Read the documentation.">
|
||||
<a class="p-2 hover:underline group-hover:dark:text-white dark:text-white text-neutral-6000"
|
||||
onclick="event.stopPropagation()" href="https://hub.docker.com/_/postgres/"
|
||||
target="_blank">
|
||||
Documentation
|
||||
</a>
|
||||
<div class="flex items-center px-2" title="Read the documentation.">
|
||||
<a class="p-2 hover:underline group-hover:dark:text-white dark:text-white text-neutral-6000"
|
||||
onclick="event.stopPropagation()" href="https://hub.docker.com/_/postgres/" target="_blank">
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap-2 border border-transparent cursor-pointer box-without-bg dark:bg-coolgray-100 bg-white dark:hover:text-neutral-400 dark:hover:bg-coollabs group flex"
|
||||
wire:click="setPostgresqlType('supabase/postgres:15.6.1.113')">
|
||||
<div class="flex flex-col">
|
||||
<div class="box-title">Supabase PostgreSQL (with extensions)</div>
|
||||
<div class="box-description">
|
||||
Supabase is a modern, open-source alternative to PostgreSQL with lots of extensions.
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap-2 border border-transparent cursor-pointer box-without-bg dark:bg-coolgray-100 bg-white dark:hover:text-neutral-400 dark:hover:bg-coollabs group flex"
|
||||
wire:click="setPostgresqlType('supabase/postgres:15.6.1.113')">
|
||||
<div class="flex flex-col">
|
||||
<div class="box-title">Supabase PostgreSQL (with extensions)</div>
|
||||
<div class="box-description">
|
||||
Supabase is a modern, open-source alternative to PostgreSQL with lots of extensions.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="flex items-center px-2" title="Read the documentation.">
|
||||
<a class="p-2 hover:underline group-hover:dark:text-white dark:text-white text-neutral-600"
|
||||
onclick="event.stopPropagation()" href="https://github.com/supabase/postgres"
|
||||
target="_blank">
|
||||
Documentation
|
||||
</a>
|
||||
<div class="flex-1"></div>
|
||||
<div class="flex items-center px-2" title="Read the documentation.">
|
||||
<a class="p-2 hover:underline group-hover:dark:text-white dark:text-white text-neutral-600"
|
||||
onclick="event.stopPropagation()" href="https://github.com/supabase/postgres"
|
||||
target="_blank">
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap-2 border border-transparent cursor-pointer box-without-bg dark:bg-coolgray-100 bg-white dark:hover:text-neutral-400 dark:hover:bg-coollabs group flex"
|
||||
wire:click="setPostgresqlType('postgis/postgis')">
|
||||
<div class="flex flex-col">
|
||||
<div class="box-title">PostGIS</div>
|
||||
<div class="box-description">
|
||||
PostGIS is a PostgreSQL extension for geographic objects.
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap-2 border border-transparent cursor-pointer box-without-bg dark:bg-coolgray-100 bg-white dark:hover:text-neutral-400 dark:hover:bg-coollabs group flex"
|
||||
wire:click="setPostgresqlType('postgis/postgis')">
|
||||
<div class="flex flex-col">
|
||||
<div class="box-title">PostGIS</div>
|
||||
<div class="box-description">
|
||||
PostGIS is a PostgreSQL extension for geographic objects.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="flex items-center px-2" title="Read the documentation.">
|
||||
<a class="p-2 hover:underline group-hover:dark:text-white dark:text-white text-neutral-600"
|
||||
onclick="event.stopPropagation()" href="https://github.com/postgis/docker-postgis"
|
||||
target="_blank">
|
||||
Documentation
|
||||
</a>
|
||||
<div class="flex-1"></div>
|
||||
<div class="flex items-center px-2" title="Read the documentation.">
|
||||
<a class="p-2 hover:underline group-hover:dark:text-white dark:text-white text-neutral-600"
|
||||
onclick="event.stopPropagation()" href="https://github.com/postgis/docker-postgis"
|
||||
target="_blank">
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap-2 border border-transparent cursor-pointer box-without-bg dark:bg-coolgray-100 bg-white dark:hover:text-neutral-400 dark:hover:bg-coollabs group flex"
|
||||
wire:click="setPostgresqlType('pgvector/pgvector:pg16')">
|
||||
<div class="flex flex-col">
|
||||
<div class="box-title">PGVector (16)</div>
|
||||
<div class="box-description">
|
||||
PGVector is a PostgreSQL extension for vector data types.
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap-2 border border-transparent cursor-pointer box-without-bg dark:bg-coolgray-100 bg-white dark:hover:text-neutral-400 dark:hover:bg-coollabs group flex"
|
||||
wire:click="setPostgresqlType('pgvector/pgvector:pg16')">
|
||||
<div class="flex flex-col">
|
||||
<div class="box-title">PGVector (16)</div>
|
||||
<div class="box-description">
|
||||
PGVector is a PostgreSQL extension for vector data types.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="flex-1"></div>
|
||||
|
||||
<div class="flex items-center px-2" title="Read the documentation.">
|
||||
<a class="p-2 hover:underline group-hover:dark:text-white dark:text-white text-neutral-600"
|
||||
onclick="event.stopPropagation()" href="https://github.com/pgvector/pgvector"
|
||||
target="_blank">
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex items-center px-2" title="Read the documentation.">
|
||||
<a class="p-2 hover:underline group-hover:dark:text-white dark:text-white text-neutral-600"
|
||||
onclick="event.stopPropagation()" href="https://github.com/pgvector/pgvector"
|
||||
target="_blank">
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<x-forms.select wire:model.live="selectedEnvironment">
|
||||
<option value="edit">Create / Edit</option>
|
||||
<option disabled>-----</option>
|
||||
@foreach ($environments as $environment)
|
||||
<option value="{{ $environment->name }}">{{ $environment->name }}
|
||||
</option>
|
||||
<option value="{{ $environment->uuid }}">{{ $environment->name }}</option>
|
||||
@endforeach
|
||||
<option disabled>-----</option>
|
||||
<option value="edit">Create / Edit</option>
|
||||
</x-forms.select>
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
<h1>Resources</h1>
|
||||
@if ($environment->isEmpty())
|
||||
<a class="button"
|
||||
href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => data_get($parameters, 'environment_name')]) }}">
|
||||
href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}">
|
||||
Clone
|
||||
</a>
|
||||
@else
|
||||
<a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_name' => data_get($parameters, 'environment_name')]) }} "
|
||||
<a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}"
|
||||
class="button">+
|
||||
New</a>
|
||||
<a class="button"
|
||||
href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => data_get($parameters, 'environment_name')]) }}">
|
||||
href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}">
|
||||
Clone
|
||||
</a>
|
||||
@endif
|
||||
@@ -44,7 +44,7 @@
|
||||
</nav>
|
||||
</div>
|
||||
@if ($environment->isEmpty())
|
||||
<a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_name' => data_get($parameters, 'environment_name')]) }} "
|
||||
<a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}"
|
||||
class="items-center justify-center box">+ Add New Resource</a>
|
||||
@else
|
||||
<div x-data="searchComponent()">
|
||||
@@ -211,7 +211,7 @@
|
||||
},
|
||||
goto(item) {
|
||||
const hrefLink = item.hrefLink;
|
||||
window.location.href = `${hrefLink}#tags`;
|
||||
window.location.href = `${hrefLink}/tags`;
|
||||
},
|
||||
filterAndSort(items) {
|
||||
if (this.search === '') {
|
||||
|
||||
@@ -1,50 +1,42 @@
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'service-stack' }">
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($service, 'name')->limit(10) }} > Configuration | Coolify
|
||||
</x-slot>
|
||||
<livewire:project.service.navbar :service="$service" :parameters="$parameters" :query="$query" />
|
||||
<div class="flex flex-col gap-8 pt-6 h-full sm:flex-row">
|
||||
<div class="flex flex-col gap-2 items-start min-w-fit">
|
||||
|
||||
<div class="flex flex-col h-full gap-8 pt-6 sm:flex-row">
|
||||
<div class="flex flex-col items-start gap-2 min-w-fit">
|
||||
<a class="menu-item sm:min-w-fit" target="_blank" href="{{ $service->documentation() }}">Documentation
|
||||
<x-external-link /></a>
|
||||
<a class="menu-item sm:min-w-fit" :class="activeTab === 'service-stack' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'service-stack';
|
||||
window.location.hash = 'service-stack'"
|
||||
href="#">Service Stack</a>
|
||||
<a class="menu-item sm:min-w-fit" :class="activeTab === 'environment-variables' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'environment-variables'; window.location.hash = 'environment-variables'"
|
||||
href="#">Environment
|
||||
Variables</a>
|
||||
<a class="menu-item sm:min-w-fit" :class="activeTab === 'storages' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'storages';
|
||||
window.location.hash = 'storages'"
|
||||
href="#">Storages</a>
|
||||
<a class="menu-item" :class="activeTab === 'scheduled-tasks' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'scheduled-tasks'; window.location.hash = 'scheduled-tasks'"
|
||||
href="#">Scheduled Tasks
|
||||
</a>
|
||||
<a class="menu-item sm:min-w-fit" :class="activeTab === 'logs' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'logs';
|
||||
window.location.hash = 'logs'"
|
||||
href="#">Logs</a>
|
||||
<a class="menu-item sm:min-w-fit" :class="activeTab === 'webhooks' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'webhooks'; window.location.hash = 'webhooks'" href="#">Webhooks
|
||||
</a>
|
||||
<a class="menu-item sm:min-w-fit" :class="activeTab === 'resource-operations' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'resource-operations'; window.location.hash = 'resource-operations'"
|
||||
href="#">Resource Operations
|
||||
</a>
|
||||
<a class="menu-item sm:min-w-fit" :class="activeTab === 'tags' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'tags'; window.location.hash = 'tags'" href="#">Tags
|
||||
</a>
|
||||
<a class="menu-item sm:min-w-fit" :class="activeTab === 'danger' && 'menu-item-active'"
|
||||
@click.prevent="activeTab = 'danger';
|
||||
window.location.hash = 'danger'"
|
||||
href="#">Danger Zone
|
||||
</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.service.configuration', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
|
||||
wire:navigate>General</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.service.environment-variables', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
|
||||
wire:navigate>Environment Variables</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.service.storages', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
|
||||
wire:navigate>Persistent Storages</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.service.scheduled-tasks.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
|
||||
wire:navigate>Scheduled Tasks</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.service.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
|
||||
wire:navigate>Webhooks</a>
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.service.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
|
||||
wire:navigate>Resource Operations</a>
|
||||
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.service.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
|
||||
wire:navigate>Tags</a>
|
||||
|
||||
<a class='menu-item' wire:current.exact="menu-item-active"
|
||||
href="{{ route('project.service.danger', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid]) }}"
|
||||
wire:navigate>Danger Zone</a>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div x-cloak x-show="activeTab === 'service-stack'">
|
||||
@if (request()->route()->getName() === 'project.service.configuration')
|
||||
<livewire:project.service.stack-form :service="$service" />
|
||||
<h3>Services</h3>
|
||||
<div class="grid grid-cols-1 gap-2 pt-4 xl:grid-cols-1">
|
||||
@@ -103,7 +95,7 @@
|
||||
</div>
|
||||
<div class="flex items-center px-4">
|
||||
<a class="mx-4 text-xs font-bold hover:underline"
|
||||
href="{{ route('project.service.index', [...$parameters, 'stack_service_uuid' => $application->uuid]) }}">
|
||||
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $application->uuid]) }}">
|
||||
Settings
|
||||
</a>
|
||||
@if (str($application->status)->contains('running'))
|
||||
@@ -151,12 +143,12 @@
|
||||
<div class="flex items-center px-4">
|
||||
@if ($database->isBackupSolutionAvailable())
|
||||
<a class="mx-4 text-xs font-bold hover:underline"
|
||||
href="{{ route('project.service.index', [...$parameters, 'stack_service_uuid' => $database->uuid]) }}#backups">
|
||||
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}#backups">
|
||||
Backups
|
||||
</a>
|
||||
@endif
|
||||
<a class="mx-4 text-xs font-bold hover:underline"
|
||||
href="{{ route('project.service.index', [...$parameters, 'stack_service_uuid' => $database->uuid]) }}">
|
||||
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}">
|
||||
Settings
|
||||
</a>
|
||||
@if (str($database->status)->contains('running'))
|
||||
@@ -173,8 +165,9 @@
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'storages'">
|
||||
@elseif (request()->route()->getName() === 'project.service.environment-variables')
|
||||
<livewire:project.shared.environment-variable.all :resource="$service" />
|
||||
@elseif (request()->route()->getName() === 'project.service.storages')
|
||||
<div class="flex gap-2 items-center">
|
||||
<h2>Storages</h2>
|
||||
</div>
|
||||
@@ -182,35 +175,23 @@
|
||||
<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 (Service Stack tab).</div>
|
||||
@foreach ($applications as $application)
|
||||
<livewire:project.service.storage wire:key="application-{{ $application->id }}" :resource="$application"
|
||||
lazy />
|
||||
<livewire:project.service.storage wire:key="application-{{ $application->id }}"
|
||||
:resource="$application" />
|
||||
@endforeach
|
||||
@foreach ($databases as $database)
|
||||
<livewire:project.service.storage wire:key="database-{{ $database->id }}" :resource="$database"
|
||||
lazy />
|
||||
<livewire:project.service.storage wire:key="database-{{ $database->id }}" :resource="$database" />
|
||||
@endforeach
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'scheduled-tasks'">
|
||||
@elseif (request()->route()->getName() === 'project.service.scheduled-tasks.show')
|
||||
<livewire:project.shared.scheduled-task.all :resource="$service" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'webhooks'">
|
||||
@elseif (request()->route()->getName() === 'project.service.webhooks')
|
||||
<livewire:project.shared.webhooks :resource="$service" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'logs'">
|
||||
<livewire:project.shared.logs :resource="$service" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'environment-variables'">
|
||||
<livewire:project.shared.environment-variable.all :resource="$service" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'resource-operations'">
|
||||
@elseif (request()->route()->getName() === 'project.service.resource-operations')
|
||||
<livewire:project.shared.resource-operations :resource="$service" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'tags'">
|
||||
@elseif (request()->route()->getName() === 'project.service.tags')
|
||||
<livewire:project.shared.tags :resource="$service" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'danger'">
|
||||
@elseif (request()->route()->getName() === 'project.service.danger')
|
||||
<livewire:project.shared.danger :resource="$service" />
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div wire:poll.10000ms="check_status_without_notification">
|
||||
<div>
|
||||
<livewire:project.shared.configuration-checker :resource="$service" />
|
||||
<x-slide-over @startservice.window="slideOverOpen = true" closeWithX fullScreen>
|
||||
<x-slot:title>Service Startup</x-slot:title>
|
||||
@@ -14,6 +14,10 @@
|
||||
href="{{ route('project.service.configuration', $parameters) }}">
|
||||
<button>Configuration</button>
|
||||
</a>
|
||||
<a class="{{ request()->routeIs('project.service.logs') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('project.service.logs', $parameters) }}">
|
||||
<button>Logs</button>
|
||||
</a>
|
||||
<a class="{{ request()->routeIs('project.service.command') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('project.service.command', $parameters) }}">
|
||||
<button>Terminal</button>
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
$resource->getMorphClass() == 'App\Models\StandaloneKeydb' ||
|
||||
$resource->getMorphClass() == 'App\Models\StandaloneDragonfly' ||
|
||||
$resource->getMorphClass() == 'App\Models\StandaloneClickhouse' ||
|
||||
$resource->getMorphClass() == 'App\Models\StandaloneMongodb')
|
||||
$resource->getMorphClass() == 'App\Models\StandaloneMongodb' ||
|
||||
$resource->getMorphClass() == 'App\Models\StandaloneMysql')
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Storages</h2>
|
||||
<x-helper
|
||||
|
||||
@@ -62,17 +62,13 @@
|
||||
<x-forms.button isError
|
||||
wire:click="stop('{{ data_get($destination, 'server.id') }}')">Stop</x-forms.button>
|
||||
@endif
|
||||
<x-modal-confirmation
|
||||
title="Confirm server removal?"
|
||||
isErrorButton
|
||||
buttonTitle="Remove Server"
|
||||
<x-modal-confirmation title="Confirm server removal?" isErrorButton buttonTitle="Remove Server"
|
||||
submitAction="removeServer({{ data_get($destination, 'id') }},{{ data_get($destination, 'server.id') }})"
|
||||
:actions="['This will stop the all running applications on this server and remove it as a deployment destination.']"
|
||||
confirmationText="{{ data_get($destination, 'server.name') }}"
|
||||
:actions="[
|
||||
'This will stop the all running applications on this server and remove it as a deployment destination.',
|
||||
]" confirmationText="{{ data_get($destination, 'server.name') }}"
|
||||
confirmationLabel="Please confirm the execution of the actions by entering the Server Name below"
|
||||
shortConfirmationLabel="Server Name"
|
||||
step3ButtonText="Permanently Remove Server"
|
||||
/>
|
||||
shortConfirmationLabel="Server Name" step3ButtonText="Permanently Remove Server" />
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div>Environment variables (secrets) for this resource. </div>
|
||||
@if ($this->resourceClass === 'App\Models\Application' && data_get($this->resource, 'build_pack') !== 'dockercompose')
|
||||
<div class="w-64 pt-2">
|
||||
<x-forms.checkbox id="resource.settings.is_env_sorting_enabled" label="Sort alphabetically"
|
||||
<x-forms.checkbox id="is_env_sorting_enabled" label="Sort alphabetically"
|
||||
helper="Turn this off if one environment is dependent on an other. It will be sorted by creation order (like you pasted them or in the order you created them)."
|
||||
instantSave></x-forms.checkbox>
|
||||
</div>
|
||||
@@ -55,10 +55,10 @@
|
||||
<h3>Preview Deployments Environment Variables</h3>
|
||||
<div>Environment (secrets) variables for Preview Deployments.</div>
|
||||
</div>
|
||||
@foreach ($resource->environment_variables_preview as $env)
|
||||
{{-- @foreach ($resource->environment_variables_preview as $env)
|
||||
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" :type="$resource->type()" />
|
||||
@endforeach
|
||||
@endforeach --}}
|
||||
@endif
|
||||
@else
|
||||
<form wire:submit.prevent='submit' class="flex flex-col gap-2">
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
<div>
|
||||
<form wire:submit='submit'
|
||||
@class([
|
||||
'flex flex-col items-center gap-4 p-4 bg-white border lg:items-start dark:bg-base',
|
||||
'border-error' => $env->is_really_required,
|
||||
'dark:border-coolgray-300' => !$env->is_really_required,
|
||||
])
|
||||
>
|
||||
<form wire:submit='submit' @class([
|
||||
'flex flex-col items-center gap-4 p-4 bg-white border lg:items-start dark:bg-base',
|
||||
'border-error' => $is_really_required,
|
||||
'dark:border-coolgray-300' => !$is_really_required,
|
||||
])>
|
||||
@if ($isLocked)
|
||||
<div class="flex flex-1 w-full gap-2">
|
||||
<x-forms.input disabled id="env.key" />
|
||||
<x-forms.input disabled id="key" />
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
|
||||
<path d="M5 13a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-6z" />
|
||||
<path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0-2 0m-3-5V7a4 4 0 1 1 8 0v4" />
|
||||
</g>
|
||||
@@ -25,49 +22,49 @@
|
||||
@else
|
||||
@if ($isDisabled)
|
||||
<div class="flex flex-col w-full gap-2 lg:flex-row">
|
||||
<x-forms.input disabled id="env.key" />
|
||||
<x-forms.input disabled type="password" id="env.value" />
|
||||
@if ($env->is_shared)
|
||||
<x-forms.input disabled type="password" id="env.real_value" />
|
||||
<x-forms.input disabled id="key" />
|
||||
<x-forms.input disabled type="password" id="value" />
|
||||
@if ($is_shared)
|
||||
<x-forms.input disabled type="password" id="real_value" />
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<div class="flex flex-col w-full gap-2 lg:flex-row">
|
||||
@if ($env->is_multiline)
|
||||
<x-forms.input isMultiline="{{ $env->is_multiline }}" id="env.key" />
|
||||
<x-forms.textarea type="password" id="env.value" />
|
||||
@if ($is_multiline)
|
||||
<x-forms.input isMultiline="{{ $is_multiline }}" id="key" />
|
||||
<x-forms.textarea type="password" id="value" />
|
||||
@else
|
||||
<x-forms.input id="env.key" />
|
||||
<x-forms.input type="password" id="env.value" />
|
||||
<x-forms.input id="key" />
|
||||
<x-forms.input type="password" id="value" />
|
||||
@endif
|
||||
@if ($env->is_shared)
|
||||
<x-forms.input disabled type="password" id="env.real_value" />
|
||||
@if ($is_shared)
|
||||
<x-forms.input disabled type="password" id="real_value" />
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex flex-col w-full gap-2 lg:flex-row">
|
||||
@if ($type === 'service')
|
||||
<x-forms.checkbox instantSave id="env.is_build_time"
|
||||
<x-forms.checkbox instantSave id="is_build_time"
|
||||
helper="If you are using Docker, remember to modify the file to be ready to receive the build time args. Ex.: for docker file, add `ARG name_of_the_variable`, or dockercompose add `- 'name_of_the_variable=${name_of_the_variable}'`"
|
||||
label="Build Variable?" />
|
||||
@else
|
||||
@if ($env->is_shared)
|
||||
<x-forms.checkbox instantSave id="env.is_build_time"
|
||||
@if ($is_shared)
|
||||
<x-forms.checkbox instantSave id="is_build_time"
|
||||
helper="If you are using Docker, remember to modify the file to be ready to receive the build time args. Ex.: for docker file, add `ARG name_of_the_variable`, or dockercompose add `- 'name_of_the_variable=${name_of_the_variable}'`"
|
||||
label="Build Variable?" />
|
||||
<x-forms.checkbox instantSave id="env.is_literal"
|
||||
<x-forms.checkbox instantSave id="is_literal"
|
||||
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it from another value. In this case, you should set this to true."
|
||||
label="Is Literal?" />
|
||||
@else
|
||||
@if ($isSharedVariable)
|
||||
<x-forms.checkbox instantSave id="env.is_multiline" label="Is Multiline?" />
|
||||
<x-forms.checkbox instantSave id="is_multiline" label="Is Multiline?" />
|
||||
@else
|
||||
<x-forms.checkbox instantSave id="env.is_build_time"
|
||||
<x-forms.checkbox instantSave id="is_build_time"
|
||||
helper="If you are using Docker, remember to modify the file to be ready to receive the build time args. Ex.: for dockerfile, add `ARG name_of_the_variable`, or dockercompose add `- 'name_of_the_variable=${name_of_the_variable}'`"
|
||||
label="Build Variable?" />
|
||||
<x-forms.checkbox instantSave id="env.is_multiline" label="Is Multiline?" />
|
||||
@if (!data_get($env, 'is_multiline'))
|
||||
<x-forms.checkbox instantSave id="env.is_literal"
|
||||
<x-forms.checkbox instantSave id="is_multiline" label="Is Multiline?" />
|
||||
@if ($is_multiline === false)
|
||||
<x-forms.checkbox instantSave id="is_literal"
|
||||
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it from another value. In this case, you should set this to true."
|
||||
label="Is Literal?" />
|
||||
@endif
|
||||
@@ -84,7 +81,7 @@
|
||||
</x-forms.button>
|
||||
<x-modal-confirmation title="Confirm Environment Variable Deletion?" isErrorButton
|
||||
buttonTitle="Delete" submitAction="delete" :actions="['The selected environment variable will be permanently deleted.']"
|
||||
confirmationText="{{ $env->key }}"
|
||||
confirmationText="{{ $key }}"
|
||||
confirmationLabel="Please confirm the execution of the actions by entering the Environment Variable Name below"
|
||||
shortConfirmationLabel="Environment Variable Name" :confirmWithPassword="false"
|
||||
step2ButtonText="Permanently Delete" />
|
||||
@@ -97,7 +94,7 @@
|
||||
</x-forms.button>
|
||||
<x-modal-confirmation title="Confirm Environment Variable Deletion?" isErrorButton
|
||||
buttonTitle="Delete" submitAction="delete" :actions="['The selected environment variable will be permanently deleted.']"
|
||||
confirmationText="{{ $env->key }}"
|
||||
confirmationText="{{ $key }}"
|
||||
confirmationLabel="Please confirm the execution of the actions by entering the Environment Variable Name below"
|
||||
shortConfirmationLabel="Environment Variable Name" :confirmWithPassword="false"
|
||||
step2ButtonText="Permanently Delete" />
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
<h1>Logs</h1>
|
||||
<livewire:project.application.heading :application="$resource" />
|
||||
<div class="pt-4">
|
||||
<h2>Logs</h2>
|
||||
<div class="subtitle">Here you can see the logs of the application.</div>
|
||||
<div class="pt-2" wire:loading wire:target="loadContainers">
|
||||
Loading containers...
|
||||
@@ -31,10 +30,8 @@
|
||||
<h1>Logs</h1>
|
||||
<livewire:project.database.heading :database="$resource" />
|
||||
<div class="pt-4">
|
||||
<div class="subtitle">Here you can see the logs of the database.</div>
|
||||
@forelse ($containers as $container)
|
||||
@if ($loop->first)
|
||||
<h2 class="pb-4">Logs</h2>
|
||||
@endif
|
||||
@if (data_get($servers, '0'))
|
||||
<livewire:project.shared.get-logs :server="data_get($servers, '0')" :resource="$resource" :container="$container" />
|
||||
@else
|
||||
@@ -45,11 +42,10 @@
|
||||
@endforelse
|
||||
</div>
|
||||
@elseif ($type === 'service')
|
||||
<div>
|
||||
<livewire:project.service.navbar :service="$resource" :parameters="$parameters" :query="$query" title="Logs" />
|
||||
<div class="pt-4">
|
||||
<div class="subtitle">Here you can see the logs of the service.</div>
|
||||
@forelse ($containers as $container)
|
||||
@if ($loop->first)
|
||||
<h2 class="pb-4">Logs</h2>
|
||||
@endif
|
||||
@if (data_get($servers, '0'))
|
||||
<livewire:project.shared.get-logs :server="data_get($servers, '0')" :resource="$resource" :container="$container" />
|
||||
@else
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
<div class="text-xs truncate subtitle lg:text-sm">{{ $project->name }}.</div>
|
||||
<div class="grid gap-2 lg:grid-cols-2">
|
||||
@forelse ($project->environments->sortBy('created_at') as $environment)
|
||||
<div class="gap-2 border border-transparent cursor-pointer box group" x-data
|
||||
x-on:click="goto('{{ $project->uuid }}','{{ $environment->name }}')">
|
||||
<div class="gap-2 border border-transparent cursor-pointer box group"
|
||||
wire:click="navigateToEnvironment('{{ $project->uuid }}', '{{ $environment->uuid }}')">
|
||||
<div class="flex flex-1 mx-6">
|
||||
<a class="flex flex-col justify-center flex-1"
|
||||
href="{{ route('project.resource.index', [$project->uuid, $environment->name]) }}">
|
||||
href="{{ route('project.resource.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}">
|
||||
<div class="font-bold dark:text-white"> {{ $environment->name }}</div>
|
||||
<div class="description">
|
||||
{{ $environment->description }}</div>
|
||||
</a>
|
||||
<div class="flex items-center justify-center gap-2 text-xs">
|
||||
<a class="font-bold hover:underline"
|
||||
href="{{ route('project.environment.edit', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => $environment->name]) }}">
|
||||
href="{{ route('project.environment.edit', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}">
|
||||
Settings
|
||||
</a>
|
||||
</div>
|
||||
@@ -37,10 +37,5 @@
|
||||
@empty
|
||||
<p>No environments found.</p>
|
||||
@endforelse
|
||||
<script>
|
||||
function goto(projectUuid, environmentName) {
|
||||
window.location.href = '/project/' + projectUuid + '/' + environmentName;
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,40 +10,44 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Advanced</h2>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
<x-modal-confirmation title="Confirm Docker Cleanup?" buttonTitle="Trigger Manual Cleanup"
|
||||
isHighlightedButton submitAction="manualCleanup" :actions="[
|
||||
'Permanently deletes all stopped containers managed by Coolify (as containers are non-persistent, no data will be lost)',
|
||||
'Permanently deletes all unused images',
|
||||
'Clears build cache',
|
||||
'Removes old versions of the Coolify helper image',
|
||||
'Optionally permanently deletes all unused volumes (if enabled in advanced options).',
|
||||
'Optionally permanently deletes all unused networks (if enabled in advanced options).',
|
||||
]" :confirmWithText="false"
|
||||
:confirmWithPassword="false" step2ButtonText="Trigger Docker Cleanup" />
|
||||
</div>
|
||||
<div>Advanced configuration for your server.</div>
|
||||
<div class="mt-3 mb-4">Advanced configuration for your server.</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<h3>Disk Usage</h3>
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-wrap gap-2 sm:flex-nowrap pt-4">
|
||||
<x-forms.input placeholder="0 23 * * *" id="serverDiskUsageCheckFrequency"
|
||||
label="Disk usage check frequency" required
|
||||
helper="Cron expression for disk usage check frequency.<br>You can use every_minute, hourly, daily, weekly, monthly, yearly.<br><br>Default is every night at 11:00 PM." />
|
||||
<x-forms.input id="serverDiskUsageNotificationThreshold"
|
||||
label="Server disk usage notification threshold (%)" required
|
||||
helper="If the server disk usage exceeds this threshold, Coolify will send a notification to the team members." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex gap-4">
|
||||
<h3>Docker Cleanup</h3>
|
||||
<x-modal-confirmation title="Confirm Docker Cleanup?" buttonTitle="Trigger Manual Cleanup"
|
||||
isHighlightedButton submitAction="manualCleanup" :actions="[
|
||||
'Permanently deletes all stopped containers managed by Coolify (as containers are non-persistent, no data will be lost)',
|
||||
'Permanently deletes all unused images',
|
||||
'Clears build cache',
|
||||
'Removes old versions of the Coolify helper image',
|
||||
'Optionally permanently deletes all unused volumes (if enabled in advanced options).',
|
||||
'Optionally permanently deletes all unused networks (if enabled in advanced options).',
|
||||
]" :confirmWithText="false"
|
||||
:confirmWithPassword="false" step2ButtonText="Trigger Docker Cleanup" />
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-4">
|
||||
@if ($forceDockerCleanup)
|
||||
<x-forms.input placeholder="*/10 * * * *" id="dockerCleanupFrequency"
|
||||
label="Docker cleanup frequency" required
|
||||
helper="Cron expression for Docker Cleanup.<br>You can use every_minute, hourly, daily, weekly, monthly, yearly.<br><br>Default is every night at midnight." />
|
||||
@else
|
||||
<x-forms.input id="dockerCleanupThreshold" label="Docker cleanup threshold (%)" required
|
||||
helper="The Docker cleanup tasks will run when the disk usage exceeds this threshold." />
|
||||
<x-forms.input placeholder="*/10 * * * *" id="dockerCleanupFrequency"
|
||||
label="Docker cleanup frequency" required
|
||||
helper="Cron expression for Docker Cleanup.<br>You can use every_minute, hourly, daily, weekly, monthly, yearly.<br><br>Default is every night at midnight." />
|
||||
@if (!$forceDockerCleanup)
|
||||
<x-forms.input id="dockerCleanupThreshold" label="Docker cleanup threshold (%)" required
|
||||
helper="The Docker cleanup tasks will run when the disk usage exceeds this threshold." />
|
||||
@endif
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox
|
||||
|
||||
@@ -20,17 +20,12 @@
|
||||
</a>
|
||||
</button>
|
||||
@endif
|
||||
<x-modal-confirmation
|
||||
title="Confirm Proxy Restart?"
|
||||
buttonTitle="Restart Proxy"
|
||||
submitAction="restart"
|
||||
:actions="['This proxy will be stopped and started again.', 'All resources hosted on coolify will be unavailable during the restart.']"
|
||||
:confirmWithText="false"
|
||||
:confirmWithPassword="false"
|
||||
step2ButtonText="Restart Proxy"
|
||||
:dispatchEvent="true"
|
||||
dispatchEventType="restartEvent"
|
||||
>
|
||||
<x-modal-confirmation title="Confirm Proxy Restart?" buttonTitle="Restart Proxy" submitAction="restart"
|
||||
:actions="[
|
||||
'This proxy will be stopped and started again.',
|
||||
'All resources hosted on coolify will be unavailable during the restart.',
|
||||
]" :confirmWithText="false" :confirmWithPassword="false" step2ButtonText="Restart Proxy"
|
||||
:dispatchEvent="true" dispatchEventType="restartEvent">
|
||||
<x-slot:button-title>
|
||||
<svg class="w-5 h-5 dark:text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
@@ -42,17 +37,12 @@
|
||||
Restart Proxy
|
||||
</x-slot:button-title>
|
||||
</x-modal-confirmation>
|
||||
<x-modal-confirmation
|
||||
title="Confirm Proxy Stopping?"
|
||||
buttonTitle="Stop Proxy"
|
||||
submitAction="stop(true)"
|
||||
:actions="['The coolify proxy will be stopped.', 'All resources hosted on coolify will be unavailable.']"
|
||||
:confirmWithText="false"
|
||||
:confirmWithPassword="false"
|
||||
step2ButtonText="Stop Proxy"
|
||||
:dispatchEvent="true"
|
||||
dispatchEventType="stopEvent"
|
||||
>
|
||||
<x-modal-confirmation title="Confirm Proxy Stopping?" buttonTitle="Stop Proxy" submitAction="stop(true)"
|
||||
:actions="[
|
||||
'The coolify proxy will be stopped.',
|
||||
'All resources hosted on coolify will be unavailable.',
|
||||
]" :confirmWithText="false" :confirmWithPassword="false" step2ButtonText="Stop Proxy" :dispatchEvent="true"
|
||||
dispatchEventType="stopEvent">
|
||||
<x-slot:button-title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-error" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
@@ -82,7 +72,6 @@
|
||||
@script
|
||||
<script>
|
||||
$wire.$on('checkProxyEvent', () => {
|
||||
$wire.$dispatch('info', 'Starting proxy.');
|
||||
$wire.$call('checkProxy');
|
||||
});
|
||||
$wire.$on('restartEvent', () => {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<div x-init="$wire.checkProxy()" class="flex gap-2">
|
||||
<x-forms.button wire:click='checkProxy(true)' :showLoadingIndicator="false">Refresh</x-forms.button>
|
||||
@if (data_get($server, 'proxy.status') === 'running')
|
||||
<x-status.running status="Proxy Running" noLoading />
|
||||
<x-status.running status="Proxy Running" />
|
||||
@elseif (data_get($server, 'proxy.status') === 'restarting')
|
||||
<x-status.restarting status="Proxy Restarting" noLoading />
|
||||
<x-status.restarting status="Proxy Restarting" />
|
||||
@elseif (data_get($server, 'proxy.force_stop'))
|
||||
<x-status.stopped status="Proxy Stopped" noLoading />
|
||||
<x-status.stopped status="Proxy Stopped" />
|
||||
@elseif (data_get($server, 'proxy.status') === 'exited')
|
||||
<x-status.stopped status="Proxy Exited" noLoading />
|
||||
<x-status.stopped status="Proxy Exited" />
|
||||
@else
|
||||
<x-status.stopped status="Proxy Not Running" noLoading />
|
||||
<x-status.stopped status="Proxy Not Running" />
|
||||
@endif
|
||||
<x-forms.button wire:click='checkProxy(true)'>Refresh</x-forms.button>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
<div class="pt-0 pb-3">{{ data_get($project, 'description') }}</div>
|
||||
@forelse ($project->environments as $environment)
|
||||
<a class="box group"
|
||||
href="{{ route('shared-variables.environment.show', ['project_uuid' => $project->uuid, 'environment_name' => $environment->name]) }}">
|
||||
href="{{ route('shared-variables.environment.show', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_uuid' => $environment->uuid
|
||||
]) }}">
|
||||
<div class="flex flex-col justify-center flex-1 mx-6 ">
|
||||
<div class="box-title"> {{ $environment->name }}</div>
|
||||
<div class="box-description">
|
||||
|
||||
Reference in New Issue
Block a user