All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			
		
			
				
	
	
		
			137 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /* eslint-disable react-x/no-array-index-key */
 | |
| import VisibilityIcon from "@mui/icons-material/Visibility";
 | |
| import {
 | |
|   Button,
 | |
|   IconButton,
 | |
|   Paper,
 | |
|   Table,
 | |
|   TableBody,
 | |
|   TableCell,
 | |
|   TableContainer,
 | |
|   TableHead,
 | |
|   TableRow,
 | |
|   Typography,
 | |
| } from "@mui/material";
 | |
| import React from "react";
 | |
| import { useNavigate } from "react-router-dom";
 | |
| import {
 | |
|   APIToken,
 | |
|   APITokenURL,
 | |
|   ExpiredAPIToken,
 | |
|   TokensApi,
 | |
| } from "../api/TokensApi";
 | |
| import { AsyncWidget } from "../widgets/AsyncWidget";
 | |
| import { RouterLink } from "../widgets/RouterLink";
 | |
| import { TimeWidget, timeDiff } from "../widgets/TimeWidget";
 | |
| import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
 | |
| 
 | |
| export function TokensListRoute(): React.ReactElement {
 | |
|   const [list, setList] = React.useState<APIToken[] | undefined>();
 | |
| 
 | |
|   const [count] = React.useState(1);
 | |
| 
 | |
|   const load = async () => {
 | |
|     setList(await TokensApi.GetList());
 | |
|   };
 | |
| 
 | |
|   return (
 | |
|     <AsyncWidget
 | |
|       loadKey={count}
 | |
|       load={load}
 | |
|       ready={list !== undefined}
 | |
|       errMsg="Failed to load the list of tokens!"
 | |
|       build={() => <TokensListRouteInner list={list!} />}
 | |
|     />
 | |
|   );
 | |
| }
 | |
| 
 | |
| export function TokensListRouteInner(p: {
 | |
|   list: APIToken[];
 | |
| }): React.ReactElement {
 | |
|   const navigate = useNavigate();
 | |
| 
 | |
|   return (
 | |
|     <VirtWebRouteContainer
 | |
|       label="API tokens"
 | |
|       actions={
 | |
|         <RouterLink to="/token/new">
 | |
|           <Button>New</Button>
 | |
|         </RouterLink>
 | |
|       }
 | |
|     >
 | |
|       {p.list.length > 0 && (
 | |
|         <TableContainer component={Paper}>
 | |
|           <Table>
 | |
|             <TableHead>
 | |
|               <TableRow>
 | |
|                 <TableCell>Name</TableCell>
 | |
|                 <TableCell>Description</TableCell>
 | |
|                 <TableCell>Created</TableCell>
 | |
|                 <TableCell>Updated</TableCell>
 | |
|                 <TableCell>Last used</TableCell>
 | |
|                 <TableCell>IP restriction</TableCell>
 | |
|                 <TableCell>Max inactivity</TableCell>
 | |
|                 <TableCell>Rights</TableCell>
 | |
|                 <TableCell>Actions</TableCell>
 | |
|               </TableRow>
 | |
|             </TableHead>
 | |
|             <TableBody>
 | |
|               {p.list.map((t) => {
 | |
|                 return (
 | |
|                   <TableRow
 | |
|                     key={t.id}
 | |
|                     hover
 | |
|                     onDoubleClick={() => navigate(APITokenURL(t))}
 | |
|                     style={{ backgroundColor: ExpiredAPIToken(t) ? "red" : "" }}
 | |
|                   >
 | |
|                     <TableCell>
 | |
|                       {t.name} {ExpiredAPIToken(t) && <i>(Expired)</i>}
 | |
|                     </TableCell>
 | |
|                     <TableCell>{t.description}</TableCell>
 | |
|                     <TableCell>
 | |
|                       <TimeWidget time={t.created} />
 | |
|                     </TableCell>
 | |
|                     <TableCell>
 | |
|                       <TimeWidget time={t.updated} />
 | |
|                     </TableCell>
 | |
|                     <TableCell>
 | |
|                       <TimeWidget time={t.last_used} />
 | |
|                     </TableCell>
 | |
|                     <TableCell>{t.ip_restriction}</TableCell>
 | |
|                     <TableCell>
 | |
|                       {t.max_inactivity && timeDiff(0, t.max_inactivity)}
 | |
|                     </TableCell>
 | |
|                     <TableCell>
 | |
|                       {t.rights.map((r, n) => {
 | |
|                         return (
 | |
|                           <div key={n}>
 | |
|                             {r.verb} {r.path}
 | |
|                           </div>
 | |
|                         );
 | |
|                       })}
 | |
|                     </TableCell>
 | |
| 
 | |
|                     <TableCell>
 | |
|                       <RouterLink to={APITokenURL(t)}>
 | |
|                         <IconButton>
 | |
|                           <VisibilityIcon />
 | |
|                         </IconButton>
 | |
|                       </RouterLink>
 | |
|                     </TableCell>
 | |
|                   </TableRow>
 | |
|                 );
 | |
|               })}
 | |
|             </TableBody>
 | |
|           </Table>
 | |
|         </TableContainer>
 | |
|       )}
 | |
| 
 | |
|       {p.list.length === 0 && (
 | |
|         <Typography style={{ textAlign: "center" }}>
 | |
|           No API token created yet.
 | |
|         </Typography>
 | |
|       )}
 | |
|     </VirtWebRouteContainer>
 | |
|   );
 | |
| }
 |