mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-11 14:00:29 +00:00
Fix guest URL editing inconsistencies: unify icons and use Portal for popover
This commit is contained in:
@@ -354,11 +354,7 @@ export const DockerHostSummaryTable: Component<DockerHostSummaryTableProps> = (p
|
||||
onClick={(e) => handleStartEditingUrl(summary.host.id, e)}
|
||||
>
|
||||
<svg class="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<Show when={getHostCustomUrl(summary.host.id)} fallback={
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" />
|
||||
}>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
|
||||
</Show>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
|
||||
</svg>
|
||||
</button>
|
||||
<Show when={getDisplayName(summary.host) !== summary.host.hostname}>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component, Show, createSignal, createEffect } from 'solid-js';
|
||||
import { Portal } from 'solid-js/web';
|
||||
|
||||
export interface UrlEditPopoverProps {
|
||||
/** Whether the popover is visible */
|
||||
@@ -57,72 +58,74 @@ export const UrlEditPopover: Component<UrlEditPopoverProps> = (props) => {
|
||||
|
||||
return (
|
||||
<Show when={props.isOpen && props.position}>
|
||||
<div
|
||||
data-url-editor
|
||||
class="fixed z-[9999] bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-xl p-3 min-w-[300px]"
|
||||
style={{ top: `${props.position!.top}px`, left: `${props.position!.left}px` }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="url"
|
||||
class="flex-1 text-sm px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
|
||||
placeholder={props.placeholder ?? 'https://example.com'}
|
||||
value={props.value}
|
||||
onInput={(e) => props.onValueChange(e.currentTarget.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
disabled={props.isSaving}
|
||||
/>
|
||||
<Portal mount={document.body}>
|
||||
<div
|
||||
data-url-editor
|
||||
class="fixed z-[9999] bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-xl p-3 min-w-[300px]"
|
||||
style={{ top: `${props.position!.top}px`, left: `${props.position!.left}px` }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="url"
|
||||
class="flex-1 text-sm px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
|
||||
placeholder={props.placeholder ?? 'https://example.com'}
|
||||
value={props.value}
|
||||
onInput={(e) => props.onValueChange(e.currentTarget.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
disabled={props.isSaving}
|
||||
/>
|
||||
|
||||
{/* Save button */}
|
||||
<button
|
||||
type="button"
|
||||
class="p-2 text-green-600 hover:text-green-700 dark:text-green-400 dark:hover:text-green-300 hover:bg-green-50 dark:hover:bg-green-900/20 rounded transition-colors disabled:opacity-50"
|
||||
title="Save (Enter)"
|
||||
disabled={props.isSaving}
|
||||
onClick={props.onSave}
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/* Delete button - only show if there's an existing URL */}
|
||||
<Show when={props.hasExistingUrl && props.onDelete}>
|
||||
{/* Save button */}
|
||||
<button
|
||||
type="button"
|
||||
class="p-2 text-red-500 hover:text-red-600 dark:text-red-400 dark:hover:text-red-300 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors disabled:opacity-50"
|
||||
title="Remove URL"
|
||||
class="p-2 text-green-600 hover:text-green-700 dark:text-green-400 dark:hover:text-green-300 hover:bg-green-50 dark:hover:bg-green-900/20 rounded transition-colors disabled:opacity-50"
|
||||
title="Save (Enter)"
|
||||
disabled={props.isSaving}
|
||||
onClick={props.onDelete}
|
||||
onClick={props.onSave}
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/* Delete button - only show if there's an existing URL */}
|
||||
<Show when={props.hasExistingUrl && props.onDelete}>
|
||||
<button
|
||||
type="button"
|
||||
class="p-2 text-red-500 hover:text-red-600 dark:text-red-400 dark:hover:text-red-300 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors disabled:opacity-50"
|
||||
title="Remove URL"
|
||||
disabled={props.isSaving}
|
||||
onClick={props.onDelete}
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||
</svg>
|
||||
</button>
|
||||
</Show>
|
||||
|
||||
{/* Cancel button */}
|
||||
<button
|
||||
type="button"
|
||||
class="p-2 text-gray-500 hover:text-gray-600 dark:text-gray-400 dark:hover:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors"
|
||||
title="Cancel (Esc)"
|
||||
onClick={props.onCancel}
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Help text */}
|
||||
<Show when={props.helpText}>
|
||||
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||
{props.helpText}
|
||||
</p>
|
||||
</Show>
|
||||
|
||||
{/* Cancel button */}
|
||||
<button
|
||||
type="button"
|
||||
class="p-2 text-gray-500 hover:text-gray-600 dark:text-gray-400 dark:hover:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors"
|
||||
title="Cancel (Esc)"
|
||||
onClick={props.onCancel}
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Help text */}
|
||||
<Show when={props.helpText}>
|
||||
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||
{props.helpText}
|
||||
</p>
|
||||
</Show>
|
||||
</div>
|
||||
</Portal>
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user