From 960275eb75406a1fda1c39875320896b9a2f5611 Mon Sep 17 00:00:00 2001 From: csawatzky Date: Thu, 24 Apr 2025 12:54:47 -0600 Subject: [PATCH] added the key manager card to the team page --- src/pages/Team.tsx | 10 +- src/providers/index.ts | 2 +- src/providers/pond/keyManagerAPI.tsx | 47 +++++++++ src/providers/pond/pond.tsx | 8 +- src/teams/TeamKeyManager.tsx | 140 +++++++++++++++++++++++++++ 5 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 src/providers/pond/keyManagerAPI.tsx create mode 100644 src/teams/TeamKeyManager.tsx diff --git a/src/pages/Team.tsx b/src/pages/Team.tsx index af2afda..095d90f 100644 --- a/src/pages/Team.tsx +++ b/src/pages/Team.tsx @@ -16,6 +16,7 @@ import { useEffect, useState } from "react"; import { useLocation, useNavigate, useParams } from 'react-router-dom'; import { getSignatureAccentColour } from "services/whiteLabel"; import TeamActions from "teams/TeamActions"; +import TeamKeyManager from "teams/TeamKeyManager"; import ObjectUsers from "user/ObjectUsers"; import UserAvatar from "user/UserAvatar"; import { or } from "utils/types"; @@ -236,12 +237,12 @@ export default function TeamPage() { refreshCallback={() => {}} /> - + - + @@ -256,6 +257,11 @@ export default function TeamPage() { + + + + + ); diff --git a/src/providers/index.ts b/src/providers/index.ts index 62f551b..a914bc9 100644 --- a/src/providers/index.ts +++ b/src/providers/index.ts @@ -35,7 +35,7 @@ export { // useStripeAPI, useDataDogProxyAPI, useMineAPI, - // useKeyManagerAPI, + useKeyManagerAPI, //TODO: update api with resolve,reject useTerminalAPI, //TODO: update api with resolve,reject useGateAPI, useObjectHeaterAPI, //TODO: update api with resolve,reject diff --git a/src/providers/pond/keyManagerAPI.tsx b/src/providers/pond/keyManagerAPI.tsx new file mode 100644 index 0000000..68993b7 --- /dev/null +++ b/src/providers/pond/keyManagerAPI.tsx @@ -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; + listKeys: (teamID: string) => Promise>; + removeKey: (teamID: string, key: string) => Promise>; +} + +export const KeyManagerAPIContext = createContext( + {} as IKeyManagerAPIContext +); + +interface Props {} + +export default function KeyManagerProvider(props: PropsWithChildren) { + 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(pondURL("/teams/" + teamID + "/apiKeys?key=" + key)); + }; + + const listKeys = (teamID: string) => { + return get(pondURL("/teams/" + teamID + "/apiKeys")); + }; + + return ( + + {children} + + ); +} + +export const useKeyManagerAPI = () => useContext(KeyManagerAPIContext); diff --git a/src/providers/pond/pond.tsx b/src/providers/pond/pond.tsx index 6f5f1f0..041bf49 100644 --- a/src/providers/pond/pond.tsx +++ b/src/providers/pond/pond.tsx @@ -33,6 +33,7 @@ import TaskProvider, { useTaskAPI } from "./taskAPI"; import DataDogProvider, { useDataDogProxyAPI } from "./datadogProxyAPI"; import ContractProvider, { useContractAPI } from "./contractAPI"; import UsageProvider, { useUsageAPI } from "./usageAPI"; +import KeyManagerProvider, { useKeyManagerAPI } from "./keyManagerAPI"; // import NoteProvider from "providers/noteAPI"; export const pondURL = (partial: string, demo: boolean = false): string => { @@ -82,7 +83,9 @@ export default function PondProvider(props: PropsWithChildren) { - {children} + + {children} + @@ -151,5 +154,6 @@ export { useTaskAPI, useDataDogProxyAPI, useContractAPI, - useUsageAPI + useUsageAPI, + useKeyManagerAPI }; diff --git a/src/teams/TeamKeyManager.tsx b/src/teams/TeamKeyManager.tsx new file mode 100644 index 0000000..c660746 --- /dev/null +++ b/src/teams/TeamKeyManager.tsx @@ -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([]); + 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 ( + + + API Keys + + + + + + + ); + }; + + const removalConfirmation = () => { + return ( + { + setOpenRemove(false); + }}> + Remove API Key + + Are you sure you want to remove {keyList[removeIndex]} as an api key? + + + + + + + ); + }; + + return ( + + {removalConfirmation()} + {header()} + + + {keyList.map((k, i) => ( + + + {k} + + + { + setOpenRemove(true); + setRemoveIndex(i); + }}> + + + + + ))} + + + ); +}