Merge remote-tracking branch 'origin/next' into fix/escape-html-log

This commit is contained in:
Andras Bacsai committed 2026-06-03 11:43:18 +02:00
commit 88b04bb920
341 files changed
+15824 -6630

No files matched your search

@@ -1,6 +1,6 @@
<div>
@if ($isConfigurationChanged && !is_null($resource->config_hash) && !$resource->isExited())
<div x-data="{ configurationDiffModalOpen: false }">
<div x-data="{ configurationDiffModalOpen: false, expandedRows: {} }">
<x-popup-small>
<x-slot:title>
The latest configuration has not been applied
@@ -274,10 +274,13 @@
<div>({{ $pull_request }})</div>
@endif
@if ($streamLogs)
<x-loading wire:poll.2000ms='getLogs(true)' />
<x-loading />
@endif
</div>
@endif
@if ($streamLogs)
<div class="sr-only" wire:poll.2000ms="getLogs(true)" aria-hidden="true"></div>
@endif
<div x-show="expanded" {{ $collapsible ? 'x-collapse' : '' }}
:class="fullscreen ? 'fullscreen flex flex-col !overflow-visible' : 'relative w-full {{ $collapsible ? 'py-4' : '' }} mx-auto'"
:style="fullscreen ? 'max-height: none !important; height: 100% !important;' : ''">
@@ -520,20 +523,19 @@
// Parse timestamp from log line (ISO 8601 format: 2025-12-04T11:48:39.136764033Z)
$timestamp = '';
$logContent = $line;
if (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}:\d{2}:\d{2})(?:\.(\d+))?Z?\s(.*)$/', $line, $matches)) {
$year = $matches[1];
$month = $matches[2];
$day = $matches[3];
$time = $matches[4];
$microseconds = isset($matches[5]) ? substr($matches[5], 0, 6) : '000000';
$logContent = $matches[6];
if (preg_match('/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d+))?Z?\s(.*)$/', $line, $matches)) {
$microseconds = isset($matches[2]) ? substr($matches[2], 0, 6) : '000000';
$logContent = $matches[3];
// Convert month number to abbreviated name
$monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
$monthName = $monthNames[(int)$month - 1] ?? $month;
// Format for display: 2025-Dec-04 09:44:58
$timestamp = "{$year}-{$monthName}-{$day} {$time}";
// Convert UTC Docker timestamp to server timezone for display
$carbonTs = \Carbon\Carbon::parse($matches[1], 'UTC');
$serverTz = getServerTimezone($server);
try {
$carbonTs->setTimezone($serverTz);
} catch (\Exception) {
// keep UTC
}
$timestamp = $carbonTs->format('Y-M-d H:i:s');
// Include microseconds in key for uniqueness
$lineKey = "{$timestamp}.{$microseconds}";
}
@@ -1,6 +1,6 @@
<form wire:submit='submit' class="flex flex-col">
<div class="flex items-center gap-2">
<h2>Healthchecks</h2>
<h2>Healthcheck</h2>
<x-forms.button canGate="update" :canResource="$resource" type="submit">Save</x-forms.button>
@if (!$healthCheckEnabled)
<x-modal-confirmation title="Confirm Healthcheck Enable?" buttonTitle="Enable Healthcheck"
@@ -5,13 +5,19 @@
<div class="pb-4">Basic metrics for your application container.</div>
<div>
@if ($resource->getMorphClass() === 'App\Models\Application' && $resource->build_pack === 'dockercompose')
<div class="alert alert-warning">Metrics are not available for Docker Compose applications yet!</div>
<x-callout type="warning" title="Not Available">
Metrics are not available for Docker Compose applications yet!
</x-callout>
@elseif(!$resource->destination->server->isMetricsEnabled())
<div class="alert alert-warning pb-1">Metrics are only available for servers with Sentinel & Metrics enabled!</div>
<div>Go to <a class="underline dark:text-white" href="{{ route('server.show', $resource->destination->server->uuid) }}/sentinel" {{ wireNavigate() }}>Server settings</a> to enable it.</div>
<x-callout type="info" title="Metrics Not Enabled">
Metrics are only available for servers with Sentinel & Metrics enabled.
Go to <a class="underline font-semibold" href="{{ route('server.metrics', ['server_uuid' => $resource->destination->server->uuid]) }}" {{ wireNavigate() }}>Server Metrics</a> to enable it.
</x-callout>
@else
@if (!str($resource->status)->contains('running'))
<div class="alert alert-warning">Metrics are only available when the application container is running!</div>
<x-callout type="warning" title="Container Not Running">
Metrics are only available when the application container is running!
</x-callout>
@else
<div>
<x-forms.select label="Interval" wire:change="setInterval" id="interval">
@@ -0,0 +1,57 @@
<div class="w-full max-h-[70vh] overflow-y-auto pr-1 -mt-4">
<div class="pb-4 text-sm dark:text-neutral-400">Identifiers for this resource. Read-only</div>
<div class="flex flex-col gap-6">
<div>
<h3>Resource</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
<x-forms.copy-button label="Name" :text="$resource->name ?? ''" />
<x-forms.copy-button label="UUID" :text="$resource->uuid ?? ''" />
</div>
</div>
@if ($environment_uuid)
<div>
<h3>Environment</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
<x-forms.copy-button label="Name" :text="$environment_name ?? ''" />
<x-forms.copy-button label="UUID" :text="$environment_uuid" />
</div>
</div>
@endif
@if ($project_uuid)
<div>
<h3>Project</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
<x-forms.copy-button label="Name" :text="$project_name ?? ''" />
<x-forms.copy-button label="UUID" :text="$project_uuid" />
</div>
</div>
@endif
@if ($server_uuid)
<div>
<h3>Server</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
<x-forms.copy-button label="Name" :text="$server_name ?? ''" />
<x-forms.copy-button label="UUID" :text="$server_uuid" />
</div>
</div>
@endif
@if (! empty($stack_applications) || ! empty($stack_databases))
<div>
<h3>Stack Sub-Resources</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
@foreach ($stack_applications as $item)
<x-forms.copy-button :label="'Application — ' . $item['name']" :text="$item['uuid']" />
@endforeach
@foreach ($stack_databases as $item)
<x-forms.copy-button :label="'Database — ' . $item['name']" :text="$item['uuid']" />
@endforeach
</div>
</div>
@endif
</div>
</div>
@@ -1,4 +1,7 @@
<div id="terminal-container" x-data="terminalData()">
@if ($isTerminalConnected)
<div class="hidden" aria-hidden="true" wire:poll.keep-alive.30s="keepTerminalPageAlive"></div>
@endif
@if (!$hasShell)
<div class="flex pt-4 items-center justify-center w-full py-4 mx-auto">
<div class="p-4 w-full rounded-sm border dark:bg-coolgray-100 dark:border-coolgray-300">
@@ -18,10 +21,37 @@
</div>
@endif
<div x-ref="terminalWrapper"
:class="fullscreen ? 'fullscreen !bg-black' : 'relative w-full h-full py-4 mx-auto max-h-[510px]'">
:class="fullscreen ? 'fixed inset-0 z-[9999] m-0 h-[100dvh] w-screen max-w-none overflow-hidden rounded-none !bg-black p-0' : 'relative w-full h-full py-4 mx-auto max-h-[510px]'">
<!-- Terminal container -->
<div x-show="terminalActive" x-cloak class="mb-2 flex justify-start">
<div class="inline-flex rounded-sm border px-2 py-1 text-xs font-medium"
:class="terminalSessionTimerClass()" x-text="terminalSessionRemainingLabel()">
</div>
</div>
<div id="terminal" wire:ignore
:class="fullscreen ? 'px-2 py-1 h-full bg-black' : 'px-2 py-1 rounded-sm bg-black'" x-show="terminalActive">
:class="fullscreen ? (mobileToolbarCollapsed ? 'h-[calc(100dvh-3.5rem)] mb-14 px-2 py-1 bg-black' : 'h-[calc(100dvh-6rem)] mb-[6rem] px-2 py-1 bg-black') : 'h-[510px] max-h-[calc(100dvh-10rem)] overflow-hidden px-2 py-1 rounded-sm bg-black'"
x-show="terminalActive">
</div>
<div x-show="terminalActive" x-cloak
:class="fullscreen ? 'absolute inset-x-0 bottom-0 z-[9999] px-2 pb-2' : 'relative mt-2'"
class="sm:hidden" data-terminal-mobile-toolbar>
<div class="mx-auto max-w-3xl rounded-lg border border-white/10 bg-black/90 p-1.5 text-white shadow-lg backdrop-blur">
<div class="flex items-center justify-between gap-2">
<span class="px-2 text-[11px] font-medium uppercase tracking-wide text-neutral-400">Terminal keys</span>
<button type="button" class="rounded px-2 py-1 text-xs text-neutral-300 hover:bg-white/10 hover:text-white"
x-on:click="mobileToolbarCollapsed = !mobileToolbarCollapsed; $nextTick(() => resizeTerminal())"
x-text="mobileToolbarCollapsed ? 'Show' : 'Hide'"
aria-label="Toggle mobile terminal toolbar"></button>
</div>
<div x-show="!mobileToolbarCollapsed" class="mt-1 grid grid-cols-6 gap-1">
<button type="button" class="terminal-mobile-key" x-on:click="sendTerminalControl('arrowUp')" aria-label="Previous command">↑</button>
<button type="button" class="terminal-mobile-key" x-on:click="sendTerminalControl('arrowDown')" aria-label="Next command">↓</button>
<button type="button" class="terminal-mobile-key" x-on:click="sendTerminalControl('arrowLeft')" aria-label="Move cursor left">←</button>
<button type="button" class="terminal-mobile-key" x-on:click="sendTerminalControl('arrowRight')" aria-label="Move cursor right">→</button>
<button type="button" class="terminal-mobile-key" x-on:click="sendTerminalControl('tab')">Tab</button>
<button type="button" class="terminal-mobile-key" x-on:click="sendTerminalControl('escape')">Esc</button>
</div>
</div>
</div>
<button title="Minimize" x-show="fullscreen" class="fixed bg-black/40 top-4 right-6 text-white"
x-on:click="makeFullscreen"><svg class="w-5 h-5 text-gray-500 hover:text-white bg-black/80"
@@ -2,11 +2,11 @@
<div class="flex items-center gap-2">
<h2>Webhooks</h2>
<x-helper
helper="For more details goto our <a class='underline dark:text-white' href='https://coolify.io/docs/api-reference/api/operations/deploy-by-tag-or-uuid' target='_blank'>docs</a>." />
helper="For more details goto our <a class='underline dark:text-white' href='https://coolify.io/docs/api-reference/authorization' target='_blank'>docs</a>." />
</div>
<div>
<x-forms.input readonly
helper="See details in our <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/api-reference/api/operations/deploy-by-tag-or-uuid'>documentation</a>."
helper="See details in our <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/api-reference/authorization'>documentation</a>."
label="Deploy Webhook (auth required)" id="deploywebhook"></x-forms.input>
</div>
@if ($resource->type() === 'application')