mirror of
https://github.com/tiennm99/coolify.git
synced 2026-08-20 06:23:23 +00:00
fix(ui): gate copy button on clipboard API support
Only show the copy control when isSecureContext and clipboard.writeText are available, and style the empty internal hostname state as a readonly input to match adjacent fields.
This commit is contained in:
@@ -1,17 +1,19 @@
|
||||
@props(['text', 'label' => null])
|
||||
|
||||
<div class="w-full" x-data="{ copied: false, isSecure: window.isSecureContext }">
|
||||
<div class="w-full"
|
||||
x-data="{ copied: false, canCopy: window.isSecureContext && typeof navigator.clipboard?.writeText === 'function' }">
|
||||
@if ($label)
|
||||
<label class="flex gap-1 items-center mb-1 text-sm font-medium text-black dark:text-white">{{ $label }}</label>
|
||||
@endif
|
||||
<div class="relative">
|
||||
<input type="text" value="{{ $text }}"
|
||||
class="input input-with-copy-button bg-white dark:bg-coolgray-100 dark:read-only:bg-coolgray-100 dark:read-only:text-white"
|
||||
class="input bg-white dark:bg-coolgray-100 dark:read-only:bg-coolgray-100 dark:read-only:text-white"
|
||||
x-bind:class="{ 'input-with-copy-button': canCopy }"
|
||||
readonly
|
||||
@keydown.prevent @paste.prevent @cut.prevent @drop.prevent
|
||||
@focus="$event.target.select()">
|
||||
<button
|
||||
x-show="isSecure"
|
||||
x-show="canCopy"
|
||||
type="button"
|
||||
@click.prevent="copied = true; navigator.clipboard.writeText({{ Js::from($text) }}); setTimeout(() => copied = false, 1000)"
|
||||
class="copy-button flex absolute inset-y-0 right-0 z-10 items-center pr-2 cursor-pointer text-neutral-500 transition-colors hover:text-black focus-visible:ring-2 focus-visible:ring-coollabs focus-visible:ring-offset-2 dark:text-neutral-400 dark:hover:text-white dark:focus-visible:ring-warning dark:focus-visible:ring-offset-base"
|
||||
|
||||
@@ -96,11 +96,12 @@
|
||||
@if ($currentInternalHostname)
|
||||
<x-forms.copy-button label="Internal hostname" :text="$currentInternalHostname" />
|
||||
@else
|
||||
<div>
|
||||
<p class="mb-1 text-sm font-medium text-black dark:text-white">Internal hostname</p>
|
||||
<p class="flex min-h-10 items-center rounded border border-neutral-300 px-3 text-sm text-neutral-500 dark:border-coolgray-300 dark:text-fg-dim">
|
||||
{{ $currentInternalHostnameLoaded ? 'No deployed container found' : 'Loading…' }}
|
||||
</p>
|
||||
<div class="w-full">
|
||||
<label class="mb-1 flex items-center gap-1 text-sm font-medium text-black dark:text-white">Internal hostname</label>
|
||||
<input type="text"
|
||||
value="{{ $currentInternalHostnameLoaded ? 'No deployed container found' : 'Loading…' }}"
|
||||
class="input input-with-copy-button bg-white dark:bg-coolgray-100 dark:read-only:bg-coolgray-100 dark:read-only:text-white"
|
||||
readonly aria-live="polite">
|
||||
</div>
|
||||
@endif
|
||||
<x-forms.copy-button label="Docker network" :text="$application->destination->network" />
|
||||
|
||||
@@ -14,6 +14,7 @@ it('shows internal Docker access details in application general settings', funct
|
||||
->toContain('Network aliases')
|
||||
->toContain('wire:init="loadCurrentInternalHostname"')
|
||||
->toContain('$currentInternalHostname')
|
||||
->toContain('class="input input-with-copy-button bg-white dark:bg-coolgray-100 dark:read-only:bg-coolgray-100 dark:read-only:text-white"')
|
||||
->not->toContain('Changes with each deployment')
|
||||
->toContain("window.scrollToSettingsSection?.('networking-section')")
|
||||
->and($generalComponent)
|
||||
|
||||
@@ -38,7 +38,9 @@ it('renders copy fields as visible readonly controls with an accessible copy act
|
||||
expect($html)
|
||||
->toContain('label class="flex gap-1 items-center mb-1 text-sm font-medium text-black dark:text-white"')
|
||||
->toContain('readonly')
|
||||
->toContain('input-with-copy-button')
|
||||
->toContain("canCopy: window.isSecureContext && typeof navigator.clipboard?.writeText === 'function'")
|
||||
->toContain("x-bind:class=\"{ 'input-with-copy-button': canCopy }\"")
|
||||
->toContain('x-show="canCopy"')
|
||||
->toContain('copy-button')
|
||||
->toContain('aria-label="Copy to clipboard"')
|
||||
->toContain('title="Copy to clipboard"')
|
||||
|
||||
Reference in New Issue
Block a user