diff --git a/frontend/src/hooks.ts b/frontend/src/hooks.ts index 7aa2a5bf1..224b508bc 100644 --- a/frontend/src/hooks.ts +++ b/frontend/src/hooks.ts @@ -4,7 +4,10 @@ import { useQuery, useMutation } from "@tanstack/react-query"; import { useAtomValue, useSetAtom } from "jotai"; import { atomWithStorage } from "jotai/utils"; import { useNavigate } from "react-router-dom"; -import { WriteResponses } from "@monitor/client/dist/responses"; +import { + ExecuteResponses, + WriteResponses, +} from "@monitor/client/dist/responses"; export const useRead = (req: T) => useQuery([req], () => client.read(req)); @@ -21,8 +24,17 @@ export const useWrite = < (await client.write({ type, params } as any)) as WriteResponses[T] ); -export const useExecute = () => - useMutation((req: T) => client.execute(req)); +export const useExecute = < + T extends Types.ExecuteRequest["type"], + P = Extract["params"] +>( + type: T +) => + useMutation( + [type], + async (params: P) => + (await client.execute({ type, params } as any)) as ExecuteResponses[T] + ); export const useUser = () => useRead({ type: "GetUser", params: {} }); diff --git a/frontend/src/layouts/config.tsx b/frontend/src/layouts/config.tsx deleted file mode 100644 index 89e09d807..000000000 --- a/frontend/src/layouts/config.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { Button } from "@ui/button"; -import { Card, CardContent, CardHeader, CardTitle } from "@ui/card"; -import { RefreshCcw, Save } from "lucide-react"; -import { ReactNode } from "react"; - -export const Config = ({ - children, - loading, - save, - reset, -}: { - children: ReactNode; - loading: boolean; - save: { disabled?: boolean; onClick: () => void }; - reset: { disabled?: boolean; onClick: () => void }; -}) => ( - - - Config -
- - -
-
- - {children} - -
-); diff --git a/frontend/src/layouts/layout.tsx b/frontend/src/layouts/layout.tsx index 813980c91..5d960b786 100644 --- a/frontend/src/layouts/layout.tsx +++ b/frontend/src/layouts/layout.tsx @@ -1,6 +1,5 @@ import { Header } from "@components/header"; import { useUser } from "@hooks"; -import { Login } from "@pages/auth/login"; import { Toaster } from "@ui/toast"; import { Outlet, useLocation, useNavigate } from "react-router-dom"; diff --git a/frontend/src/layouts/resources.tsx b/frontend/src/layouts/resources.tsx deleted file mode 100644 index b5cf14aab..000000000 --- a/frontend/src/layouts/resources.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { useRead } from "@hooks"; -import { DeploymentCard } from "@resources/deployment/card"; -import { Button } from "@ui/button"; -import { Input } from "@ui/input"; -import { PlusCircle } from "lucide-react"; -import { useState } from "react"; - -export const Deployments = () => { - const deployments = useRead({ type: "ListDeployments", params: {} }).data; - const [search, set] = useState(""); - - return ( -
-
-

Deployments

-
- set(e.target.value)} - /> - -
-
-
- {deployments?.map( - ({ id, name }) => - (search.includes(name) || name.includes(search)) && ( - - ) - )} -
-
- ); -}; diff --git a/frontend/src/pages/dashboard/components/deployments-chart.tsx b/frontend/src/pages/dashboard/components/deployments-chart.tsx index c17aa95c7..306d8ee00 100644 --- a/frontend/src/pages/dashboard/components/deployments-chart.tsx +++ b/frontend/src/pages/dashboard/components/deployments-chart.tsx @@ -1,4 +1,3 @@ -import { Button } from "@ui/button"; import { Card, CardHeader, @@ -7,7 +6,6 @@ import { CardContent, } from "@ui/card"; import { WithLoading } from "@components/util"; -import { ChevronRight } from "lucide-react"; import { PieChart } from "react-minimal-pie-chart"; import { Link } from "react-router-dom"; import { useRead } from "@hooks"; diff --git a/frontend/src/pages/dashboard/components/recently-viewed.tsx b/frontend/src/pages/dashboard/components/recently-viewed.tsx index 1c1117f4e..f2b8f14ad 100644 --- a/frontend/src/pages/dashboard/components/recently-viewed.tsx +++ b/frontend/src/pages/dashboard/components/recently-viewed.tsx @@ -1,5 +1,5 @@ import { useGetRecentlyViewed } from "@hooks"; -import { BuildCard, ServerCard } from ".."; +import { BuildCard } from ".."; import { useState } from "react"; import { DropdownMenu, @@ -14,6 +14,8 @@ import { Button } from "@ui/button"; import { ChevronDown, PlusCircle } from "lucide-react"; import { DeploymentCard } from "@resources/deployment/card"; import { NewDeployment } from "@resources/deployment/new"; +import { ServerCard } from "@resources/server/util"; +import { NewBuild } from "@resources/build/new"; const NewButton = () => { const [open, set] = useState<"deployment" | "build" | "server" | boolean>( @@ -59,7 +61,7 @@ const NewButton = () => { - {/* */} + ); }; diff --git a/frontend/src/pages/dashboard/components/servers-chart.tsx b/frontend/src/pages/dashboard/components/servers-chart.tsx index a074bba4a..3a8440fe3 100644 --- a/frontend/src/pages/dashboard/components/servers-chart.tsx +++ b/frontend/src/pages/dashboard/components/servers-chart.tsx @@ -1,4 +1,3 @@ -import { Button } from "@ui/button"; import { Card, CardHeader, @@ -7,7 +6,6 @@ import { CardContent, } from "@ui/card"; import { WithLoading } from "@components/util"; -import { ChevronRight } from "lucide-react"; import { PieChart } from "react-minimal-pie-chart"; import { Link } from "react-router-dom"; import { useRead } from "@hooks"; diff --git a/frontend/src/pages/dashboard/index.tsx b/frontend/src/pages/dashboard/index.tsx index bbbaf99a9..fbf2e2de9 100644 --- a/frontend/src/pages/dashboard/index.tsx +++ b/frontend/src/pages/dashboard/index.tsx @@ -1,95 +1,11 @@ -import { useRead, useUser, useWrite } from "@hooks"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@ui/card"; +import { useRead, useUser } from "@hooks"; +import { Card, CardDescription, CardHeader, CardTitle } from "@ui/card"; import { version_to_string } from "@util/helpers"; import { ServersChart } from "./components/servers-chart"; import { DeploymentsChart } from "./components/deployments-chart"; -import { Input } from "@ui/input"; import { Link } from "react-router-dom"; -import { Button } from "@ui/button"; -import { - Dialog, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, -} from "@ui/dialog"; -import { useState } from "react"; import { RecentlyViewed } from "./components/recently-viewed"; -import { ServerStats, ServerStatusIcon } from "@resources/server/util"; - -const NewBuild = ({ - open, - set, -}: { - open: boolean; - set: (b: boolean) => void; -}) => { - const { mutate } = useWrite(); - const [name, setName] = useState(""); - - return ( - - - - New Build - -
-
Build Name
- setName(e.target.value)} - /> -
- - - -
-
- ); -}; - -export const ServerCard = ({ id }: { id: string }) => { - const servers = useRead({ type: "ListServers", params: {} }).data; - const server = servers?.find((server) => server.id === id); - if (!server) return null; - - return ( - - - -
- {server.name} - {server.status} -
- -
- - - -
- - ); -}; +import { ServerStatusIcon } from "@resources/server/util"; export const BuildCard = ({ id }: { id: string }) => { const builds = useRead({ type: "ListBuilds", params: {} }).data; diff --git a/frontend/src/pages/servers/index.tsx b/frontend/src/pages/servers/index.tsx index e1ae69c27..4946ed284 100644 --- a/frontend/src/pages/servers/index.tsx +++ b/frontend/src/pages/servers/index.tsx @@ -1,5 +1,5 @@ import { useRead } from "@hooks"; -import { ServerCard } from "@pages/dashboard"; +import { ServerCard } from "@resources/server/util"; import { Button } from "@ui/button"; import { Input } from "@ui/input"; import { PlusCircle } from "lucide-react"; diff --git a/frontend/src/resources/build/components/actions.tsx b/frontend/src/resources/build/components/actions.tsx index 7e961dcff..6a9fefb18 100644 --- a/frontend/src/resources/build/components/actions.tsx +++ b/frontend/src/resources/build/components/actions.tsx @@ -3,15 +3,13 @@ import { useExecute } from "@hooks"; import { Hammer } from "lucide-react"; export const RebuildBuild = ({ buildId }: { buildId: string }) => { - const { mutate, isLoading } = useExecute(); + const { mutate, isLoading } = useExecute("RunBuild"); return ( } - onClick={() => - mutate({ type: "RunBuild", params: { build_id: buildId } }) - } + onClick={() => mutate({ build_id: buildId })} disabled={isLoading} /> ); diff --git a/frontend/src/resources/build/new.tsx b/frontend/src/resources/build/new.tsx new file mode 100644 index 000000000..eb5fc0e75 --- /dev/null +++ b/frontend/src/resources/build/new.tsx @@ -0,0 +1,53 @@ +import { useState } from "react"; +import { useWrite } from "@hooks"; +import { Button } from "@ui/button"; +import { + Dialog, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@ui/dialog"; +import { Input } from "@ui/input"; + +export const NewBuild = ({ + open, + set, +}: { + open: boolean; + set: (b: boolean) => void; +}) => { + const { mutate } = useWrite("CreateBuild"); + const [name, setName] = useState(""); + + return ( + + + + New Build + +
+
Build Name
+ setName(e.target.value)} + /> +
+ + + +
+
+ ); +}; diff --git a/frontend/src/resources/deployment/components/actions.tsx b/frontend/src/resources/deployment/components/actions.tsx index 6c61e9f55..89c7b038f 100644 --- a/frontend/src/resources/deployment/components/actions.tsx +++ b/frontend/src/resources/deployment/components/actions.tsx @@ -3,89 +3,66 @@ import { RefreshCw, Play, Trash, Pause } from "lucide-react"; import { useExecute, useRead } from "@hooks"; import { DockerContainerState } from "@monitor/client/dist/types"; -export const RedeployContainer = ({ - deploymentId, -}: { - deploymentId: string; -}) => { - const { mutate, isLoading } = useExecute(); +interface DeploymentId { + deployment_id: string; +} + +export const RedeployContainer = ({ deployment_id }: DeploymentId) => { + const { mutate, isLoading } = useExecute("Deploy"); return ( } - onClick={() => - mutate({ type: "Deploy", params: { deployment_id: deploymentId } }) - } + onClick={() => mutate({ deployment_id })} disabled={isLoading} /> ); }; -const StartContainer = ({ deploymentId }: { deploymentId: string }) => { - const { mutate, isLoading } = useExecute(); - +const StartContainer = ({ deployment_id }: DeploymentId) => { + const { mutate, isLoading } = useExecute("StartContainer"); return ( } - onClick={() => - mutate({ - type: "StartContainer", - params: { deployment_id: deploymentId }, - }) - } + onClick={() => mutate({ deployment_id })} disabled={isLoading} /> ); }; -const StopContainer = ({ deploymentId }: { deploymentId: string }) => { - const { mutate, isLoading } = useExecute(); +const StopContainer = ({ deployment_id }: DeploymentId) => { + const { mutate, isLoading } = useExecute("StopContainer"); return ( } - onClick={() => - mutate({ - type: "StopContainer", - params: { deployment_id: deploymentId }, - }) - } + onClick={() => mutate({ deployment_id })} disabled={isLoading} /> ); }; -export const StartOrStopContainer = ({ - deploymentId, -}: { - deploymentId: string; -}) => { +export const StartOrStopContainer = ({ deployment_id }: DeploymentId) => { const { data } = useRead({ type: "ListDeployments", params: {} }); - const deployment = data?.find((d) => d.id == deploymentId); + const deployment = data?.find((d) => d.id == deployment_id); if (deployment?.state === DockerContainerState.Running) - return ; - return ; + return ; + return ; }; -export const RemoveContainer = ({ deploymentId }: { deploymentId: string }) => { - const { mutate, isLoading } = useExecute(); - +export const RemoveContainer = ({ deployment_id }: DeploymentId) => { + const { mutate, isLoading } = useExecute("RemoveContainer"); return ( } - onClick={() => - mutate({ - type: "RemoveContainer", - params: { deployment_id: deploymentId }, - }) - } + onClick={() => mutate({ deployment_id })} disabled={isLoading} /> ); diff --git a/frontend/src/resources/server/util.tsx b/frontend/src/resources/server/util.tsx index 7bcf063b4..aa64fcd9c 100644 --- a/frontend/src/resources/server/util.tsx +++ b/frontend/src/resources/server/util.tsx @@ -1,9 +1,16 @@ import { useRead } from "@hooks"; import { ServerStatus } from "@monitor/client/dist/types"; -import { CardDescription } from "@ui/card"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@ui/card"; import { cn } from "@util/helpers"; import { Circle, Cpu, Database, MemoryStick } from "lucide-react"; import { useEffect } from "react"; +import { Link } from "react-router-dom"; export const ServerName = ({ serverId }: { serverId: string | undefined }) => { const servers = useRead({ type: "ListServers", params: {} }).data; @@ -78,3 +85,26 @@ export const ServerStatusIcon = ({ /> ); }; + +export const ServerCard = ({ id }: { id: string }) => { + const servers = useRead({ type: "ListServers", params: {} }).data; + const server = servers?.find((server) => server.id === id); + if (!server) return null; + + return ( + + + +
+ {server.name} + {server.status} +
+ +
+ + + +
+ + ); +};