Skip to content
This repository has been archived by the owner on Dec 29, 2023. It is now read-only.

Commit

Permalink
draft: drop in react query
Browse files Browse the repository at this point in the history
  • Loading branch information
aosasona committed Feb 24, 2023
1 parent 713de06 commit 2321bf1
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 134 deletions.
71 changes: 0 additions & 71 deletions ui/src/components/Bazooka.tsx

This file was deleted.

106 changes: 45 additions & 61 deletions ui/src/components/SideBar.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,67 @@
import { Dispatch, SetStateAction, SyntheticEvent, useState } from "react";
import { toast } from "react-toastify";
import { get, post } from "../lib/request";
import type { Process } from "../lib/types";
import { useState } from "react";
import { FiRefreshCw } from "react-icons/fi/index";
import Loading from "./Loading";
import { QueryClient, useMutation } from "@tanstack/react-query";
import { killProcesses } from "../queries/process/mutations";
import { onError } from "../lib/error";

interface Props {
PIDs: Number[];
setProcesses: Dispatch<SetStateAction<Process[]>>;
setLoading: Dispatch<SetStateAction<boolean>>;
refresh: () => Promise<void>;
queryClient: QueryClient;
refetch: Function;
}

export default function SideBar({
PIDs,
setProcesses,
setLoading,
refresh,
}: Props) {
export default function SideBar({ PIDs, refetch, queryClient }: Props) {
const [port, setPort] = useState("");
const [isKilling, setIsKilling] = useState<boolean>(false);

const killProcesses = async () => {
try {
setIsKilling(true);
const body = {
pids: PIDs,
};
const data = await post("/processes/kill", body);
const killProcessesMutation = useMutation({
mutationFn: killProcesses,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["processes"] });
},
onError,
});

if (!data.ok) {
toast(data?.message, { type: "error" });
return;
}
await refresh();
toast(data?.message, { type: "success" });
} catch (err) {
toast("Something went wrong", { type: "error" });
} finally {
setIsKilling(false);
}
};
function handleKillProcesses() {
killProcessesMutation.mutate(PIDs);
}

const findProcessByPort = async (e: SyntheticEvent<HTMLFormElement>) => {
try {
e.preventDefault();

if (!port) {
return await refresh();
}

setLoading(true);
const data = await get(`/processes/port/${port}`);

if (!data.ok) {
toast(data?.message, { type: "error" });
return;
}

setProcesses([data.data]);
toast(data?.message, { type: "success" });
} catch (err: any) {
toast("Something went wrong", { type: "error" });
} finally {
setLoading(false);
}
};
// const findProcessByPort = async (e: SyntheticEvent<HTMLFormElement>) => {
// try {
// e.preventDefault();
//
// if (!port) {
// return await refresh();
// }
//
// setLoading(true);
// const data = await get(`/processes/port/${port}`);
//
// if (!data.ok) {
// toast(data?.message, { type: "error" });
// return;
// }
//
// setProcesses([data.data]);
// toast(data?.message, { type: "success" });
// } catch (err: any) {
// toast("Something went wrong", { type: "error" });
// } finally {
// setLoading(false);
// }
// };

return (
<section className="w-full md:w-[30%]">
<div className="flex justify-end">
<button
className="bg-zinc-800 rounded-md py-2 px-4 mb-3"
onClick={refresh}
onClick={() => refetch()}
>
<FiRefreshCw size={12} className="text-zinc-500" />
</button>
</div>
<form className="space-y-3" onSubmit={findProcessByPort}>
<form className="space-y-3" onSubmit={() => "// do later"}>
<input
name="search"
className="w-full text-sm bg-zinc-800 placeholder-zinc-500 focus:outline-none focus:border-none px-3 py-2.5 rounded-md"
Expand All @@ -93,13 +77,13 @@ export default function SideBar({
</button>
</form>

{isKilling ? (
{killProcessesMutation.isLoading ? (
<Loading />
) : (
<button
disabled={PIDs.length == 0}
className="w-full text-red-500 disabled:opacity-40 hover:bg-zinc-800 font-medium text-center disabled:cursor-not-allowed rounded-md py-2.5 mt-6 transition-all"
onClick={killProcesses}
onClick={handleKillProcesses}
>
Kill selected processes
</button>
Expand Down
9 changes: 9 additions & 0 deletions ui/src/lib/CustomException.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default class CustomException extends Error {
public static errorName = "CustomException" as const;
constructor(message: string, err?: Error) {
super(message);
this.name = CustomException.errorName;
this.message = message;
this.cause = err?.message || "";
}
}
11 changes: 11 additions & 0 deletions ui/src/lib/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { toast } from "react-toastify";
import CustomException from "./CustomException";

export function onError(error: Error) {
toast(
error.name == CustomException.errorName || error instanceof CustomException
? error.message
: "Something went wrong!",
{ type: "error" }
);
}
4 changes: 2 additions & 2 deletions ui/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
import Layout from "../layouts/Layout.astro";
import Bazooka from "../components/Bazooka";
import Bazooka from "../react/Bazooka";
import Footer from "../components/Footer.astro";
---

<Layout title="Bazooka">
<main class="max-w-6xl px-4 mt-6 md:mt-14 mx-auto">
<Bazooka client:idle />
<Bazooka client:load />
<Footer />
</main>
</Layout>
12 changes: 12 additions & 0 deletions ui/src/queries/process/fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import CustomException from "../../lib/CustomException";
import { get } from "../../lib/request";
import type { Process } from "../../lib/types";

export async function fetchProcesses(): Promise<Process[]> {
const data = await get("/processes");
if (!data.ok) {
throw new CustomException(data.message);
}

return data.data;
}
15 changes: 15 additions & 0 deletions ui/src/queries/process/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import CustomException from "../../lib/CustomException";
import { post } from "../../lib/request";

export async function killProcesses(PIDs: Number[]) {
const body = {
pids: PIDs,
};
const data = await post("/processes/kill", body);

if (!data.ok) {
throw new CustomException(data.message);
}

return data.data;
}
53 changes: 53 additions & 0 deletions ui/src/react/Bazooka.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { useState } from "react";
import { ToastContainer } from "react-toastify";
import Display from "../components/Display";
import SideBar from "../components/SideBar";
import {
useQuery,
QueryClient,
QueryClientProvider,
} from "@tanstack/react-query";
import "react-toastify/dist/ReactToastify.css";
import { fetchProcesses } from "../queries/process/fetch";
import type { Process } from "../lib/types";
import { onError } from "../lib/error";

export default function Bazooka() {
const [processes, setProcesses] = useState<Process[]>([]);
const [PIDs, setPIDs] = useState<number[]>([]);

const queryClient = new QueryClient();
const { isLoading, refetch } = useQuery({
queryKey: ["processes"],
queryFn: fetchProcesses,
onSuccess: (data) => {
if (data) {
setProcesses(data);
}
},
onError,
});

return (
<QueryClientProvider client={queryClient}>
<main className="w-full flex flex-col-reverse md:flex-row gap-6">
<Display
loading={isLoading}
PIDs={PIDs}
processes={processes}
setProcesses={setProcesses}
setPIDs={setPIDs}
/>
<SideBar PIDs={PIDs} refetch={refetch} queryClient={queryClient} />
</main>
<ToastContainer
theme="dark"
position="top-right"
autoClose={5000}
hideProgressBar
draggable
closeOnClick
/>
</QueryClientProvider>
);
}

0 comments on commit 2321bf1

Please sign in to comment.