Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service Accounts UI Refresh #600

Merged
merged 2 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,10 @@ const ServiceAccountCreate: React.FC<ServiceAccountCreateProps> = ({
return (
<>
<Button
leftIcon={<Icon as={FaPlusCircle} />}
variant="primary"
onClick={onOpen}
data-testid="sa-create-second-btn"
>
New Service Account
Create New Service Account
</Button>
<Modal
isOpen={isOpen}
Expand All @@ -102,7 +100,7 @@ const ServiceAccountCreate: React.FC<ServiceAccountCreateProps> = ({
<ModalOverlay />
<ModalContent>
<ModalHeader>
<Text>Assign scopes for the new service account</Text>
Create New Service Account
</ModalHeader>
<ModalBody>
{isLoading && (
Expand All @@ -114,17 +112,17 @@ const ServiceAccountCreate: React.FC<ServiceAccountCreateProps> = ({
<form ref={formRef} onSubmit={handleSubmit}>
<VStack spacing={4}>
<FormControl>
<FormLabel>Permissions</FormLabel>
<FormLabel mb={8}>Assign scopes</FormLabel>
<CheckboxGroup>
<Wrap spacing={4}>
<VStack align="flex-start" spacing={4}>
{data.currentNamespace?.scopes?.map((s) => (
<WrapItem key={s.name}>
<Checkbox value={s.name} name="scopes">
{s.name}
</Checkbox>
</WrapItem>
))}
</Wrap>
</VStack>
</CheckboxGroup>
</FormControl>
</VStack>
Expand Down
166 changes: 83 additions & 83 deletions src/nextapp/pages/manager/service-accounts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,40 @@ import * as React from 'react';
import api, { useApi } from '@/shared/services/api';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might just need to run Prettier in this file as the formatting appears to be a bit off in places

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I also saw there was an unused variable and removed that as well.

import {
Box,
Button,
Container,
Text,
Divider,
Heading,
Table,
Thead,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton,
Tr,
Th,
Tbody,
Td,
Center,
Icon,
Alert,
AlertDescription,
AlertIcon,
} from '@chakra-ui/react';
import Card from '@/components/card';
import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
import { gql } from 'graphql-request';
import Head from 'next/head';
import PageHeader from '@/components/page-header';
import { QueryClient, useQueryClient } from 'react-query';
import { Query } from '@/shared/types/query.types';
import { Query, ServiceAccess } from '@/shared/types/query.types';
import ViewSecret from '@/components/view-secret';
import { dehydrate } from 'react-query/hydration';
import ServiceAccountDelete from '@/components/service-account-delete/service-account-delete';
import Table from '@/components/table';
import { format } from 'date-fns';
import { FaKey } from 'react-icons/fa';
import { FaCheckCircle } from 'react-icons/fa';
import ServiceAccountCreate from '@/components/service-account-create';
import breadcrumbs from '@/components/ns-breadcrumb';
import { useNamespaceBreadcrumbs } from '@/shared/hooks';

export const getServerSideProps: GetServerSideProps = async (context) => {
const queryKey = 'getServiceAccounts';
Expand All @@ -36,9 +44,13 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
await queryClient.prefetchQuery(
queryKey,
async () =>
await api<Query>(query, {}, {
headers: context.req.headers as HeadersInit,
})
await api<Query>(
query,
{},
{
headers: context.req.headers as HeadersInit,
}
)
);

return {
Expand All @@ -52,6 +64,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
const ServiceAccountsPage: React.FC<
InferGetServerSidePropsType<typeof getServerSideProps>
> = ({ queryKey }) => {
const breadcrumbs = useNamespaceBreadcrumbs([{ text: 'Service Accounts' }]);
const client = useQueryClient();
const [credentials, setCredentials] = React.useState<Record<string, string>>(
null
Expand Down Expand Up @@ -83,86 +96,73 @@ const ServiceAccountsPage: React.FC<
</Head>
<Container maxW="6xl">
<PageHeader
breadcrumb={breadcrumbs()}
breadcrumb={breadcrumbs}
actions={<ServiceAccountCreate onCreate={handleCreate} />}
title="Service Accounts"
>
<Text>
Service Accounts allow you to access BC Government APIs via the
Gateway API or the Gateway CLI.
</Text>
<Box maxW="45%" mb={8}>
<Text>
Service Accounts allow you to access BC Government APIs via the
Gateway API or the Gateway CLI
</Text>
</Box>
</PageHeader>
<Modal
size="3xl"
isOpen={Boolean(credentials)}
onClose={() => setCredentials(null)}
>
<ModalOverlay />
<ModalContent>
<ModalHeader display="flex" alignItems="center" gridGap={2}>
New Service Account Created{' '}
<Icon as={FaCheckCircle} color="green" />
</ModalHeader>
<ModalCloseButton />
<ModalBody>
{credentials && (
<>
<ViewSecret credentials={credentials} />
<Alert status="warning" variant="outline" mt={8}>
<AlertIcon />
<AlertDescription>
Please store your new service account tokens somewhere
safe because as soon as you navigate away from this
dialog, we will not be able to retrieve these tokens.
</AlertDescription>
</Alert>
</>
)}
</ModalBody>
<ModalFooter>
<Button mr={3} onClick={() => setCredentials(null)}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>

{credentials && (
<Box my={4} bgColor="white">
<Box p={4} display="flex" alignItems="center">
<Icon as={FaKey} mr={2} color="bc-yellow" />
<Heading size="md">New Service Account Tokens</Heading>
</Box>
<Divider />
<Box p={4}>
<Text mb={4}>
These are your tokens. Copy and paste them somewhere safe like a
text file.
</Text>
</Box>
<Box p={4}>
<ViewSecret credentials={credentials} />
</Box>
</Box>
)}
<Box bgColor="white" mb={4}>
<Box
p={4}
display="flex"
alignItems="center"
justifyContent="space-between"
<Card mb={8}>
<Table
sortable
data={data.allNamespaceServiceAccounts}
columns={[
{ name: 'ID', key: 'active', sortable: true },
{ name: 'Created On', key: 'name', sortable: true },
{ name: '', key: 'id' },
]}
>
<Heading size="md">All Service Accounts</Heading>
</Box>
<Divider />
<Table variant="simple">
<Thead>
<Tr>
<Th>ID</Th>
<Th>Created At</Th>
<Th textAlign="right">Action</Th>
{(d: ServiceAccess) => (
<Tr key={d.id}>
<Td>{d.name}</Td>
<Td>{format(new Date(d.createdAt), 'MMM do, yyyy')}</Td>
<Td textAlign="right">
<ServiceAccountDelete id={d.id} onDelete={handleDelete} />
</Td>
</Tr>
</Thead>
<Tbody data-testid="service-account-table">
{data.allNamespaceServiceAccounts?.length === 0 && (
<Tr>
<Td colSpan={5}>
<Center>
<Box m={8} textAlign="center">
<Heading mb={2} size="md">
Create your first Service Account
</Heading>
<Text color="gray.600">
Service Accounts can be used to access our API for
functions like publish gateway configuration.
</Text>
<Box mt={4}>
<ServiceAccountCreate onCreate={handleCreate} />
</Box>
</Box>
</Center>
</Td>
</Tr>
)}

{data.allNamespaceServiceAccounts?.map((d) => (
<Tr key={d.id}>
<Td>{d.name}</Td>
<Td>{format(new Date(d.createdAt), 'MMM do, yyyy')}</Td>
<Td textAlign="right">
<ServiceAccountDelete id={d.id} onDelete={handleDelete} />
</Td>
</Tr>
))}
</Tbody>
)}
</Table>
</Box>
</Card>
</Container>
</>
);
Expand Down