diff --git a/ui/src/apikey/ApiKeyList.jsx b/ui/src/apikey/ApiKeyList.jsx
index 42a43aa15..2f656111f 100644
--- a/ui/src/apikey/ApiKeyList.jsx
+++ b/ui/src/apikey/ApiKeyList.jsx
@@ -1,17 +1,45 @@
-import React from 'react'
+import React, { useState } from 'react'
import {
+ CreateButton,
Datagrid,
DateField,
Filter,
+ FunctionField,
List,
SearchInput,
TextField,
+ useNotify,
useTranslate,
} from 'react-admin'
-import { useMediaQuery } from '@material-ui/core'
+import {
+ IconButton,
+ makeStyles,
+ Tooltip,
+ useMediaQuery,
+} from '@material-ui/core'
import { SimpleList } from '../common'
import AddIcon from '@material-ui/icons/Add'
-import { CreateButton } from 'react-admin'
+import VisibilityIcon from '@material-ui/icons/Visibility'
+import VisibilityOffIcon from '@material-ui/icons/VisibilityOff'
+import FileCopyIcon from '@material-ui/icons/FileCopy'
+
+const useStyles = makeStyles({
+ actionContainer: {
+ display: 'flex',
+ alignItems: 'center',
+ },
+ keyContainer: {
+ display: 'flex',
+ alignItems: 'center',
+ flex: 1,
+ },
+ visibilityButton: {
+ padding: 4,
+ },
+ copyButton: {
+ padding: 4,
+ },
+})
const ApiKeyFilter = (props) => (
@@ -19,6 +47,80 @@ const ApiKeyFilter = (props) => (
)
+const MaskedKeyField = ({ record, isSimpleMode }) => {
+ const [visible, setVisible] = useState(false)
+ const classes = useStyles()
+ const notify = useNotify()
+
+ if (!record || !record.key) return null
+
+ const maskKey = (key) => {
+ return '*'.repeat(key.length)
+ }
+
+ const handleCopy = (e) => {
+ if (isSimpleMode) {
+ e.preventDefault()
+ } else {
+ e.stopPropagation()
+ }
+ navigator.clipboard.writeText(record.key)
+ notify('API key copied to clipboard', 'info')
+ }
+
+ const toggleVisibility = (e) => {
+ if (isSimpleMode) {
+ e.preventDefault()
+ } else {
+ e.stopPropagation()
+ }
+ setVisible(!visible)
+ }
+
+ const keyVisibilityButton = (
+
+ {visible ? (
+
+ ) : (
+
+ )}
+
+ )
+ const copyButton = (
+
+
+
+ )
+
+ return (
+
+
+ {visible ? record.key : maskKey(record.key)}
+
+ {isSimpleMode ? (
+ <>{keyVisibilityButton}>
+ ) : (
+
+ {keyVisibilityButton}
+
+ )}
+ {isSimpleMode ? (
+ <>{copyButton}>
+ ) : (
+
{copyButton}
+ )}
+
+ )
+}
+
const ApiKeyList = (props) => {
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
const translate = useTranslate()
@@ -40,14 +142,21 @@ const ApiKeyList = (props) => {
{isXsmall ? (
r.name}
- secondaryText={(r) => r.key}
+ secondaryText={(r) => (
+
+ )}
tertiaryText={(r) => }
linkType={'edit'}
/>
) : (
-
+ (
+
+ )}
+ />
)}