mirror of
https://github.com/usatiuk/dhfs.git
synced 2025-10-29 04:57:48 +01:00
web ui beginnings
This commit is contained in:
8
webui/.proxyrc
Normal file
8
webui/.proxyrc
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"/apiproxy": {
|
||||||
|
"target": "http://localhost:8080/",
|
||||||
|
"pathRewrite": {
|
||||||
|
"^/apiproxy": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,8 @@ import {
|
|||||||
import "./App.scss";
|
import "./App.scss";
|
||||||
import { Home } from "./Home";
|
import { Home } from "./Home";
|
||||||
import { PeerState } from "./PeerState";
|
import { PeerState } from "./PeerState";
|
||||||
|
import { peerStateLoader } from "./PeerStatePlumbing";
|
||||||
|
import { ErrorGate } from "./ErrorGate";
|
||||||
|
|
||||||
const router = createBrowserRouter(
|
const router = createBrowserRouter(
|
||||||
[
|
[
|
||||||
@@ -21,11 +23,19 @@ const router = createBrowserRouter(
|
|||||||
// return redirect("/home");
|
// return redirect("/home");
|
||||||
// }
|
// }
|
||||||
},
|
},
|
||||||
|
errorElement: <ErrorGate />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/home",
|
path: "/home",
|
||||||
element: <Home />,
|
element: <Home />,
|
||||||
children: [{ path: "peers", element: <PeerState /> }],
|
children: [
|
||||||
|
{
|
||||||
|
path: "peers",
|
||||||
|
element: <PeerState />,
|
||||||
|
loader: peerStateLoader,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errorElement: <ErrorGate />,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
{ basename: "/webui" },
|
{ basename: "/webui" },
|
||||||
|
|||||||
7
webui/src/ErrorGate.tsx
Normal file
7
webui/src/ErrorGate.tsx
Normal 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>;
|
||||||
|
}
|
||||||
@@ -1,5 +1,14 @@
|
|||||||
import "./PeerState.scss";
|
import "./PeerState.scss";
|
||||||
|
import { useLoaderData } from "react-router-dom";
|
||||||
|
import { LoaderToType } from "./commonPlumbing";
|
||||||
|
import { peerStateLoader } from "./PeerStatePlumbing";
|
||||||
|
|
||||||
export function PeerState() {
|
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>;
|
||||||
}
|
}
|
||||||
|
|||||||
7
webui/src/PeerStatePlumbing.tsx
Normal file
7
webui/src/PeerStatePlumbing.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { getAvailablePeers } from "./api/PeerState";
|
||||||
|
|
||||||
|
export async function peerStateLoader() {
|
||||||
|
return {
|
||||||
|
availablePeers: await getAvailablePeers(),
|
||||||
|
};
|
||||||
|
}
|
||||||
13
webui/src/api/PeerState.ts
Normal file
13
webui/src/api/PeerState.ts
Normal 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);
|
||||||
|
}
|
||||||
@@ -33,3 +33,18 @@ export type TTokenTo = z.infer<typeof TokenTo>;
|
|||||||
|
|
||||||
export const TokenToResp = CreateAPIResponse(TokenTo);
|
export const TokenToResp = CreateAPIResponse(TokenTo);
|
||||||
export type TTokenToResp = z.infer<typeof TokenToResp>;
|
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>;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { jwtDecode } from "jwt-decode";
|
import { jwtDecode } from "jwt-decode";
|
||||||
import { isError } from "./dto";
|
import { isError, TErrorTo } from "./dto";
|
||||||
|
|
||||||
declare const process: {
|
declare const process: {
|
||||||
env: {
|
env: {
|
||||||
@@ -8,7 +8,9 @@ declare const process: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const apiRoot: string =
|
const apiRoot: string =
|
||||||
process.env.NODE_ENV == "production" ? "" : "http://localhost:8080";
|
process.env.NODE_ENV == "production"
|
||||||
|
? ""
|
||||||
|
: "http://localhost:1234/apiproxy";
|
||||||
|
|
||||||
let token: string | null;
|
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");
|
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);
|
||||||
|
|||||||
3
webui/src/commonPlumbing.ts
Normal file
3
webui/src/commonPlumbing.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export type LoaderToType<T extends (...args: any) => any> =
|
||||||
|
| Exclude<Awaited<ReturnType<T>>, Response>
|
||||||
|
| undefined;
|
||||||
Reference in New Issue
Block a user