Merge branch 'next' into fix-postgres-init-scripts

This commit is contained in:
Andras Bacsai
2024-12-18 10:35:16 +01:00
137 changed files with 1903 additions and 1514 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 === '') {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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">

View File

@@ -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" />

View File

@@ -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

View File

@@ -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>