From 812c8cb209f9c4d76350b08c63305767e655ab09 Mon Sep 17 00:00:00 2001 From: ml729 <85370083+ml729@users.noreply.github.com> Date: Fri, 20 Jan 2023 01:35:48 -0500 Subject: [PATCH] create status page --- website/src/pages/admin/status/index.tsx | 168 ++++++++++++++++++ website/src/pages/api/admin/stats.ts | 18 ++ .../src/pages/api/admin/tasks_availability.ts | 28 +++ website/src/pages/api/admin/tree_manager.ts | 18 ++ 4 files changed, 232 insertions(+) create mode 100644 website/src/pages/admin/status/index.tsx create mode 100644 website/src/pages/api/admin/stats.ts create mode 100644 website/src/pages/api/admin/tasks_availability.ts create mode 100644 website/src/pages/api/admin/tree_manager.ts diff --git a/website/src/pages/admin/status/index.tsx b/website/src/pages/admin/status/index.tsx new file mode 100644 index 00000000..6af65b61 --- /dev/null +++ b/website/src/pages/admin/status/index.tsx @@ -0,0 +1,168 @@ +import { Box, Button, Container, Flex, FormControl, FormLabel, Input, Select, SimpleGrid, Stack, Text, useToast } from "@chakra-ui/react"; +import { + Spacer, + Table, + TableCaption, + TableContainer, + Tbody, + Td, + Th, + Thead, + Tr, + useColorMode +} from "@chakra-ui/react"; +/* import { Field, Form, Formik } from "formik"; */ +import Head from "next/head"; +import { useRouter } from "next/router"; +import { useSession } from "next-auth/react"; +import { useEffect } from "react"; +import { getAdminLayout } from "src/components/Layout"; +import poster from "src/lib/poster"; +import prisma from "src/lib/prismadb"; +import useSWR from "swr/mutation"; + +import { useState } from "react"; +import useSWRMutation from "swr/mutation"; +import useSWRImmutable from "swr/immutable"; +import { get, post } from "src/lib/api"; + +/* import TreeManagerCell from "src/components/TreeManagerCell"; */ + +/** + * Provides the admin status page that shows result of calls to several backend API endpoints, + * namely /api/v1/tasks/availability, /api/v1/stats/, /api/v1/stats/tree_manager + */ + +const StatusIndex = ({ user }) => { + const toast = useToast(); + const router = useRouter(); + const { data: session, status } = useSession(); + + const { colorMode } = useColorMode(); + const backgroundColor = colorMode === "light" ? "white" : "gray.700"; + const dataBackgroundColor = colorMode === "light" ? "gray.100" : "gray.700"; + // Check when the user session is loaded and re-route if the user is not an + // admin. This follows the suggestion by NextJS for handling private pages: + // https://nextjs.org/docs/api-reference/next/router#usage + // + // All admin pages should use the same check and routing steps. + useEffect(() => { + if (status === "loading") { + return; + } + if (session?.user?.role === "admin") { + return; + } + router.push("/"); + }, [router, session, status]); + + const [availability, setAvailability] = useState(0); + const [stats, setStats] = useState(0); + const [treeManager, setTreeManager] = useState(0); + + const {data: dataAvailability, error: errorAvailability, isLoading: isLoadingAvailability} = useSWRImmutable("/api/admin/tasks_availability", get, { + onSuccess: (data) => { + setAvailability(data); } + }); + const {data: dataStats, error: errorStats, isLoading: isLoadingStats} = useSWRImmutable("/api/admin/stats", get, { + onSuccess: (data) => { setStats(data); } + }); + const {data: dataTreeManager, error: errorTreeManager, isLoading: isLoadingTreeManager} = useSWRImmutable("/api/admin/tree_manager", get, { + onSuccess: (data) => { + setTreeManager(data); } + }); + + return ( + <> + + Status - Open Assistant + + + + + + + /api/v1/tasks/availability + + +
+                            {availability ? JSON.stringify(availability, null, 2) : "None"}
+                        
+
+
+ + + + /api/v1/stats/ + + +
+                            {stats ? JSON.stringify(stats, null, 2) : "None"}
+                        
+
+
+ +
+
+ + + + + /api/v1/stats/tree_manager + + + {treeManager ? + + + state_counts + + +
+                                 {JSON.stringify(treeManager.state_counts, null, 2)}
+                             
+
+ +
+ + message_counts + + + Tree Manager + + + + + + + + + + + + + {treeManager.message_counts.map(({ message_tree_id, state, depth, oldest, youngest, count, goal_tree_size }) => ( + + + + + + + + + + ))} + +
Message Tree IDStateDepthOldestYoungestCountGoal Tree Size
{message_tree_id}{state}{depth}{oldest}{youngest}{count}{goal_tree_size}
+
+ : "None"} +
+ + ); +}; + +StatusIndex.getLayout = getAdminLayout; + +export default StatusIndex; diff --git a/website/src/pages/api/admin/stats.ts b/website/src/pages/api/admin/stats.ts new file mode 100644 index 00000000..1dedbd30 --- /dev/null +++ b/website/src/pages/api/admin/stats.ts @@ -0,0 +1,18 @@ +import { withRole } from "src/lib/auth"; + +/** + * Returns the messages recorded by the backend for a user. + */ +const handler = withRole("admin", async (req, res) => { + const statsRes = await fetch(`${process.env.FASTAPI_URL}/api/v1/stats/`, { + method: "GET", + headers: { + "X-API-Key": process.env.FASTAPI_KEY, + }, + }); + const stats = await statsRes.json(); + + res.status(statsRes.status).json(stats); +}); + +export default handler; diff --git a/website/src/pages/api/admin/tasks_availability.ts b/website/src/pages/api/admin/tasks_availability.ts new file mode 100644 index 00000000..6d64d88b --- /dev/null +++ b/website/src/pages/api/admin/tasks_availability.ts @@ -0,0 +1,28 @@ +import { withRole } from "src/lib/auth"; +import { oasstApiClient } from "src/lib/oasst_api_client"; +import type { Message } from "src/types/Conversation"; + +/** + * Returns the messages recorded by the backend for a user. + */ +const handler = withRole("admin", async (req, res) => { + + const tasksAvailabilityRes = await fetch(`${process.env.FASTAPI_URL}/api/v1/tasks/availability`, { + method: "POST", + headers: { + "X-API-Key": process.env.FASTAPI_KEY, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: "__dummy_user__", + display_name: "Dummy User", + auth_method: "local", + }), + + }); + const tasksAvailability = await tasksAvailabilityRes.json(); + + res.status(tasksAvailabilityRes.status).json(tasksAvailability); +}); + +export default handler; diff --git a/website/src/pages/api/admin/tree_manager.ts b/website/src/pages/api/admin/tree_manager.ts new file mode 100644 index 00000000..b47562bf --- /dev/null +++ b/website/src/pages/api/admin/tree_manager.ts @@ -0,0 +1,18 @@ +import { withRole } from "src/lib/auth"; + +/** + * Returns the messages recorded by the backend for a user. + */ +const handler = withRole("admin", async (req, res) => { + const treeManagerRes = await fetch(`${process.env.FASTAPI_URL}/api/v1/stats/tree_manager`, { + method: "GET", + headers: { + "X-API-Key": process.env.FASTAPI_KEY, + }, + }); + const treeManager = await treeManagerRes.json(); + + res.status(treeManagerRes.status).json(treeManager); +}); + +export default handler;