| import { useEnv } from "./lib/state"; |
| import { Copy, Check, ExternalLink } from "lucide-react"; |
| import { Button } from "./components/ui/button"; |
| import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./components/ui/tooltip"; |
| import { useCallback, useMemo, useState } from "react"; |
| import { AccessType } from "./components/icon"; |
| import { Access } from "config"; |
| |
| export function Gateways() { |
| const env = useEnv(); |
| console.log(env.access); |
| const filtered = useMemo(() => { |
| return env.access.filter((a) => a.type !== "env_var"); |
| }, [env.access]); |
| const groupedAccess = filtered.reduce((acc, curr) => { |
| if (!acc.has(curr.name)) { |
| acc.set(curr.name, []); |
| } |
| acc.get(curr.name)!.push(curr); |
| return acc; |
| }, new Map<string, typeof env.access>()); |
| return ( |
| <ul> |
| {Array.from(groupedAccess.entries()).map(([name, access]) => ( |
| <> |
| {access.map((a) => ( |
| <li key={name}> |
| <Gateway g={a} /> |
| </li> |
| ))} |
| </> |
| ))} |
| </ul> |
| ); |
| } |
| |
| export function Gateway({ g }: { g: Access }) { |
| const [hidden, content] = ((): [string, string] => { |
| switch (g.type) { |
| case "https": |
| return [g.address, g.address]; |
| case "ssh": |
| case "tcp": |
| case "udp": |
| return [`${g.host}:${g.port}`, `${g.host}:${g.port}`]; |
| case "postgresql": |
| return [ |
| `postgresql://${g.username}:*****@${g.host}:${g.port}/${g.database}`, |
| `postgresql://${g.username}:${g.password}@${g.host}:${g.port}/${g.database}`, |
| ]; |
| case "mongodb": |
| return [ |
| `mongodb://${g.username}:*****@${g.host}:${g.port}/${g.database}`, |
| `mongodb://${g.username}:${g.password}@${g.host}:${g.port}/${g.database}`, |
| ]; |
| default: |
| throw new Error(`Unknown gateway type: ${g.type}`); |
| } |
| })(); |
| const [clicked, setClicked] = useState(false); |
| const [open, setOpen] = useState(false); |
| const copy = useCallback(() => { |
| navigator.clipboard.writeText(content); |
| setClicked(true); |
| setOpen(true); |
| setTimeout(() => { |
| setClicked(false); |
| setOpen(false); |
| }, 1000); |
| }, [content, setClicked, setOpen]); |
| const handleClick = useCallback(() => { |
| if (g.type === "https") { |
| window.open(content, "_blank"); |
| } else { |
| copy(); |
| } |
| }, [g.type, content, copy]); |
| |
| return ( |
| <TooltipProvider> |
| <Tooltip delayDuration={100} open={open} onOpenChange={setOpen}> |
| <TooltipTrigger asChild> |
| <Button variant="ghost" className="!gap-1 !p-0 !h-fit" onClick={handleClick}> |
| <AccessType access={g} className="w-4 h-4" /> |
| <div className="hover:bg-gray-200 p-x-1">{hidden}</div> |
| </Button> |
| </TooltipTrigger> |
| <TooltipContent |
| side="right" |
| className="!bg-transparent cursor-pointer !p-0" |
| sideOffset={10} |
| onClick={copy} |
| > |
| {g.type === "https" ? ( |
| <ExternalLink className="w-4 h-4 !bg-transparent" color="black" /> |
| ) : ( |
| <> |
| {!clicked && <Copy className="w-4 h-4 !bg-transparent" color="black" />} |
| {clicked && <Check className="w-4 h-4 !bg-transparent" color="black" />} |
| </> |
| )} |
| </TooltipContent> |
| </Tooltip> |
| </TooltipProvider> |
| ); |
| } |