From bd4f12c98ff68741876e8e037707bb5cef5254a9 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Tue, 28 Oct 2025 23:14:38 +0000 Subject: [PATCH] Fix Docker URL link icon to appear immediately after save Optimistically update local and parent state before the API call completes, so the external link icon appears instantly when the user saves a URL. If the API fails, the state reverts automatically. Before: Link icon appeared after API response (~100-500ms delay) After: Link icon appears immediately with smooth fade-in animation --- .../components/Docker/DockerUnifiedTable.tsx | 68 +++++++++++-------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/frontend-modern/src/components/Docker/DockerUnifiedTable.tsx b/frontend-modern/src/components/Docker/DockerUnifiedTable.tsx index 163de71..946287a 100644 --- a/frontend-modern/src/components/Docker/DockerUnifiedTable.tsx +++ b/frontend-modern/src/components/Docker/DockerUnifiedTable.tsx @@ -459,23 +459,22 @@ const DockerContainerRow: Component<{ // If URL hasn't changed, don't save if (newUrl === (customUrl() || '')) return; + // Animate if transitioning from no URL to having a URL + const hadUrl = !!customUrl(); + if (!hadUrl && newUrl) { + setShouldAnimateIcon(true); + setTimeout(() => setShouldAnimateIcon(false), 200); + } + + // Optimistically update local and parent state immediately + setCustomUrl(newUrl || undefined); + if (props.onCustomUrlUpdate) { + props.onCustomUrlUpdate(resourceId(), newUrl); + } + try { await DockerMetadataAPI.updateMetadata(resourceId(), { customUrl: newUrl }); - // Animate if transitioning from no URL to having a URL - const hadUrl = !!customUrl(); - if (!hadUrl && newUrl) { - setShouldAnimateIcon(true); - setTimeout(() => setShouldAnimateIcon(false), 200); - } - - setCustomUrl(newUrl || undefined); - - // Notify parent to update metadata - if (props.onCustomUrlUpdate) { - props.onCustomUrlUpdate(resourceId(), newUrl); - } - if (newUrl) { showSuccess('Container URL saved'); } else { @@ -484,6 +483,11 @@ const DockerContainerRow: Component<{ } catch (err: any) { console.error('Failed to save container URL:', err); showError(err.message || 'Failed to save container URL'); + // Revert on error + setCustomUrl(hadUrl ? customUrl() : undefined); + if (props.onCustomUrlUpdate) { + props.onCustomUrlUpdate(resourceId(), hadUrl ? customUrl() || '' : ''); + } } }; @@ -576,7 +580,7 @@ const DockerContainerRow: Component<{ onClick={toggle} aria-expanded={expanded()} > - +
{/* Name - show input when editing, otherwise show name with optional link */} setShouldAnimateIcon(false), 200); + } + + // Optimistically update local and parent state immediately + setCustomUrl(newUrl || undefined); + if (props.onCustomUrlUpdate) { + props.onCustomUrlUpdate(resourceId(), newUrl); + } + try { await DockerMetadataAPI.updateMetadata(resourceId(), { customUrl: newUrl }); - // Animate if transitioning from no URL to having a URL - const hadUrl = !!customUrl(); - if (!hadUrl && newUrl) { - setShouldAnimateIcon(true); - setTimeout(() => setShouldAnimateIcon(false), 200); - } - - setCustomUrl(newUrl || undefined); - - // Notify parent to update metadata - if (props.onCustomUrlUpdate) { - props.onCustomUrlUpdate(resourceId(), newUrl); - } - if (newUrl) { showSuccess('Service URL saved'); } else { @@ -942,6 +945,11 @@ const DockerServiceRow: Component<{ } catch (err: any) { console.error('Failed to save service URL:', err); showError(err.message || 'Failed to save service URL'); + // Revert on error + setCustomUrl(hadUrl ? customUrl() : undefined); + if (props.onCustomUrlUpdate) { + props.onCustomUrlUpdate(resourceId(), hadUrl ? customUrl() || '' : ''); + } } }; @@ -1008,7 +1016,7 @@ const DockerServiceRow: Component<{ onClick={toggle} aria-expanded={expanded()} > - +
{/* Name - show input when editing, otherwise show name with optional link */}