ExecuteCustomNodeCommandDialogContent.tsx raw
1 import React from "react";
2 import { toast } from "sonner";
3 import {
4 AlertDialogAction,
5 AlertDialogCancel,
6 AlertDialogContent,
7 AlertDialogDescription,
8 AlertDialogFooter,
9 AlertDialogHeader,
10 AlertDialogTitle,
11 } from "src/components/ui/alert-dialog";
12 import { Textarea } from "src/components/ui/textarea";
13 import { useInfo } from "src/hooks/useInfo";
14 import { request } from "src/utils/request";
15
16 type ExecuteCustomNodeCommandDialogContentProps = {
17 availableCommands: string;
18 setCommandResponse: (response: string) => void;
19 };
20
21 export function ExecuteCustomNodeCommandDialogContent({
22 setCommandResponse,
23 availableCommands,
24 }: ExecuteCustomNodeCommandDialogContentProps) {
25 const { mutate: reloadInfo } = useInfo();
26 const [command, setCommand] = React.useState<string>();
27
28 let parsedAvailableCommands = availableCommands;
29 try {
30 parsedAvailableCommands = JSON.stringify(
31 JSON.parse(availableCommands).commands,
32 null,
33 2
34 );
35 } catch {
36 // ignore unexpected json
37 }
38
39 async function executeCommand() {
40 try {
41 if (!command) {
42 throw new Error("No command set");
43 }
44 const result = await request("/api/command", {
45 method: "POST",
46 body: JSON.stringify({ command }),
47 headers: {
48 "Content-Type": "application/json",
49 },
50 });
51 await reloadInfo();
52
53 const parsedResponse = JSON.stringify(result);
54 setCommandResponse(parsedResponse);
55
56 toast("Command executed", { description: parsedResponse });
57 } catch (error) {
58 console.error(error);
59 toast.error("Something went wrong: " + error);
60 }
61 }
62
63 const handleSubmit = (e: React.FormEvent) => {
64 e.preventDefault();
65 executeCommand();
66 };
67
68 return (
69 <AlertDialogContent>
70 <AlertDialogHeader>
71 <AlertDialogTitle>Execute Custom Node Command</AlertDialogTitle>
72 <AlertDialogDescription className="text-left">
73 <form id="execute-command-form" onSubmit={handleSubmit}>
74 <Textarea
75 className="h-36 font-mono"
76 value={command}
77 onChange={(e) => setCommand(e.target.value)}
78 placeholder="commandname --arg1=value1"
79 />
80 </form>
81 <p className="mt-2">Available commands</p>
82 <Textarea
83 readOnly
84 className="mt-2 font-mono"
85 value={parsedAvailableCommands}
86 rows={10}
87 />
88 </AlertDialogDescription>
89 </AlertDialogHeader>
90 <AlertDialogFooter>
91 <AlertDialogCancel onClick={() => setCommand("")}>
92 Cancel
93 </AlertDialogCancel>
94 <AlertDialogAction type="submit" form="execute-command-form">
95 Execute
96 </AlertDialogAction>
97 </AlertDialogFooter>
98 </AlertDialogContent>
99 );
100 }
101