diff --git a/src/frontend/src/constants/alerts_constants.tsx b/src/frontend/src/constants/alerts_constants.tsx
index c3e3ba946..ebc7543d5 100644
--- a/src/frontend/src/constants/alerts_constants.tsx
+++ b/src/frontend/src/constants/alerts_constants.tsx
@@ -23,6 +23,7 @@ export const USER_EDIT_ERROR_ALERT = "Error on edit user";
export const USER_ADD_ERROR_ALERT = "Error when adding new user";
export const SIGNIN_ERROR_ALERT = "Error signing in";
export const DEL_KEY_ERROR_ALERT = "Error on delete key";
+export const DEL_KEY_ERROR_ALERT_PLURAL = "Error on delete keys";
export const UPLOAD_ERROR_ALERT = "Error uploading file";
export const WRONG_FILE_ERROR_ALERT = "Invalid file type";
export const UPLOAD_ALERT_LIST = "Please upload a JSON file";
@@ -54,6 +55,7 @@ export const USER_DEL_SUCCESS_ALERT = "Success! User deleted!";
export const USER_EDIT_SUCCESS_ALERT = "Success! User edited!";
export const USER_ADD_SUCCESS_ALERT = "Success! New user added!";
export const DEL_KEY_SUCCESS_ALERT = "Success! Key deleted!";
+export const DEL_KEY_SUCCESS_ALERT_PLURAL = "Success! Keys deleted!";
export const FLOW_BUILD_SUCCESS_ALERT = `Flow built successfully`;
export const SAVE_SUCCESS_ALERT = "Changes saved successfully!";
diff --git a/src/frontend/src/constants/constants.ts b/src/frontend/src/constants/constants.ts
index b0a0b55c5..ce9bf4d37 100644
--- a/src/frontend/src/constants/constants.ts
+++ b/src/frontend/src/constants/constants.ts
@@ -613,11 +613,8 @@ export const FETCH_ERROR_DESCRIPION =
export const SIGN_UP_SUCCESS = "Account created! Await admin activation. ";
-export const API_PAGE_PARAGRAPH_1 =
- "Your secret API keys are listed below. Please note that we do not display your secret API keys again after you generate them.";
-
-export const API_PAGE_PARAGRAPH_2 =
- "Do not share your API key with others, or expose it in the browser or other client-side code.";
+export const API_PAGE_PARAGRAPH =
+ "Your secret API keys are listed below. Do not share your API key with others, or expose it in the browser or other client-side code.";
export const API_PAGE_USER_KEYS =
"This user does not have any keys assigned at the moment.";
diff --git a/src/frontend/src/pages/ApiKeysPage/index.tsx b/src/frontend/src/pages/ApiKeysPage/index.tsx
index c971042d0..4e271825e 100644
--- a/src/frontend/src/pages/ApiKeysPage/index.tsx
+++ b/src/frontend/src/pages/ApiKeysPage/index.tsx
@@ -22,8 +22,7 @@ import {
DEL_KEY_SUCCESS_ALERT,
} from "../../constants/alerts_constants";
import {
- API_PAGE_PARAGRAPH_1,
- API_PAGE_PARAGRAPH_2,
+ API_PAGE_PARAGRAPH,
API_PAGE_USER_KEYS,
LAST_USED_SPAN_1,
LAST_USED_SPAN_2,
@@ -128,9 +127,7 @@ export default function ApiKeysPage() {
API keys
- {API_PAGE_PARAGRAPH_1}
-
- {API_PAGE_PARAGRAPH_2}
+ {API_PAGE_PARAGRAPH}
diff --git a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/index.tsx
index c6eb048d7..96eca02d5 100644
--- a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/index.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/index.tsx
@@ -2,149 +2,154 @@ import IconComponent from "../../../../components/genericIconComponent";
import { Button } from "../../../../components/ui/button";
import { ColDef, ColGroupDef, SelectionChangedEvent } from "ag-grid-community";
-import { useEffect, useState } from "react";
+import { useContext, useEffect, useRef, useState } from "react";
import AddNewVariableButton from "../../../../components/addNewVariableButtonComponent/addNewVariableButton";
import Dropdown from "../../../../components/dropdownComponent";
import ForwardedIconComponent from "../../../../components/genericIconComponent";
import TableComponent from "../../../../components/tableComponent";
import { Badge } from "../../../../components/ui/badge";
import { Card, CardContent } from "../../../../components/ui/card";
-import { deleteGlobalVariable } from "../../../../controllers/API";
+import {
+ deleteApiKey,
+ deleteGlobalVariable,
+ getApiKey,
+} from "../../../../controllers/API";
import useAlertStore from "../../../../stores/alertStore";
import { useGlobalVariablesStore } from "../../../../stores/globalVariablesStore/globalVariables";
import { cn } from "../../../../utils/utils";
+import {
+ API_PAGE_PARAGRAPH,
+ LAST_USED_SPAN_1,
+ LAST_USED_SPAN_2,
+} from "../../../../constants/constants";
+import TableAutoCellRender from "../../../../components/tableAutoCellRender";
+import {
+ DEL_KEY_SUCCESS_ALERT,
+ DEL_KEY_ERROR_ALERT,
+ DEL_KEY_SUCCESS_ALERT_PLURAL,
+ DEL_KEY_ERROR_ALERT_PLURAL,
+} from "../../../../constants/alerts_constants";
+import { AuthContext } from "../../../../contexts/authContext";
+import { ApiKey } from "../../../../types/components";
+import SecretKeyModal from "../../../../modals/secretKeyModal";
export default function ApiKeysPage() {
- const globalVariablesEntries = useGlobalVariablesStore(
- (state) => state.globalVariablesEntries,
- );
- const removeGlobalVariable = useGlobalVariablesStore(
- (state) => state.removeGlobalVariable,
- );
- const globalVariables = useGlobalVariablesStore(
- (state) => state.globalVariables,
- );
+ const [loadingKeys, setLoadingKeys] = useState(true);
+ const [selectedRows, setSelectedRows] = useState([]);
+ const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
- const getVariableId = useGlobalVariablesStore((state) => state.getVariableId);
-
- const BadgeRenderer = (props) => {
- return props.value !== "" ? (
-
-
- {props.value}
-
-
- ) : (
-
- );
- };
-
- const [rowData, setRowData] = useState<
- {
- type: string | undefined;
- id: string;
- name: string;
- default_fields: string | undefined;
- }[]
- >([]);
+ const { userData } = useContext(AuthContext);
+ const [userId, setUserId] = useState("");
+ const keysList = useRef([]);
useEffect(() => {
- const rows: Array<{
- type: string | undefined;
- id: string;
- name: string;
- default_fields: string | undefined;
- }> = [];
- if (globalVariablesEntries === undefined) return;
- globalVariablesEntries.forEach((entrie) => {
- const globalVariableObj = globalVariables[entrie];
- rows.push({
- type: globalVariableObj.type,
- id: globalVariableObj.id,
- default_fields: (globalVariableObj.default_fields ?? []).join(", "),
- name: entrie,
- });
- });
- setRowData(rows);
- }, [globalVariables]);
+ getKeys();
+ }, [userData]);
- const DropdownEditor = ({ options, value, onValueChange }) => {
+ function getKeys() {
+ setLoadingKeys(true);
+ if (userData) {
+ getApiKey()
+ .then((keys: [ApiKey]) => {
+ keysList.current = keys["api_keys"].map((apikey: ApiKey) => ({
+ ...apikey,
+ last_used_at: apikey.last_used_at ?? "Never",
+ }));
+ setUserId(keys["user_id"]);
+ setLoadingKeys(false);
+ })
+ .catch((error) => {
+ setLoadingKeys(false);
+ });
+ }
+ }
+
+ function resetFilter() {
+ getKeys();
+ }
+
+ function handleDeleteKey() {
+ Promise.all(selectedRows.map((selectedRow) => deleteApiKey(selectedRow)))
+ .then((res) => {
+ resetFilter();
+ setSuccessData({
+ title:
+ selectedRows.length === 1
+ ? DEL_KEY_SUCCESS_ALERT
+ : DEL_KEY_SUCCESS_ALERT_PLURAL,
+ });
+ })
+ .catch((error) => {
+ setErrorData({
+ title:
+ selectedRows.length === 1
+ ? DEL_KEY_ERROR_ALERT
+ : DEL_KEY_ERROR_ALERT_PLURAL,
+ list: [error["response"]["data"]["detail"]],
+ });
+ });
+ }
+
+ function lastUsedMessage() {
return (
-
-
-
+
+
+ {LAST_USED_SPAN_1}
+
{LAST_USED_SPAN_2}
+
+
);
- };
- // Column Definitions: Defines the columns to be displayed.
- const [colDefs, setColDefs] = useState<(ColDef | ColGroupDef)[]>([
+ }
+
+ const columnDefs = [
{
headerCheckboxSelection: true,
checkboxSelection: true,
showDisabledCheckboxes: true,
- headerName: "Variable Name",
+ headerName: "Name",
field: "name",
+ cellRenderer: TableAutoCellRender,
flex: 2,
- }, //This column will be twice as wide as the others
- {
- field: "type",
- cellRenderer: BadgeRenderer,
- cellEditor: DropdownEditor,
- cellEditorParams: {
- options: ["Generic", "Credential"],
- },
- flex: 1,
- editable: false,
},
- // {
- // field: "value",
- // cellEditor: "agLargeTextCellEditor",
- // flex: 2,
- // editable: false,
- // },
{
- headerName: "Apply To Fields",
- field: "default_fields",
+ headerName: "Key",
+ field: "api_key",
+ cellRenderer: TableAutoCellRender,
+ flex: 1,
+ },
+ {
+ headerName: "Created",
+ field: "created_at",
+ cellRenderer: TableAutoCellRender,
+ flex: 1,
+ },
+ {
+ headerName: "Last Used",
+ field: "last_used_at",
+ cellRenderer: TableAutoCellRender,
+ flex: 1,
+ },
+ {
+ headerName: "Total Uses",
+ field: "total_uses",
+ cellRenderer: TableAutoCellRender,
flex: 1,
- editable: false,
resizable: false,
},
- ]);
-
- const [selectedRows, setSelectedRows] = useState([]);
-
- async function removeVariables() {
- const deleteGlobalVariablesPromise = selectedRows.map(async (row) => {
- const id = getVariableId(row);
- const deleteGlobalVariables = deleteGlobalVariable(id!);
- await deleteGlobalVariables;
- });
- Promise.all(deleteGlobalVariablesPromise)
- .then(() => {
- selectedRows.forEach((row) => {
- removeGlobalVariable(row);
- });
- })
- .catch(() => {
- setErrorData({
- title: `Error deleting global variables.`,
- });
- });
- }
+ ];
return (
- Global Variables
+ API Keys
-
- Manage global variables and assign them to fields.
-
+
{API_PAGE_PARAGRAPH}
@@ -177,14 +189,14 @@ export default function ApiKeysPage() {
overlayNoRowsTemplate="No data available"
onSelectionChanged={(event: SelectionChangedEvent) => {
setSelectedRows(
- event.api.getSelectedRows().map((row) => row.name),
+ event.api.getSelectedRows().map((row) => row.id),
);
}}
rowSelection="multiple"
suppressRowClickSelection={true}
pagination={true}
- columnDefs={colDefs}
- rowData={rowData}
+ columnDefs={columnDefs}
+ rowData={keysList.current}
/>