blob: 6e02bc19c0149af7248614ba09e7842aadf9b9d1 [file] [log] [blame]
giocc5ce582025-06-25 07:45:21 +04001import { useEnv } from "./lib/state";
giob1632592025-08-04 11:41:44 +00002import { Copy, Check, ExternalLink } from "lucide-react";
giob77cb932025-05-19 09:37:14 +00003import { Button } from "./components/ui/button";
4import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./components/ui/tooltip";
gio8323a052025-08-04 06:12:26 +00005import { useCallback, useMemo, useState } from "react";
gio48679462025-05-21 04:27:27 +00006import { AccessType } from "./components/icon";
giocc5ce582025-06-25 07:45:21 +04007import { Access } from "config";
giob77cb932025-05-19 09:37:14 +00008
9export function Gateways() {
10 const env = useEnv();
gio8323a052025-08-04 06:12:26 +000011 console.log(env.access);
12 const filtered = useMemo(() => {
13 return env.access.filter((a) => a.type !== "env_var");
14 }, [env.access]);
15 const groupedAccess = filtered.reduce((acc, curr) => {
giob77cb932025-05-19 09:37:14 +000016 if (!acc.has(curr.name)) {
17 acc.set(curr.name, []);
18 }
19 acc.get(curr.name)!.push(curr);
20 return acc;
21 }, new Map<string, typeof env.access>());
22 return (
23 <ul>
24 {Array.from(groupedAccess.entries()).map(([name, access]) => (
gio40370782025-05-19 11:04:52 +000025 <>
giob77cb932025-05-19 09:37:14 +000026 {access.map((a) => (
gio40370782025-05-19 11:04:52 +000027 <li key={name}>
28 <Gateway g={a} />
29 </li>
giob77cb932025-05-19 09:37:14 +000030 ))}
gio40370782025-05-19 11:04:52 +000031 </>
giob77cb932025-05-19 09:37:14 +000032 ))}
33 </ul>
34 );
35}
36
gio9f3d4f52025-07-04 08:42:34 +000037export function Gateway({ g }: { g: Access }) {
giocc5ce582025-06-25 07:45:21 +040038 const [hidden, content] = ((): [string, string] => {
giob77cb932025-05-19 09:37:14 +000039 switch (g.type) {
40 case "https":
41 return [g.address, g.address];
42 case "ssh":
43 case "tcp":
44 case "udp":
45 return [`${g.host}:${g.port}`, `${g.host}:${g.port}`];
46 case "postgresql":
47 return [
48 `postgresql://${g.username}:*****@${g.host}:${g.port}/${g.database}`,
49 `postgresql://${g.username}:${g.password}@${g.host}:${g.port}/${g.database}`,
50 ];
51 case "mongodb":
52 return [
53 `mongodb://${g.username}:*****@${g.host}:${g.port}/${g.database}`,
54 `mongodb://${g.username}:${g.password}@${g.host}:${g.port}/${g.database}`,
55 ];
giocc5ce582025-06-25 07:45:21 +040056 default:
57 throw new Error(`Unknown gateway type: ${g.type}`);
giob77cb932025-05-19 09:37:14 +000058 }
59 })();
60 const [clicked, setClicked] = useState(false);
61 const [open, setOpen] = useState(false);
62 const copy = useCallback(() => {
63 navigator.clipboard.writeText(content);
64 setClicked(true);
65 setOpen(true);
66 setTimeout(() => {
67 setClicked(false);
68 setOpen(false);
69 }, 1000);
70 }, [content, setClicked, setOpen]);
giob1632592025-08-04 11:41:44 +000071 const handleClick = useCallback(() => {
72 if (g.type === "https") {
73 window.open(content, "_blank");
74 } else {
75 copy();
76 }
77 }, [g.type, content, copy]);
78
giob77cb932025-05-19 09:37:14 +000079 return (
80 <TooltipProvider>
81 <Tooltip delayDuration={100} open={open} onOpenChange={setOpen}>
82 <TooltipTrigger asChild>
giob1632592025-08-04 11:41:44 +000083 <Button variant="ghost" className="!gap-1 !p-0 !h-fit" onClick={handleClick}>
giocc5ce582025-06-25 07:45:21 +040084 <AccessType access={g} className="w-4 h-4" />
giob77cb932025-05-19 09:37:14 +000085 <div className="hover:bg-gray-200 p-x-1">{hidden}</div>
86 </Button>
87 </TooltipTrigger>
giob1632592025-08-04 11:41:44 +000088 <TooltipContent
89 side="right"
90 className="!bg-transparent cursor-pointer !p-0"
91 sideOffset={10}
92 onClick={copy}
93 >
94 {g.type === "https" ? (
95 <ExternalLink className="w-4 h-4 !bg-transparent" color="black" />
96 ) : (
97 <>
98 {!clicked && <Copy className="w-4 h-4 !bg-transparent" color="black" />}
99 {clicked && <Check className="w-4 h-4 !bg-transparent" color="black" />}
100 </>
101 )}
giob77cb932025-05-19 09:37:14 +0000102 </TooltipContent>
103 </Tooltip>
104 </TooltipProvider>
105 );
106}