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];
}
@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 {
@apply rounded-sm hover:bg-neutral-300 dark:hover:bg-coolgray-500/20;
}

View file

@ -1,7 +1,6 @@
<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',
'cursor-pointer' => !$upgrade,
'hover:border-l-red-500 cursor-not-allowed' => $upgrade,
'coolbox group',
'!cursor-not-allowed hover:border-l-red-500' => $upgrade,
])>
<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">

View file

@ -17,7 +17,7 @@
@if ($foundUsers->count() > 0)
<div class="flex flex-wrap gap-2 pt-4">
@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="box-title">{{ $user->name }}</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)
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
@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>
<div class="flex flex-1 mx-6">
<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)
<a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
@class([
'gap-2 border cursor-pointer box group',
'gap-2 border cursor-pointer coolbox group',
'border-red-500' =>
!$server->settings->is_reachable || $server->settings->force_disabled,
])>

View file

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

View file

@ -13,7 +13,7 @@
<div class="subtitle">All your projects are here.</div>
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2 -mt-1">
@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>
<div class="flex flex-1 mx-6">
<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 ">
@forelse ($private_keys as $key)
@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 }}">
<div class="flex flex-col mx-6">
<div class="box-title">
@ -20,7 +20,7 @@ class="loading loading-xs dark:text-warning loading-spinner"></span>
</div>
</div>
@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 }}">
<div class="flex flex-col mx-6">
<div class="box-title">

View file

@ -21,7 +21,7 @@
<div class="flex flex-col justify-center gap-2 text-left">
@foreach ($github_apps as $ghapp)
<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:key="{{ $ghapp->id }}">
<div class="flex mr-4">

View file

@ -1,8 +1,9 @@
<div x-data x-init="$wire.loadServers">
<div x-data="searchResources()">
@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 class="flex flex-col gap-4 lg:flex-row mb-4">
<div x-init="window.addEventListener('scroll', () => isSticky = window.pageYOffset > 100)"
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>
<div class="w-full lg:w-96">
<x-forms.select wire:model.live="selectedEnvironment">
@ -23,25 +24,34 @@
<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">
<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">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
<svg class="w-4 h-4 text-neutral-400 shrink-0" 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>
</div>
<!-- Active State -->
<div x-show="!loading && categories.length > 0"
@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">
<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>
<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" />
<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>
<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>
</div>
<!-- Dropdown Menu -->
<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">
<div 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..."
<div
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"
@click.stop>
</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 === '' }">
<span class="text-sm">All Categories</span>
</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"
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 }">
@ -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" class="flex flex-col gap-4 py-4">
<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">
<h4>Git Based</h4>
<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 }">
<x-resource-view>
<x-slot:title><span x-text="application.name"></span></x-slot>
<x-slot:description>
<span x-html="window.sanitizeHTML(application.description)"></span>
</x-slot>
<x-slot:logo>
<img 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:logo>
<x-slot:description>
<span x-html="window.sanitizeHTML(application.description)"></span>
</x-slot>
<x-slot:logo>
<img 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:logo>
</x-resource-view>
</div>
</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 }">
<x-resource-view>
<x-slot:title><span x-text="application.name"></span></x-slot>
<x-slot:description><span x-text="application.description"></span></x-slot>
<x-slot:logo> <img
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>
<x-slot:description><span x-text="application.description"></span></x-slot>
<x-slot:logo> <img
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>
</x-resource-view>
</div>
</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 x-show="filteredDatabases.length > 0" class="mt-8">
<h2 class="mb-4">Databases</h2>
<div x-show="filteredDatabases.length > 0"
class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
<template x-for="database in filteredDatabases" :key="database.id">
<div x-on:click="setType(database.id)"
:class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }">
<x-resource-view>
<x-slot:title><span x-text="database.name"></span></x-slot>
<div x-show="filteredDatabases.length > 0"
class="grid justify-start grid-cols-1 gap-4 text-left xl:grid-cols-3">
<template x-for="database in filteredDatabases" :key="database.id">
<div x-on:click="setType(database.id)"
:class="{ 'cursor-pointer': !selecting, 'cursor-not-allowed opacity-50': selecting }">
<x-resource-view>
<x-slot:title><span x-text="database.name"></span></x-slot>
<x-slot:description><span x-text="database.description"></span></x-slot>
<x-slot:logo>
<span x-show="database.logo">
<span x-html="database.logo"></span>
</span>
</x-slot>
</x-resource-view>
</div>
</template>
</div>
<x-slot:logo>
<span x-show="database.logo">
<span x-html="database.logo"></span>
</span>
</x-slot>
</x-resource-view>
</div>
</template>
</div>
</div>
<div x-show="filteredServices.length > 0" class="mt-8">
<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>
</div>
<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>
<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">
<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 }">
<x-resource-view>
<x-slot:title>
<template x-if="service.name">
<span x-text="service.name"></span>
</template>
</x-slot>
<x-slot:description>
<template x-if="service.slogan">
<span x-text="service.slogan"></span>
</template>
</x-slot>
<x-slot: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"
:src='service.logo'
x-on:error.window="$event.target.src = service.logo_github_url"
onerror="this.onerror=null; this.src=this.getAttribute('data-fallback');"
x-on:error="$event.target.src = '/coolify-logo.svg'"
:data-fallback='service.logo_github_url' />
</template>
</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-slot>
<x-slot:description>
<template x-if="service.slogan">
<span x-text="service.slogan"></span>
</template>
</x-slot>
<x-slot: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"
:src='service.logo'
x-on:error.window="$event.target.src = service.logo_github_url"
onerror="this.onerror=null; this.src=this.getAttribute('data-fallback');"
x-on:error="$event.target.src = '/coolify-logo.svg'"
:data-fallback='service.logo_github_url' />
</template>
</x-slot:logo>
</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>
</template>
</div>
@ -197,6 +213,8 @@ function searchResources() {
gitBasedApplications: [],
dockerBasedApplications: [],
databases: [],
docLinkCache: {}, // Cache resolved doc URLs: { serviceName: url | null }
docCheckInProgress: {}, // Track ongoing checks: { serviceName: boolean }
setType(type) {
if (this.selecting) return;
this.selecting = true;
@ -221,6 +239,81 @@ function searchResources() {
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) {
const searchLower = this.search.trim().toLowerCase();
let filtered = Object.values(items);
@ -231,9 +324,10 @@ function searchResources() {
filtered = filtered.filter(item => {
if (!item.category) return false;
// Handle comma-separated categories
const categories = item.category.includes(',')
? item.category.split(',').map(c => c.trim().toLowerCase())
: [item.category.toLowerCase()];
const categories = item.category.includes(',') ?
item.category.split(',').map(c => c.trim().toLowerCase()) : [item.category
.toLowerCase()
];
return categories.includes(selectedCategoryLower);
});
}
@ -297,7 +391,7 @@ function searchResources() {
</a> </div>
@else
@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="box-title">
{{ $server->name }}
@ -310,7 +404,8 @@ function searchResources() {
@empty
<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
</a></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">
@if ($server->isSwarm())
@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="font-bold dark:group-hover:text-white">
Swarm Docker <span class="text-xs">({{ $swarmDocker->name }})</span>
@ -336,7 +431,7 @@ function searchResources() {
@endforeach
@else
@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="box-title">
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.">
<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
</a>
</div>
@ -388,7 +484,8 @@ function searchResources() {
<div class="flex-1"></div>
<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"
onclick="event.stopPropagation()" href="https://github.com/supabase/postgres" target="_blank">
onclick="event.stopPropagation()" href="https://github.com/supabase/postgres"
target="_blank">
Documentation
</a>
</div>
@ -426,7 +523,8 @@ function searchResources() {
<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"
onclick="event.stopPropagation()" href="https://github.com/pgvector/pgvector" target="_blank">
onclick="event.stopPropagation()" href="https://github.com/pgvector/pgvector"
target="_blank">
Documentation
</a>
</div>
@ -441,4 +539,4 @@ function searchResources() {
<x-forms.button type="submit">Add Database</x-forms.button>
</form>
@endif
</div>
</div>

View file

@ -54,7 +54,7 @@ class="button">+
@if ($environment->isEmpty())
@can('createAnyResource')
<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
<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">
@ -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">
<template x-for="item in filteredApplications" :key="item.uuid">
<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 gap-2 px-4">
<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">
<template x-for="item in filteredDatabases" :key="item.uuid">
<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 gap-2 px-4">
<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">
<template x-for="item in filteredServices" :key="item.uuid">
<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 gap-2 px-4">
<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">
@foreach ($networks as $network)
<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 class="box-title">
Server: {{ data_get($network, 'server.name') }}

View file

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

View file

@ -21,7 +21,7 @@
<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 box group">
<div class="gap-2 coolbox group">
<div class="flex flex-1 mx-6">
<a class="flex flex-col justify-center flex-1"
href="{{ route('project.resource.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid]) }}">

View file

@ -16,7 +16,7 @@
@forelse ($privateKeys as $key)
@can('view', $key)
{{-- 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')]) }}">
<div class="flex flex-col justify-center mx-6">
<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>
@else
{{-- 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="box-title">
{{ data_get($key, 'name') }}

View file

@ -4,7 +4,7 @@
<div>
<x-modal-input title="Connect a Hetzner Server">
<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">
<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" />

View file

@ -15,7 +15,7 @@
@forelse ($servers as $server)
<a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
@class([
'gap-2 border cursor-pointer box group',
'gap-2 border cursor-pointer coolbox group',
'border-red-500' =>
!$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>
@can('update', $server)
<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)
</x-forms.button>
<x-forms.button class="box" wire:click="selectProxy('TRAEFIK')">
<x-forms.button class="coolbox" wire:click="selectProxy('TRAEFIK')">
Traefik
</x-forms.button>
<x-forms.button class="box" wire:click="selectProxy('CADDY')">
<x-forms.button class="coolbox" wire:click="selectProxy('CADDY')">
Caddy
</x-forms.button>
{{-- <x-forms.button disabled class="box">

View file

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

View file

@ -8,19 +8,19 @@
<div class="subtitle">Set Team / Project / Environment wide variables.</div>
<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="box-title">Team wide</div>
<div class="box-description">Usable for all resources in a team.</div>
</div>
</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="box-title">Project wide</div>
<div class="box-description">Usable for all resources in a project.</div>
</div>
</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="box-title">Environment wide</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="flex flex-col gap-2">
@forelse ($projects as $project)
<a class="box group"
<a class="coolbox group"
href="{{ route('shared-variables.project.show', ['project_uuid' => data_get($project, 'uuid')]) }}">
<div class="flex flex-col justify-center mx-6 ">
<div class="box-title">{{ $project->name }}</div>

View file

@ -35,7 +35,7 @@
</svg>
<span>You must complete this step before you can use this source!</span>
</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
</a>
@else

View file

@ -13,7 +13,7 @@
<div class="subtitle">S3 storages for backups.</div>
<div class="grid gap-4 lg:grid-cols-2 -mt-1">
@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="box-title">
{{ $storage->name }}

View file

@ -8,7 +8,7 @@
<div class="flex flex-wrap gap-2 ">
@forelse ($tags as $oneTag)
<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>
@empty
<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">
@if (isset($applications) && count($applications) > 0)
@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="box-title">
{{ $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
@if (isset($services) && count($services) > 0)
@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="box-title">
{{ $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">
@foreach ($deployments as $deployment)
<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',
'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">
@forelse ($sources as $source)
@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')]) }}">
{{-- <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">