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

     1  import {Table, TableCell, TableBody, TableContainer, TableHead, TableRow, Paper, Typography, Box} from '@mui/material';
     2  import React, {FunctionComponent, ReactElement, useEffect, useMemo, useRef, useState} from "react";
     3  import {Skeleton} from "@mui/material";
     4  
     5  
     6  
     7  interface Record {
     8      [key: string]: string | number | boolean | null
     9  }
    10  
    11  interface ExportData extends Record {
    12      "Type": string
    13      "Local Path": string
    14      "Namespace Prefix": string
    15  }
    16  
    17  export const TableCellOverflow: FunctionComponent<any> = ({ children, ...props }) => {
    18  
    19      const cellRef = useRef<HTMLTableCellElement>(null);
    20      const [overflow, setOverflow] = useState<boolean>(false);
    21  
    22      useEffect(() => {
    23          if(cellRef.current) {
    24              setOverflow(cellRef.current.scrollWidth > cellRef.current.clientWidth)
    25          }
    26      }, [])
    27  
    28      return (
    29          <TableCell
    30              ref={cellRef}
    31              sx={{
    32                  overflowX: "scroll",
    33                  whiteSpace: "nowrap",
    34                  boxShadow: overflow ? "inset -13px 0px 20px -21px rgba(0,0,0,0.75)" : "none",
    35                  ...props?.sx
    36          }}>
    37              {children}
    38          </TableCell>
    39      )
    40  }
    41  
    42  export const RecordTable = ({ data }: { data: Record[] }): ReactElement  => {
    43      return (
    44          <TableContainer>
    45              <Table sx={{tableLayout: "fixed"}}>
    46                  <TableHead>
    47                      <TableRow>
    48                          {Object.keys(data[0]).map((key, index) => (
    49                              <TableCell key={index} sx={{width: index == 0 ? "20%" : "40%"}}>{key}</TableCell>
    50                          ))}
    51                      </TableRow>
    52                  </TableHead>
    53                  <TableBody>
    54                      {data.map((record, index) => (
    55                          <TableRow key={index}>
    56                              {Object.values(record).map((value, index) => (
    57                                  <TableCellOverflow key={index} sx={{width: index == 0 ? "20%" : "40%"}}>{value == null ? "NULL" : value}</TableCellOverflow>
    58                              ))}
    59                          </TableRow>
    60                      ))}
    61                  </TableBody>
    62              </Table>
    63          </TableContainer>
    64      )
    65  }
    66  
    67  
    68  export const DataExportTable = () => {
    69  
    70      const [data, setData] = useState<ExportData[] | undefined>(undefined);
    71      const [error, setError] = useState<string | undefined>(undefined);
    72  
    73  
    74      const getData = async () => {
    75          let response = await fetch("/api/v1.0/config")
    76          if (response.ok) {
    77              const responseData = await response.json()
    78  
    79              setData([{
    80                  "Type": "POSIX",
    81                  "Local Path": ["", undefined].includes(responseData?.Xrootd?.Mount) ? "NULL" : responseData?.Xrootd?.Mount,
    82                  "Namespace Prefix": ["", undefined].includes(responseData?.Origin?.NamespacePrefix) ? "NULL" : responseData?.Origin?.NamespacePrefix
    83              }])
    84  
    85          } else {
    86              setError("Failed to fetch config, response status: " + response.status)
    87          }
    88      }
    89  
    90      useEffect(() => {
    91          getData()
    92      }, [])
    93  
    94      if(error){
    95          return (
    96              <Box p={1}>
    97                  <Typography sx={{color: "red"}} variant={"subtitle2"}>{error}</Typography>
    98              </Box>
    99          )
   100      }
   101  
   102      return (
   103          <>
   104              {data ? <RecordTable data={data} /> : <Skeleton variant={"rectangular"} height={200} width={"100%"} />}
   105          </>
   106      )
   107  }