import { useState } from "react"; import { Dialog, DialogBackdrop, DialogPanel, DialogTitle, } from "@headlessui/react"; import { WithTooltip } from "./ui/Tooltip"; import type { Image } from "../types"; import { theme } from "../theme"; import { CodeBlock } from "./CodeBlock"; import { Box, CircleArrowUp, CircleCheck, HelpCircle, Timer, TriangleAlert, X, } from "lucide-react"; import Badge from "./Badge"; import { getDescription } from "../utils"; const clickable_registries = [ "registry-1.docker.io", "ghcr.io", "quay.io", "gcr.io", ]; // Not all registries redirect to an info page when visiting the image reference in a browser (e.g. Gitea and derivatives), so we only enable clicking those who do. export default function Image({ data }: { data: Image }) { const [open, setOpen] = useState(false); const handleOpen = () => { setOpen(true); }; const handleClose = () => { setOpen(false); }; const new_reference = data.result.info?.type == "version" ? data.reference.split(":")[0] + ":" + data.result.info.new_tag : data.reference; const info = getInfo(data); let url: string | null = null; if (data.url) { url = data.url; } else if (clickable_registries.includes(data.parts.registry)) { switch (data.parts.registry) { case "registry-1.docker.io": url = `https://hub.docker.com/r/${data.parts.repository}`; break; default: url = `https://${data.parts.registry}/${data.parts.repository}`; break; } } return ( <>
{url ? ( <> {data.reference} ) : ( data.reference )}
{info.description}
Checked in {data.time} ms
{data.result.error && (
{data.result.error}
)} {data.result.has_update && (
Pull command docker pull {new_reference}
)}
{data.result.info?.type == "digest" && ( <> {data.result.info.local_digests.length > 1 ? "Local digests" : "Local digest"} {data.result.info.local_digests.join("\n")} {data.result.info.remote_digest && (
Remote digest {data.result.info.remote_digest}
)} )}
); } function getInfo(data: Image): { color: string; icon: typeof HelpCircle; description: string; } { const description = getDescription(data); switch (description) { case "Unknown": return { color: "text-gray-500", icon: HelpCircle, description, }; case "Up to date": return { color: "text-green-500", icon: CircleCheck, description, }; case "Major update": return { color: "text-red-500", icon: CircleArrowUp, description, }; case "Minor update": return { color: "text-yellow-500", icon: CircleArrowUp, description, }; case "Patch update": return { color: "text-blue-500", icon: CircleArrowUp, description, }; case "Digest update": return { color: "text-blue-500", icon: CircleArrowUp, description, }; } }