packages/app/src/manage-tokens.tsx (87 lines of code) (raw):
/**
* Copyright 2021 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as React from "react";
import Button from '@mui/material/Button';
import Container from '@mui/material/Container';
import CssBaseline from '@mui/material/CssBaseline';
import DeleteForever from '@mui/icons-material/DeleteForever';
import Paper from '@mui/material/Paper';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import { useTokens, TokenType } from './tokens-provider.tsx';
import Nav from './nav.tsx';
export default function ManageTokens() {
const [initialLoad, setInitialLoad] = React.useState<boolean>(true);
const [deleting, setDeleting] = React.useState<boolean>(false);
const tokens = useTokens();
React.useEffect(() => {
if (!initialLoad) return;
setInitialLoad(false);
async function getTokens() {
const resp = await fetch('/_/api/v1/tokens');
const json = await resp.json();
if (json.data) {
const newTokens: Array<TokenType> = json.data.map((data) => {
return {
created: data.created,
prefix: data.prefix,
package: data.package ?? null,
expiration: data.expiration ? data.expiration : null,
releaseBacked: !!data['release-backed']
}
});
tokens.set(newTokens);
}
}
getTokens();
}, [initialLoad, tokens]);
async function deleteToken(token: TokenType) {
setDeleting(true);
await tokens.remove(token.prefix, token.created);
setDeleting(false);
}
return (
<main>
<CssBaseline />
<Nav />
<Container maxWidth="md">
<h2>Manage Tokens</h2>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} size="small" aria-label="a dense table">
<TableHead>
<TableRow>
<TableCell>prefix</TableCell>
<TableCell>package</TableCell>
<TableCell>created</TableCell>
<TableCell>expires</TableCell>
<TableCell>release-backed</TableCell>
<TableCell>actions</TableCell>
</TableRow>
</TableHead>
<TableBody>
{tokens.tokens.map((row) => (
<TableRow
key={`${row.prefix}-${row.created}`}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">{row.prefix}</TableCell>
<TableCell>{row.package ? row.package : 'all packages'}</TableCell>
<TableCell>{(new Date(row.created)).toISOString()}</TableCell>
<TableCell>{row.expiration ? (new Date(row.expiration)).toISOString() : 'never'}</TableCell>
<TableCell>{row.releaseBacked ? 'true' : 'false'}</TableCell>
<TableCell>
<Button variant="outlined" startIcon={<DeleteForever />} disabled={deleting} onClick={() => {
deleteToken(row)
}}>
Delete
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Container>
</main>
);
}