mirror of
https://github.com/Myzel394/kleckrelay-website.git
synced 2025-06-18 23:45:26 +02:00
feat(api-key): Add delete functionality
This commit is contained in:
parent
dace44f1d9
commit
9605fafe54
@ -61,7 +61,8 @@
|
|||||||
"deleted": "Report has been deleted!"
|
"deleted": "Report has been deleted!"
|
||||||
},
|
},
|
||||||
"apiKey": {
|
"apiKey": {
|
||||||
"keyCopied": "API key has been copied to your clipboard!"
|
"keyCopied": "API key has been copied to your clipboard!",
|
||||||
|
"deleted": "API key has been deleted!"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
|
@ -31,5 +31,12 @@
|
|||||||
"emptyState": {
|
"emptyState": {
|
||||||
"title": "Welcome to your API Keys",
|
"title": "Welcome to your API Keys",
|
||||||
"description": "Create an API Key to get started with the API."
|
"description": "Create an API Key to get started with the API."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"delete": {
|
||||||
|
"label": "Delete API Key",
|
||||||
|
"description": "Are you sure you want to delete this API Key? Your existing integrations using this API Key will stop working. You can create a new API Key to replace it.",
|
||||||
|
"continueActionLabel": "Delete API Key"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {client} from "~/constants/axios-client"
|
import {client} from "~/constants/axios-client"
|
||||||
|
import {SimpleDetailResponse} from "~/server-types"
|
||||||
|
|
||||||
export default async function deleteApiKey(id: string): Promise<void> {
|
export default async function deleteAPIKey(id: string): Promise<SimpleDetailResponse> {
|
||||||
const {data} = await client.delete(`${import.meta.env.VITE_SERVER_BASE_URL}/v1/api-key/${id}`, {
|
const {data} = await client.delete(`${import.meta.env.VITE_SERVER_BASE_URL}/v1/api-key/${id}`, {
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
})
|
})
|
||||||
|
@ -25,6 +25,8 @@ export interface DeleteAPIButtonProps {
|
|||||||
description?: string
|
description?: string
|
||||||
successMessage?: string
|
successMessage?: string
|
||||||
navigateTo?: string
|
navigateTo?: string
|
||||||
|
children?: (onDelete: () => void) => ReactElement
|
||||||
|
onDone?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DeleteAPIButton({
|
export default function DeleteAPIButton({
|
||||||
@ -33,7 +35,9 @@ export default function DeleteAPIButton({
|
|||||||
label,
|
label,
|
||||||
continueLabel,
|
continueLabel,
|
||||||
description,
|
description,
|
||||||
navigateTo = "/aliases",
|
navigateTo,
|
||||||
|
onDone,
|
||||||
|
children: render,
|
||||||
}: DeleteAPIButtonProps): ReactElement {
|
}: DeleteAPIButtonProps): ReactElement {
|
||||||
const {t} = useTranslation("common")
|
const {t} = useTranslation("common")
|
||||||
const {showError, showSuccess} = useErrorSuccessSnacks()
|
const {showError, showSuccess} = useErrorSuccessSnacks()
|
||||||
@ -43,7 +47,12 @@ export default function DeleteAPIButton({
|
|||||||
onError: showError,
|
onError: showError,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
showSuccess(successMessage || t("messages.deletedObject"))
|
showSuccess(successMessage || t("messages.deletedObject"))
|
||||||
navigate(navigateTo)
|
|
||||||
|
if (navigateTo) {
|
||||||
|
navigate(navigateTo)
|
||||||
|
} else if (onDone) {
|
||||||
|
onDone()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -51,15 +60,19 @@ export default function DeleteAPIButton({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
{render ? (
|
||||||
variant="outlined"
|
render(() => setShowDeleteDialog(true))
|
||||||
color="error"
|
) : (
|
||||||
size="small"
|
<Button
|
||||||
startIcon={<MdDelete />}
|
variant="outlined"
|
||||||
onClick={() => setShowDeleteDialog(true)}
|
color="error"
|
||||||
>
|
size="small"
|
||||||
{label}
|
startIcon={<MdDelete />}
|
||||||
</Button>
|
onClick={() => setShowDeleteDialog(true)}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
<Dialog open={showDeleteDialog} onClose={() => setShowDeleteDialog(false)}>
|
<Dialog open={showDeleteDialog} onClose={() => setShowDeleteDialog(false)}>
|
||||||
<DialogTitle>{label}</DialogTitle>
|
<DialogTitle>{label}</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
|
@ -4,14 +4,21 @@ import {Alert, IconButton, ListItem, ListItemSecondaryAction, ListItemText} from
|
|||||||
import {useTranslation} from "react-i18next"
|
import {useTranslation} from "react-i18next"
|
||||||
import {MdContentCopy, MdDelete} from "react-icons/md"
|
import {MdContentCopy, MdDelete} from "react-icons/md"
|
||||||
import {useCopyToClipboard} from "react-use"
|
import {useCopyToClipboard} from "react-use"
|
||||||
import {ErrorSnack, SuccessSnack} from "~/components"
|
import {DeleteButton, ErrorSnack, SuccessSnack} from "~/components"
|
||||||
|
import {deleteAPIKey} from "~/apis"
|
||||||
|
import {queryClient} from "~/constants/react-query"
|
||||||
|
|
||||||
export interface APIKeyListItemProps {
|
export interface APIKeyListItemProps {
|
||||||
apiKey: APIKey
|
apiKey: APIKey
|
||||||
|
queryKey: readonly string[]
|
||||||
privateKey?: string
|
privateKey?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function APIKeyListItem({apiKey, privateKey}: APIKeyListItemProps): ReactElement {
|
export default function APIKeyListItem({
|
||||||
|
queryKey,
|
||||||
|
apiKey,
|
||||||
|
privateKey,
|
||||||
|
}: APIKeyListItemProps): ReactElement {
|
||||||
const {t} = useTranslation(["settings-api-keys", "common"])
|
const {t} = useTranslation(["settings-api-keys", "common"])
|
||||||
|
|
||||||
const [{value, error}, copy] = useCopyToClipboard()
|
const [{value, error}, copy] = useCopyToClipboard()
|
||||||
@ -43,9 +50,24 @@ export default function APIKeyListItem({apiKey, privateKey}: APIKeyListItemProps
|
|||||||
<>
|
<>
|
||||||
<ListItemText primary={apiKey.label} secondary={apiKey.expiresAt.toString()} />
|
<ListItemText primary={apiKey.label} secondary={apiKey.expiresAt.toString()} />
|
||||||
<ListItemSecondaryAction>
|
<ListItemSecondaryAction>
|
||||||
<IconButton edge="end">
|
<DeleteButton
|
||||||
<MdDelete />
|
onDelete={() => deleteAPIKey(apiKey.id)}
|
||||||
</IconButton>
|
onDone={() =>
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
label={t("actions.delete.label")}
|
||||||
|
description={t("actions.delete.description")}
|
||||||
|
continueLabel={t("actions.delete.continueActionLabel")}
|
||||||
|
successMessage={t("messages.apiKey.deleted", {ns: "common"})}
|
||||||
|
>
|
||||||
|
{onDelete => (
|
||||||
|
<IconButton edge="end" onClick={onDelete}>
|
||||||
|
<MdDelete />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</DeleteButton>
|
||||||
</ListItemSecondaryAction>
|
</ListItemSecondaryAction>
|
||||||
</>
|
</>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user