feat: IPv6 support and multi-IP per node (closes #60)

- maskIp handles IPv6 addresses (masks second and last group)
- maskIp handles comma-separated IP strings (masks each address)
- Add splitIps() helper to parse comma-separated IP field
- Add primaryIp() helper used by status checker (first IP wins)
- BaseNode renders each IP on its own line when comma-separated
- NodeModal placeholder shows comma-separated example
- Backend status_checker uses only first IP for connectivity checks
- Expand maskIp test suite: IPv6, comma-separated, splitIps, primaryIp
This commit is contained in:
Pouzor
2026-04-19 02:02:14 +02:00
parent 6c9974b357
commit ef96cafcc8
7 changed files with 111 additions and 19 deletions
@@ -8,7 +8,7 @@ import { resolvePropertyIcon } from '@/utils/propertyIcons'
import { useThemeStore } from '@/stores/themeStore'
import { THEMES } from '@/utils/themes'
import { useCanvasStore } from '@/stores/canvasStore'
import { maskIp } from '@/utils/maskIp'
import { maskIp, splitIps } from '@/utils/maskIp'
import { BOTTOM_HANDLE_IDS, BOTTOM_HANDLE_POSITIONS } from '@/utils/handleUtils'
interface BaseNodeProps extends NodeProps<Node<NodeData>> {
@@ -98,15 +98,16 @@ export function BaseNode({ id, data, selected, icon: typeIcon, width, height }:
>
{data.label}
</div>
{data.ip && (
{data.ip && splitIps(data.ip).map((ip) => (
<div
key={ip}
className="font-mono text-[10px] truncate"
style={{ color: theme.colors.nodeSubtextColor }}
title={data.ip}
title={ip}
>
{hideIp ? maskIp(data.ip) : data.ip}
{hideIp ? maskIp(ip) : ip}
</div>
)}
))}
</div>
</div>