added the key manager card to the team page
This commit is contained in:
parent
08b100d035
commit
960275eb75
5 changed files with 202 additions and 5 deletions
|
|
@ -16,6 +16,7 @@ import { useEffect, useState } from "react";
|
||||||
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||||
import { getSignatureAccentColour } from "services/whiteLabel";
|
import { getSignatureAccentColour } from "services/whiteLabel";
|
||||||
import TeamActions from "teams/TeamActions";
|
import TeamActions from "teams/TeamActions";
|
||||||
|
import TeamKeyManager from "teams/TeamKeyManager";
|
||||||
import ObjectUsers from "user/ObjectUsers";
|
import ObjectUsers from "user/ObjectUsers";
|
||||||
import UserAvatar from "user/UserAvatar";
|
import UserAvatar from "user/UserAvatar";
|
||||||
import { or } from "utils/types";
|
import { or } from "utils/types";
|
||||||
|
|
@ -236,12 +237,12 @@ export default function TeamPage() {
|
||||||
refreshCallback={() => {}}
|
refreshCallback={() => {}}
|
||||||
/>
|
/>
|
||||||
<Grid2 container spacing={1}>
|
<Grid2 container spacing={1}>
|
||||||
<Grid2 size={{ xs: 12, sm: 6 }}>
|
<Grid2 size={{ xs: 12, sm: 4 }}>
|
||||||
<Card className={ isMobile ? classes.cardMobile : classes.card }>
|
<Card className={ isMobile ? classes.cardMobile : classes.card }>
|
||||||
<Chat objectKey={team.key()} type={pond.NoteType.NOTE_TYPE_TEAM}/>
|
<Chat objectKey={team.key()} type={pond.NoteType.NOTE_TYPE_TEAM}/>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
<Grid2 size={{ xs: 12, sm: 6 }}>
|
<Grid2 size={{ xs: 12, sm: 4 }}>
|
||||||
<Card className={ isMobile ? classes.cardMobile : classes.card }>
|
<Card className={ isMobile ? classes.cardMobile : classes.card }>
|
||||||
<List>
|
<List>
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
@ -256,6 +257,11 @@ export default function TeamPage() {
|
||||||
</List>
|
</List>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
|
<Grid2 size={{ xs: 12, sm: 4 }}>
|
||||||
|
<Card className={ isMobile ? classes.cardMobile : classes.card }>
|
||||||
|
<TeamKeyManager teamId={teamKey} permissions={team.permissions ?? []} />
|
||||||
|
</Card>
|
||||||
|
</Grid2>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ export {
|
||||||
// useStripeAPI,
|
// useStripeAPI,
|
||||||
useDataDogProxyAPI,
|
useDataDogProxyAPI,
|
||||||
useMineAPI,
|
useMineAPI,
|
||||||
// useKeyManagerAPI,
|
useKeyManagerAPI, //TODO: update api with resolve,reject
|
||||||
useTerminalAPI, //TODO: update api with resolve,reject
|
useTerminalAPI, //TODO: update api with resolve,reject
|
||||||
useGateAPI,
|
useGateAPI,
|
||||||
useObjectHeaterAPI, //TODO: update api with resolve,reject
|
useObjectHeaterAPI, //TODO: update api with resolve,reject
|
||||||
|
|
|
||||||
47
src/providers/pond/keyManagerAPI.tsx
Normal file
47
src/providers/pond/keyManagerAPI.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { AxiosResponse } from "axios";
|
||||||
|
import { useHTTP } from "hooks";
|
||||||
|
import { pond } from "protobuf-ts/pond";
|
||||||
|
import { createContext, PropsWithChildren, useContext } from "react";
|
||||||
|
import { pondURL } from "./pond";
|
||||||
|
|
||||||
|
export interface IKeyManagerAPIContext {
|
||||||
|
addKey: (teamID: string) => Promise<any>;
|
||||||
|
listKeys: (teamID: string) => Promise<AxiosResponse<pond.ListAPIKeysResponse>>;
|
||||||
|
removeKey: (teamID: string, key: string) => Promise<AxiosResponse<pond.RemoveAPIKeyResponse>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const KeyManagerAPIContext = createContext<IKeyManagerAPIContext>(
|
||||||
|
{} as IKeyManagerAPIContext
|
||||||
|
);
|
||||||
|
|
||||||
|
interface Props {}
|
||||||
|
|
||||||
|
export default function KeyManagerProvider(props: PropsWithChildren<Props>) {
|
||||||
|
const { children } = props;
|
||||||
|
const { get, del, post } = useHTTP();
|
||||||
|
|
||||||
|
const addKey = (teamID: string) => {
|
||||||
|
return post(pondURL("/teams/" + teamID + "/apiKeys"));
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeKey = (teamID: string, key: string) => {
|
||||||
|
return del<pond.RemoveAPIKeyResponse>(pondURL("/teams/" + teamID + "/apiKeys?key=" + key));
|
||||||
|
};
|
||||||
|
|
||||||
|
const listKeys = (teamID: string) => {
|
||||||
|
return get<pond.ListAPIKeysResponse>(pondURL("/teams/" + teamID + "/apiKeys"));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<KeyManagerAPIContext.Provider
|
||||||
|
value={{
|
||||||
|
addKey,
|
||||||
|
listKeys,
|
||||||
|
removeKey
|
||||||
|
}}>
|
||||||
|
{children}
|
||||||
|
</KeyManagerAPIContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useKeyManagerAPI = () => useContext(KeyManagerAPIContext);
|
||||||
|
|
@ -33,6 +33,7 @@ import TaskProvider, { useTaskAPI } from "./taskAPI";
|
||||||
import DataDogProvider, { useDataDogProxyAPI } from "./datadogProxyAPI";
|
import DataDogProvider, { useDataDogProxyAPI } from "./datadogProxyAPI";
|
||||||
import ContractProvider, { useContractAPI } from "./contractAPI";
|
import ContractProvider, { useContractAPI } from "./contractAPI";
|
||||||
import UsageProvider, { useUsageAPI } from "./usageAPI";
|
import UsageProvider, { useUsageAPI } from "./usageAPI";
|
||||||
|
import KeyManagerProvider, { useKeyManagerAPI } from "./keyManagerAPI";
|
||||||
// import NoteProvider from "providers/noteAPI";
|
// import NoteProvider from "providers/noteAPI";
|
||||||
|
|
||||||
export const pondURL = (partial: string, demo: boolean = false): string => {
|
export const pondURL = (partial: string, demo: boolean = false): string => {
|
||||||
|
|
@ -82,7 +83,9 @@ export default function PondProvider(props: PropsWithChildren<any>) {
|
||||||
<DataDogProvider>
|
<DataDogProvider>
|
||||||
<ContractProvider>
|
<ContractProvider>
|
||||||
<UsageProvider>
|
<UsageProvider>
|
||||||
{children}
|
<KeyManagerProvider>
|
||||||
|
{children}
|
||||||
|
</KeyManagerProvider>
|
||||||
</UsageProvider>
|
</UsageProvider>
|
||||||
</ContractProvider>
|
</ContractProvider>
|
||||||
</DataDogProvider>
|
</DataDogProvider>
|
||||||
|
|
@ -151,5 +154,6 @@ export {
|
||||||
useTaskAPI,
|
useTaskAPI,
|
||||||
useDataDogProxyAPI,
|
useDataDogProxyAPI,
|
||||||
useContractAPI,
|
useContractAPI,
|
||||||
useUsageAPI
|
useUsageAPI,
|
||||||
|
useKeyManagerAPI
|
||||||
};
|
};
|
||||||
|
|
|
||||||
140
src/teams/TeamKeyManager.tsx
Normal file
140
src/teams/TeamKeyManager.tsx
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
Divider,
|
||||||
|
Grid2 as Grid,
|
||||||
|
IconButton,
|
||||||
|
Typography
|
||||||
|
} from "@mui/material";
|
||||||
|
import ResponsiveDialog from "common/ResponsiveDialog";
|
||||||
|
import DeleteIcon from "products/AgIcons/Delete";
|
||||||
|
import { pond } from "protobuf-ts/pond";
|
||||||
|
import { useKeyManagerAPI } from "providers";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
teamId: string;
|
||||||
|
permissions: pond.Permission[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TeamKeyManager(props: Props) {
|
||||||
|
const { permissions, teamId } = props;
|
||||||
|
const [keyList, setKeyList] = useState<string[]>([]);
|
||||||
|
const [openRemove, setOpenRemove] = useState(false);
|
||||||
|
const [removeIndex, setRemoveIndex] = useState(0);
|
||||||
|
const keyManagerAPI = useKeyManagerAPI();
|
||||||
|
|
||||||
|
const listKeys = () => {
|
||||||
|
keyManagerAPI.listKeys(teamId).then(resp => {
|
||||||
|
if (resp.data.keys.length > 0) {
|
||||||
|
let keys = resp.data.keys;
|
||||||
|
setKeyList([...keys]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const addKey = () => {
|
||||||
|
keyManagerAPI.addKey(teamId).then(resp => {
|
||||||
|
let keys = keyList;
|
||||||
|
keys.push(resp.data.key);
|
||||||
|
setKeyList([...keys]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeKey = (i: number) => {
|
||||||
|
keyManagerAPI.removeKey(teamId, keyList[i]).then(resp => {
|
||||||
|
let keys = keyList;
|
||||||
|
keys.splice(i, 1);
|
||||||
|
setKeyList([...keys]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const header = () => {
|
||||||
|
return (
|
||||||
|
<Grid container justifyContent="space-between" alignItems="center">
|
||||||
|
<Grid>
|
||||||
|
<Typography>API Keys</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid>
|
||||||
|
<Button
|
||||||
|
disabled={!permissions.includes(pond.Permission.PERMISSION_WRITE)}
|
||||||
|
style={{ marginRight: 5 }}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={listKeys}>
|
||||||
|
Display Keys
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
disabled={!permissions.includes(pond.Permission.PERMISSION_WRITE)}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={addKey}>
|
||||||
|
Add New Key
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removalConfirmation = () => {
|
||||||
|
return (
|
||||||
|
<ResponsiveDialog
|
||||||
|
open={openRemove}
|
||||||
|
onClose={() => {
|
||||||
|
setOpenRemove(false);
|
||||||
|
}}>
|
||||||
|
<DialogTitle>Remove API Key</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
Are you sure you want to remove {keyList[removeIndex]} as an api key?
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setOpenRemove(false);
|
||||||
|
}}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
style={{ backgroundColor: "red" }}
|
||||||
|
onClick={() => {
|
||||||
|
removeKey(removeIndex);
|
||||||
|
setOpenRemove(false);
|
||||||
|
}}>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</ResponsiveDialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box padding={2} style={{ display: "flex", flexDirection: "column", overflow: "hidden" }}>
|
||||||
|
{removalConfirmation()}
|
||||||
|
{header()}
|
||||||
|
<Divider />
|
||||||
|
<Grid style={{ padding: 10 }} container justifyContent="space-between" alignItems="center">
|
||||||
|
{keyList.map((k, i) => (
|
||||||
|
<React.Fragment key={k}>
|
||||||
|
<Grid size={10}>
|
||||||
|
{k}
|
||||||
|
</Grid>
|
||||||
|
<Grid size={2}>
|
||||||
|
<IconButton
|
||||||
|
disabled={!permissions.includes(pond.Permission.PERMISSION_WRITE)}
|
||||||
|
onClick={() => {
|
||||||
|
setOpenRemove(true);
|
||||||
|
setRemoveIndex(i);
|
||||||
|
}}>
|
||||||
|
<DeleteIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Grid>
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue