web ui beginnings

This commit is contained in:
2024-07-06 17:28:47 +02:00
parent ca580d0585
commit e70649bfc5
9 changed files with 96 additions and 4 deletions

8
webui/.proxyrc Normal file
View File

@@ -0,0 +1,8 @@
{
"/apiproxy": {
"target": "http://localhost:8080/",
"pathRewrite": {
"^/apiproxy": ""
}
}
}

View File

@@ -8,6 +8,8 @@ import {
import "./App.scss";
import { Home } from "./Home";
import { PeerState } from "./PeerState";
import { peerStateLoader } from "./PeerStatePlumbing";
import { ErrorGate } from "./ErrorGate";
const router = createBrowserRouter(
[
@@ -21,11 +23,19 @@ const router = createBrowserRouter(
// return redirect("/home");
// }
},
errorElement: <ErrorGate />,
},
{
path: "/home",
element: <Home />,
children: [{ path: "peers", element: <PeerState /> }],
children: [
{
path: "peers",
element: <PeerState />,
loader: peerStateLoader,
},
],
errorElement: <ErrorGate />,
},
],
{ basename: "/webui" },

7
webui/src/ErrorGate.tsx Normal file
View File

@@ -0,0 +1,7 @@
import { useRouteError } from "react-router-dom";
export function ErrorGate() {
const error = useRouteError();
console.error(error);
return <div>{JSON.stringify(error)}</div>;
}

View File

@@ -1,5 +1,14 @@
import "./PeerState.scss";
import { useLoaderData } from "react-router-dom";
import { LoaderToType } from "./commonPlumbing";
import { peerStateLoader } from "./PeerStatePlumbing";
export function PeerState() {
return <div id={"PeerState"}>peerstate</div>;
const loaderData = useLoaderData() as LoaderToType<typeof peerStateLoader>;
const availablePeers = loaderData?.availablePeers.map((p) => {
return <div>{p.uuid}</div>;
});
return <div id={"PeerState"}>{availablePeers}</div>;
}

View File

@@ -0,0 +1,7 @@
import { getAvailablePeers } from "./api/PeerState";
export async function peerStateLoader() {
return {
availablePeers: await getAvailablePeers(),
};
}

View File

@@ -0,0 +1,13 @@
import { fetchJSON_throws } from "./utils";
import {
AvailablePeerInfoToResp,
TAvailablePeerInfoArrTo,
TAvailablePeerInfoToResp,
} from "./dto";
export async function getAvailablePeers(): Promise<TAvailablePeerInfoArrTo> {
return fetchJSON_throws<
TAvailablePeerInfoToResp,
typeof AvailablePeerInfoToResp
>("/objects-manage/available-peers", "GET", AvailablePeerInfoToResp);
}

View File

@@ -33,3 +33,18 @@ export type TTokenTo = z.infer<typeof TokenTo>;
export const TokenToResp = CreateAPIResponse(TokenTo);
export type TTokenToResp = z.infer<typeof TokenToResp>;
export const AvailablePeerInfoTo = z.object({
uuid: z.string(),
addr: z.string(),
port: z.number(),
});
export type TAvailablePeerInfoTo = z.infer<typeof AvailablePeerInfoTo>;
export const AvailablePeerInfoArrTo = z.array(AvailablePeerInfoTo);
export type TAvailablePeerInfoArrTo = z.infer<typeof AvailablePeerInfoArrTo>;
export const AvailablePeerInfoToResp = CreateAPIResponse(
AvailablePeerInfoArrTo,
);
export type TAvailablePeerInfoToResp = z.infer<typeof AvailablePeerInfoToResp>;

View File

@@ -1,5 +1,5 @@
import { jwtDecode } from "jwt-decode";
import { isError } from "./dto";
import { isError, TErrorTo } from "./dto";
declare const process: {
env: {
@@ -8,7 +8,9 @@ declare const process: {
};
const apiRoot: string =
process.env.NODE_ENV == "production" ? "" : "http://localhost:8080";
process.env.NODE_ENV == "production"
? ""
: "http://localhost:1234/apiproxy";
let token: string | null;
@@ -88,3 +90,21 @@ export async function fetchJSONAuth<T, P extends { parse: (arg: string) => T }>(
throw new Error("Not logged in");
}
}
function errorCheck<A extends unknown[], R>(
fn: (...args: A) => R,
): (...args: A) => Promise<Exclude<Awaited<R>, TErrorTo>> {
return async (...args: A): Promise<Exclude<Awaited<R>, TErrorTo>> => {
const ret = await fn(...args);
if (isError(ret)) {
throw ret;
} else {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return ret;
}
};
}
export const fetchJSON_throws = errorCheck(fetchJSON);
export const fetchJSONAuth_throws = errorCheck(fetchJSONAuth);

View File

@@ -0,0 +1,3 @@
export type LoaderToType<T extends (...args: any) => any> =
| Exclude<Awaited<ReturnType<T>>, Response>
| undefined;