mirror of
https://github.com/navidrome/navidrome.git
synced 2026-08-31 07:30:32 +00:00
Add the toggle visibility button and copy to the clipboard button for API keys
This commit is contained in:
parent
b139f87c7e
commit
5756ec89ea
@ -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) => (
|
||||
<Filter {...props} variant={'outlined'}>
|
||||
@ -19,6 +47,80 @@ const ApiKeyFilter = (props) => (
|
||||
</Filter>
|
||||
)
|
||||
|
||||
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 = (
|
||||
<IconButton
|
||||
className={classes.visibilityButton}
|
||||
onClick={toggleVisibility}
|
||||
size="small"
|
||||
>
|
||||
{visible ? (
|
||||
<VisibilityOffIcon fontSize="small" />
|
||||
) : (
|
||||
<VisibilityIcon fontSize="small" />
|
||||
)}
|
||||
</IconButton>
|
||||
)
|
||||
const copyButton = (
|
||||
<IconButton
|
||||
className={classes.copyButton}
|
||||
onClick={handleCopy}
|
||||
size="small"
|
||||
>
|
||||
<FileCopyIcon fontSize="small" />
|
||||
</IconButton>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className={classes.actionContainer}>
|
||||
<div className={classes.keyContainer}>
|
||||
{visible ? record.key : maskKey(record.key)}
|
||||
</div>
|
||||
{isSimpleMode ? (
|
||||
<>{keyVisibilityButton}</>
|
||||
) : (
|
||||
<Tooltip title={visible ? 'Hide key' : 'Show key'}>
|
||||
{keyVisibilityButton}
|
||||
</Tooltip>
|
||||
)}
|
||||
{isSimpleMode ? (
|
||||
<>{copyButton}</>
|
||||
) : (
|
||||
<Tooltip title="Copy to clipboard">{copyButton}</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ApiKeyList = (props) => {
|
||||
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
|
||||
const translate = useTranslate()
|
||||
@ -40,14 +142,21 @@ const ApiKeyList = (props) => {
|
||||
{isXsmall ? (
|
||||
<SimpleList
|
||||
primaryText={(r) => r.name}
|
||||
secondaryText={(r) => r.key}
|
||||
secondaryText={(r) => (
|
||||
<MaskedKeyField record={r} isSimpleMode={true} />
|
||||
)}
|
||||
tertiaryText={(r) => <DateField record={r} source="createdAt" />}
|
||||
linkType={'edit'}
|
||||
/>
|
||||
) : (
|
||||
<Datagrid rowClick="edit">
|
||||
<TextField source="name" />
|
||||
<TextField source="key" />
|
||||
<FunctionField
|
||||
label="Key"
|
||||
render={(record) => (
|
||||
<MaskedKeyField isSimpleMode={false} record={record} />
|
||||
)}
|
||||
/>
|
||||
<DateField source="createdAt" showTime />
|
||||
</Datagrid>
|
||||
)}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user