Merge icon fallback chain and SSH name-based icon matching

# Conflicts:
#	src/pages/Infrastructure.tsx
This commit is contained in:
Claude 2026-06-21 20:15:48 +00:00
commit f3dcbab444
No known key found for this signature in database

View file

@ -92,6 +92,42 @@ const cdnIconCandidatesByIntegrationType: Record<string, string[]> = {
netbird: ['https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/netbird.png'], netbird: ['https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/netbird.png'],
cloudflare: ['https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/cloudflare.png'], cloudflare: ['https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/cloudflare.png'],
ssh: ['https://samuelsjames.github.io/assets-public/logos/linux-logo.svg'], ssh: ['https://samuelsjames.github.io/assets-public/logos/linux-logo.svg'],
proxmox: [
'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/proxmox.png',
'https://api.iconify.design/simple-icons/proxmox.svg',
],
weather: [
'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/openweathermap.png',
'https://api.iconify.design/mdi/weather-partly-cloudy.svg',
],
remote_desktop: [
'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/guacamole.png',
'https://api.iconify.design/simple-icons/apacheguacamole.svg',
'https://api.iconify.design/mdi/remote-desktop.svg',
],
}
// SSH connections are named by the user after whatever host/service they point at
// (e.g. "Linode", "Portainer") — match known keywords in the connection name to a
// more specific icon before falling back to the generic Linux icon above.
const sshNameIconCandidates: { keyword: string; candidates: string[] }[] = [
{ keyword: 'linode', candidates: [
'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/linode.png',
'https://api.iconify.design/simple-icons/linode.svg',
] },
{ keyword: 'portainer', candidates: [
'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/portainer.png',
'https://api.iconify.design/simple-icons/portainer.svg',
] },
]
function iconCandidatesForNode(node: NodeTile): string[] {
if (node.integrationType === 'ssh') {
const name = ('isGroup' in node ? node.integration : node.name).toLowerCase()
const match = sshNameIconCandidates.find((m) => name.includes(m.keyword))
if (match) return [...match.candidates, ...cdnIconCandidatesByIntegrationType.ssh]
}
return cdnIconCandidatesByIntegrationType[node.integrationType] ?? []
} }
interface NodeGroup { interface NodeGroup {
@ -372,7 +408,7 @@ export default function Infrastructure() {
<span style={{ width: '7px', height: '7px', borderRadius: '50%', backgroundColor: nodeStatusColor[node.status], boxShadow: `0 0 6px ${nodeStatusColor[node.status]}` }} /> <span style={{ width: '7px', height: '7px', borderRadius: '50%', backgroundColor: nodeStatusColor[node.status], boxShadow: `0 0 6px ${nodeStatusColor[node.status]}` }} />
<TileIcon <TileIcon
customUrl={node.iconUrl} customUrl={node.iconUrl}
candidates={cdnIconCandidatesByIntegrationType[node.integrationType] ?? []} candidates={iconCandidatesForNode(node)}
fallback={NodeIcon} fallback={NodeIcon}
/> />
</div> </div>