github.com/pelicanplatform/pelican@v1.0.5/web_ui/frontend/components/ServerTable.tsx (about)

     1  import {Table, TableCell, TableBody, TableContainer, TableHead, TableRow, Paper, Typography, Box} from '@mui/material';
     2  import React, {
     3      FunctionComponent,
     4      ReactElement,
     5      ReactNode,
     6      useCallback,
     7      useEffect,
     8      useMemo,
     9      useRef,
    10      useState
    11  } from "react";
    12  import {Skeleton} from "@mui/material";
    13  import Link from "next/link";
    14  
    15  import DataTable, {Record} from "@/components/DataTable";
    16  import {TableCellOverflow} from "@/components/Cell";
    17  
    18  
    19  interface ExportData extends Record {
    20      "Type": string
    21      "Local Path": string
    22      "Namespace Prefix": string
    23  }
    24  
    25  const TableCellOverflowLink: React.JSX.ElementType = ({ children, ...props }) => {
    26  
    27      if (children === null){
    28          children = ""
    29      }
    30  
    31      return (
    32          <TableCellOverflow sx={{color: "blue", cursor: "pointer"}} {...props}>
    33              <Link href={children as string}>
    34                  {children as string}
    35              </Link>
    36          </TableCellOverflow>
    37      )
    38  }
    39  
    40  
    41  
    42  interface Server extends Record {
    43      name: string
    44      authUrl: string
    45      url: string
    46      webUrl: string
    47      type: string
    48      latitude: number
    49      longitude: number
    50  }
    51  
    52  
    53  interface ServerTableProps {
    54      type?: "cache" | "origin"
    55  }
    56  
    57  export const ServerTable = ({type} : ServerTableProps) => {
    58  
    59      const [data, setData] = useState<Server[] | undefined>(undefined);
    60      const [error, setError] = useState<string | undefined>(undefined);
    61  
    62      const keyToName = {
    63          "name": {
    64              name: "Name",
    65              cellNode: TableCellOverflow
    66          },
    67          "authUrl": {
    68              name: "Auth URL",
    69              cellNode: TableCellOverflowLink
    70          },
    71          "url": {
    72              name: "URL",
    73              cellNode: TableCellOverflowLink
    74          },
    75          "webUrl": {
    76              name: "Web URL",
    77              cellNode: TableCellOverflowLink
    78          }
    79      }
    80  
    81      const getData = useCallback(async () => {
    82          const url = new URL("/api/v1.0/director_ui/servers", window.location.origin)
    83          if (type){
    84              url.searchParams.append("server_type", type)
    85          }
    86  
    87          let response = await fetch(url)
    88          if (response.ok) {
    89              const responseData: Server[] = await response.json()
    90              responseData.sort((a, b) => a.name.localeCompare(b.name))
    91              setData(responseData)
    92  
    93          } else {
    94              setError("Failed to fetch config, response status: " + response.status)
    95          }
    96      }, [type])
    97  
    98      useEffect(() => {
    99          getData()
   100      }, [])
   101  
   102      if(error){
   103          return (
   104              <Box p={1}>
   105                  <Typography sx={{color: "red"}} variant={"subtitle2"}>{error}</Typography>
   106              </Box>
   107          )
   108      }
   109  
   110      return (
   111          <>
   112              {data ? <DataTable columnMap={keyToName} data={data} /> : <Skeleton variant={"rectangular"} height={200} width={"100%"} />}
   113          </>
   114      )
   115  }