Refactor UI components to use 'coolbox' class for consistent styling across various views

- Updated dashboard, destination, project, and server views to replace 'box' class with 'coolbox' for improved visual consistency.
- Modified links and buttons in shared variables and scheduled tasks views to utilize 'coolbox' class.
- Ensured all relevant components reflect the new styling approach, enhancing user experience and interface coherence.
This commit is contained in:
Andras Bacsai 2025-11-28 13:55:54 +01:00
parent d71efadce4
commit d905ae107b
24 changed files with 219 additions and 118 deletions

View file

@ -179,6 +179,10 @@ @utility box-without-bg-without-border {
@apply flex p-2 transition-colors dark:hover:text-white hover:no-underline min-h-[4rem]; @apply flex p-2 transition-colors dark:hover:text-white hover:no-underline min-h-[4rem];
} }
@utility coolbox {
@apply flex transition-all duration-150 dark:bg-coolgray-100 bg-white p-2 rounded-lg border border-neutral-200 dark:border-coolgray-400 hover:ring-2 dark:hover:ring-yellow-400 hover:ring-coollabs cursor-pointer min-h-[4rem];
}
@utility on-box { @utility on-box {
@apply rounded-sm hover:bg-neutral-300 dark:hover:bg-coolgray-500/20; @apply rounded-sm hover:bg-neutral-300 dark:hover:bg-coolgray-500/20;
} }

View file

@ -1,7 +1,6 @@
<div @class([ <div @class([
'transition-all duration-150 box-without-bg dark:bg-coolgray-100 bg-white group p-2 rounded-lg border border-neutral-200 dark:border-coolgray-400 hover:ring-2 dark:hover:ring-yellow-400 hover:ring-coollabs', 'coolbox group',
'cursor-pointer' => !$upgrade, '!cursor-not-allowed hover:border-l-red-500' => $upgrade,
'hover:border-l-red-500 cursor-not-allowed' => $upgrade,
])> ])>
<div class="flex items-center"> <div class="flex items-center">
<div class="w-[4.5rem] h-[4.5rem] flex items-center justify-center text-black dark:text-white shrink-0 rounded-lg overflow-hidden"> <div class="w-[4.5rem] h-[4.5rem] flex items-center justify-center text-black dark:text-white shrink-0 rounded-lg overflow-hidden">

View file

@ -17,7 +17,7 @@
@if ($foundUsers->count() > 0) @if ($foundUsers->count() > 0)
<div class="flex flex-wrap gap-2 pt-4"> <div class="flex flex-wrap gap-2 pt-4">
@foreach ($foundUsers as $user) @foreach ($foundUsers as $user)
<div class="box w-64 group" wire:click="switchUser({{ $user->id }})"> <div class="coolbox w-64 group" wire:click="switchUser({{ $user->id }})">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<div class="box-title">{{ $user->name }}</div> <div class="box-title">{{ $user->name }}</div>
<div class="box-description">{{ $user->email }}</div> <div class="box-description">{{ $user->email }}</div>

View file

@ -35,7 +35,7 @@ class="flex items-center justify-center size-4 text-white rounded hover:bg-coolg
@if ($projects->count() > 0) @if ($projects->count() > 0)
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2"> <div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
@foreach ($projects as $project) @foreach ($projects as $project)
<div class="relative gap-2 cursor-pointer box group"> <div class="relative gap-2 cursor-pointer coolbox group">
<a href="{{ $project->navigateTo() }}" class="absolute inset-0"></a> <a href="{{ $project->navigateTo() }}" class="absolute inset-0"></a>
<div class="flex flex-1 mx-6"> <div class="flex flex-1 mx-6">
<div class="flex flex-col justify-center flex-1"> <div class="flex flex-col justify-center flex-1">
@ -103,7 +103,7 @@ class="flex items-center justify-center size-4 text-white rounded hover:bg-coolg
@foreach ($servers as $server) @foreach ($servers as $server)
<a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}" <a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
@class([ @class([
'gap-2 border cursor-pointer box group', 'gap-2 border cursor-pointer coolbox group',
'border-red-500' => 'border-red-500' =>
!$server->settings->is_reachable || $server->settings->force_disabled, !$server->settings->is_reachable || $server->settings->force_disabled,
])> ])>

View file

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

View file

@ -13,7 +13,7 @@
<div class="subtitle">All your projects are here.</div> <div class="subtitle">All your projects are here.</div>
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2 -mt-1"> <div class="grid grid-cols-1 gap-4 xl:grid-cols-2 -mt-1">
@foreach ($projects as $project) @foreach ($projects as $project)
<div class="relative gap-2 cursor-pointer box group"> <div class="relative gap-2 cursor-pointer coolbox group">
<a href="{{ $project->navigateTo() }}" class="absolute inset-0"></a> <a href="{{ $project->navigateTo() }}" class="absolute inset-0"></a>
<div class="flex flex-1 mx-6"> <div class="flex flex-1 mx-6">
<div class="flex flex-col justify-center flex-1"> <div class="flex flex-col justify-center flex-1">

View file

@ -7,7 +7,7 @@
<div class="flex flex-col justify-center gap-2 text-left "> <div class="flex flex-col justify-center gap-2 text-left ">
@forelse ($private_keys as $key) @forelse ($private_keys as $key)
@if ($private_key_id == $key->id) @if ($private_key_id == $key->id)
<div class="gap-2 py-4 cursor-pointer group hover:bg-coollabs bg-coolgray-100 box" <div class="gap-2 py-4 cursor-pointer group hover:bg-coollabs bg-coolgray-100 coolbox"
wire:click="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}"> wire:click="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
<div class="flex flex-col mx-6"> <div class="flex flex-col mx-6">
<div class="box-title"> <div class="box-title">
@ -20,7 +20,7 @@ class="loading loading-xs dark:text-warning loading-spinner"></span>
</div> </div>
</div> </div>
@else @else
<div class="gap-2 py-4 cursor-pointer group hover:bg-coollabs bg-coolgray-100 box" <div class="gap-2 py-4 cursor-pointer group hover:bg-coollabs bg-coolgray-100 coolbox"
wire:click="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}"> wire:click="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
<div class="flex flex-col mx-6"> <div class="flex flex-col mx-6">
<div class="box-title"> <div class="box-title">

View file

@ -21,7 +21,7 @@
<div class="flex flex-col justify-center gap-2 text-left"> <div class="flex flex-col justify-center gap-2 text-left">
@foreach ($github_apps as $ghapp) @foreach ($github_apps as $ghapp)
<div class="flex"> <div class="flex">
<div class="w-full gap-2 py-4 bg-white cursor-pointer group hover:bg-coollabs dark:bg-coolgray-200 box" <div class="w-full gap-2 py-4 bg-white cursor-pointer group hover:bg-coollabs dark:bg-coolgray-200 coolbox"
wire:click.prevent="loadRepositories({{ $ghapp->id }})" wire:click.prevent="loadRepositories({{ $ghapp->id }})"
wire:key="{{ $ghapp->id }}"> wire:key="{{ $ghapp->id }}">
<div class="flex mr-4"> <div class="flex mr-4">

View file

@ -1,8 +1,9 @@
<div x-data x-init="$wire.loadServers"> <div x-data x-init="$wire.loadServers">
<div x-data="searchResources()"> <div x-data="searchResources()">
@if ($current_step === 'type') @if ($current_step === 'type')
<div x-init="window.addEventListener('scroll', () => isSticky = window.pageYOffset > 100)" class="sticky z-10 top-0 py-4 backdrop-blur-sm border-b border-neutral-200 dark:border-coolgray-400"> <div x-init="window.addEventListener('scroll', () => isSticky = window.pageYOffset > 100)"
<div class="flex flex-col gap-4 lg:flex-row mb-4"> class="sticky z-10 top-0 backdrop-blur-sm border-b border-neutral-200 dark:border-coolgray-400">
<div class="flex flex-col gap-4 lg:flex-row">
<h1>New Resource</h1> <h1>New Resource</h1>
<div class="w-full lg:w-96"> <div class="w-full lg:w-96">
<x-forms.select wire:model.live="selectedEnvironment"> <x-forms.select wire:model.live="selectedEnvironment">
@ -23,25 +24,34 @@
<div x-show="loading || categories.length === 0" <div x-show="loading || categories.length === 0"
class="flex items-center justify-between gap-2 py-1.5 px-3 w-64 text-sm rounded-sm border-0 ring-2 ring-inset ring-neutral-200 dark:ring-coolgray-300 bg-neutral-100 dark:bg-coolgray-200 cursor-not-allowed whitespace-nowrap opacity-50"> class="flex items-center justify-between gap-2 py-1.5 px-3 w-64 text-sm rounded-sm border-0 ring-2 ring-inset ring-neutral-200 dark:ring-coolgray-300 bg-neutral-100 dark:bg-coolgray-200 cursor-not-allowed whitespace-nowrap opacity-50">
<span class="text-sm text-neutral-400 dark:text-neutral-600">Filter by category</span> <span class="text-sm text-neutral-400 dark:text-neutral-600">Filter by category</span>
<svg class="w-4 h-4 text-neutral-400 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-4 h-4 text-neutral-400 shrink-0" fill="none" stroke="currentColor"
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7" />
</svg> </svg>
</div> </div>
<!-- Active State --> <!-- Active State -->
<div x-show="!loading && categories.length > 0" <div x-show="!loading && categories.length > 0"
@click="openCategoryDropdown = !openCategoryDropdown; $nextTick(() => { if (openCategoryDropdown) $refs.categorySearchInput.focus() })" @click="openCategoryDropdown = !openCategoryDropdown; $nextTick(() => { if (openCategoryDropdown) $refs.categorySearchInput.focus() })"
class="flex items-center justify-between gap-2 py-1.5 px-3 w-64 text-sm rounded-sm border-0 ring-2 ring-inset ring-neutral-200 dark:ring-coolgray-300 bg-white dark:bg-coolgray-100 cursor-pointer hover:ring-coolgray-400 transition-all whitespace-nowrap"> class="flex items-center justify-between gap-2 py-1.5 px-3 w-64 text-sm rounded-sm border-0 ring-2 ring-inset ring-neutral-200 dark:ring-coolgray-300 bg-white dark:bg-coolgray-100 cursor-pointer hover:ring-coolgray-400 transition-all whitespace-nowrap">
<span class="text-sm truncate" x-text="selectedCategory === '' ? 'Filter by category' : selectedCategory" :class="selectedCategory === '' ? 'text-neutral-400 dark:text-neutral-600' : 'capitalize text-black dark:text-white'"></span> <span class="text-sm truncate"
<svg class="w-4 h-4 transition-transform text-neutral-400 shrink-0" :class="{ 'rotate-180': openCategoryDropdown }" fill="none" x-text="selectedCategory === '' ? 'Filter by category' : selectedCategory"
stroke="currentColor" viewBox="0 0 24 24"> :class="selectedCategory === '' ? 'text-neutral-400 dark:text-neutral-600' :
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> 'capitalize text-black dark:text-white'"></span>
<svg class="w-4 h-4 transition-transform text-neutral-400 shrink-0"
:class="{ 'rotate-180': openCategoryDropdown }" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7" />
</svg> </svg>
</div> </div>
<!-- Dropdown Menu --> <!-- Dropdown Menu -->
<div x-show="openCategoryDropdown" x-transition <div x-show="openCategoryDropdown" x-transition
class="absolute z-50 w-full mt-1 bg-white dark:bg-coolgray-100 border border-neutral-300 dark:border-coolgray-400 rounded shadow-lg overflow-hidden"> class="absolute z-50 w-full mt-1 bg-white dark:bg-coolgray-100 border border-neutral-300 dark:border-coolgray-400 rounded shadow-lg overflow-hidden">
<div class="sticky top-0 p-2 bg-white dark:bg-coolgray-100 border-b border-neutral-300 dark:border-coolgray-400"> <div
<input type="text" x-ref="categorySearchInput" x-model="categorySearch" placeholder="Search categories..." class="sticky top-0 p-2 bg-white dark:bg-coolgray-100 border-b border-neutral-300 dark:border-coolgray-400">
<input type="text" x-ref="categorySearchInput" x-model="categorySearch"
placeholder="Search categories..."
class="w-full px-2 py-1 text-sm rounded border border-neutral-300 dark:border-coolgray-400 bg-white dark:bg-coolgray-200 focus:outline-none focus:ring-2 focus:ring-coolgray-400" class="w-full px-2 py-1 text-sm rounded border border-neutral-300 dark:border-coolgray-400 bg-white dark:bg-coolgray-200 focus:outline-none focus:ring-2 focus:ring-coolgray-400"
@click.stop> @click.stop>
</div> </div>
@ -51,7 +61,9 @@ class="px-3 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-coolgray-200"
:class="{ 'bg-neutral-50 dark:bg-coolgray-300': selectedCategory === '' }"> :class="{ 'bg-neutral-50 dark:bg-coolgray-300': selectedCategory === '' }">
<span class="text-sm">All Categories</span> <span class="text-sm">All Categories</span>
</div> </div>
<template x-for="category in categories.filter(cat => categorySearch === '' || cat.toLowerCase().includes(categorySearch.toLowerCase()))" :key="category"> <template
x-for="category in categories.filter(cat => categorySearch === '' || cat.toLowerCase().includes(categorySearch.toLowerCase()))"
:key="category">
<div @click="selectedCategory = category; categorySearch = ''; openCategoryDropdown = false" <div @click="selectedCategory = category; categorySearch = ''; openCategoryDropdown = false"
class="px-3 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-coolgray-200 capitalize" class="px-3 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-coolgray-200 capitalize"
:class="{ 'bg-neutral-50 dark:bg-coolgray-300': selectedCategory === category }"> :class="{ 'bg-neutral-50 dark:bg-coolgray-300': selectedCategory === category }">
@ -66,7 +78,8 @@ class="px-3 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-coolgray-200
<div x-show="loading">Loading...</div> <div x-show="loading">Loading...</div>
<div x-show="!loading" class="flex flex-col gap-4 py-4"> <div x-show="!loading" class="flex flex-col gap-4 py-4">
<h2 x-show="filteredGitBasedApplications.length > 0">Applications</h2> <h2 x-show="filteredGitBasedApplications.length > 0">Applications</h2>
<div x-show="filteredGitBasedApplications.length > 0 || filteredDockerBasedApplications.length > 0" class="grid grid-cols-1 lg:grid-cols-2 gap-8"> <div x-show="filteredGitBasedApplications.length > 0 || filteredDockerBasedApplications.length > 0"
class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div x-show="filteredGitBasedApplications.length > 0" class="space-y-4"> <div x-show="filteredGitBasedApplications.length > 0" class="space-y-4">
<h4>Git Based</h4> <h4>Git Based</h4>
<div class="grid justify-start grid-cols-1 gap-4 text-left"> <div class="grid justify-start grid-cols-1 gap-4 text-left">
@ -75,13 +88,13 @@ class="px-3 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-coolgray-200
:class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }"> :class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }">
<x-resource-view> <x-resource-view>
<x-slot:title><span x-text="application.name"></span></x-slot> <x-slot:title><span x-text="application.name"></span></x-slot>
<x-slot:description> <x-slot:description>
<span x-html="window.sanitizeHTML(application.description)"></span> <span x-html="window.sanitizeHTML(application.description)"></span>
</x-slot> </x-slot>
<x-slot:logo> <x-slot:logo>
<img class="w-full h-full p-2 transition-all duration-200 dark:bg-white/10 bg-black/10 object-contain" <img class="w-full h-full p-2 transition-all duration-200 dark:bg-white/10 bg-black/10 object-contain"
:src="application.logo"> :src="application.logo">
</x-slot:logo> </x-slot:logo>
</x-resource-view> </x-resource-view>
</div> </div>
</template> </template>
@ -95,10 +108,10 @@ class="px-3 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-coolgray-200
:class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }"> :class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }">
<x-resource-view> <x-resource-view>
<x-slot:title><span x-text="application.name"></span></x-slot> <x-slot:title><span x-text="application.name"></span></x-slot>
<x-slot:description><span x-text="application.description"></span></x-slot> <x-slot:description><span x-text="application.description"></span></x-slot>
<x-slot:logo> <img <x-slot:logo> <img
class="w-full h-full p-2 transition-all duration-200 dark:bg-white/10 bg-black/10 object-contain" class="w-full h-full p-2 transition-all duration-200 dark:bg-white/10 bg-black/10 object-contain"
:src="application.logo"></x-slot> :src="application.logo"></x-slot>
</x-resource-view> </x-resource-view>
</div> </div>
</template> </template>
@ -107,23 +120,23 @@ class="w-full h-full p-2 transition-all duration-200 dark:bg-white/10 bg-black/1
</div> </div>
<div x-show="filteredDatabases.length > 0" class="mt-8"> <div x-show="filteredDatabases.length > 0" class="mt-8">
<h2 class="mb-4">Databases</h2> <h2 class="mb-4">Databases</h2>
<div x-show="filteredDatabases.length > 0" <div x-show="filteredDatabases.length > 0"
class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3"> class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
<template x-for="database in filteredDatabases" :key="database.id"> <template x-for="database in filteredDatabases" :key="database.id">
<div x-on:click="setType(database.id)" <div x-on:click="setType(database.id)"
:class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }"> :class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }">
<x-resource-view> <x-resource-view>
<x-slot:title><span x-text="database.name"></span></x-slot> <x-slot:title><span x-text="database.name"></span></x-slot>
<x-slot:description><span x-text="database.description"></span></x-slot> <x-slot:description><span x-text="database.description"></span></x-slot>
<x-slot:logo> <x-slot:logo>
<span x-show="database.logo"> <span x-show="database.logo">
<span x-html="database.logo"></span> <span x-html="database.logo"></span>
</span> </span>
</x-slot> </x-slot>
</x-resource-view> </x-resource-view>
</div> </div>
</template> </template>
</div> </div>
</div> </div>
<div x-show="filteredServices.length > 0" class="mt-8"> <div x-show="filteredServices.length > 0" class="mt-8">
<div class="flex items-center gap-4" x-init="loadResources"> <div class="flex items-center gap-4" x-init="loadResources">
@ -131,46 +144,49 @@ class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
<x-forms.button x-on:click="loadResources">Reload List</x-forms.button> <x-forms.button x-on:click="loadResources">Reload List</x-forms.button>
</div> </div>
<x-callout type="info" title="Trademarks Policy" class="mt-4 mb-6"> <x-callout type="info" title="Trademarks Policy" class="mt-4 mb-6">
The respective trademarks mentioned here are owned by the respective companies, and use of them does not imply any affiliation or endorsement. The respective trademarks mentioned here are owned by the respective companies, and use of them
does not imply any affiliation or endorsement.
</x-callout> </x-callout>
<div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3"> <div class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
<template x-for="service in filteredServices" :key="service.name"> <template x-for="service in filteredServices" :key="service.name">
<div x-on:click="setType('one-click-service-' + service.name)" <div class="relative" x-on:click="setType('one-click-service-' + service.name)"
:class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }"> :class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }">
<x-resource-view> <x-resource-view>
<x-slot:title> <x-slot:title>
<template x-if="service.name"> <template x-if="service.name">
<span x-text="service.name"></span> <span x-text="service.name"></span>
</template> </template>
</x-slot> </x-slot>
<x-slot:description> <x-slot:description>
<template x-if="service.slogan"> <template x-if="service.slogan">
<span x-text="service.slogan"></span> <span x-text="service.slogan"></span>
</template> </template>
</x-slot> </x-slot>
<x-slot:logo> <x-slot:logo>
<template x-if="service.logo"> <template x-if="service.logo">
<img class="w-full h-full p-2 transition-all duration-200 dark:bg-white/10 bg-black/10 object-contain" <img class="w-full h-full p-2 transition-all duration-200 dark:bg-white/10 bg-black/10 object-contain"
:src='service.logo' :src='service.logo'
x-on:error.window="$event.target.src = service.logo_github_url" x-on:error.window="$event.target.src = service.logo_github_url"
onerror="this.onerror=null; this.src=this.getAttribute('data-fallback');" onerror="this.onerror=null; this.src=this.getAttribute('data-fallback');"
x-on:error="$event.target.src = '/coolify-logo.svg'" x-on:error="$event.target.src = '/coolify-logo.svg'"
:data-fallback='service.logo_github_url' /> :data-fallback='service.logo_github_url' />
</template> </template>
</x-slot:logo> </x-slot:logo>
<x-slot:documentation>
<template x-if="service.documentation">
<div class="flex items-center px-2" title="Read the documentation.">
<a class="p-2 rounded-sm hover:bg-gray-100 dark:hover:bg-coolgray-200 hover:no-underline dark:group-hover:text-white text-neutral-600"
onclick="event.stopPropagation()" :href="service.documentation"
target="_blank">
Docs
</a>
</div>
</template>
</x-slot:documentation>
</x-resource-view> </x-resource-view>
<template x-if="shouldShowDocIcon(service)">
<a :href="getDocLink(service) || coolifyDocsUrl(service.name)" target="_blank"
@click.stop @mouseenter="resolveDocLink(service)"
class="absolute top-2 right-2 p-1.5 rounded hover:bg-neutral-200 dark:hover:bg-coolgray-300 transition-colors"
:class="{ 'opacity-50': docCheckInProgress[service.name] }"
title="View documentation">
<svg class="w-4 h-4 text-neutral-600 dark:text-neutral-400" fill="none"
stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
</a>
</template>
</div> </div>
</template> </template>
</div> </div>
@ -197,6 +213,8 @@ function searchResources() {
gitBasedApplications: [], gitBasedApplications: [],
dockerBasedApplications: [], dockerBasedApplications: [],
databases: [], databases: [],
docLinkCache: {}, // Cache resolved doc URLs: { serviceName: url | null }
docCheckInProgress: {}, // Track ongoing checks: { serviceName: boolean }
setType(type) { setType(type) {
if (this.selecting) return; if (this.selecting) return;
this.selecting = true; this.selecting = true;
@ -221,6 +239,81 @@ function searchResources() {
this.$refs.searchInput.focus(); this.$refs.searchInput.focus();
}); });
}, },
extractBaseServiceName(serviceName) {
// Convert to lowercase and replace spaces with dashes to match original format
const normalized = serviceName.toLowerCase().replace(/\s+/g, '-');
// Remove flavor suffixes: -with-*, -without-*
return normalized.replace(/-(with|without)-.+$/, '');
},
coolifyDocsUrl(serviceName) {
const baseName = this.extractBaseServiceName(serviceName);
return 'https://coolify.io/docs/services/' + baseName;
},
officialDocsUrl(service) {
return service.documentation || null;
},
async checkUrlExists(url) {
if (!url) return false;
try {
const response = await fetch(url, {
method: 'HEAD'
});
return response.ok;
} catch (e) {
// CORS error or network error - assume URL exists
return true;
}
},
async resolveDocLink(service) {
const serviceName = service.name;
// Already cached?
if (this.docLinkCache.hasOwnProperty(serviceName)) {
return this.docLinkCache[serviceName];
}
// Already checking?
if (this.docCheckInProgress[serviceName]) {
return null;
}
this.docCheckInProgress[serviceName] = true;
// 1. Try Coolify docs first
const coolifyUrl = this.coolifyDocsUrl(serviceName);
const coolifyExists = await this.checkUrlExists(coolifyUrl);
if (coolifyExists) {
this.docLinkCache[serviceName] = coolifyUrl;
this.docCheckInProgress[serviceName] = false;
return coolifyUrl;
}
// 2. Fall back to official docs
const officialUrl = this.officialDocsUrl(service);
if (officialUrl) {
const officialExists = await this.checkUrlExists(officialUrl);
if (officialExists) {
this.docLinkCache[serviceName] = officialUrl;
this.docCheckInProgress[serviceName] = false;
return officialUrl;
}
}
// 3. Both failed - cache null to hide icon
this.docLinkCache[serviceName] = null;
this.docCheckInProgress[serviceName] = false;
return null;
},
getDocLink(service) {
return this.docLinkCache[service.name];
},
shouldShowDocIcon(service) {
const cached = this.docLinkCache[service.name];
// Show icon if: not checked yet OR has a valid URL
return cached === undefined || cached !== null;
},
filterAndSort(items, isSort = true) { filterAndSort(items, isSort = true) {
const searchLower = this.search.trim().toLowerCase(); const searchLower = this.search.trim().toLowerCase();
let filtered = Object.values(items); let filtered = Object.values(items);
@ -231,9 +324,10 @@ function searchResources() {
filtered = filtered.filter(item => { filtered = filtered.filter(item => {
if (!item.category) return false; if (!item.category) return false;
// Handle comma-separated categories // Handle comma-separated categories
const categories = item.category.includes(',') const categories = item.category.includes(',') ?
? item.category.split(',').map(c => c.trim().toLowerCase()) item.category.split(',').map(c => c.trim().toLowerCase()) : [item.category
: [item.category.toLowerCase()]; .toLowerCase()
];
return categories.includes(selectedCategoryLower); return categories.includes(selectedCategoryLower);
}); });
} }
@ -297,7 +391,7 @@ function searchResources() {
</a> </div> </a> </div>
@else @else
@forelse($servers as $server) @forelse($servers as $server)
<div class="w-full box group" wire:click="setServer({{ $server }})"> <div class="w-full coolbox group" wire:click="setServer({{ $server }})">
<div class="flex flex-col mx-6"> <div class="flex flex-col mx-6">
<div class="box-title"> <div class="box-title">
{{ $server->name }} {{ $server->name }}
@ -310,7 +404,8 @@ function searchResources() {
@empty @empty
<div> <div>
<div>No validated & reachable servers found. <a class="underline dark:text-white" href="/servers"> <div>No validated & reachable servers found. <a class="underline dark:text-white"
href="/servers">
Go to servers page Go to servers page
</a></div> </a></div>
</div> </div>
@ -326,7 +421,7 @@ function searchResources() {
<div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap"> <div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap">
@if ($server->isSwarm()) @if ($server->isSwarm())
@foreach ($swarmDockers as $swarmDocker) @foreach ($swarmDockers as $swarmDocker)
<div class="w-full box group" wire:click="setDestination('{{ $swarmDocker->uuid }}')"> <div class="w-full coolbox group" wire:click="setDestination('{{ $swarmDocker->uuid }}')">
<div class="flex flex-col mx-6"> <div class="flex flex-col mx-6">
<div class="font-bold dark:group-hover:text-white"> <div class="font-bold dark:group-hover:text-white">
Swarm Docker <span class="text-xs">({{ $swarmDocker->name }})</span> Swarm Docker <span class="text-xs">({{ $swarmDocker->name }})</span>
@ -336,7 +431,7 @@ function searchResources() {
@endforeach @endforeach
@else @else
@foreach ($standaloneDockers as $standaloneDocker) @foreach ($standaloneDockers as $standaloneDocker)
<div class="w-full box group" wire:click="setDestination('{{ $standaloneDocker->uuid }}')"> <div class="w-full coolbox group" wire:click="setDestination('{{ $standaloneDocker->uuid }}')">
<div class="flex flex-col mx-6"> <div class="flex flex-col mx-6">
<div class="box-title"> <div class="box-title">
Standalone Docker <span class="text-xs">({{ $standaloneDocker->name }})</span> Standalone Docker <span class="text-xs">({{ $standaloneDocker->name }})</span>
@ -370,7 +465,8 @@ function searchResources() {
<div class="flex items-center px-2" title="Read the documentation."> <div class="flex items-center px-2" title="Read the documentation.">
<a class="p-2 hover:underline dark:group-hover:text-white dark:text-white text-neutral-6000" <a class="p-2 hover:underline dark:group-hover:text-white dark:text-white text-neutral-6000"
onclick="event.stopPropagation()" href="https://hub.docker.com/_/postgres/" target="_blank"> onclick="event.stopPropagation()" href="https://hub.docker.com/_/postgres/"
target="_blank">
Documentation Documentation
</a> </a>
</div> </div>
@ -388,7 +484,8 @@ function searchResources() {
<div class="flex-1"></div> <div class="flex-1"></div>
<div class="flex items-center px-2" title="Read the documentation."> <div class="flex items-center px-2" title="Read the documentation.">
<a class="p-2 hover:underline dark:group-hover:text-white dark:text-white text-neutral-600" <a class="p-2 hover:underline dark:group-hover:text-white dark:text-white text-neutral-600"
onclick="event.stopPropagation()" href="https://github.com/supabase/postgres" target="_blank"> onclick="event.stopPropagation()" href="https://github.com/supabase/postgres"
target="_blank">
Documentation Documentation
</a> </a>
</div> </div>
@ -426,7 +523,8 @@ function searchResources() {
<div class="flex items-center px-2" title="Read the documentation."> <div class="flex items-center px-2" title="Read the documentation.">
<a class="p-2 hover:underline dark:group-hover:text-white dark:text-white text-neutral-600" <a class="p-2 hover:underline dark:group-hover:text-white dark:text-white text-neutral-600"
onclick="event.stopPropagation()" href="https://github.com/pgvector/pgvector" target="_blank"> onclick="event.stopPropagation()" href="https://github.com/pgvector/pgvector"
target="_blank">
Documentation Documentation
</a> </a>
</div> </div>
@ -441,4 +539,4 @@ function searchResources() {
<x-forms.button type="submit">Add Database</x-forms.button> <x-forms.button type="submit">Add Database</x-forms.button>
</form> </form>
@endif @endif
</div> </div>

View file

@ -54,7 +54,7 @@ class="button">+
@if ($environment->isEmpty()) @if ($environment->isEmpty())
@can('createAnyResource') @can('createAnyResource')
<a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}" <a href="{{ route('project.resource.create', ['project_uuid' => data_get($parameters, 'project_uuid'), 'environment_uuid' => data_get($environment, 'uuid')]) }}"
class="items-center justify-center box">+ Add Resource</a> class="items-center justify-center coolbox">+ Add Resource</a>
@else @else
<div <div
class="flex flex-col items-center justify-center p-8 text-center border border-dashed border-neutral-300 dark:border-coolgray-300 rounded-lg"> class="flex flex-col items-center justify-center p-8 text-center border border-dashed border-neutral-300 dark:border-coolgray-300 rounded-lg">
@ -94,7 +94,7 @@ class="font-semibold" x-text="search"></span>".</p>
class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3"> class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
<template x-for="item in filteredApplications" :key="item.uuid"> <template x-for="item in filteredApplications" :key="item.uuid">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 coolbox group" :href="item.hrefLink">
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<div class="flex gap-2 px-4"> <div class="flex gap-2 px-4">
<div class="pb-2 truncate box-title" x-text="item.name"></div> <div class="pb-2 truncate box-title" x-text="item.name"></div>
@ -143,7 +143,7 @@ class="flex flex-wrap gap-1 pt-1 dark:group-hover:text-white group-hover:text-bl
class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3"> class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
<template x-for="item in filteredDatabases" :key="item.uuid"> <template x-for="item in filteredDatabases" :key="item.uuid">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 coolbox group" :href="item.hrefLink">
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<div class="flex gap-2 px-4"> <div class="flex gap-2 px-4">
<div class="pb-2 truncate box-title" x-text="item.name"></div> <div class="pb-2 truncate box-title" x-text="item.name"></div>
@ -192,7 +192,7 @@ class="flex flex-wrap gap-1 pt-1 dark:group-hover:text-white group-hover:text-bl
class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3"> class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
<template x-for="item in filteredServices" :key="item.uuid"> <template x-for="item in filteredServices" :key="item.uuid">
<span> <span>
<a class="h-24 box group" :href="item.hrefLink"> <a class="h-24 coolbox group" :href="item.hrefLink">
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<div class="flex gap-2 px-4"> <div class="flex gap-2 px-4">
<div class="pb-2 truncate box-title" x-text="item.name"></div> <div class="pb-2 truncate box-title" x-text="item.name"></div>

View file

@ -90,7 +90,7 @@ class="absolute bg-error -top-1 -left-1 badge "></div>
<div class="grid grid-cols-1 gap-4"> <div class="grid grid-cols-1 gap-4">
@foreach ($networks as $network) @foreach ($networks as $network)
<div wire:click="addServer('{{ $network->id }}','{{ data_get($network, 'server.id') }}')" <div wire:click="addServer('{{ $network->id }}','{{ data_get($network, 'server.id') }}')"
class="relative flex flex-col dark:text-white box group"> class="relative flex flex-col dark:text-white coolbox group">
<div> <div>
<div class="box-title"> <div class="box-title">
Server: {{ data_get($network, 'server.name') }} Server: {{ data_get($network, 'server.name') }}

View file

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

View file

@ -21,7 +21,7 @@
<div class="text-xs truncate subtitle lg:text-sm">{{ $project->name }}.</div> <div class="text-xs truncate subtitle lg:text-sm">{{ $project->name }}.</div>
<div class="grid gap-2 lg:grid-cols-2"> <div class="grid gap-2 lg:grid-cols-2">
@forelse ($project->environments->sortBy('created_at') as $environment) @forelse ($project->environments->sortBy('created_at') as $environment)
<div class="gap-2 box group"> <div class="gap-2 coolbox group">
<div class="flex flex-1 mx-6"> <div class="flex flex-1 mx-6">
<a class="flex flex-col justify-center flex-1" <a class="flex flex-col justify-center flex-1"
href="{{ route('project.resource.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}"> href="{{ route('project.resource.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}">

View file

@ -16,7 +16,7 @@
@forelse ($privateKeys as $key) @forelse ($privateKeys as $key)
@can('view', $key) @can('view', $key)
{{-- Admin/Owner: Clickable link --}} {{-- Admin/Owner: Clickable link --}}
<a class="box group" <a class="coolbox group"
href="{{ route('security.private-key.show', ['private_key_uuid' => data_get($key, 'uuid')]) }}"> href="{{ route('security.private-key.show', ['private_key_uuid' => data_get($key, 'uuid')]) }}">
<div class="flex flex-col justify-center mx-6"> <div class="flex flex-col justify-center mx-6">
<div class="box-title"> <div class="box-title">
@ -33,7 +33,7 @@ class="inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-ye
</a> </a>
@else @else
{{-- Member: Visible but not clickable --}} {{-- Member: Visible but not clickable --}}
<div class="box opacity-60 cursor-not-allowed hover:bg-transparent dark:hover:bg-transparent" title="You don't have permission to view this private key"> <div class="coolbox opacity-60 !cursor-not-allowed hover:bg-transparent dark:hover:bg-transparent" title="You don't have permission to view this private key">
<div class="flex flex-col justify-center mx-6"> <div class="flex flex-col justify-center mx-6">
<div class="box-title"> <div class="box-title">
{{ data_get($key, 'name') }} {{ data_get($key, 'name') }}

View file

@ -4,7 +4,7 @@
<div> <div>
<x-modal-input title="Connect a Hetzner Server"> <x-modal-input title="Connect a Hetzner Server">
<x-slot:content> <x-slot:content>
<div class="relative gap-2 cursor-pointer box group"> <div class="relative gap-2 cursor-pointer coolbox group">
<div class="flex items-center gap-4 mx-6"> <div class="flex items-center gap-4 mx-6">
<svg class="w-10 h-10 flex-shrink-0" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <svg class="w-10 h-10 flex-shrink-0" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="200" fill="#D50C2D" rx="8" /> <rect width="200" height="200" fill="#D50C2D" rx="8" />

View file

@ -15,7 +15,7 @@
@forelse ($servers as $server) @forelse ($servers as $server)
<a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}" <a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
@class([ @class([
'gap-2 border cursor-pointer box group', 'gap-2 border cursor-pointer coolbox group',
'border-red-500' => 'border-red-500' =>
!$server->settings->is_reachable || $server->settings->force_disabled, !$server->settings->is_reachable || $server->settings->force_disabled,
])> ])>

View file

@ -170,13 +170,13 @@ class="underline text-white">Traefik changelog</a> to understand breaking change
<div class="subtitle">Select a proxy you would like to use on this server.</div> <div class="subtitle">Select a proxy you would like to use on this server.</div>
@can('update', $server) @can('update', $server)
<div class="grid gap-4"> <div class="grid gap-4">
<x-forms.button class="box" wire:click="selectProxy('NONE')"> <x-forms.button class="coolbox" wire:click="selectProxy('NONE')">
Custom (None) Custom (None)
</x-forms.button> </x-forms.button>
<x-forms.button class="box" wire:click="selectProxy('TRAEFIK')"> <x-forms.button class="coolbox" wire:click="selectProxy('TRAEFIK')">
Traefik Traefik
</x-forms.button> </x-forms.button>
<x-forms.button class="box" wire:click="selectProxy('CADDY')"> <x-forms.button class="coolbox" wire:click="selectProxy('CADDY')">
Caddy Caddy
</x-forms.button> </x-forms.button>
{{-- <x-forms.button disabled class="box"> {{-- <x-forms.button disabled class="box">

View file

@ -11,7 +11,7 @@
<h2>Project: {{ data_get($project, 'name') }}</h2> <h2>Project: {{ data_get($project, 'name') }}</h2>
<div class="pt-0 pb-3">{{ data_get($project, 'description') }}</div> <div class="pt-0 pb-3">{{ data_get($project, 'description') }}</div>
@forelse ($project->environments as $environment) @forelse ($project->environments as $environment)
<a class="box group" <a class="coolbox group"
href="{{ route('shared-variables.environment.show', [ href="{{ route('shared-variables.environment.show', [
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
'environment_uuid' => $environment->uuid, 'environment_uuid' => $environment->uuid,

View file

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

View file

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

View file

@ -35,7 +35,7 @@
</svg> </svg>
<span>You must complete this step before you can use this source!</span> <span>You must complete this step before you can use this source!</span>
</div> </div>
<a class="items-center justify-center box" href="{{ getInstallationPath($github_app) }}"> <a class="items-center justify-center coolbox" href="{{ getInstallationPath($github_app) }}">
Install Repositories on GitHub Install Repositories on GitHub
</a> </a>
@else @else

View file

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

View file

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

View file

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