port ranges also in stacks display

This commit is contained in:
jarek committed 2026-04-19 10:28:47 +02:00
1 parent aaaf252d4c
commit 1a34f73ae3
2 files changed
+16 -12

No files matched your search

+9 -6
View File
@@ -6,23 +6,26 @@ export interface PortMapping {
}
interface PortInfo {
PublicPort: number;
PrivatePort: number;
PublicPort?: number;
PrivatePort?: number;
publicPort?: number;
privatePort?: number;
}
/**
* Format Docker port mappings, collapsing consecutive ranges.
* Accepts both Docker API format (PublicPort/PrivatePort) and camelCase (publicPort/privatePort).
* e.g. 8080:8080, 8081:8081, 8082:8082 → 8080-8082:8080-8082
*/
export function formatPorts(ports: PortInfo[] | undefined | null): PortMapping[] {
if (!ports || ports.length === 0) return [];
const seen = new Set<string>();
const individual = ports
.filter(p => p.PublicPort)
.filter(p => (p.PublicPort || p.publicPort))
.map(p => ({
publicPort: p.PublicPort,
privatePort: p.PrivatePort,
display: `${p.PublicPort}:${p.PrivatePort}`
publicPort: p.PublicPort || p.publicPort!,
privatePort: p.PrivatePort || p.privatePort!,
display: `${p.PublicPort || p.publicPort}:${p.PrivatePort || p.privatePort}`
}))
.filter(p => {
const key = p.display;
+7 -6
View File
@@ -15,6 +15,7 @@
import * as Popover from '$lib/components/ui/popover';
import MultiSelectFilter from '$lib/components/MultiSelectFilter.svelte';
import { Play, Square, Trash2, Plus, ArrowBigDown, Search, Pencil, ExternalLink, GitBranch, RefreshCw, Loader2, FileCode, FileText, FileOutput, Box, RotateCcw, ScrollText, Terminal, Eye, Network, HardDrive, Heart, HeartPulse, HeartOff, ChevronsUpDown, ChevronsDownUp, Rocket, AlertTriangle, X, Layers, Pause, CircleDashed, Skull, FolderOpen, Variable, Clock, RotateCw, Import, Ship, Cable, LayoutPanelLeft, Rows3, GripVertical } from 'lucide-svelte';
import { formatPorts } from '$lib/utils/port-format';
import ConfirmPopover from '$lib/components/ConfirmPopover.svelte';
import BatchOperationModal from '$lib/components/BatchOperationModal.svelte';
import type { ComposeStackInfo, ContainerStats } from '$lib/types';
@@ -2014,11 +2015,11 @@
{/key}
{/if}
<div class="flex flex-wrap gap-1.5 mb-2 text-2xs">
<!-- Clickable ports (dedupe by publicPort for IPv4/IPv6) -->
<!-- Clickable ports with range collapsing -->
{#if container.ports.length > 0}
{@const uniquePorts = container.ports.filter((p, i, arr) => p.publicPort && arr.findIndex(x => x.publicPort === p.publicPort) === i)}
{#each uniquePorts as port}
{@const url = getPortUrl(port.publicPort)}
{@const mappedPorts = formatPorts(container.ports)}
{#each mappedPorts as port}
{@const url = !port.isRange ? getPortUrl(port.publicPort) : null}
{#if url}
<a
href={url}
@@ -2028,12 +2029,12 @@
class="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 hover:bg-blue-200 dark:hover:bg-blue-800 transition-colors"
title="Open {url} in new tab"
>
<code>:{port.publicPort}</code>
<code>{port.display}</code>
<ExternalLink class="w-2.5 h-2.5" />
</a>
{:else}
<span class="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200">
<code>:{port.publicPort}</code>
<code>{port.display}</code>
</span>
{/if}
{/each}