Merge branch 'next' into fix-environement-route

This commit is contained in:
Andras Bacsai
2024-12-17 12:17:50 +01:00
committed by GitHub
426 changed files with 11051 additions and 5406 deletions

View File

@@ -8,11 +8,13 @@
@endisset>
{{ $slot }}
@if ($attributes->whereStartsWith('wire:click')->first())
<x-loading-on-button wire:target="{{ $attributes->whereStartsWith('wire:click')->first() }}"
wire:loading.delay />
@elseif($attributes->whereStartsWith('wire:target')->first())
<x-loading-on-button wire:target="{{ $attributes->whereStartsWith('wire:target')->first() }}"
wire:loading.delay />
@if ($showLoadingIndicator)
@if ($attributes->whereStartsWith('wire:click')->first())
<x-loading-on-button wire:target="{{ $attributes->whereStartsWith('wire:click')->first() }}"
wire:loading.delay />
@elseif($attributes->whereStartsWith('wire:target')->first())
<x-loading-on-button wire:target="{{ $attributes->whereStartsWith('wire:target')->first() }}"
wire:loading.delay />
@endif
@endif
</button>

View File

@@ -5,8 +5,8 @@
'disabled' => false,
'instantSave' => false,
'value' => null,
'domValue' => null,
'checked' => false,
'hideLabel' => false,
'fullWidth' => false,
])
@@ -14,26 +14,32 @@
'flex flex-row items-center gap-4 pr-2 py-1 form-control min-w-fit dark:hover:bg-coolgray-100',
'w-full' => $fullWidth,
])>
@if (!$hideLabel)
<label @class([
'flex gap-4 items-center px-0 min-w-fit label w-full cursor-pointer',
])>
<span class="flex flex-grow gap-2">
@if ($label)
{!! $label !!}
@else
{{ $id }}
@endif
@if ($helper)
<x-helper :helper="$helper" />
@endif
</span>
@endif
<input @disabled($disabled) type="checkbox" {{ $attributes->merge(['class' => $defaultClass]) }}
@if ($instantSave) wire:loading.attr="disabled" wire:click='{{ $instantSave === 'instantSave' || $instantSave == '1' ? 'instantSave' : $instantSave }}'
@if ($checked) checked @endif
wire:model={{ $id }} @else wire:model={{ $value ?? $id }} @endif />
@if (!$hideLabel)
</label>
@endif
<label @class([
'flex gap-4 items-center px-0 min-w-fit label w-full cursor-pointer',
])>
<span class="flex flex-grow gap-2">
@if ($label)
{!! $label !!}
@else
{{ $id }}
@endif
@if ($helper)
<x-helper :helper="$helper" />
@endif
</span>
@if ($instantSave)
<input type="checkbox" @disabled($disabled) {{ $attributes->merge(['class' => $defaultClass]) }}
wire:loading.attr="disabled"
wire:click='{{ $instantSave === 'instantSave' || $instantSave == '1' ? 'instantSave' : $instantSave }}'
wire:model={{ $id }} @if ($checked) checked @endif />
@else
@if ($domValue)
<input type="checkbox" @disabled($disabled) {{ $attributes->merge(['class' => $defaultClass]) }}
value={{ $domValue }} @if ($checked) checked @endif />
@else
<input type="checkbox" @disabled($disabled) {{ $attributes->merge(['class' => $defaultClass]) }}
wire:model={{ $value ?? $id }} @if ($checked) checked @endif />
@endif
@endif
</label>
</div>

View File

@@ -7,6 +7,9 @@
monacoLoader: true,
monacoFontSize: '15px',
monacoId: $id('monaco-editor'),
isDarkMode() {
return document.documentElement.classList.contains('dark') || localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches);
},
monacoEditor(editor) {
editor.onDidChangeModelContent((e) => {
this.monacoContent = editor.getValue();
@@ -41,357 +44,9 @@
let proxy = URL.createObjectURL(new Blob([` self.MonacoEnvironment = { baseUrl: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.39.0/min' }; importScripts('https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.39.0/min/vs/base/worker/workerMain.min.js');`], { type: 'text/javascript' }));
window.MonacoEnvironment = { getWorkerUrl: () => proxy };
require(['vs/editor/editor.main'], () => {
monaco.editor.defineTheme('blackboard', {
'base': 'vs-dark',
'inherit': true,
'rules': [{
'background': editorBackground,
'token': ''
},
{
'foreground': '959da5',
'token': 'comment'
},
{
'foreground': '959da5',
'token': 'punctuation.definition.comment'
},
{
'foreground': '959da5',
'token': 'string.comment'
},
{
'foreground': 'c8e1ff',
'token': 'constant'
},
{
'foreground': 'c8e1ff',
'token': 'entity.name.constant'
},
{
'foreground': 'c8e1ff',
'token': 'variable.other.constant'
},
{
'foreground': 'c8e1ff',
'token': 'variable.language'
},
{
'foreground': 'b392f0',
'token': 'entity'
},
{
'foreground': 'b392f0',
'token': 'entity.name'
},
{
'foreground': 'f6f8fa',
'token': 'variable.parameter.function'
},
{
'foreground': '7bcc72',
'token': 'entity.name.tag'
},
{
'foreground': 'ea4a5a',
'token': 'keyword'
},
{
'foreground': 'ea4a5a',
'token': 'storage'
},
{
'foreground': 'ea4a5a',
'token': 'storage.type'
},
{
'foreground': 'f6f8fa',
'token': 'storage.modifier.package'
},
{
'foreground': 'f6f8fa',
'token': 'storage.modifier.import'
},
{
'foreground': 'f6f8fa',
'token': 'storage.type.java'
},
{
'foreground': '79b8ff',
'token': 'string'
},
{
'foreground': '79b8ff',
'token': 'punctuation.definition.string'
},
{
'foreground': '79b8ff',
'token': 'string punctuation.section.embedded source'
},
{
'foreground': 'c8e1ff',
'token': 'support'
},
{
'foreground': 'c8e1ff',
'token': 'meta.property-name'
},
{
'foreground': 'fb8532',
'token': 'variable'
},
{
'foreground': 'f6f8fa',
'token': 'variable.other'
},
{
'foreground': 'd73a49',
'fontStyle': 'bold italic underline',
'token': 'invalid.broken'
},
{
'foreground': 'd73a49',
'fontStyle': 'bold italic underline',
'token': 'invalid.deprecated'
},
{
'foreground': 'fafbfc',
'background': 'd73a49',
'fontStyle': 'italic underline',
'token': 'invalid.illegal'
},
{
'foreground': 'fafbfc',
'background': 'd73a49',
'fontStyle': 'italic underline',
'token': 'carriage-return'
},
{
'foreground': 'd73a49',
'fontStyle': 'bold italic underline',
'token': 'invalid.unimplemented'
},
{
'foreground': 'd73a49',
'token': 'message.error'
},
{
'foreground': 'f6f8fa',
'token': 'string source'
},
{
'foreground': 'c8e1ff',
'token': 'string variable'
},
{
'foreground': '79b8ff',
'token': 'source.regexp'
},
{
'foreground': '79b8ff',
'token': 'string.regexp'
},
{
'foreground': '79b8ff',
'token': 'string.regexp.character-class'
},
{
'foreground': '79b8ff',
'token': 'string.regexp constant.character.escape'
},
{
'foreground': '79b8ff',
'token': 'string.regexp source.ruby.embedded'
},
{
'foreground': '79b8ff',
'token': 'string.regexp string.regexp.arbitrary-repitition'
},
{
'foreground': '7bcc72',
'fontStyle': 'bold',
'token': 'string.regexp constant.character.escape'
},
{
'foreground': 'c8e1ff',
'token': 'support.constant'
},
{
'foreground': 'c8e1ff',
'token': 'support.variable'
},
{
'foreground': 'c8e1ff',
'token': 'meta.module-reference'
},
{
'foreground': 'fb8532',
'token': 'markup.list'
},
{
'foreground': '0366d6',
'fontStyle': 'bold',
'token': 'markup.heading'
},
{
'foreground': '0366d6',
'fontStyle': 'bold',
'token': 'markup.heading entity.name'
},
{
'foreground': 'c8e1ff',
'token': 'markup.quote'
},
{
'foreground': 'f6f8fa',
'fontStyle': 'italic',
'token': 'markup.italic'
},
{
'foreground': 'f6f8fa',
'fontStyle': 'bold',
'token': 'markup.bold'
},
{
'foreground': 'c8e1ff',
'token': 'markup.raw'
},
{
'foreground': 'b31d28',
'background': 'ffeef0',
'token': 'markup.deleted'
},
{
'foreground': 'b31d28',
'background': 'ffeef0',
'token': 'meta.diff.header.from-file'
},
{
'foreground': 'b31d28',
'background': 'ffeef0',
'token': 'punctuation.definition.deleted'
},
{
'foreground': '176f2c',
'background': 'f0fff4',
'token': 'markup.inserted'
},
{
'foreground': '176f2c',
'background': 'f0fff4',
'token': 'meta.diff.header.to-file'
},
{
'foreground': '176f2c',
'background': 'f0fff4',
'token': 'punctuation.definition.inserted'
},
{
'foreground': 'b08800',
'background': 'fffdef',
'token': 'markup.changed'
},
{
'foreground': 'b08800',
'background': 'fffdef',
'token': 'punctuation.definition.changed'
},
{
'foreground': '2f363d',
'background': '959da5',
'token': 'markup.ignored'
},
{
'foreground': '2f363d',
'background': '959da5',
'token': 'markup.untracked'
},
{
'foreground': 'b392f0',
'fontStyle': 'bold',
'token': 'meta.diff.range'
},
{
'foreground': 'c8e1ff',
'token': 'meta.diff.header'
},
{
'foreground': '0366d6',
'fontStyle': 'bold',
'token': 'meta.separator'
},
{
'foreground': '0366d6',
'token': 'meta.output'
},
{
'foreground': 'ffeef0',
'token': 'brackethighlighter.tag'
},
{
'foreground': 'ffeef0',
'token': 'brackethighlighter.curly'
},
{
'foreground': 'ffeef0',
'token': 'brackethighlighter.round'
},
{
'foreground': 'ffeef0',
'token': 'brackethighlighter.square'
},
{
'foreground': 'ffeef0',
'token': 'brackethighlighter.angle'
},
{
'foreground': 'ffeef0',
'token': 'brackethighlighter.quote'
},
{
'foreground': 'd73a49',
'token': 'brackethighlighter.unmatched'
},
{
'foreground': 'd73a49',
'token': 'sublimelinter.mark.error'
},
{
'foreground': 'fb8532',
'token': 'sublimelinter.mark.warning'
},
{
'foreground': '6a737d',
'token': 'sublimelinter.gutter-mark'
},
{
'foreground': '79b8ff',
'fontStyle': 'underline',
'token': 'constant.other.reference.link'
},
{
'foreground': '79b8ff',
'fontStyle': 'underline',
'token': 'string.other.link'
}
],
'colors': {
'editor.foreground': '#f6f8fa',
'editor.background': editorBackground,
'editor.selectionBackground': '#4c2889',
'editor.inactiveSelectionBackground': '#444d56',
'editor.lineHighlightBackground': '#444d56',
'editorCursor.foreground': '#ffffff',
'editorWhitespace.foreground': '#6a737d',
'editorIndentGuide.background': '#6a737d',
'editorIndentGuide.activeBackground': '#f6f8fa',
'editor.selectionHighlightBorder': '#444d56'
}
});
const editor = monaco.editor.create($refs.monacoEditorElement, {
value: monacoContent,
theme: editorTheme,
theme: document.documentElement.classList.contains('dark') ? 'vs-dark' : 'vs',
wordWrap: 'on',
readOnly: '{{ $readonly ?? false }}',
minimap: { enabled: false },
@@ -399,7 +54,20 @@
lineNumbersMinChars: 3,
automaticLayout: true,
language: '{{ $language }}'
});
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === 'class') {
const isDark = document.documentElement.classList.contains('dark');
monaco.editor.setTheme(isDark ? 'vs-dark' : 'vs');
}
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
});
monacoEditor(editor);
@@ -411,7 +79,6 @@
updatePlaceholder(editor.getValue());
// Watch for changes in monacoContent from Livewire
$watch('monacoContent', value => {
if (editor.getValue() !== value) {
editor.setValue(value);

View File

@@ -3,8 +3,8 @@
@if (isset($text))
<div>{{ $text }}</div>
@endif
<svg class="w-4 h-4 mx-1 ml-3 text-coollabs dark:text-warning animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24">
<svg class="w-4 h-4 mx-1 ml-3 text-coollabs dark:text-warning animate-spin" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">

View File

@@ -258,6 +258,7 @@
<input type="text" x-model="confirmationText"
class="p-2 pr-10 w-full text-black rounded cursor-text input" readonly>
<button @click="copyConfirmationText()"
x-show="window.isSecureContext"
class="absolute right-2 top-1/2 text-gray-500 transform -translate-y-1/2 hover:text-gray-700"
title="Copy confirmation text" x-ref="copyButton">
<template x-if="!copied">

View File

@@ -7,6 +7,7 @@
'action' => 'delete',
'content' => null,
'closeOutside' => true,
'minWidth' => '36rem',
])
<div x-data="{ modalOpen: false }" :class="{ 'z-40': modalOpen }" @keydown.window.escape="modalOpen=false"
class="relative w-auto h-auto" wire:ignore>
@@ -40,7 +41,7 @@
x-transition:leave="ease-in duration-100"
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
x-transition:leave-end="opacity-0 -translate-y-2 sm:scale-95"
class="relative w-full py-6 border rounded drop-shadow min-w-full lg:min-w-[36rem] max-w-fit bg-white border-neutral-200 dark:bg-base px-6 dark:border-coolgray-300">
class="relative w-full py-6 border rounded drop-shadow min-w-full lg:min-w-[{{ $minWidth }}] max-w-fit bg-white border-neutral-200 dark:bg-base px-6 dark:border-coolgray-300">
<div class="flex items-center justify-between pb-3">
<h3 class="text-2xl font-bold">{{ $title }}</h3>
<button @click="modalOpen=false"

View File

@@ -7,8 +7,13 @@
}
window.location.reload();
},
setZoom(zoom) {
localStorage.setItem('zoom', zoom);
window.location.reload();
},
init() {
this.full = localStorage.getItem('pageWidth');
this.zoom = localStorage.getItem('zoom');
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
const userSettings = localStorage.getItem('theme');
if (userSettings !== 'system') {
@@ -21,6 +26,7 @@
}
});
this.queryTheme();
this.checkZoom();
},
setTheme(type) {
this.theme = type;
@@ -44,6 +50,30 @@
this.theme = 'system';
document.documentElement.classList.remove('dark');
}
},
checkZoom() {
if (this.zoom === null) {
this.setZoom(100);
}
if (this.zoom === '90') {
const style = document.createElement('style');
style.textContent = `
html {
font-size: 93.75%;
}
:root {
--vh: 1vh;
}
@media (min-width: 1024px) {
html {
font-size: 87.5%;
}
}
`;
document.head.appendChild(style);
}
}
}">
<div class="flex pt-6 pb-4 pl-2">
@@ -69,7 +99,7 @@
</div>
</x-slot:title>
<div class="flex flex-col gap-1">
<div class="mb-1 font-bold border-b dark:border-coolgray-500 dark:text-white text-md">Color</div>
<div class="font-bold border-b dark:border-coolgray-500 dark:text-white text-md">Color</div>
<button @click="setTheme('dark')" class="px-1 dropdown-item-no-padding">Dark</button>
<button @click="setTheme('light')" class="px-1 dropdown-item-no-padding">Light</button>
<button @click="setTheme('system')" class="px-1 dropdown-item-no-padding">System</button>
@@ -78,6 +108,9 @@
x-show="full === 'full'">Center</button>
<button @click="switchWidth()" class="px-1 dropdown-item-no-padding"
x-show="full === 'center'">Full</button>
<div class="my-1 font-bold border-b dark:border-coolgray-500 dark:text-white text-md">Zoom</div>
<button @click="setZoom(100)" class="px-1 dropdown-item-no-padding">100%</button>
<button @click="setZoom(90)" class="px-1 dropdown-item-no-padding">90%</button>
</div>
</x-dropdown>
</div>
@@ -163,8 +196,8 @@
class="{{ request()->is('storages*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('storage.index') }}">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
<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="M4 6a8 3 0 1 0 16 0A8 3 0 1 0 4 6" />
<path d="M4 6v6a8 3 0 0 0 16 0V6" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6" />
@@ -307,17 +340,19 @@
</li>
@endif
@if (isCloud() && isInstanceAdmin())
<li>
<a title="Admin" class="menu-item" href="/admin">
<svg class="text-pink-600 icon" viewBox="0 0 256 256"
xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor"
d="M177.62 159.6a52 52 0 0 1-34 34a12.2 12.2 0 0 1-3.6.55a12 12 0 0 1-3.6-23.45a28 28 0 0 0 18.32-18.32a12 12 0 0 1 22.9 7.2ZM220 144a92 92 0 0 1-184 0c0-28.81 11.27-58.18 33.48-87.28a12 12 0 0 1 17.9-1.33l19.69 19.11L127 19.89a12 12 0 0 1 18.94-5.12C168.2 33.25 220 82.85 220 144m-24 0c0-41.71-30.61-78.39-52.52-99.29l-20.21 55.4a12 12 0 0 1-19.63 4.5L80.71 82.36C67 103.38 60 124.06 60 144a68 68 0 0 0 136 0" />
</svg>
Admin
</a>
</li>
@if (isCloud() || isDev())
@if (isInstanceAdmin() || session('impersonating'))
<li>
<a title="Admin" class="menu-item" href="/admin">
<svg class="text-pink-600 icon" viewBox="0 0 256 256"
xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor"
d="M177.62 159.6a52 52 0 0 1-34 34a12.2 12.2 0 0 1-3.6.55a12 12 0 0 1-3.6-23.45a28 28 0 0 0 18.32-18.32a12 12 0 0 1 22.9 7.2ZM220 144a92 92 0 0 1-184 0c0-28.81 11.27-58.18 33.48-87.28a12 12 0 0 1 17.9-1.33l19.69 19.11L127 19.89a12 12 0 0 1 18.94-5.12C168.2 33.25 220 82.85 220 144m-24 0c0-41.71-30.61-78.39-52.52-99.29l-20.21 55.4a12 12 0 0 1-19.63 4.5L80.71 82.36C67 103.38 60 124.06 60 144a68 68 0 0 0 136 0" />
</svg>
Admin
</a>
</li>
@endif
@endif
<div class="flex-1"></div>
@if (isInstanceAdmin() && !isCloud())

View File

@@ -7,14 +7,22 @@
href="{{ route('notifications.email') }}">
<button>Email</button>
</a>
<a class="{{ request()->routeIs('notifications.telegram') ? 'dark:text-white' : '' }}"
href="{{ route('notifications.telegram') }}">
<button>Telegram</button>
</a>
<a class="{{ request()->routeIs('notifications.discord') ? 'dark:text-white' : '' }}"
href="{{ route('notifications.discord') }}">
<button>Discord</button>
</a>
<a class="{{ request()->routeIs('notifications.telegram') ? 'dark:text-white' : '' }}"
href="{{ route('notifications.telegram') }}">
<button>Telegram</button>
</a>
<a class="{{ request()->routeIs('notifications.slack') ? 'dark:text-white' : '' }}"
href="{{ route('notifications.slack') }}">
<button>Slack</button>
</a>
<a class="{{ request()->routeIs('notifications.pushover') ? 'dark:text-white' : '' }}"
href="{{ route('notifications.pushover') }}">
<button>Pushover</button>
</a>
</nav>
</div>
</div>

View File

@@ -8,7 +8,7 @@
<li class="inline-flex items-center">
<div class="flex items-center">
<a class="text-xs truncate lg:text-sm"
href="{{ route('project.show', ['project_uuid' => $this->parameters['project_uuid']]) }}">
href="{{ route('project.show', ['project_uuid' => data_get($resource, 'environment.project.uuid')]) }}">
{{ data_get($resource, 'environment.project.name', 'Undefined Name') }}</a>
<svg aria-hidden="true" class="w-4 h-4 mx-1 font-bold dark:text-warning" fill="currentColor"
viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
@@ -21,9 +21,7 @@
<li>
<div class="flex items-center">
<a class="text-xs truncate lg:text-sm"
href="{{ route('project.resource.index', ['environment_uuid' => $this->parameters['environment_uuid'], 'project_uuid' => $this->parameters['project_uuid']]) }}">
{{ data_get($resource, 'environment.name', $this->parameters['environment_uuid']) }}
</a>
href="{{ route('project.resource.index', ['environment_uuid' => $this->parameters['environment_uuid', 'project_uuid' => data_get($resource, 'environment.project.uuid')]) }}">{{ data_get($resource, 'environment.name') }}</a>
<svg aria-hidden="true" class="w-4 h-4 mx-1 font-bold dark:text-warning" fill="currentColor"
viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"

View File

@@ -49,5 +49,6 @@
<div class="order-first sm:order-last">
<livewire:server.proxy.deploy :server="$server" />
</div>
</div>
</div>

View File

@@ -5,30 +5,42 @@
'noLoading' => false,
])
<div class="flex items-center">
@if (!$noLoading)
<x-loading wire:loading.delay.longer />
@endif
<span wire:loading.remove.delay.longer class="flex items-center">
<div class="badge badge-success "></div>
<div class="pl-2 pr-1 text-xs font-bold tracking-wider text-success" @if($title) title="{{$title}}" @endif>
@if ($lastDeploymentLink)
<a href="{{ $lastDeploymentLink }}" target="_blank" class="underline cursor-pointer">
{{ str($status)->before(':')->headline() }}
</a>
@else
{{ str($status)->before(':')->headline() }}
@endif
</div>
@if (!str($status)->startsWith('Proxy') && !str($status)->contains('('))
@if (str($status)->contains('unhealthy'))
<x-helper helper="Unhealthy state. <span class='dark:text-warning text-coollabs'>This doesn't mean that the resource is malfunctioning.</span><br><br>- If the resource is accessible, it indicates that no health check is configured - it is not mandatory.<br>- If the resource is not accessible (returning 404 or 503), it may indicate that a health check is needed and has not passed. <span class='dark:text-warning text-coollabs'>Your action is required.</span><br><br>More details in the <a href='https://coolify.io/docs/knowledge-base/traefik/healthcheck/' class='underline dark:text-warning text-coollabs' target='_blank'>documentation</a>." >
<div class="flex items-center">
<span wire:loading.delay.longer>
<div class="badge badge-warning"></div>
</span>
<span wire:loading.remove.delay.longer>
<div class="badge badge-success"></div>
</span>
<div class="pl-2 pr-1 text-xs font-bold tracking-wider text-success"
@if ($title) title="{{ $title }}" @endif>
@if ($lastDeploymentLink)
<a href="{{ $lastDeploymentLink }}" target="_blank" class="underline cursor-pointer">
{{ str($status)->before(':')->headline() }}
</a>
@else
{{ str($status)->before(':')->headline() }}
@endif
</div>
@php
$showUnhealthyHelper =
!str($status)->startsWith('Proxy') &&
!str($status)->contains('(') &&
str($status)->contains('unhealthy');
@endphp
@if ($showUnhealthyHelper)
<x-helper
helper="Unhealthy state. <span class='dark:text-warning text-coollabs'>This doesn't mean that the resource is malfunctioning.</span><br><br>- If the resource is accessible, it indicates that no health check is configured - it is not mandatory.<br>- If the resource is not accessible (returning 404 or 503), it may indicate that a health check is needed and has not passed. <span class='dark:text-warning text-coollabs'>Your action is required.</span><br><br>More details in the <a href='https://coolify.io/docs/knowledge-base/traefik/healthcheck/' class='underline dark:text-warning text-coollabs' target='_blank'>documentation</a>.">
<x-slot:icon>
<svg class="hidden w-4 h-4 dark:text-warning lg:block" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor" d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16"></path>
<svg class="hidden w-4 h-4 dark:text-warning lg:block" viewBox="0 0 256 256"
xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor"
d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16">
</path>
</svg>
</x-slot:icon>
</x-helper>
@endif
@endif
</span>
</div>
</div>

View File

@@ -11,16 +11,20 @@
toast(this.title, { description: this.description, type: this.type, position: this.position, html: html })
}
}" x-init="window.toast = function(message, options = {}) {
let description = '';
let type = 'default';
let position = 'top-center';
let html = '';
if (typeof options.description != 'undefined') description = options.description;
if (typeof options.type != 'undefined') type = options.type;
if (typeof options.position != 'undefined') position = options.position;
if (typeof options.html != 'undefined') html = options.html;
try {
let description = '';
let type = 'default';
let position = 'top-center';
let html = '';
if (typeof options.description != 'undefined') description = options.description;
if (typeof options.type != 'undefined') type = options.type;
if (typeof options.position != 'undefined') position = options.position;
if (typeof options.html != 'undefined') html = options.html;
window.dispatchEvent(new CustomEvent('toast-show', { detail: { type: type, message: message, description: description, position: position, html: html } }));
window.dispatchEvent(new CustomEvent('toast-show', { detail: { type: type, message: message, description: description, position: position, html: html } }));
} catch (error) {
console.error('Error showing toast:', error);
}
}" class="relative space-y-5">
<template x-teleport="body">
<ul x-data="{

View File

@@ -1,4 +1,4 @@
<a {{ $attributes->merge(['class' => 'text-xs cursor-pointer opacity-90 hover:opacity-100 dark:hover:text-white hover:text-black']) }}
href="https://github.com/coollabsio/coolify/releases/tag/v{{ config('version') }}" target="_blank">
v{{ config('version') }}
</a>
href="https://github.com/coollabsio/coolify/releases/tag/v{{ config('constants.coolify.version') }}" target="_blank">
v{{ config('constants.coolify.version') }}
</a>